Circuit API (v0.2b)
This is the documentation of the Circuit Public API HTTP endpoints. The Circuit Public API is a way for you to interact with Circuit products programmatically.
The API has a set of HTTP methods to operate on Circuit resources for a specific team.
Currently, Circuit offers no programming SDKs for interacting with the Public API, but you can implement your own interface by calling the methods documented on this page.
This section describes how the Circuit API should be used, if you whish to see example implementations take a look at the API Usage Examples page.
The base API address for this version of the API to be used before every
endpoint listed here is: https://api.getcircuit.com/public/v0.2b
Notice the https://
prefix, Circuit API will not accept plain HTTP
requests.
To use Circuit Public API endpoints you will first need to generate an API key for authenticating with our servers.
To do this you need to go to your Circuit For Teams settings page > Integrations > API, and generate a new key there.
After you have the API key you can use it in the Authorization
header with
the Basic Authentication
Schema, where the
API key you just created is the user, and the password should be empty.
Example with curl
:
curl "https://api.getcircuit.com/public/v0.2b/plans" -u yourApiKey:
If you did everything correctly you should get a list of your team's plans in response to this request.
The -u
flag adds a header to the request in the following format:
Authorization: Basic eW91ckFwaUtleToK
The value of the header is simply the given credentials with base64
encoding.
Every response from the Circuit Public API will be as JSON Objects, and every
request that has a body also needs to be in that type, and the header
Content-type: application/json
needs to present, so the server knows that the
body you are sending is valid JSON. Circuit will reject requests without that
header, so be sure to use it.
Every resource in the Circuit Public API has a unique ID. This ID is generated by Circuit and is unique for every resource per collection.
Every resource representation returned by the API will show the ID in the following format:
{
"id": "collectionName/resourceId"
}
And if the resource is on a sub-collection, it will be in the following format:
{
"id": "collectionName/resourceId/subcollectionName/subResourceId"
}
For example, a stop with ID stop1
under a plan with ID plan1
will have the
following representation on its serialized ID field:
{
"id": "plans/plan1/stops/stop1"
}
This means that if you wish to directly retrieve this stop by using a GET endpoint you can simply use this ID as follows:
curl "https://api.getcircuit.com/public/v0.2b/`serializedId`" -u yourApiKey:
For the example above this would be:
curl "https://api.getcircuit.com/public/v0.2b/plans/plan1/stops/stop1" -u yourApiKey:
When using list endpoints, you have the ability to combine various query options to locate the desired results. Some endpoints even offer specific filter options to aid in this search.
All the list endpoints employ pagination. This means that a single request might
only return a part of the entire set of resources you're aiming to retrieve. To
move through the subsequent pages, the Circuit API provides a nextPageToken
field in the response of every list endpoint query.
It's crucial to understand that when a nextPageToken
is returned, it indicates
that more data is available. For every subsequent request, this token should be
added as the pageToken
query parameter. And, importantly, all the original
query parameters used in the first request must also be included.
Here's a step-by-step example to elucidate this:
- Suppose you initiate a request to list your plans:
curl "https://api.getcircuit.com/public/v0.2b/plans?filter.startsGte=2023-05-01" -u yourApiKey:
- The Circuit API might return a response like:
{
// other attributes
"nextPageToken": "I53Jr5Eu2qK9omh0iA8q"
}
- To retrieve the next page of data, use the returned
nextPageToken
as thepageToken
query parameter, and ensure all initial query parameters remain the same:
curl "https://api.getcircuit.com/public/v0.2b/plans?filter.startsGte=2023-05-01&pageToken=I53Jr5Eu2qK9omh0iA8q" -u yourApiKey:
- Repeat step 3 for all subsequent pages, updating the
pageToken
parameter with the latestnextPageToken
value returned untilnextPageToken
isnull
in the response.
Circuit also accepts limiting the maximum number of results per page by using
the maxPageSize
query parameter, but notice that each individual endpoint has
a maximum value you can set this to.
Update methods differ from the other methods in the API in the sense that missing values in the JSON representation will not act upon the representation of the resource.
Explaining this by example: Suppose you have a Plan with the ID plan1
in your
plans' collection, and you wanted to merely update its title to My API Plan
without changing other information, such as assigned drivers or the start date.
To do this you would issue the following request:
curl -X PATCH http://localhost:5005/public/v0.2b/plans/plan1 -H 'Content-type: application/json' -d '{"title": "My API Plan"}' -u yourApiKey:
Notice how we don't pass any other information in the JSON, only the title. This
ensures that the PATCH
request will only operate on the provided parameters
and keep the other parameters as-is.
It is important to also notice that when updating an array the whole array will be replaced, Circuit API does not support partial updates on arrays.
All the endpoints in the Circuit Public API are rate-limited. This means that we will reject requests if they are coming in too fast.
To know if your request was rate-limited, just check if the response has the HTTP status code 429.
Each endpoint has a different rate-limit, and this rate-limit can be changed by Circuit at any moment.
Most write endpoints currently have a rate-limit of 5 requests per second. Exceptions are:
- The Stops and Unassigned Stops import endpoints have a rate-limit of 10 requests per minute, but can be used to import up to 100 stops at a time, this means a total of 1000 stops per minute;
- The Plan optimization and re-optimization endpoints have a rate-limit of 3 requests per minute, due to the long-running nature of these tasks.
All read endpoints have a rate-limit of 10 requests per second, including the list endpoints.
Circuit API will occasionally support bursts of requests, but this cannot be sustained and will be rejected if it goes on for too long.
When Circuit rejects your request due to exceeding the rate-limiting you will need to wait before retrying the request, we suggest you use an exponential backoff approach for this.
We also recommend, besides the exponential backoff algorithm, that you add a random delay to each attempt, to prevent a thundering herd problem.
If the client keeps on retrying rate-limited requests while being rejected with a 429 at a high rate, Circuit will keep on rejecting the requests until the rate at which requests are made is turned down.
Circuit will also limit requests if it keeps receiving requests at a high frequency at or close to the requests limit for an extended period of time, so we do support occasional burst of requests, but if this is sustained for a long period, we will rate-limit the client making these requests.
After this section you will find all the Circuit Public API endpoints available.
Every representation of resources that these endpoints create and return are documented in the Models page of the docs.
Endpoints to operate on Plans resources.
Create a new plan
Authorizations:
Request Body schema: application/json
The request body for creating a plan.
title required | string [ 1 .. 255 ] characters The title of the plan. |
required | object The date the plan starts. Does not accept dates that are too far in the future or past. |
drivers | Array of any <= 50 items Default: [] The drivers IDs of the plan, in the format |
depot | any or null The depot id, in the format |
Responses
Request samples
- Payload
{- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "drivers": [ ],
- "depot": null
}
Response samples
- 200
- 400
- 401
- 409
- 500
- default
{- "id": null,
- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "depot": { },
- "distributed": true,
- "writable": true,
- "optimization": "creating",
- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "routes": [
- null
]
}
List plans
Authorizations:
query Parameters
pageToken | string [ 1 .. 255 ] characters The page token, if any. |
maxPageSize | number [ 1 .. 10 ] Default: 10 The max page size. |
object The filter to apply to the list of plans. The filter params are passed like this: |
Responses
Response samples
- 200
- 400
- 401
- 500
- default
{- "plans": [
- {
- "id": null,
- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "depot": { },
- "distributed": true,
- "writable": true,
- "optimization": "creating",
- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "routes": [
- null
]
}
], - "nextPageToken": null
}
Update an existing plan
Update an existing plan. If the plan writable
property is false, prefer using the Live Plans API.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Request Body schema: application/json
The request body for updating a plan. All the values present in the request will update the plan value, if you wish to update only certain fields, only set them and do not set the others. Any fields not set will not be updated.
Important: Notice that the drivers
Array will be completely replaced. If a single driver is provided in the request, the plan will have all other previous drivers discarded.
title | string [ 1 .. 255 ] characters The title of the plan. |
object The date the plan starts. Does not accept dates that are too far in the future or past. | |
drivers | Array of any <= 50 items The drivers IDs of the plan, in the format |
depot | any or null The depot id, in the format |
Responses
Request samples
- Payload
{- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "drivers": [
- null
], - "depot": null
}
Response samples
- 200
- 400
- 401
- 404
- 409
- default
{- "id": null,
- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "depot": { },
- "distributed": true,
- "writable": true,
- "optimization": "creating",
- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "routes": [
- null
]
}
Retrieve a plan
Retrieve a plan
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 500
- default
{- "id": null,
- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "depot": { },
- "distributed": true,
- "writable": true,
- "optimization": "creating",
- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "routes": [
- null
]
}
Delete a plan
Delete a plan and related routes. This action cannot be undone and will delete all the releated routes as well, even if the plan is not in a writable state. As this action is not atomic, it is possible that only partial deletion occurs if the endpoint errors out with a 500. In that case it is recommended to retry the request.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Responses
Response samples
- 400
- 401
- 404
- 500
- default
{- "message": "string",
- "code": "string",
- "param": "string",
- "url": "string"
}
Optimize a plan
Optimize a plan. Returns the created operation, which can be polled for the result. Use the returned id
with the operations endpoints to poll for the result.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 409
- 500
- default
{- "id": null,
- "type": "plan_optimization",
- "done": true,
- "metadata": {
- "canceled": true,
- "startedAt": 0,
- "finishedAt": null,
- "startedBy": "dispatcher",
- "targetPlanId": null
}, - "result": {
- "numOptimizedStops": 0,
- "skippedStops": [
- {
- "id": null,
- "reason": "impossible_time_window"
}
]
}
}
Distribute a plan
Distribute a plan to its drivers. This will send then their routes.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 409
- 500
- default
{- "id": null,
- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "depot": { },
- "distributed": true,
- "writable": true,
- "optimization": "creating",
- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "routes": [
- null
]
}
Endpoints to operate on Stop resources.
For any Plans created before 2023-04-01 the stop collections and all related operations will not be available.
For any operations here you will need a Plan ID beforehand. You can retrieve an existing Plan by listing your Plans or you can create a new one.
Create a new stop
Create a new stop with the given data. Prefer using the batch import endpoint if you want to create multiple stops at once as it is more efficient and will produce better geocoding results. If the plan is not writable, this will fail, prefer using the Live Create Stop API instead.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Request Body schema: application/json
The request body for creating a stop. The only required field is address, you need to provide at least one of the fields in it. The latitude and longitude fields will override any of the other fields if they are set(and they need to be both set if any of them are). The more fields you provide the more accurate the geocoding will be.
required | object Address of the stop, at least one of the fields is required. If the latitude and longitude fields are set they will override any of the others. The addressName field is not used for geocoding and is only for display purposes. |
object or null Timing information for this stop | |
object or null Recipient information for this stop | |
object or null Order information for this stop | |
driver | any or null Deprecated. Prefer using the |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. This field is mutually exclusive with the |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" The preferred order of this stop in the optimized route. If not provided or |
packageCount | number or null [ 1 .. 10000 ] Number of packages in the stop |
notes | string or null [ 1 .. 2000 ] characters Notes for the stop |
circuitClientId | string or null [ 1 .. 100 ] characters Client ID of the retailer in Circuit Client Portal |
Responses
Request samples
- Payload
{- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "driver": null,
- "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "circuitClientId": "string"
}
Response samples
- 200
- 400
- 401
- 404
- 409
- 410
- 422
- 500
- default
{- "id": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "driverIdentifier": null,
- "allowedDriversIdentifiers": [
- "string"
], - "estimatedTravelDuration": null,
- "estimatedTravelDistance": null,
- "notes": null,
- "packageCount": null,
- "type": "start",
- "packageLabel": null,
- "stopPosition": null,
- "trackingLink": null,
- "webAppLink": "string",
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "placeInVehicle": {
- "x": "left",
- "y": "front",
- "z": "floor"
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "deliveryInfo": {
- "attempted": true,
- "attemptedAt": 0,
- "attemptedLocation": {
- "latitude": 0,
- "longitude": 0
}, - "driverProvidedInternalNotes": "string",
- "driverProvidedRecipientNotes": "string",
- "photoUrls": [
- "string"
], - "recipientProvidedNotes": "string",
- "signatureUrl": "string",
- "signeeName": "string",
- "succeeded": true,
- "state": "delivered_to_recipient"
}, - "plan": null,
- "route": {
- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}, - "eta": {
- "estimatedArrivalAt": 0,
- "estimatedLatestArrivalAt": 0,
- "estimatedEarliestArrivalAt": 0
}, - "etaNullReason": {
- "reason": "not_optimized",
- "message": "string",
- "url": "string"
}, - "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
List stops
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
query Parameters
pageToken | string [ 1 .. 255 ] characters The page token, if any. |
maxPageSize | number [ 1 .. 10 ] Default: 10 The max page size. |
object The filter to apply to the list of stops. The filter params are passed like this: |
Responses
Response samples
- 200
- 400
- 401
- 404
- 500
- default
{- "stops": [
- {
- "id": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "driverIdentifier": null,
- "allowedDriversIdentifiers": [
- "string"
], - "estimatedTravelDuration": null,
- "estimatedTravelDistance": null,
- "notes": null,
- "packageCount": null,
- "type": "start",
- "packageLabel": null,
- "stopPosition": null,
- "trackingLink": null,
- "webAppLink": "string",
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "placeInVehicle": {
- "x": "left",
- "y": "front",
- "z": "floor"
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "deliveryInfo": {
- "attempted": true,
- "attemptedAt": 0,
- "attemptedLocation": {
- "latitude": 0,
- "longitude": 0
}, - "driverProvidedInternalNotes": "string",
- "driverProvidedRecipientNotes": "string",
- "photoUrls": [
- "string"
], - "recipientProvidedNotes": "string",
- "signatureUrl": "string",
- "signeeName": "string",
- "succeeded": true,
- "state": "delivered_to_recipient"
}, - "plan": null,
- "route": {
- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}, - "eta": {
- "estimatedArrivalAt": 0,
- "estimatedLatestArrivalAt": 0,
- "estimatedEarliestArrivalAt": 0
}, - "etaNullReason": {
- "reason": "not_optimized",
- "message": "string",
- "url": "string"
}, - "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
], - "nextPageToken": null
}
Batch import stops
Batch import stops. The request body must contain an array of stops to import. If the plan is not writable, the request will fail, prefer using the Import Live Stops API instead.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Request Body schema: application/json
An array of stops to import in batch. Supports a maximum of 100 stops per request.
required | object Address of the stop, at least one of the fields is required. If the latitude and longitude fields are set they will override any of the others. The addressName field is not used for geocoding and is only for display purposes. |
object or null Timing information for this stop | |
object or null Recipient information for this stop | |
object or null Order information for this stop | |
driver | any or null Deprecated. Prefer using the |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. This field is mutually exclusive with the |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" The preferred order of this stop in the optimized route. If not provided or |
packageCount | number or null [ 1 .. 10000 ] Number of packages in the stop |
notes | string or null [ 1 .. 2000 ] characters Notes for the stop |
circuitClientId | string or null [ 1 .. 100 ] characters Client ID of the retailer in Circuit Client Portal |
Responses
Request samples
- Payload
[- {
- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "driver": null,
- "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "circuitClientId": "string"
}
]
Response samples
- 200
- 400
- 401
- 404
- 409
- 410
- 422
- 500
- default
{- "success": [
- null
], - "failed": [
- {
- "error": {
- "message": "string"
}, - "stop": {
- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}
}
}
]
}
Update an existing stop
Does not support updating a stop's location, nor the circuitClientId
. To do so, delete the stop and create a new one. If the plan is not writable, the request will fail, prefer using the Update Live Stops API instead.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
stopId required | string^[a-zA-Z0-9---_]{1,50}$ The stop id |
Request Body schema: application/json
The request body for updating a stop. All the values present in the request will update the stop value, if you wish to update only certain fields, only set them and do not set the others. Any fields not set will not be updated.
object or null Recipient information for this stop | |
object or null Order information for this stop | |
driver | any or null |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. This field is mutually exclusive with the |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" |
packageCount | number or null [ 1 .. 10000 ] |
notes | string or null [ 1 .. 2000 ] characters |
object or null |
Responses
Request samples
- Payload
{- "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "driver": null,
- "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}
}
Response samples
- 200
- 400
- 401
- 404
- 409
- 500
- default
{- "id": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "driverIdentifier": null,
- "allowedDriversIdentifiers": [
- "string"
], - "estimatedTravelDuration": null,
- "estimatedTravelDistance": null,
- "notes": null,
- "packageCount": null,
- "type": "start",
- "packageLabel": null,
- "stopPosition": null,
- "trackingLink": null,
- "webAppLink": "string",
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "placeInVehicle": {
- "x": "left",
- "y": "front",
- "z": "floor"
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "deliveryInfo": {
- "attempted": true,
- "attemptedAt": 0,
- "attemptedLocation": {
- "latitude": 0,
- "longitude": 0
}, - "driverProvidedInternalNotes": "string",
- "driverProvidedRecipientNotes": "string",
- "photoUrls": [
- "string"
], - "recipientProvidedNotes": "string",
- "signatureUrl": "string",
- "signeeName": "string",
- "succeeded": true,
- "state": "delivered_to_recipient"
}, - "plan": null,
- "route": {
- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}, - "eta": {
- "estimatedArrivalAt": 0,
- "estimatedLatestArrivalAt": 0,
- "estimatedEarliestArrivalAt": 0
}, - "etaNullReason": {
- "reason": "not_optimized",
- "message": "string",
- "url": "string"
}, - "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
Retrieve a stop
Retrieve a stop
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
stopId required | string^[a-zA-Z0-9---_]{1,50}$ The stop id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 500
- default
{- "id": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "driverIdentifier": null,
- "allowedDriversIdentifiers": [
- "string"
], - "estimatedTravelDuration": null,
- "estimatedTravelDistance": null,
- "notes": null,
- "packageCount": null,
- "type": "start",
- "packageLabel": null,
- "stopPosition": null,
- "trackingLink": null,
- "webAppLink": "string",
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "placeInVehicle": {
- "x": "left",
- "y": "front",
- "z": "floor"
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "deliveryInfo": {
- "attempted": true,
- "attemptedAt": 0,
- "attemptedLocation": {
- "latitude": 0,
- "longitude": 0
}, - "driverProvidedInternalNotes": "string",
- "driverProvidedRecipientNotes": "string",
- "photoUrls": [
- "string"
], - "recipientProvidedNotes": "string",
- "signatureUrl": "string",
- "signeeName": "string",
- "succeeded": true,
- "state": "delivered_to_recipient"
}, - "plan": null,
- "route": {
- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}, - "eta": {
- "estimatedArrivalAt": 0,
- "estimatedLatestArrivalAt": 0,
- "estimatedEarliestArrivalAt": 0
}, - "etaNullReason": {
- "reason": "not_optimized",
- "message": "string",
- "url": "string"
}, - "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
Delete a stop
Delete a stop. This action cannot be undone and will delete all the data associated with the stop. If the plan is not writable, this will fail, prefer using the Live Delete Stop API instead.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
stopId required | string^[a-zA-Z0-9---_]{1,50}$ The stop id |
Responses
Response samples
- 400
- 401
- 404
- 409
- 500
- default
{- "message": "string",
- "code": "string",
- "param": "string",
- "url": "string"
}
Endpoints to operate on Unassigned Stop resources.
Retrieve an unassigned stop
Retrieve an unassigned stop
Authorizations:
path Parameters
unassignedStopId required | string^[a-zA-Z0-9---_]{1,50}$ The unassigned stop id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 500
- default
{- "id": null,
- "depot": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "allowedDriversIdentifiers": [
- "string"
], - "notes": null,
- "packageCount": null,
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
Delete an unassigned stop
Delete an unassigned stop. This action cannot be undone and will delete all the data associated with the unassigned stop.
Authorizations:
path Parameters
unassignedStopId required | string^[a-zA-Z0-9---_]{1,50}$ The unassigned stop id |
Responses
Response samples
- 400
- 401
- 404
- 500
- default
{- "message": "string",
- "code": "string",
- "param": "string",
- "url": "string"
}
Update an existing unassigned stop
Does not support updating a unassigned stop's location, nor the circuitClientId
. To do so, delete the unassignedStop and create a new one.
Authorizations:
path Parameters
unassignedStopId required | string^[a-zA-Z0-9---_]{1,50}$ The unassigned stop id |
Request Body schema: application/json
The request body for updating an unassigned stop. All the values present in the request will update the unassigned stop value. If you wish to update only certain fields, only set those and do not set the others. Any fields not set will not be updated.
object or null Recipient information for this stop | |
object or null Order information for this stop | |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" |
packageCount | number or null [ 1 .. 10000 ] |
notes | string or null [ 1 .. 2000 ] characters |
object or null | |
depot | any or null |
Responses
Request samples
- Payload
{- "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "depot": null
}
Response samples
- 200
- 400
- 401
- 404
- 500
- default
{- "id": null,
- "depot": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "allowedDriversIdentifiers": [
- "string"
], - "notes": null,
- "packageCount": null,
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
List unassigned stops
Authorizations:
query Parameters
pageToken | string [ 1 .. 255 ] characters The page token to continue from. |
maxPageSize | number [ 1 .. 20 ] Default: 20 The maximum number of unassigned stops to return per page. |
object The filter to apply to the list of unassigned stops. |
Responses
Response samples
- 200
- 400
- 401
- 500
{- "unassignedStops": [
- {
- "id": null,
- "depot": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "allowedDriversIdentifiers": [
- "string"
], - "notes": null,
- "packageCount": null,
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
], - "nextPageToken": null
}
Create a new unassigned stop
Create a new unassigned stop with the given data.
Authorizations:
Request Body schema: application/json
The request body for creating an unassigned stop. Address is a required field, you need to provide at least one of the fields in it. The latitude and longitude fields will override any of the other fields if they are set (and they need to be both set if any of them are). The more fields you provide the more accurate the geocoding will be. The depotId field is not required, but will default to the main depot of the team if not provided, be sure to provide it if you want to use a different depot.
required | object Address of the stop, at least one of the fields is required. If the latitude and longitude fields are set they will override any of the others. The addressName field is not used for geocoding and is only for display purposes. |
depot | any or null The Depot ID that this unassigned stop belongs to, in the format |
object or null Timing information for this stop | |
object or null Recipient information for this stop | |
object or null Order information for this stop | |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" The preferred order of this stop in the optimized route. If not provided or |
packageCount | number or null [ 1 .. 10000 ] Number of packages in the stop |
notes | string or null [ 1 .. 2000 ] characters Notes for the stop |
circuitClientId | string or null [ 1 .. 100 ] characters Client ID of the retailer in Circuit Client Portal |
Responses
Request samples
- Payload
{- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "depot": null,
- "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "circuitClientId": "string"
}
Response samples
- 200
- 400
- 401
- 404
- 422
- 500
- default
{- "id": null,
- "depot": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "allowedDriversIdentifiers": [
- "string"
], - "notes": null,
- "packageCount": null,
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
Batch import unassigned stops
Batch import unassigned stops. The request body must contain an array of unassigned stops to import. Note that the depot
is the same for all unassigned stops in a same request. This is because the depot is used as a biasing location for the unassigned stops, so that the geocoding results are more accurate for a same region.
Authorizations:
Request Body schema: application/json
required | Array of objects [ 1 .. 100 ] items An array of unassigned stops to import in batch. Supports a maximum of 100 unassigned stops per request. Note that the |
depot | any or null The Depot ID the unassigned stops in the batch belong to, in the format |
Responses
Request samples
- Payload
{- "unassignedStops": [
- {
- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "circuitClientId": "string"
}
], - "depot": null
}
Response samples
- 200
- 400
- 401
- 404
- 422
- 500
- default
{- "success": [
- null
], - "failed": [
- {
- "error": {
- "message": "string"
}, - "unassignedStop": {
- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}
}
}
]
}
Endpoints to operate on Plans resources when it's pending re-optimization and re-distribution.
You must use these endpoints to apply the changes when any Live Stops request returns pending = true
.
Re-optimize a plan
Re-optimize a plan. This endpoint should be used only after updating a live plan. Returns the created operation, which can be polled for the result. Use the returned id
with the operations endpoints to poll for the result.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Request Body schema: application/json
The request body for reoptimize a plan.
optimizationType | string Default: "reorder_changed_stops" Enum: "reorder_changed_stops" "reorder_all_stops" "redistribute_stops_between_drivers" The type of optimization to use |
Responses
Request samples
- Payload
{- "optimizationType": "reorder_changed_stops"
}
Response samples
- 200
- 400
- 401
- 404
- 409
- 500
- default
{- "id": null,
- "type": "plan_optimization",
- "done": true,
- "metadata": {
- "canceled": true,
- "startedAt": 0,
- "finishedAt": null,
- "startedBy": "dispatcher",
- "targetPlanId": null
}, - "result": {
- "numOptimizedStops": 0,
- "skippedStops": [
- {
- "id": null,
- "reason": "impossible_time_window"
}
]
}
}
Re-distribute a plan
Re-distribute a plan to its drivers. This endpoint should be used only after updating a live plan. This will apply the re-optimization changes and send the drivers their routes.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 409
- 500
- default
{- "id": null,
- "title": "string",
- "starts": {
- "day": 1,
- "month": 1,
- "year": 0
}, - "depot": { },
- "distributed": true,
- "writable": true,
- "optimization": "creating",
- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "routes": [
- null
]
}
Save the plan changes
Save the plan changes after re-optimization without distributing it. This endpoint is optional since re-distribute already saves the changes.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Responses
Response samples
- 400
- 401
- 404
- 409
- 500
- default
{- "message": "string",
- "code": "string",
- "param": "string",
- "url": "string"
}
Endpoints to operate on Stop resources when the plan is already optimized and therefore not writable.
All the endpoints return the field pending
. This field indicates whether the
change has been applied to the plan or if it's pending a new optimization and distribution. On pending = true
,
you must use the re-optimize and re-distribute
endpoints to apply the changes to the plan.
Create a new stop
Create a new stop with the given data on live plans. When the plan is not writable, this endpoint starts an editing session and the action can be applied through a new optimization, or be discarded. Prefer using the batch import endpoint if you want to create multiple stops at once as it is more efficient and will produce better geocoding results.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Request Body schema: application/json
The request body for creating a stop. The only required field is address, you need to provide at least one of the fields in it. The latitude and longitude fields will override any of the other fields if they are set(and they need to be both set if any of them are). The more fields you provide the more accurate the geocoding will be.
required | object Address of the stop, at least one of the fields is required. If the latitude and longitude fields are set they will override any of the others. The addressName field is not used for geocoding and is only for display purposes. |
object or null Timing information for this stop | |
object or null Recipient information for this stop | |
object or null Order information for this stop | |
driver | any or null Deprecated. Prefer using the |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. This field is mutually exclusive with the |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" The preferred order of this stop in the optimized route. If not provided or |
packageCount | number or null [ 1 .. 10000 ] Number of packages in the stop |
notes | string or null [ 1 .. 2000 ] characters Notes for the stop |
circuitClientId | string or null [ 1 .. 100 ] characters Client ID of the retailer in Circuit Client Portal |
Responses
Request samples
- Payload
{- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "driver": null,
- "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "circuitClientId": "string"
}
Response samples
- 200
- 400
- 401
- 404
- 409
- 410
- 422
- 500
- default
{- "pending": true,
- "stop": {
- "id": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "driverIdentifier": null,
- "allowedDriversIdentifiers": [
- "string"
], - "estimatedTravelDuration": null,
- "estimatedTravelDistance": null,
- "notes": null,
- "packageCount": null,
- "type": "start",
- "packageLabel": null,
- "stopPosition": null,
- "trackingLink": null,
- "webAppLink": "string",
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "placeInVehicle": {
- "x": "left",
- "y": "front",
- "z": "floor"
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "deliveryInfo": {
- "attempted": true,
- "attemptedAt": 0,
- "attemptedLocation": {
- "latitude": 0,
- "longitude": 0
}, - "driverProvidedInternalNotes": "string",
- "driverProvidedRecipientNotes": "string",
- "photoUrls": [
- "string"
], - "recipientProvidedNotes": "string",
- "signatureUrl": "string",
- "signeeName": "string",
- "succeeded": true,
- "state": "delivered_to_recipient"
}, - "plan": null,
- "route": {
- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}, - "eta": {
- "estimatedArrivalAt": 0,
- "estimatedLatestArrivalAt": 0,
- "estimatedEarliestArrivalAt": 0
}, - "etaNullReason": {
- "reason": "not_optimized",
- "message": "string",
- "url": "string"
}, - "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
}
Update an existing stop
Update a stop on live plans. When the plan is not writable, this endpoint starts an editing session and the action can be applied through a new optimization, or be discarded. It does not support updating a stop's location. To do so, delete the stop and create a new one.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
stopId required | string^[a-zA-Z0-9---_]{1,50}$ The stop id |
Request Body schema: application/json
The request body for updating a stop. All the values present in the request will update the stop value, if you wish to update only certain fields, only set them and do not set the others. Any fields not set will not be updated.
object or null Recipient information for this stop | |
object or null Order information for this stop | |
driver | any or null |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. This field is mutually exclusive with the |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" |
packageCount | number or null [ 1 .. 10000 ] |
notes | string or null [ 1 .. 2000 ] characters |
object or null |
Responses
Request samples
- Payload
{- "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "driver": null,
- "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}
}
Response samples
- 200
- 400
- 401
- 404
- 409
- 422
- 500
- default
{- "pending": true,
- "stop": {
- "id": null,
- "address": {
- "address": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "latitude": -90,
- "longitude": -180,
- "placeId": null,
- "placeTypes": [
- "string"
]
}, - "driverIdentifier": null,
- "allowedDriversIdentifiers": [
- "string"
], - "estimatedTravelDuration": null,
- "estimatedTravelDistance": null,
- "notes": null,
- "packageCount": null,
- "type": "start",
- "packageLabel": null,
- "stopPosition": null,
- "trackingLink": null,
- "webAppLink": "string",
- "orderInfo": {
- "products": [
- "string"
], - "sellerName": null,
- "sellerOrderId": null,
- "sellerWebsite": null
}, - "placeInVehicle": {
- "x": "left",
- "y": "front",
- "z": "floor"
}, - "recipient": {
- "name": null,
- "email": null,
- "phone": null,
- "externalId": null
}, - "activity": "delivery",
- "deliveryInfo": {
- "attempted": true,
- "attemptedAt": 0,
- "attemptedLocation": {
- "latitude": 0,
- "longitude": 0
}, - "driverProvidedInternalNotes": "string",
- "driverProvidedRecipientNotes": "string",
- "photoUrls": [
- "string"
], - "recipientProvidedNotes": "string",
- "signatureUrl": "string",
- "signeeName": "string",
- "succeeded": true,
- "state": "delivered_to_recipient"
}, - "plan": null,
- "route": {
- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}, - "eta": {
- "estimatedArrivalAt": 0,
- "estimatedLatestArrivalAt": 0,
- "estimatedEarliestArrivalAt": 0
}, - "etaNullReason": {
- "reason": "not_optimized",
- "message": "string",
- "url": "string"
}, - "timing": {
- "estimatedAttemptDuration": null,
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}
}, - "optimizationOrder": "first",
- "circuitClientId": null
}
}
Batch import stops
Import stops to live plans. When the plan is not writable, this endpoint starts an editing session and the action can be applied through a new optimization, or be discarded.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
Request Body schema: application/json
An array of stops to import in batch. Supports a maximum of 100 stops per request.
required | object Address of the stop, at least one of the fields is required. If the latitude and longitude fields are set they will override any of the others. The addressName field is not used for geocoding and is only for display purposes. |
object or null Timing information for this stop | |
object or null Recipient information for this stop | |
object or null Order information for this stop | |
driver | any or null Deprecated. Prefer using the |
allowedDrivers | Array of any or null <= 100 items Driver IDs that are allowed to be assigned to this stop. If not provided, the stop will be assigned to any available driver during optimization. This field is mutually exclusive with the |
activity | string or null Default: "delivery" Enum: "delivery" "pickup" Activity type |
optimizationOrder | string or null Enum: "first" "last" "default" The preferred order of this stop in the optimized route. If not provided or |
packageCount | number or null [ 1 .. 10000 ] Number of packages in the stop |
notes | string or null [ 1 .. 2000 ] characters Notes for the stop |
circuitClientId | string or null [ 1 .. 100 ] characters Client ID of the retailer in Circuit Client Portal |
Responses
Request samples
- Payload
[- {
- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "timing": {
- "earliestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "latestAttemptTime": {
- "hour": 23,
- "minute": 59
}, - "estimatedAttemptDuration": 1
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}, - "orderInfo": {
- "products": [
- "string"
], - "sellerOrderId": "string",
- "sellerName": "string",
- "sellerWebsite": "string"
}, - "driver": null,
- "allowedDrivers": [
- null
], - "activity": "delivery",
- "optimizationOrder": "first",
- "packageCount": 1,
- "notes": "string",
- "circuitClientId": "string"
}
]
Response samples
- 200
- 400
- 401
- 404
- 409
- 410
- 422
- 500
- default
{- "success": [
- null
], - "failed": [
- {
- "error": {
- "message": "string"
}, - "stop": {
- "address": {
- "addressName": "string",
- "addressLineOne": "string",
- "addressLineTwo": "string",
- "city": "string",
- "state": "string",
- "zip": "string",
- "country": "string",
- "latitude": -90,
- "longitude": -180
}, - "recipient": {
- "externalId": "string",
- "email": "string",
- "phone": "string",
- "name": "string"
}
}
}
], - "pending": true
}
Delete a stop
Delete a stop on live plans. When the plan is not writable, this endpoint starts an editing session and the action can be applied through a new optimization, or be discarded.
Authorizations:
path Parameters
planId required | string^[a-zA-Z0-9---_]{1,50}$ The plan id |
stopId required | string^[a-zA-Z0-9---_]{1,50}$ The stop id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 409
- 422
- 500
- default
{- "pending": true
}
Endpoints to operate on Drivers resources.
This resource is currently read-only on the API.
List Drivers
Authorizations:
query Parameters
maxPageSize | number [ 1 .. 50 ] Default: 50 The maximum number of drivers to return. |
pageToken | string [ 1 .. 255 ] characters The page token to continue from. |
object The filter to apply to the list of drivers. The filter param is passed like this: |
Responses
Response samples
- 200
- 400
- 401
- 500
- default
{- "drivers": [
- {
- "id": null,
- "name": null,
- "email": null,
- "phone": null,
- "displayName": null,
- "active": true
}
], - "nextPageToken": null
}
Endpoints to operate on Depots resources.
This resource is currently read-only on the API.
List Depots
Authorizations:
query Parameters
pageToken | string [ 1 .. 255 ] characters The page token to continue from. |
maxPageSize | number [ 1 .. 20 ] Default: 20 The maximum number of depots to return. |
Responses
Response samples
- 200
- 400
- 401
- 500
- default
{- "depots": [
- {
- "id": null,
- "name": "string"
}
], - "nextPageToken": null
}
Endpoints to operate on Routes resources.
This resource is currently read-only on the API.
Retrieve a route
Authorizations:
path Parameters
routeId required | string^[a-zA-Z0-9---_]{1,50}$ The route id |
Responses
Response samples
- 200
- 400
- 401
- 404
- 500
- default
{- "id": null,
- "title": "string",
- "stopCount": 0,
- "driver": { },
- "state": {
- "completed": true,
- "completedAt": 0,
- "distributed": true,
- "distributedAt": 0,
- "notifiedRecipients": true,
- "notifiedRecipientsAt": 0,
- "started": true,
- "startedAt": 0
}, - "plan": { }
}
Endpoints to operate on Operations resources.
Cancel an operation
Cancel an operation that is not yet done.
Authorizations:
path Parameters
operationId required | string^[a-zA-Z0-9---_]{1,50}$ The ID of the operation to cancel. |
Responses
Response samples
- 200
- 400
- 401
- 404
- 409
- 500
{- "id": null,
- "type": "plan_optimization",
- "done": true,
- "metadata": {
- "canceled": true,
- "startedAt": 0,
- "finishedAt": null,
- "startedBy": "dispatcher",
- "targetPlanId": null
}, - "result": {
- "numOptimizedStops": 0,
- "skippedStops": [
- {
- "id": null,
- "reason": "impossible_time_window"
}
]
}
}
Retrieve an operation
Authorizations:
path Parameters
operationId required | string^[a-zA-Z0-9---_]{1,50}$ The ID of the operation to cancel. |
Responses
Response samples
- 200
- 400
- 401
- 404
- 500
{- "id": null,
- "type": "plan_optimization",
- "done": true,
- "metadata": {
- "canceled": true,
- "startedAt": 0,
- "finishedAt": null,
- "startedBy": "dispatcher",
- "targetPlanId": null
}, - "result": {
- "numOptimizedStops": 0,
- "skippedStops": [
- {
- "id": null,
- "reason": "impossible_time_window"
}
]
}
}
List operations
Authorizations:
query Parameters
pageToken | string [ 1 .. 255 ] characters The page token to continue from. |
maxPageSize | number [ 1 .. 20 ] Default: 20 The maximum number of operations to return per page. |
object The filter to apply to the list of operations. |
Responses
Response samples
- 200
- 400
- 401
- 500
{- "operations": [
- {
- "id": null,
- "type": "plan_optimization",
- "done": true,
- "metadata": {
- "canceled": true,
- "startedAt": 0,
- "finishedAt": null,
- "startedBy": "dispatcher",
- "targetPlanId": null
}, - "result": {
- "numOptimizedStops": 0,
- "skippedStops": [
- {
- "id": null,
- "reason": "impossible_time_window"
}
]
}
}
], - "nextPageToken": null
}