Arrival estimates
Recompute arrival times along a route from progress so far.
eta.estimate
Stable
call
How to call it
REST
POST
/v1/eta
GraphQL
query
openEta
MCP
open_eta_estimate
Project a route's remaining arrival times forward from the last observed event. This is a projection of YOUR plan, not a traffic forecast: it applies no pace correction and calls no traffic service. Billed one call.
Request schema
Generated from the same validation rules the endpoint runs, so a field cannot be documented without being validated.
POST /v1/eta
{
"type": "object",
"properties": {
"departed_at": [],
"horizon": {
"type": [
"integer",
"null"
],
"minimum": 1,
"maximum": 50
},
"now": [],
"stops": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"completed_at": [],
"id": {
"type": [
"string",
"null"
],
"maxLength": 128
},
"sequence": {
"type": [
"integer",
"null"
]
},
"service_seconds": {
"type": [
"integer",
"null"
],
"minimum": 0
},
"time_window": {
"type": [
"array",
"null"
]
},
"travel_seconds": {
"type": [
"integer",
"null"
],
"minimum": 0
}
}
}
}
},
"additionalProperties": false,
"required": [
"stops"
]
}
Request example
{
"departed_at": "2026-11-02T09:00:00-05:00",
"now": "2026-11-02T09:20:00-05:00",
"stops": [
{
"id": "order-1001",
"travel_seconds": 600,
"service_seconds": 300,
"completed_at": "2026-11-02T09:15:00-05:00"
},
{
"id": "order-1002",
"travel_seconds": 720,
"service_seconds": 300,
"time_window": {
"from": "2026-11-02T09:00:00-05:00",
"to": "2026-11-02T09:25:00-05:00"
}
},
{
"id": "order-1003",
"travel_seconds": 540,
"service_seconds": 240
}
]
}
Response
What a successful call returns: the schema of `data` and `meta`, with a description of each field, followed by an example response from a real call.
POST /v1/eta
Response schema
{
"description": "Arrival times for the stops not yet completed, projected from the last observation (the latest completed stop, else `departed_at`, else `now`). A projection of the caller's plan, not a traffic forecast. Times are in UTC.",
"data": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"in_progress",
"not_started",
"complete"
],
"description": "`not_started`: no completed stop and no departure, so nothing is projected; `complete`: every stop is done."
},
"anchor": {
"type": [
"object",
"null"
],
"description": "Null unless `status` is in_progress.",
"properties": {
"at": {
"type": "string",
"description": "The observation projected from, UTC."
},
"at_epoch": {
"type": "integer"
},
"source": {
"type": "string",
"enum": [
"completion",
"departure",
"now"
],
"description": "What the anchor is: the latest completed stop, `departed_at`, or `now`."
},
"stop_id": {
"type": [
"string",
"null"
],
"description": "The completed stop anchored on."
},
"age_seconds": {
"type": "integer",
"description": "How old the observation is at `now`. Past 45 minutes an ANCHOR_STALE warning is added."
}
}
},
"finish_eta": {
"type": [
"string",
"null"
],
"description": "When the last stop is finished, UTC."
},
"finish_eta_epoch": {
"type": "integer"
},
"remaining": {
"type": "object",
"description": "What is left of the route.",
"properties": {
"stops": {
"type": "integer"
},
"travel_seconds": {
"type": "integer"
},
"service_seconds": {
"type": "integer"
}
}
},
"stops": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"eta": {
"type": "string",
"description": "Arrival, UTC."
},
"eta_epoch": {
"type": "integer"
},
"departure_eta": {
"type": "string",
"description": "Departure after service, UTC."
},
"window_status": {
"type": [
"string",
"null"
],
"enum": [
"early",
"on_time",
"late",
null
],
"description": "Against the stop's `time_window`; null when it has none."
},
"minutes_late": {
"type": [
"integer",
"null"
],
"description": "Minutes past the end of the window; null when not late."
}
}
},
"description": "The next `horizon` stops (default 3). Beyond that a HORIZON_TRUNCATED warning is added; use `finish_eta`."
},
"confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
],
"description": "`high` from two or more completed stops, `medium` from one, `low` when the anchor is a departure, `now` or stale."
}
}
},
"meta": {
"type": "object",
"properties": {
"model": {
"type": "string",
"enum": [
"anchored_plan_projection"
]
},
"pace_correction": {
"type": "boolean",
"description": "Always false: no pace correction is applied."
},
"traffic_aware": {
"type": "boolean",
"description": "Always false: no traffic service is called."
},
"stops": {
"type": "integer",
"description": "Stops sent."
},
"mode": {
"type": "string"
}
}
}
}
Response example
{
"request_id": "req_01k8zq3m5n7p9r1t3v5x7z9b2d",
"capability": "eta.estimate",
"billing": {
"unit": "call",
"quantity": 1,
"counted": true,
"breakdown": {
"stops": 3
}
},
"data": {
"status": "in_progress",
"anchor": {
"at": "2026-11-02T14:15:00Z",
"at_epoch": 1793628900,
"source": "completion",
"stop_id": "order-1001",
"age_seconds": 300
},
"finish_eta": "2026-11-02T14:45:00Z",
"finish_eta_epoch": 1793630700,
"remaining": {
"stops": 2,
"travel_seconds": 1260,
"service_seconds": 540
},
"stops": [
{
"id": "order-1002",
"eta": "2026-11-02T14:27:00Z",
"eta_epoch": 1793629620,
"departure_eta": "2026-11-02T14:32:00Z",
"window_status": "late",
"minutes_late": 2
},
{
"id": "order-1003",
"eta": "2026-11-02T14:41:00Z",
"eta_epoch": 1793630460,
"departure_eta": "2026-11-02T14:45:00Z",
"window_status": null,
"minutes_late": null
}
],
"confidence": "medium"
},
"meta": {
"model": "anchored_plan_projection",
"pace_correction": false,
"traffic_aware": false,
"stops": 3,
"mode": "sync"
}
}
What it costs
One call, whatever its size.
Every billable response carries a billing block with the unit, the quantity and how the quantity was derived.
Errors it can return
| Status | Code | Description |
|---|---|---|
| 401 | TOKEN_INVALID |
Unknown or revoked API token. |
| 401 | TOKEN_MISSING |
No API token. Send Authorization: Bearer <your token>. |
| 402 | QUOTA_EXHAUSTED |
The included allowance for this capability is used up for the current period. |
| 403 | CAPABILITY_NOT_ENABLED |
This capability is not enabled for your account. See :doc to enable it. |
| 403 | CAPABILITY_NOT_GRANTED_TO_KEY |
Your account has this capability, but this API key was not granted it. |
| 403 | OPEN_API_DISABLED |
Open Platform access is not enabled for this account. |
| 422 | VALIDATION_FAILED |
The request failed validation. See details. |
| 429 | RATE_LIMITED |
Too many requests. Please retry after the indicated delay. |
| 500 | INTERNAL_ERROR |
An unexpected error occurred. Quote the request_id when contacting support. |