Skip to main content
Version: v1.0

Stop Schema

Model

Stop

Stop = object

The Stop data model. All stops in the API will have this format.

Description

A stop is a location that a driver will visit. A stop will always be associated with a plan, and can be associated with a route. A stop can be associated with a route if it is part of a plan that has been optimized.

Example

{
"id": "plans/zeOCJaJCzZhpKVCVAC9o/stops/rpX5zK2kRFlIfwREp1js",
"plan": "plans/gjaqksJIa26qGPzsgBXT",
"route": {
"id": "routes/gjaqksJIa26qGPzsgBXT",
"title": "Tue, Nov 22 Route 1",
"stopCount": 28,
"state": {
"completed": false,
"completedAt": null,
"distributed": true,
"distributedAt": 1669153050,
"notifiedRecipients": false,
"notifiedRecipientsAt": null,
"started": false,
"startedAt": null
},
"driver": "drivers/gjaqksJIa26qGPzsgBXT",
"plan": "plans/gjaqksJIa26qGPzsgBXT"
},
"address": {
"address": "Very nice St., 150 - Nice Neighbourhood, Campinas - SP, 130876, Brazil",
"placeId": "1cda3f263368264eefbb",
"latitude": -22.12345,
"longitude": -47.12345,
"placeTypes": [
"street_address"
],
"addressLineOne": "Very nice St., 150",
"addressLineTwo": "Nice Neighbourhood, Campinas - SP, 130876, Brazil"
},
"barcodes": ["123456789"],
"allowedDrivers": ["drivers/gjaqksJIa26qGPzsgBXT"],
"estimatedTravelDuration": 654,
"estimatedTravelDistance": 1234,
"notes": null,
"timing": {
"estimatedAttemptDuration": 300,
"earliestAttemptTime": {
"hour": 8,
"minute": 0,
},
"latestAttemptTime": {
"hour": 10,
"minute": 0,
}
},
"orderInfo": {
"products": ["Taco"],
"sellerName": "Sam's Taco Truck",
"sellerOrderId": "ON-2301",
"sellerWebsite": "https://sams.taco"
},
"paymentOnDelivery": {
"amount": 1000,
"currency": "USD"
},
"packageCount": 5,
"weight": {
"amount": 15,
"unit": "kilogram"
},
"placeInVehicle": null,
"type": "stop",
"activity": "delivery",
"recipient": {
"email": "alvena.schulist33@spoke.com",
"externalId": "The recipient's ID on your system",
"name": "Alvena Schulist",
"phone": "+1-555-555-5555"
},
"deliveryInfo": {
"state": "unattempted",
"attempted": false,
"photoUrls": [],
"succeeded": false,
"signeeName": null,
"attemptedAt": null,
"signatureUrl": null,
"attemptedLocation": null,
"recipientProvidedNotes": null,
"driverProvidedInternalNotes": null,
"driverProvidedRecipientNotes": null
},
"proofOfAttemptRequirements": {
"enabled": null
},
"packageLabel": null,
"eta": {
"status": "available",
"value": {
"estimatedArrivalAt": 1669153050,
"estimatedEarliestArrivalAt": 1669152050,
"estimatedLatestArrivalAt": 1669154050
}
},
"customProperties": {
"6f6a65df-3ece-402c-9ff7-0b324e0c666f": "123456",
"58eefa1b-35f5-4f3d-9c82-7a02415f8dd7": null
},
"stopPosition": 1,
"trackingLink": "https://track.spoke.com/123456789",
"webAppLink": "https://dispatch.spoke.com/view-route?routeId=gjaqksJIa26qGPzsgBXT&planId=gjaqksJIa26qGPzsgBXT&stopId=rpX5zK2kRFlIfwREp1js&startsAt=1670382000",
"clientId": "pjaqksJIa26qGPzsgBXT",
"serviceInfo": {
"status": "available",
"value": {
"identifier": "NDE",
"name": "Next Day Delivery",
"slaStartsAt": 1773702856,
"slaDueDate": {
"year": 2026,
"month": 3,
"day": 17
},
"slaDueTime": null,
"deliveryHorizon": {
"unit": "days",
"value": 1
},
"price": {
"value": 500,
"currency": "USD"
},
"hasPaymentOnDelivery": false,
"definedAt": 1773702856
}
}
}

Properties

PropertyTypeDescription

id

StopId

The stop identifier.

address

StopAddress

Object containing the address of the stop.

barcodes

string[]

List of barcodes associated with the Stop

Example

["123456789"]

Default

[]

allowedDrivers

DriverId[]

An array of driver IDs. This information is used to force a specific stop in a plan to be assigned only to specific drivers.

If no drivers are listed here, the stop will be assigned to any driver.

Default

[]

See

Driver

timing

TimingData

Timing information for the stop

estimatedTravelDuration

number | null

Estimated time that the driver will take to arrive at this stop from the previous stop in seconds.

Default

null

estimatedTravelDistance

number | null

Estimated travel distance the driver will take to arrive at this stop from the previous stop in meters.

Default

null

notes

string | null

Notes for the delivery.

Default

null

orderInfo

OrderInfo

Information of the order made by the recipient.

Default

null

packageCount

number | null

Amount of packages to be delivered in the stop.

Default

null

weight

PackageWeight | null

Weight of the packages in the stop.

The unit will be defined by the team's capacity unit within the team's settings in Dispatch web UI.

Default

null

placeInVehicle

PlaceInVehicle | null

The place where the package is in the vehicle of the driver.

Default

null

type

"stop" | "start" | "end"

The type of the stop.

Description

  • start: The first stop of the route.
  • end: The last stop of the route.
  • stop: Any other stop kind.

recipient

StopRecipient

The recipient of the delivery.

activity

StopActivity

The activity performed at the stop by the driver.

Default

'delivery'

packageLabel

string | null

The package identifier used for drivers to identify the package associated with the stop. A number is uniquely generated by clients, but drivers can edit it as necessary.

Default

null

deliveryInfo

DeliveryInfo | null

Information about the delivery of the package.

Default

null

paymentOnDelivery

PaymentOnDelivery | null

Payment on delivery (also known as "Cash on Delivery") data for this stop.

proofOfAttemptRequirements

ProofOfAttemptRequirements

The requirements on the proof of attempt for this stop.

This dictates whether or not the driver will be required to collect proof, be it a signature or a photo, when attempting the stop.

Please notice that this will only be enforced if your team subscription allows collecting proof of attempt.

plan

PlanId

Information about the plan related to the stop.

See

Plan

route

Route | null

Information about the route related to the stop.

See

Route

optimizationOrder

"first" | "last" | "default"

The preferred order of the stop after optimizing the route.

Description

  • first: The stop will be placed at the start of the route.
  • last: The stop will be placed at the end of the route.
  • default: The stop will be placed in an optimal position based on the route optimization algorithm.

Default

'default'

eta

ETAWrapper

Estimated time of arrival at the stop.

customProperties

Record<string, string | null> | null

A map of custom properties associated with this stop.

See

Custom Stop Property

stopPosition

number | null

Stop position in the route. If the stop has the type 'start', it will be 0. All the 'stop' type stops will start at 1. The 'end' type stop will be the last position in the route. Note: This value is the position of the stop in the optimized route, if the driver completes stops in a different order, this field will not reflect that, if needed to order the stops by the actual delivery order when not following the optimized route, use the DeliveryInfo.attemptedAt field.

trackingLink

string | null

Tracking link for this stop. Not available for 'start' and 'end' stops.

webAppLink

string

Link to the stop in Spoke Dispatch Web App

clientId

string | null

If set, the stop will be associated with the Spoke Connect with the given Client ID.

serviceInfo

StopServiceInfoWrapper

Service offering data for this stop.

Description

A typed state wrapper. When status is available, value holds the service info (identity, SLA, pricing snapshotted at assignment time, or just slaStartsAt with identifier: null when only an SLA is set). When status is empty, this stop has no service info. When status is restricted, the team's subscription does not include service offerings.

Identifier

StopId

StopId = `plans/${string}/stops/${string}`

A stop id is a string that is unique for a stop. It is used to identify the stop in the API.

Example

"plans/zeOCJaJCzZhpKVCVAC9o/stops/rpX5zK2kRFlIfwREp1js"

Fields

Date

Date = object

A Date is an object representing a day in the year.

Example

{
"year": 2023,
"month": 2,
"day": 1
}

Properties

PropertyType

year

number

month

number

day

number


EpochTimestamp

EpochTimestamp = number

Timestamp in seconds from epoch.


LoadAmount

LoadAmount = number

A load amount expressed in the team's configured capacity unit.


DisplayLoadUnit

DisplayLoadUnit = "kilogram" | "pound" | "metric-ton"

The unit used to display a load amount.


PriceInMinorUnits

PriceInMinorUnits = number

A non-negative price in the currency's minor unit (e.g. cents).


StopAddress

StopAddress = object

Data used to identify the stop location.

Example

{
"address": "Very nice St., 150 - Nice Neighbourhood, Campinas - SP, 130876, Brazil",
"placeId": "1cda3f263368264eefbb",
"latitude": -22.12345,
"longitude": -47.12345,
"placeTypes": [
"street_address"
],
"addressLineOne": "Very nice St., 150",
"addressLineTwo": "Nice Neighbourhood, Campinas - SP, 130876, Brazil"
},

Properties

PropertyTypeDescription

address

string

Combined address string.

Default

''

Description

It will always be an empty string '' if imported from a spreadsheet using latitude and longitude.

addressLineOne

string

First line of the address.

Default

''

addressLineTwo

string

Second line of the address.

Default

''

latitude

number | null

Latitude coordinate of the stop location in decimal degrees.

Default

null

longitude

number | null

Longitude coordinate of the stop location in decimal degrees.

Default

null

placeId

string | null

The identifier of the Place corresponding to this stop on Google Places.

Default

null

placeTypes

string[]

Array of strings that is provided by the Google AutoCompleteAPI.

Default

[]

StopRecipient

StopRecipient = object

Information on the recipient of the package.

Example

{
"email": "alvena.schulist33@spoke.com",
"externalId": "The recipient's ID on your system",
"name": "Alvena Schulist",
"phone": "+1-555-555-5555"
}

Properties

PropertyTypeDescription

email

string | null

Email address of recipient

Default

null

externalId

string | null

Id of recipient in external system of the team's company

Default

null

name

string | null

Full name of recipient

Default

null

phone

string | null

Phone number of recipient

Default

null

DeliveryInfo

DeliveryInfo = object

Information about the delivery of the package.

Example

{
"state": "delivered_to_recipient",
"attempted": true,
"photoUrls": [],
"succeeded": true,
"signeeName": "",
"attemptedAt": 1669151179,
"timeAtStopInfo": {
"status": "available",
"value": {
"arrivedAt": 1669151100,
"departedAt": 1669151179,
"isEstimated": false
}
},
"signatureUrl": null,
"attemptedLocation": {
"latitude": -3.1234,
"longitude": -38.7654
},
"recipientProvidedNotes": null,
"driverProvidedInternalNotes": "",
"driverProvidedRecipientNotes": ""
}

Properties

PropertyTypeDescription

attempted

boolean

Default

false

attemptedAt

EpochTimestamp | null

Timestamp in seconds of when the driver attempted the delivery.

Default

null

timeAtStopInfo

TimeAtStopInfoWrapper

Typed state wrapper for time-at-stop data.

Description

Uses a status discriminator to indicate whether time-at-stop data is available, restricted by subscription, or pending (no arrival/departure events yet).

attemptedLocation

Location | null

The location this stop was attempted at

Default

null

driverProvidedInternalNotes

string | null

Internal notes provided by the driver.

Default

null

driverProvidedRecipientNotes

string | null

Recipient notes provided by the driver.

Default

null

photoUrls

string[]

URLs of proof of delivery photos taken and uploaded by the driver. The URLs here can return not found if the driver mobile app is still uploading the photos, but once the upload is complete, the URL will contain the image.

Default

[]

recipientProvidedNotes

string | null

Notes provided by the recipient.

Default

null

signatureUrl

string | null

URL of the recipient signature. The URL here can return not found if the driver mobile app is still uploading it, but once the upload is complete, the URL will contain the image.

Default

null

signeeName

string | null

Signee name

Default

null

state

DeliveryState

Default

'unattempted'

succeeded

boolean

If the delivery was successful.

Default

false

PaymentOnDelivery

PaymentOnDelivery = object

Payment on delivery (also known as "Cash on Delivery") data for this stop.

Example

{
"amount": 599,
"currency": "USD"
}

Properties

PropertyTypeDescription

amount

PriceInMinorUnits | null

The amount in minor units (e.g. cents) to be collected upon delivery.

Example

599

currency

string

The payment's currency in ISO 4217 standard.

Example

'USD'

ProofOfAttemptRequirements

ProofOfAttemptRequirements = object

Requirements on the proof of attempt for this stop.

Description

This dictates whether or not the driver will be required to collect proof, be it a signature or a photo, when attempting the stop.

Please notice that this will only be enforced if your team subscription allows collecting proof of attempt.

Example

{
"enabled": true
}

Properties

PropertyTypeDescription

enabled

boolean | null

Whether collecting the proof of attempt is enabled for this stop.

Please notice that this will only be enforced if your team subscription allows collecting proof of attempt.

Description

If this is null it will use the default value for the team.

Set explicitly to false to disable the proof of attempt collection for this stop.

Set explicitly to true to enable the proof of attempt collection for this stop, following the policies of the team on each type of attempt.

Default

null

OrderInfo

OrderInfo = object

Information of the order made by the recipient.

Example

{
"products": ["Taco"],
"sellerName": "Sam's Taco Truck",
"sellerOrderId": "ON-2301",
"sellerWebsite": "https://sams.taco"
}

Properties

PropertyTypeDescription

products

string[]

Name of the products to be delivered.

Default

[]

Description

To get the products to be split in this array, whether using the Web UI or submitting via a spreadsheet, use a , (comma) or a ; (semicolon) as a delimiter between each product.

sellerOrderId

string | null

The ID of the order created by the seller that is usually shared with the client.

Default

null

sellerName

string | null

Name of the seller where the user bought the products.

Default

null

sellerWebsite

string | null

Website where the user bought the products.

Default

null

PlaceInVehicle

PlaceInVehicle = object

Where in the vehicle the package was placed.

Example

{
"x": "left",
"y": "front",
"z": "floor"
}

Properties

PropertyTypeDescription

x

"left" | "right" | null

Default

null

y

"front" | "middle" | "back" | null

Default

null

z

"floor" | "shelf" | null

Default

null

ETAData

ETAData = object

Estimated time of arrival at the stop.

Description

It is important to note that this is not a guarantee that the driver will arrive at the stop at the specified time. It is only an estimate, especially if the driver has not started the route yet, as the estimated start time is then based on the expected start time of the route.

Example

{
"estimatedArrivalAt": 1669153050,
"estimatedEarliestArrivalAt": 1669152050,
"estimatedLatestArrivalAt": 1669154050
}

Properties

PropertyTypeDescription

estimatedArrivalAt

EpochTimestamp

The estimated time of arrival in seconds since epoch.

estimatedEarliestArrivalAt

EpochTimestamp

The estimated earliest possible window time of arrival in seconds since epoch.

estimatedLatestArrivalAt

EpochTimestamp

The estimated latest possible window time of arrival in seconds since epoch.


ETAWrapper

ETAWrapper = { status: "available"; value: ETAData; } | { status: "restricted"; requiredFeature?: string; upgradeUrl?: string; restrictionCode?: string; } | { status: "pending"; pendingReason?: string; }

Typed state wrapper for ETA data.

Description

Uses a status discriminator to indicate whether ETA data is available, restricted by subscription, or pending optimization.


TimeAtStopInfo

TimeAtStopInfo = object

Grouped time-at-stop data.

Description

Contains arrival time, departure time, and whether the values were estimated. Individual fields are null when the corresponding event has not yet occurred.

Example

{
"arrivedAt": 1669151100,
"departedAt": 1669151179,
"isEstimated": false
}

Properties

PropertyTypeDescription

arrivedAt

EpochTimestamp | null

Timestamp in seconds of when the driver arrived at the delivery location.

Default

null

departedAt

EpochTimestamp | null

Timestamp in seconds of when the driver departed from the delivery location.

Default

null

isEstimated

boolean | null

Whether the time at stop was estimated rather than directly measured. When true, the arrivedAt and/or departedAt values were calculated rather than captured from the driver's actual arrival/departure events.

Default

null

TimeAtStopInfoWrapper

TimeAtStopInfoWrapper = { status: "available"; value: TimeAtStopInfo; } | { status: "restricted"; requiredFeature?: string; upgradeUrl?: string; restrictionCode?: string; } | { status: "pending"; pendingReason?: string; }

Typed state wrapper for time-at-stop data.

Description

Uses a status discriminator to indicate whether time-at-stop data is available, restricted by subscription, or pending (no arrival/departure events yet).


TimingData

TimingData = object

Timing information for the stop.

Description

The timing information for the stop. This will be used to calculate the optimal time to visit the stop.

Example

{
"earliestAttemptTime": {
"hour": 8,
"minute": 0
},
"latestAttemptTime": {
"hour": 10,
"minute": 0
},
"estimatedAttemptDuration": 300
}

Properties

PropertyTypeDescription

earliestAttemptTime

TimeOfDay | null

Earliest attempt time this stop should occur at.

Default

null

latestAttemptTime

TimeOfDay | null

Latest attempt time this stop should occur at.

Default

null

estimatedAttemptDuration

number | null

Time that the driver estimates to spend on the stop to do his job (deliver a parcel, visit a client, etc) in seconds. This will only be set if this was overidden for this stop, otherwise this will be null and all the calculations will use the default team value.

Default

null

TimeOfDay

TimeOfDay = object

The time of day in hours and minutes.

Description

The time of day in hours and minutes.

Example

{
"hour": 8,
"minute": 0
}

Properties

PropertyTypeDescription

hour

number

The hour of the day in 24-hour format.

minute

number

The minute of the hour.


DeliveryState

DeliveryState = "delivered_to_recipient" | "delivered_to_third_party" | "delivered_to_mailbox" | "delivered_to_safe_place" | "delivered_to_pickup_point" | "delivered_other" | "picked_up_from_customer" | "picked_up_unmanned" | "picked_up_from_locker" | "picked_up_other" | "failed_not_home" | "failed_cant_find_address" | "failed_no_parking" | "failed_no_time" | "failed_package_not_available" | "failed_missing_required_proof" | "failed_payment_not_received" | "failed_other" | "unattempted"

The current delivery state when this event is emitted.

Description

  • unattempted: The delivery has not been attempted yet.
  • delivered_to_recipient: The delivery was successfully delivered to the recipient.
  • delivered_to_third_party: The delivery was successfully delivered to a third party.
  • delivered_to_mailbox: The delivery was successfully delivered to a mailbox.
  • delivered_to_safe_place: The delivery was successfully delivered to a safe place.
  • delivered_to_pickup_point: The delivery was successfully delivered to a pickup point.
  • delivered_other: The delivery was successfully delivered with an unknown method.
  • picked_up_from_customer: The delivery was successfully picked up from the customer.
  • picked_up_unmanned: The delivery was successfully picked up without interaction with the customer.
  • picked_up_from_locker: The delivery was successfully picked up from a locker.
  • picked_up_other: The delivery was successfully picked up with an unknown method.
  • failed_not_home: The delivery failed because the recipient was not at home.
  • failed_cant_find_address: The delivery failed because the address could not be found.
  • failed_no_parking: The delivery failed because there was no parking space available.
  • failed_no_time: The delivery failed because the driver did not have enough time to complete the delivery.
  • failed_package_not_available: The delivery failed because the package was not available on the truck.
  • failed_missing_required_proof: The delivery failed because the driver did not collect the required proof of delivery.
  • failed_payment_not_received: The delivery failed because the driver did not collect the payment.
  • failed_other: The delivery failed for an unknown reason.

StopActivity

StopActivity = "delivery" | "pickup"

The activity performed at the stop by the driver.

Description

  • delivery: The driver has to deliver the package
  • pickup: The driver has to pick up the package

Location

Location = object

A location object with latitude and longitude.

Example

{
"latitude": -22.12345,
"longitude": -47.12345
}

Properties

PropertyType

latitude

number

longitude

number


StopServiceInfo

StopServiceInfo = StopLinkedServiceInfo | StopServicelessServiceInfo

Service offering information for a stop.

Description

A discriminated union on the identifier field:

  • When identifier is a string, a service is assigned and all SLA/pricing fields are present.
  • When identifier is null, only slaStartsAt is set (e.g. via import or API before a service is assigned).

StopServiceInfoWrapper

StopServiceInfoWrapper = { status: "available"; value: StopServiceInfo; } | { status: "empty"; } | { status: "restricted"; requiredFeature?: string; upgradeUrl?: string; restrictionCode?: string; }

Typed state wrapper for service offering data.

Description

Uses a status discriminator to indicate why service info is or isn't set:

  • availablevalue holds the service info.
  • empty — this stop has no service info.
  • restricted — the team's subscription does not include service offerings.

StopLinkedServiceInfo

StopLinkedServiceInfo = object

Service data when a service offering is assigned to the stop.

Properties

PropertyTypeDescription

identifier

string

The service identifier at the time of assignment.

Example

"NDE"

name

string

The human-readable service name at the time of assignment.

Example

"Next Day Delivery"

slaStartsAt

EpochTimestamp

The SLA start time in seconds since epoch.

slaDueDate

Date

The computed SLA due date in the team's timezone, as a day object.

Example

{ "year": 2026, "month": 5, "day": 15 }

slaDueTime

TimeOfDay | null

The SLA due time-of-day in the team's timezone. null for day-level SLA (v1).

Default

null

deliveryHorizon

StopServiceDeliveryHorizon

The delivery horizon for this service.

price

StopServicePrice

Price for this service at assignment time.

hasPaymentOnDelivery

boolean

Whether cash on delivery is enabled for this stop via the service.

definedAt

EpochTimestamp

When the service was assigned or re-assigned in seconds since epoch.


StopServicelessServiceInfo

StopServicelessServiceInfo = object

Service data when only an SLA start time is set, without a service offering.

Properties

PropertyTypeDescription

identifier

null

null indicates no service offering is linked.

slaStartsAt

EpochTimestamp

The SLA start time in seconds since epoch.


StopServiceDeliveryHorizon

StopServiceDeliveryHorizon = object

Delivery horizon for a service offering.

Example

{ "unit": "days", "value": 1 }

Properties

PropertyTypeDescription

unit

"days" | "hours" | string & object

The time unit for the delivery horizon. Known values are days and hours, modeled as an open union so a new unit is not a breaking change for clients that generated bindings against an older schema.

value

number

The number of time units.


StopServicePrice

StopServicePrice = object

Price for a service offering.

Example

{ "value": 500, "currency": "EUR" }

The example above represents €5.00 (500 cents).

Properties

PropertyTypeDescription

value

PriceInMinorUnits

Price in the currency's minor units (e.g. cents for EUR/USD, pence for GBP). For example, 500 with currency "EUR" means €5.00.

currency

CurrencyCode | string & object

3-letter ISO 4217 currency code. Known values are the supported currency codes, modeled as an open union so a new currency is not a breaking change for clients that generated bindings against an older schema.


PackageWeight

PackageWeight = object

Package weight at the stop.

Example

{
"amount": 15,
"unit": "kilogram"
}

Properties

PropertyType

amount

LoadAmount

unit

DisplayLoadUnit