Overview
This document shows a workflow to use the S&D API to
- Create orders in Gravitate
- View existing orders in Gravitate
- Update an order status in Gravitate
- Save a BOL
- Save a drop
Pre-Requirements
A consultant will set up a client_id and client_secret for your integration. Store these values in a secure place; you will need them to authenticate.
Step 1: Authenticating with the API
To refer to the official documentation please navigate to:
https://docs.gravitate.energy/docs/api/supply-dispatch-public-api
To acquire a token from our API, you must provide the following parameters in your request:
- Client ID
- Client Secret
Example python implementation:
Parameters
| Name | Type | Description |
|---|---|---|
client_id | String | The client_id for authentication. |
client_secret | String | The client_secret for authentication. |
scope | String | The scope of the access token (e.g., "bbd"). |
Request
- HTTP Method: POST
- URL:
{base_url}/v1/token
Response
-
Success Response (200 OK)
jsonCopy code
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
// Other JWT claims...
}access_token(String): The access token (JWT) issued upon successful authentication.- Error Response
- 401 Unauthorized: If the provided credentials are invalid or if the user is not authorized.
Example python implementation:
def get_token(client_id:str, client_secret:str, scope:str = 'bbd') -> str | None:
r = requests.post(
f"{self.url}/api/token",
data={
"client_id": client_id,
"client_secret": client_secret,
"scope": scope,
},
)
if r.ok:
return r.json()["access_token"]
except requests.exceptions.HTTPError as http_err:
logging.error(f"HTTP error occurred: {http_err}")
except Exception as err:
logging.error(f"An error occurred: {err}")
return None
Step 2: Creating a new order
To refer to the official documentation, see https://docs.gravitate.energy/docs/api/order-create-ep-v-1-order-create-post
Request:
HTTP Method: POST
URL: {base_url}/v1/order/create
Parameters
| Name | Type | Description | Required? |
|---|---|---|---|
reference_order_number | String | This is the external order number attached to the order, which can be used as a reference for an outside system. | Yes |
delivery_window | DeliveryWindow | This specifies the delivery window for the order, with a default timezone of UTC. This parameter is an object with the fields described below. | Yes |
delivery_window.start | Datetime | The start time of the delivery window | Yes |
delivery_window.end | Datetime | The end time of the delivery window | Yes |
delivery_window.timezone | String or None | The timezone for the delivery window. Defaults to UTC. | No |
drops | Array of Drops | The list of drops to be made on this order. One drop is one product dropped into one tank at one site. This parameter is an array of objects with the fields described below | Yes |
supply_owner | Counterparty | The supply owner to pull the supply options from. If left blank the system defaults to the supply owner of the first drop site. See Matching a Counterparty. | No |
sourcing_strategy | String | Defines the strategy for how the order is sourced. May be one of “Specific Supply”, “Tank Supply Default”, “Use Best”, or “Manual”. If left blank the system will use the supply owner’s default strategy. | No |
manual_supply_fallback | Boolean | True if a manual request should be submitted when the order can’t be automatically sourced. | No |
allow_alternate_products | Boolean | True if alternate products can be used as substitutes for the requested products. | No |
note | String | An optional note to be included with the order. | No |
Drop Parameters
These are the parameters for a Drop object
| Name | Type | Description | Required? |
|---|---|---|---|
site | Site | The site identifier for the drop request. See the section Matching a site. | Yes |
tank_id | String or None | Identifies the tank for the drop. If this is left blank then the drop will default to the first tank that contains the requested product at that site. | No |
product | Product | The product to be delivered to that site. This will be validated against the product in the specified tank_id, if specified. See the section Matching a product. | Yes |
volume | Integer | The requested volume of product to be delivered. If the volume cannot be autofit into a trailer the order will fail to supply. | Yes |
loads | Array of Loads | The supply parameters to be used to load a requested product. The documentation has more details on how to select loads. If this is left blank then the system will assume any load is acceptable to fulfill the order. See the section Loads | No |
Matching a site
There are three ways that a site can be matched, and the site parameter has 4 fields to enable any of those three ways. These methods are:
- Source ID and Source System
- ID in Gravitate
- Number in Gravitate
When setting the site parameter you can pass in an object with only the key(s) that you want to use. If you pass in multiple keys, they will be used in the priority they were listed above. At least one of these fields must be set, although all are individually optional.
| Name | Type | Description |
|---|---|---|
id | String | The Site ID in Gravitate. |
number | String | The Site Number in Gravitate |
source_system | String | The name of the external system this site is integrated from. Must be set with source_id. |
source_id | String | The unique identifier of this site in source_system. Must be set with source_system. |
Matching a Product
Like sites, there are three ways that a product can be matched, and the product parameter has 4 fields to enable any of those three ways.
- Source ID and Source System
- ID in Gravitate
- Name in Gravitate
When you set the product parameter you can pass in an object with only the key(s) that you want to use. If you pass in multiple keys, they will be used in the priority they were listed above. At least one of those fields must be set, although all are individually optional.
| Name | Type | Description |
|---|---|---|
id | String | The product ID in Gravitate |
name | String | The product name in Gravitate |
source_system | String | The name of the external system this product is integrated from. Must be set with source_id. |
source_id | String | The unique identifier of this product in source_system. Must be set with source_system. |
Matching a Counterparty
Like sites, there are three ways that a counterparty can be matched, and the counterparty parameter has 4 fields to enable any of those three ways.
- Source ID and Source System
- ID in Gravitate
- Name in Gravitate
When you set the counterparty parameter you can pass in an object with only the key(s) that you want to use. If you pass in multiple keys, they will be used in the priority they were listed above. At least one of those fields must be set, although all are individually optional.
| Name | Type | Description |
|---|---|---|
id | String | The product ID in Gravitate |
name | String | The product name in Gravitate |
source_system | String | The name of the external system this product is integrated from. Must be set with source_id. |
source_id | String | The unique identifier of this product in source_system. Must be set with source_system. |
Loads
Loads can be used to specify a supply for the product.T he supply parameters are treated as filters to the pool of available supply options. If a parameter is left unfilled the system will assume that any value is acceptable for that parameter. For example sending a terminal with no supplier will allow any supplier to be used at the specified terminal. See the original documentation page for information about creating blends. All of the following fields are optional.
| Name | Type | Description |
|---|---|---|
terminal | String | The terminal ID to be used for the supply option. |
product | Product | The product to use for supply option. This should only be set when creating blends. See Matching a Product. |
supplier | Counterparty | The supplier to be used for the supply option. If not set the system will default to the supplier with the most available supply options. See Matching a Counterparty. |
price_type | String | May be either “contract” or “rack” |
Minimal Sample Request
POST {base_url}/v1/get_orders
Authorization: Bearer {access_token}
Content-Type: application/json
{
"reference_order_number": "ORDER1000",
"delivery_window": {
"start": "2024-08-27T08:00:00",
"end": "2024-08-28T08:00:00",
"timezone": "US/Eastern",
},
"note": "Extra instructions: pull around using the west entrance.",
"drops": [
{
"site": {
"id": "SITE01",
},
"tank_id": "3",
"product": {
"name": "REG E10",
},
"volume": 8100,
}
]
}
Response
A successful response will show the status, order number, and order object that was created.
{
"status": "Order Successfully Created",
"order_number": 0,
"order": {...}
}
Step 3: Retrieving an Order using get_orders
You can retrieve an order using the {base_url}/v1/order/get_orders endpoint.
HTTP Method: POST
URL: {base_url}/v1/order/get_orders
Parameters
All parameters are optional. Any can be used to search orders
| Name | Type | Description |
|---|---|---|
order_id | String | The internal order ID. If provided the endpoint will return the single order with this ID, if one exists. |
order_number | String | Unique number for the order. If provided the endpoint will return the single order with this number. This is the order number reported in the 200 response for the order creation endpoint. |
type | String | Filters returned orders to only include orders of the specified type. May be either “Regular” or “Backhaul” |
state | String | Filter orders to include only those in the specified state. May be either “Accepted”, “Assigned”, “In Progress”, “Complete”, or “Canceled”. |
last_change_date | Datetime | Filters returned orders to include only those changed after the provided date. |
Sample Request
{
"order_id": "string",
"order_number": 0,
"type": "string",
"state": "canceled",
"last_change_date": "2024-08-27T20:21:14.317Z"
}
Response
An order object or list of order objects is returned.
Step 4: Update order status
This endpoint allows you to update the status of an order.
HTTP Method: POST
URL: {base_url}/v1/order/update_status
Parameters
All parameters are required. The body is an array of BOLs to save. Each BOL has the following parameters.
| Name | Type | Description | Required? |
|---|---|---|---|
order_id | String | The internal order ID. | Yes |
order_number | String | The order number provided by the create_order endpoint. | No |
status | String | The new status to apply to the order. May be one of - “driving_to_load” - “arrived_at_load” - “loading” - “completed_load” - “driving_to_drop” - “arrived_at_drop” - “dropping” - “completed_drop” - “completed” | Yes |
location_id | String | The internal location ID | No |
eta | Datetime | The estimated drop time for the order. | No |
actual | Datetime | The actual drop time for the order. | No |
Sample Request
{
"order_id": "string",
"status": "dropping",
}
Step 5: Save BOL Endpoint
This endpoint allows you to update an order and save a BOL.
HTTP Method: POST
URL: {base_url}/v1/order/save_bol
Parameters
All parameters are required. The body is an array of BOLs to save. Each BOL has the following parameters.
| Name | Type | Description |
|---|---|---|
order_id | String | The internal order ID. |
bol_number | String | Bill-of-Lading number |
terminal_id | String | The unique identifier for the terminal associated with the BOL |
bol_date | Datetime | Timestamp of the BOL |
details | Array | An array of Details objects, described below. |
Details Parameters
| Name | Type | Description | Required? |
|---|---|---|---|
supplier_id | String | The unique ID for the supplier. | Yes |
product_id | String | The unique ID for the product. | Yes |
contract | String | The contract number | No |
price_type | String | Price type. May be “rack” or “contract”, but is not required. | No |
net_volume | float | Yes | |
gross_volume | float | Yes |
Sample Request
[
{
"order_id": "string",
"bol_number": "string",
"terminal_id": "string",
"bol_date": "2024-08-27T20:21:14.329Z",
"details": [
{
"supplier_id": "string",
"product_id": "string",
"contract": "string",
"net_volume": 0,
"gross_volume": 0,
"price_type": "rack"
}
]
}
]
Response
Returns a 200 if the BOLs were saved successfully.
Step 6: Save Drop Endpoint
This endpoint allows you to update an order and save a drop.
HTTP Method: POST
URL: {base_url}/v1/order/save_drop
Parameters
All parameters are required.
| Name | Type | Description |
|---|---|---|
order_id | String | The internal order ID. |
location_id | String | Unique ID for the location. |
mode | String | The mode to use when saving drop details. May be one of “append”, “replace” |
details | Array | An array of DropDetail objects, described below. |
DropDetail Parameters
| Name | Type | Description | Required? |
|---|---|---|---|
product_id | String | The unique ID for the product. | Yes |
quantity | float | Volume of the product dropped. | Yes |
tank_id | String | Unique ID for the tank where product was dropped. | No |
pre_drop_volume | float | Volume before the drop | No |
pre_drop_inches | float | Inches measurement before the drop | No |
pre_drop_time | Datetime | Timestamp of the measurement before the drop | No |
post_drop_volume | float | Volume after the drop | No |
post_drop_inches | float | Inches measurement after the drop | No |
Sample Request
{
"mode": "append",
"order_id": "string",
"location_id": "string",
"details": [
{
"counterparty_id": "string",
"product_id": "string",
"quantity": 0,
"tank_id": 0,
"pre_drop_time": "2024-08-27T20:21:14.329Z",
"pre_drop_volume": 0,
"pre_drop_inches": 0,
"post_drop_time": "2024-08-27T20:21:14.329Z",
"post_drop_volume": 0,
"post_drop_inches": 0
}
]
}
Response
Returns a 200 if the BOLs were saved successfully.