Skip to main content

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.

Introduction

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.

Using the API

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.

Address

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.

Authentication

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.

An example request using curl follows:

curl "https://api.getcircuit.com/public/v0.2b/plans" -u yourApiKey:

If you did everything right you should see a list of your team's plans as the response

On resource types

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.

On resource IDs

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:

On List endpoints

When using list endpoints you are able to combine a set of query options to find what you are looking for as some endpoints have filter options for that.

All the list endpoints are paginated, which means that any requests made to it can possibly return only a subset of the resources you are looking for. To navigate between the pages, Circuit API will return a field called nextPageToken on every list endpoint query which, if set, should be used in the pageToken query parameter of the request along with the previous query parameters for retrieving the next page of the resource.

As an example suppose you make the following request to list your plans:

curl "https://api.getcircuit.com/public/v0.2b/plans?filter.startsGte=2023-05-01" -u yourApiKey:

and that Circuit API returns a response with the following:

{
  // other atributes
  "nextPageToken": "I53Jr5Eu2qK9omh0iA8q"
}

To keep querying the next pages you would use the returned nextPageToken as follows:

curl "https://api.getcircuit.com/public/v0.2b/plans?filter.startsGte=2023-05-01&pageToken=I53Jr5Eu2qK9omh0iA8q" -u yourApiKey:

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.

On Update endpoints (HTTP PATCH verb)

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.

On Rate-Limiting

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. Exception is:

  • The stop creation endpoint has a rate-limit of 1 request per second, so we recommend using the batch-import endpoint instead, which has a rate-limit of 4 requests per minute, but can be used to import up to 100 stops at a time

Most read endpoints have a rate-limit of 5 requests per second.

  • As an exception all list endpoints have a rate-limit of 2 per second

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.

On the models

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.

Plans

Endpoints to operate on Plans resources.

Create a new plan

Authorizations:
HTTP: BasicAuth
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 drivers/<id>

depot
any or null

The depot id, in the format depots/<id>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "starts": {
    },
  • "drivers": [ ],
  • "depot": null
}

Response samples

Content type
application/json
{
  • "id": null,
  • "title": "string",
  • "starts": {
    },
  • "depot": { },
  • "distributed": true,
  • "writable": true,
  • "optimization": "creating",
  • "drivers": [
    ],
  • "routes": [
    ]
}

List plans

Authorizations:
HTTP: BasicAuth
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: ?filter[title]=foo or like this: ?filter.title=foo

Responses

Response samples

Content type
application/json
{
  • "plans": [
    ],
  • "nextPageToken": null
}

Update an existing plan

Authorizations:
HTTP: BasicAuth
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.

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 drivers/<id>

depot
any or null

The depot id, in the format depots/<id>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "starts": {
    },
  • "drivers": [
    ],
  • "depot": null
}

Response samples

Content type
application/json
{
  • "id": null,
  • "title": "string",
  • "starts": {
    },
  • "depot": { },
  • "distributed": true,
  • "writable": true,
  • "optimization": "creating",
  • "drivers": [
    ],
  • "routes": [
    ]
}

Retrieve a plan

Retrieve a plan

Authorizations:
HTTP: BasicAuth
path Parameters
planId
required
string^[a-zA-Z0-9---_]{1,50}$

The plan id

Responses

Response samples

Content type
application/json
{
  • "id": null,
  • "title": "string",
  • "starts": {
    },
  • "depot": { },
  • "distributed": true,
  • "writable": true,
  • "optimization": "creating",
  • "drivers": [
    ],
  • "routes": [
    ]
}

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:
HTTP: BasicAuth
path Parameters
planId
required
string^[a-zA-Z0-9---_]{1,50}$

The plan id

Responses

Response samples

Content type
application/json
null

Stops

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.

Authorizations:
HTTP: BasicAuth
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

Driver ID that should 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

packageCount
number or null [ 1 .. 100 ]

Number of packages in the stop

notes
string or null [ 1 .. 2000 ] characters

Notes for the stop

Responses

Request samples

Content type
application/json
{
  • "address": {
    },
  • "timing": {
    },
  • "recipient": {
    },
  • "orderInfo": {
    },
  • "driver": null,
  • "activity": "delivery",
  • "packageCount": 1,
  • "notes": "string"
}

Response samples

Content type
application/json
{
  • "id": null,
  • "address": {
    },
  • "driverIdentifier": null,
  • "estimatedTravelDuration": null,
  • "estimatedTravelDistance": null,
  • "notes": null,
  • "packageCount": null,
  • "type": "start",
  • "packageLabel": null,
  • "stopPosition": null,
  • "trackingLink": null,
  • "webAppLink": "string",
  • "orderInfo": {
    },
  • "placeInVehicle": {
    },
  • "recipient": {
    },
  • "activity": "delivery",
  • "deliveryInfo": {
    },
  • "plan": null,
  • "route": {
    },
  • "eta": {
    },
  • "etaNullReason": {
    },
  • "timing": {
    }
}

List stops

Authorizations:
HTTP: BasicAuth
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: ?filter[externalId]=foo or like this: ?filter.externalId=foo

Responses

Response samples

Content type
application/json
{
  • "stops": [
    ],
  • "nextPageToken": null
}

Batch import stops

Authorizations:
HTTP: BasicAuth
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.

Array ([ 1 .. 100 ] items)
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

Driver ID that should 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

packageCount
number or null [ 1 .. 100 ]

Number of packages in the stop

notes
string or null [ 1 .. 2000 ] characters

Notes for the stop

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Response samples

Content type
application/json
{
  • "success": [
    ],
  • "failed": [
    ]
}

Update an existing stop

Does not support updating a stop’s location. To do so, delete the stop and create a new one.

Authorizations:
HTTP: BasicAuth
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
activity
string or null
Default: "delivery"
Enum: "delivery" "pickup"

Activity type

packageCount
number or null [ 1 .. 100 ]
notes
string or null [ 1 .. 2000 ] characters
object or null

Responses

Request samples

Content type
application/json
{
  • "recipient": {
    },
  • "orderInfo": {
    },
  • "driver": null,
  • "activity": "delivery",
  • "packageCount": 1,
  • "notes": "string",
  • "timing": {
    }
}

Response samples

Content type
application/json
{
  • "id": null,
  • "address": {
    },
  • "driverIdentifier": null,
  • "estimatedTravelDuration": null,
  • "estimatedTravelDistance": null,
  • "notes": null,
  • "packageCount": null,
  • "type": "start",
  • "packageLabel": null,
  • "stopPosition": null,
  • "trackingLink": null,
  • "webAppLink": "string",
  • "orderInfo": {
    },
  • "placeInVehicle": {
    },
  • "recipient": {
    },
  • "activity": "delivery",
  • "deliveryInfo": {
    },
  • "plan": null,
  • "route": {
    },
  • "eta": {
    },
  • "etaNullReason": {
    },
  • "timing": {
    }
}

Retrieve a stop

Retrieve a stop

Authorizations:
HTTP: BasicAuth
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

Content type
application/json
{
  • "id": null,
  • "address": {
    },
  • "driverIdentifier": null,
  • "estimatedTravelDuration": null,
  • "estimatedTravelDistance": null,
  • "notes": null,
  • "packageCount": null,
  • "type": "start",
  • "packageLabel": null,
  • "stopPosition": null,
  • "trackingLink": null,
  • "webAppLink": "string",
  • "orderInfo": {
    },
  • "placeInVehicle": {
    },
  • "recipient": {
    },
  • "activity": "delivery",
  • "deliveryInfo": {
    },
  • "plan": null,
  • "route": {
    },
  • "eta": {
    },
  • "etaNullReason": {
    },
  • "timing": {
    }
}

Delete a stop

Delete a stop and related routes. This action cannot be undone and will delete all the releated routes as well, even if the stop is not in a writable state.

Authorizations:
HTTP: BasicAuth
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

Content type
application/json
null

Drivers

Endpoints to operate on Drivers resources.

This resource is currently read-only on the API.

List Drivers

Authorizations:
HTTP: BasicAuth
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: ?filter[active]=true or like this: ?filter.active=true

Responses

Response samples

Content type
application/json
{
  • "drivers": [
    ],
  • "nextPageToken": null
}

Retrieve a driver

Authorizations:
HTTP: BasicAuth
path Parameters
driverId
required
string^[a-zA-Z0-9---_]{1,50}$

The driver id

Responses

Response samples

Content type
application/json
{
  • "id": null,
  • "name": null,
  • "email": null,
  • "phone": null,
  • "active": true
}

Depots

Endpoints to operate on Depots resources.

This resource is currently read-only on the API.

List Depots

Authorizations:
HTTP: BasicAuth
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

Content type
application/json
{
  • "depots": [
    ],
  • "nextPageToken": null
}

Retrieve a depot

Authorizations:
HTTP: BasicAuth
path Parameters
depotId
required
string^[a-zA-Z0-9---_]{1,50}$

The depot id

Responses

Response samples

Content type
application/json
{
  • "id": null,
  • "name": "string"
}

Routes

Endpoints to operate on Routes resources.

This resource is currently read-only on the API.

Retrieve a route

Authorizations:
HTTP: BasicAuth
path Parameters
routeId
required
string^[a-zA-Z0-9---_]{1,50}$

The route id

Responses

Response samples

Content type
application/json
{
  • "id": null,
  • "title": "string",
  • "stopCount": 0,
  • "driver": { },
  • "state": {
    },
  • "plan": { }
}