Circuit Live Stops API

Endpoints to operate on [Stop](/docs/models/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](#tag/Live-Plans/operation/reoptimizePlan) and [re-distribute](#tag/Live-Plans/operation/redistributePlan) endpoints to apply the changes to the plan.

OpenAPI Specification

circuit-live-stops-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Spoke Depots Live Stops API
  description: "This is the documentation of the Spoke Public API HTTP endpoints. The Spoke\nPublic API is a way for you to interact with Spoke products programmatically.\n\n# Introduction\n\nThe API has a set of HTTP methods to operate on Spoke resources for a specific\nteam.\n\nCurrently, Spoke offers no programming SDKs for interacting with the Public\nAPI, but you can implement your own interface by calling the methods documented\non this page.\n\n# Using the API\n\nThis section describes how the Spoke API should be used, if you wish to see\nexample implementations take a look at the [API Usage\nExamples](/docs/api-examples) page.\n\n## Address\n\nThe base API address for this version of the API to be used before every\nendpoint listed here is: `https://api.spoke.com/public/v0.2b`\n\nNotice the `https://` prefix, Spoke API will **not** accept plain HTTP\nrequests.\n\n## Authentication\n\nTo use Spoke Public API endpoints you will first need to generate an API key\nfor authenticating with our servers.\n\nTo do this you need to go to your Spoke Dispatch settings page > Integrations\n\\> API, and generate a new key there.\n\nOnce you have the API key you can use it in the `Authorization` header\neither using the Basic scheme, or as a Bearer token.\n\n### Basic Auth\n\n[Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) is the primary authentication scheme used\nby Spoke's API.\n\nBasic authentication typically uses a base64 encoded `username:password`\npair, but since we only require an API key we instead structure the payload as `[yourApiKey]:[empty]`. This\nvalue is then base64 encoded as usual.\n\nExample with `curl`:\n\n```bash\ncurl \"https://api.spoke.com/public/v0.2b/plans\" -u yourApiKey:\n```\n\nIf you did everything correctly you should see a list of your team's plans in response\nto this request.\n\nThe `-u` flag adds a header to the request in the following format:\n\n```http\nAuthorization: Basic eW91ckFwaUtleToK\n```\n\nNote that curl automatically base64 encoded the data. Other clients will do the same e.g. if using Postman you would\nconfigure the request's Authorization option instead of adding a header directly.\n\n### Bearer Token\n\nAlternatively you can pass the API key as a Bearer token without any special encoding.\ni.e. `Authorization: Bearer [yourApiKey]`.\n\nExample with `curl`:\n\n```bash\ncurl \"https://api.spoke.com/public/v0.2b/plans\" -H \"Authorization: Bearer yourApiKey\"\n```\n\n## On resource types\n\nEvery response from the Spoke Public API will be as JSON Objects, and every\nrequest that has a body also needs to be in that type, and the header\n`Content-type: application/json` needs to present, so the server knows that the\nbody you are sending is valid JSON. Spoke will reject requests without that\nheader, so be sure to use it.\n\n## On resource IDs\n\nEvery resource in the Spoke Public API has a unique ID. This ID is generated\nby Spoke and is unique for every resource per collection.\n\nEvery resource representation returned by the API will show the ID in the\nfollowing format:\n\n```json\n{\n  \"id\": \"collectionName/resourceId\"\n}\n```\n\nAnd if the resource is on a sub-collection, it will be in the following format:\n\n```json\n{\n  \"id\": \"collectionName/resourceId/subcollectionName/subResourceId\"\n}\n```\n\nFor example, a stop with ID `stop1` under a plan with ID `plan1` will have the\nfollowing representation on its serialized ID field:\n\n```json\n{\n  \"id\": \"plans/plan1/stops/stop1\"\n}\n```\n\nThis means that if you wish to directly retrieve this stop by using a GET\nendpoint you can simply use this ID as follows:\n\n```bash\ncurl \"https://api.spoke.com/public/v0.2b/`serializedId`\" -u yourApiKey:\n```\n\nFor the example above this would be:\n\n```bash\ncurl \"https://api.spoke.com/public/v0.2b/plans/plan1/stops/stop1\" -u yourApiKey:\n```\n\n## On List endpoints\n\nWhen using list endpoints, you have the ability to combine various query options\nto locate the desired results. Some endpoints even offer specific filter options\nto aid in this search.\n\nAll the list endpoints employ pagination. This means that a single request might\nonly return a part of the entire set of resources you're aiming to retrieve. To\nmove through the subsequent pages, the Spoke API provides a `nextPageToken`\nfield in the response of every list endpoint query.\n\nIt's crucial to understand that when a `nextPageToken` is returned, it indicates\nthat more data is available. For every subsequent request, this token should be\nadded as the `pageToken` query parameter. And, importantly, **all the original\nquery parameters** used in the first request must also be included.\n\nHere's a step-by-step example to elucidate this:\n\n1. Suppose you initiate a request to list your plans:\n\n```bash\ncurl \"https://api.spoke.com/public/v0.2b/plans?filter.startsGte=2023-05-01\" -u yourApiKey:\n```\n\n2. The Spoke API might return a response like:\n\n```json\n{\n  // other attributes\n  \"nextPageToken\": \"I53Jr5Eu2qK9omh0iA8q\"\n}\n```\n\n3. To retrieve the next page of data, use the returned `nextPageToken` as the\n   `pageToken` query parameter, and ensure all initial query parameters remain\n   the same:\n\n```bash\ncurl \"https://api.spoke.com/public/v0.2b/plans?filter.startsGte=2023-05-01&pageToken=I53Jr5Eu2qK9omh0iA8q\" -u yourApiKey:\n```\n\n4. Repeat step 3 for all subsequent pages, updating the `pageToken` parameter\n   with the latest `nextPageToken` value returned until `nextPageToken` is\n   `null` in the response.\n\nSpoke also accepts limiting the maximum number of results per page by using\nthe `maxPageSize` query parameter, but notice that each individual endpoint has\na maximum value you can set this to.\n\n## On Update endpoints (HTTP PATCH verb)\n\nUpdate methods differ from the other methods in the API in the sense that\nmissing values in the JSON representation will **not** act upon the\nrepresentation of the resource.\n\nExplaining this by example: Suppose you have a Plan with the ID `plan1` in your\nplans' collection, and you wanted to merely update its title to `My API Plan`\nwithout changing other information, such as assigned drivers or the start date.\nTo do this you would issue the following request:\n\n```bash\ncurl -X PATCH http://localhost:5005/public/v0.2b/plans/plan1 -H 'Content-type: application/json' -d '{\"title\": \"My API Plan\"}' -u yourApiKey:\n```\n\nNotice how we don't pass any other information in the JSON, only the title. This\nensures that the `PATCH` request will only operate on the provided parameters\nand keep the other parameters as-is.\n\nIt is important to also notice that when updating an array the whole array will\nbe replaced, Spoke API does not support partial updates on arrays.\n\n## On Rate-Limiting\n\nAll the endpoints in the Spoke Public API are rate-limited, which means we\nwill reject requests that come in too fast.\n\nTo know if your request was rate-limited, check if the response has the HTTP\nstatus code 429.\n\nEach endpoint has a different rate limit, and Spoke can change this rate\nlimit at any moment.\n\nThe rate limits are as follows:\n\n- **Rate Limits for Write Endpoints**: All write endpoints have a limit of 5\n  requests per second, which includes Creation (POST), Update (PATCH), and\n  Deletion (DELETE) operations for all models.\n  - An exception to this rule is the Driver Creation endpoint, which is limited to\n    1 request per second. Thus, we recommend using the Batch Import Drivers\n    when adding multiple drivers.\n- **Rate Limits for Read Endpoints**: All read endpoints, including list\n  endpoints, are limited to 10 requests per second.\n- **Rate Limits for Batch Import**:\n  - The _Batch Import_ endpoints for Stops and Unassigned Stops models are\n    limited to 100 requests per _10 minutes_ (with a maximum rate of 30 per _minute_).\n    However, these endpoints can handle the import of up to 1,000 stops per minute.\n    The Creation, Update, and Deletion endpoints for these models still maintain\n    a rate limit of 5 requests per second.\n  - The _Batch Import_ endpoint for Drivers is limited to 2 requests per\n    _minute_. This allows for the import of up to 100 drivers per minute.\n- **Rate Limits for Optimization Endpoints**: The Plan _optimization_ and\n  _re-optimization_ endpoints are limited to 100 requests per _10 minutes_\n  (with a maximum rate of 30 per _minute_), due to the long running nature of these operations.\n\nSpoke API will occasionally support bursts of requests, but they cannot be\nsustained and will be rejected if they last too long.\n\nIf Spoke rejects your request because it exceeds the rate limit, you must\nwait before retrying it. We suggest you use an [exponential\nbackoff](https://en.wikipedia.org/wiki/Exponential_backoff) approach for this.\n\nWe also recommend, besides the exponential backoff algorithm, that you add a\nrandom delay to each attempt to prevent a [thundering herd\nproblem](https://en.wikipedia.org/wiki/Thundering_herd_problem).\n\nIf the client keeps retrying rate-limited requests while being rejected with a\n429 at a high rate, Spoke will keep rejecting the requests until you turn\ndown the request rate.\n\nSpoke will also limit requests if it keeps receiving them at a high frequency\nat or close to the requests limit for an extended period, so while we support\nan occasional burst of requests, if this is sustained for a long period, we\nwill rate-limit the client making them.\n\nWhile we feel these rate-limits will work for the vast majority of use cases we\nunderstand every team is different. So please reach out to us and describe your\nuse case if these limits are not enough for you, and we will evaluate\nincreasing them for your team.\n\n## On the models\n\nAfter this section you will find all the Spoke Public API endpoints available.\n\nEvery representation of resources that these endpoints create and return are\ndocumented in the [Models](/docs/category/models) page of the docs.\n"
  version: v0.2b
servers:
- url: https://api.spoke.com/public/v0.2b
security:
- BasicAuth: []
tags:
- name: Live Stops
  description: 'Endpoints to operate on [Stop](/docs/models/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](#tag/Live-Plans/operation/reoptimizePlan) and [re-distribute](#tag/Live-Plans/operation/redistributePlan)

    endpoints to apply the changes to the plan.

    '
paths:
  /plans/{planId}/stops:liveCreate:
    post:
      operationId: createLiveStop
      summary: Create a new stop
      tags:
      - Live Stops
      description: 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](#tag/Stops/operation/importLiveStops) if you want to create multiple stops at once as it is more efficient and will produce better geocoding results.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                address:
                  type: object
                  properties:
                    addressName:
                      description: The name of the address. This will not be used for geocoding, and is only for the final address display purposes.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 255
                      - type: 'null'
                    addressLineOne:
                      description: The first line of the address.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 255
                      - type: 'null'
                    addressLineTwo:
                      description: The second line of the address.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 255
                      - type: 'null'
                    city:
                      description: The city of the address.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 100
                      - type: 'null'
                    state:
                      description: The state of the address.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 100
                      - type: 'null'
                    zip:
                      description: The zip code of the address.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 100
                      - type: 'null'
                    country:
                      description: The country of the address.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 100
                      - type: 'null'
                    latitude:
                      description: The latitude of the address in decimal degrees.
                      anyOf:
                      - type: number
                        minimum: -90
                        maximum: 90
                      - type: 'null'
                    longitude:
                      description: The longitude of the address in decimal degrees.
                      anyOf:
                      - type: number
                        minimum: -180
                        maximum: 180
                      - type: 'null'
                  additionalProperties: false
                timing:
                  anyOf:
                  - description: Timing information for this stop
                    type: object
                    properties:
                      earliestAttemptTime:
                        description: Time of day of the earliest time this stop should happen
                        anyOf:
                        - description: Time of day in hours and minutes. Use a 24 hour clock.
                          type: object
                          properties:
                            hour:
                              description: Hour of the day
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            minute:
                              description: Minute of the hour
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                          required:
                          - hour
                          - minute
                          additionalProperties: false
                        - type: 'null'
                      latestAttemptTime:
                        description: Time of day of the latest time this stop should happen
                        anyOf:
                        - description: Time of day in hours and minutes. Use a 24 hour clock.
                          type: object
                          properties:
                            hour:
                              description: Hour of the day
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            minute:
                              description: Minute of the hour
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                          required:
                          - hour
                          - minute
                          additionalProperties: false
                        - type: 'null'
                      estimatedAttemptDuration:
                        description: Duration in seconds of the activity in this stop, only set if you want to override the default. This can be set up to 8 hours.
                        anyOf:
                        - type: integer
                          minimum: -9007199254740991
                          maximum: 9007199254740991
                        - type: 'null'
                    additionalProperties: false
                  - type: 'null'
                recipient:
                  anyOf:
                  - description: Recipient information for this stop
                    type: object
                    properties:
                      externalId:
                        description: External ID of the recipient, as defined by the API user
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                      email:
                        description: Email of the recipient
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                      phone:
                        description: Phone number of the recipient
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                      name:
                        description: Name of the recipient
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                    additionalProperties: false
                  - type: 'null'
                orderInfo:
                  anyOf:
                  - description: Order information for this stop
                    type: object
                    properties:
                      products:
                        description: Products in this stop
                        maxItems: 100
                        type: array
                        items:
                          type: string
                          minLength: 1
                          maxLength: 255
                      sellerOrderId:
                        description: Seller order ID
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                      sellerName:
                        description: Seller name
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                      sellerWebsite:
                        description: Seller website
                        anyOf:
                        - type: string
                          minLength: 1
                          maxLength: 255
                        - type: 'null'
                    additionalProperties: false
                  - type: 'null'
                paymentOnDelivery:
                  anyOf:
                  - description: Payment on delivery (also known as "Cash on Delivery") data for this stop
                    type: object
                    properties:
                      amount:
                        description: Amount *in minor units* (e.g. cents) to be collected upon delivery
                        anyOf:
                        - type: integer
                          minimum: 0
                          maximum: 9007199254740991
                        - type: 'null'
                      currency:
                        description: Currency of the payment. Defaults to the team's currency.
                        anyOf:
                        - type: string
                          enum:
                          - AED
                          - ARS
                          - AUD
                          - BRL
                          - CAD
                          - CHF
                          - CLP
                          - CNY
                          - COP
                          - DKK
                          - EGP
                          - EUR
                          - GBP
                          - HKD
                          - HUF
                          - ILS
                          - INR
                          - JPY
                          - KRW
                          - MYR
                          - MXN
                          - NOK
                          - NZD
                          - PEN
                          - RON
                          - RUB
                          - SAR
                          - SEK
                          - SGD
                          - TRY
                          - USD
                          - UYU
                          - ZAR
                        - type: 'null'
                    additionalProperties: false
                  - type: 'null'
                proofOfAttemptRequirements:
                  anyOf:
                  - description: Proof of attempt requirement settings for this stop
                    type: object
                    properties:
                      enabled:
                        description: Whether proof of attempt is required for this stop
                        anyOf:
                        - type: boolean
                        - type: 'null'
                    additionalProperties: false
                  - type: 'null'
                driver:
                  description: 'Deprecated. Prefer using the `allowedDrivers` field instead.

                    Driver ID that should 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 `allowedDrivers` field.'
                  anyOf:
                  - type: string
                    pattern: ^drivers\/[a-zA-Z0-9---_]{1,50}$
                  - type: 'null'
                allowedDrivers:
                  description: 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 `driver` field. When the stop is first created, all the drivers in this list will be added to the plan as well. If the stop is updated, no changes will be made to the plan, so if you want to add a driver to the plan, you must also add them to the plan separately, if they are not already.
                  anyOf:
                  - maxItems: 100
                    type: array
                    items:
                      type: string
                      pattern: ^drivers\/[a-zA-Z0-9---_]{1,50}$
                  - type: 'null'
                activity:
                  description: Activity type
                  default: delivery
                  anyOf:
                  - type: string
                    enum:
                    - delivery
                    - pickup
                  - type: 'null'
                optimizationOrder:
                  description: The preferred order of this stop in the optimized route. If not provided or `"default"`, the stop will be placed in the optimal order, decided by the optimization algorithm. Otherwise it will be placed either `"first"` or `"last"`.
                  anyOf:
                  - type: string
                    enum:
                    - first
                    - last
                    - default
                  - type: 'null'
                packageCount:
                  description: Number of packages in the stop
                  anyOf:
                  - type: number
                    minimum: 1
                    maximum: 10000
                  - type: 'null'
                weight:
                  description: Weight information for this stop.
                  anyOf:
                  - type: object
                    properties:
                      amount:
                        description: The weight amount for this stop.
                        type: number
                        minimum: 0
                        maximum: 999999
                        multipleOf: 0.01
                      unit:
                        description: The weight unit in which the amount is specified.
                        type: string
                        enum:
                        - kilogram
                        - pound
                        - metric-ton
                    required:
                    - amount
                    - unit
                  - type: 'null'
                notes:
                  description: Notes for the stop
                  anyOf:
                  - type: string
                    minLength: 1
                    maxLength: 2000
                  - type: 'null'
                circuitClientId:
                  description: Client ID of the retailer in Spoke Connect
                  anyOf:
                  - type: string
                    minLength: 1
                    maxLength: 100
                  - type: 'null'
                barcodes:
                  description: List of barcode IDs associated with this stop
                  maxItems: 200
                  type: array
                  items:
                    type: string
                    minLength: 1
                    maxLength: 255
                customProperties:
                  description: Key-value pairs of custom stop properties for this stop. The keys must be unique and match a custom stop property defined in your team.
                  anyOf:
                  - type: object
                    propertyNames:
                      description: The custom stop property id
                      type: string
                      maxLength: 50
                    additionalProperties:
                      description: The value of the custom stop property, up to 255 characters.
                      anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 255
                      - type: 'null'
                  - type: 'null'
              required:
              - address
              additionalProperties: false
        required: true
      parameters:
      - schema:
          type: string
          pattern: ^[a-zA-Z0-9---_]{1,50}$
        in: path
        name: planId
        required: true
        description: The plan id
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  pending:
                    type: boolean
                  stop:
                    $ref: '#/components/schemas/stopSchema'
                required:
                - pending
                - stop
                definitions:
                  stopSchema:
                    type: object
                    properties:
                      id:
                        type: string
                        pattern: ^plans\/[a-zA-Z0-9---_]{1,50}\/stops\/[a-zA-Z0-9---_]{1,50}$
                        description: The id of the stop, in the format `plans/<id>/stops/<id>`.
                      address:
                        type: object
                        properties:
                          address:
                            type: string
                            description: The address of the stop.
                          addressLineOne:
                            type: string
                            description: The first line of the address.
                          addressLineTwo:
                            type: string
                            description: The second line of the address.
                          latitude:
                            anyOf:
                            - type: number
                              minimum: -90
                              maximum: 90
                            - type: 'null'
                            description: The latitude of the address in decimal degrees.
                          longitude:
                            anyOf:
                            - type: number
                              minimum: -180
                              maximum: 180
                            - type: 'null'
                            description: The longitude of the address in decimal degrees.
                          placeId:
                            anyOf:
                            - type: string
                            - type: 'null'
                            description: The identifier of the place corresponding to this stop on Google Places
                          placeTypes:
                            type: array
                            items:
                              type: string
                            description: Array of strings that is provided by the Google AutoCompleteAPI
                        required:
                        - address
                        - addressLineOne
                        - addressLineTwo
                        - latitude
                        - longitude
                        - placeId
                        - placeTypes
                        additionalProperties: false
                        description: The address of the stop.
                      barcodes:
                        type: array
                        items:
                          type: string
                        description: List of Barcode IDs associated with the stop.
                      driverIdentifier:
                        anyOf:
                        - type: string
                        - type: 'null'
                        description: The driver identifier. This field is deprecated, prefer using `allowedDriversIdentifiers`.
                      allowedDriversIdentifiers:
                        type: array
                        items:
                          type: string
                        description: The allowed drivers that can be assigned to this stop, replaces the `driverIdentifier` field.
                      estimatedTravelDuration:
                        anyOf:
                        - type: number
                        - type: 'null'
                        description: Estimated time that the driver will take to arrive at this stop from the previous stop in seconds.
                      estimatedTravelDistance:
                        anyOf:
                        - type: number
                        - type: 'null'
                        description: The distance in meters between the previous stop and this stop.
                      notes:
                        anyOf:
                        - type: string
                        - type: 'null'
                        description: Notes for the stop.
                      packageCount:
                        anyOf:
                        - type: number
                        - type: 'null'
                        description: The number of packages.
                      weight:
                        anyOf:
                        - type: object
                          properties:
                            amount:
                              type: number
                              minimum: 0
                              description: The weight amount for this stop.
                            unit:
                              type: string
                              enum:
                              - kilogram
                              - pound
                              - metric-ton
                              description: The weight unit in which the amount is specified (defined at team's capacity unit).
                          required:
                          - amount
         

# --- truncated at 32 KB (178 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/circuit/refs/heads/main/openapi/circuit-live-stops-api-openapi.yml