Plan routes for voice agents
For voice models and voice agents, this endpoint reduces response tokens and keeps spoken-answer tool calls focused. Return up to the first two structurally unique route alternatives from /v1/routes in a normalized compact response for clients that need a smaller payload. Alternatives with the same ordered transit services, directions and boarding/alighting stops are deduplicated even when their departure and arrival times differ. Field names are declared once in *Fields arrays; data rows contain values in that order and connect through integer *Ref indexes. Geometry, intermediate stop objects and presentation-only metadata are omitted, while journey instructions, stop and route identifiers, directions, times, accessibility and alerts are retained for follow-up requests.
Voice-ready response: This JSON REST method uses a smaller positional representation so voice models spend fewer tokens on repeated fields and map-only data. It does not accept or process audio.
The standard endpoint returns the complete application and map-oriented response for the same capability.
View the standard endpoint →Response fields and units
| Field | Format / unit | Meaning |
|---|---|---|
*Fields + matching data array | columnar JSON | Each row uses the field order declared once by its matching *Fields array |
routes[].legRefs | array of indexes | Ordered indexes into legs for this route alternative |
legs[].serviceRef | index | Index into services with routeId, countryIso, line and headsign for /v1/line and direction-specific follow-ups |
legs[].fromPlaceRef, toPlaceRef | indexes | Indexes into places with stop identifiers and coordinates |
legs[].departureTime, arrivalTime | ISO 8601 | Scheduled local times with offset |
legs[].realtimeDepartureTime, realtimeArrivalTime | ISO 8601 | Live local times when available |
Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
origin | string | Yes | Origin coordinates in 'lat,lon' format | 51.537511,-0.152208 |
destination | string | Yes | Destination coordinates in 'lat,lon' format | 51.531921,-0.082569 |
arrivalTime | string | No | ISO 8601 arrival time. Z for UTC, an offset like +01:00 (encode + as %2B), or no zone for origin-local time. Send arrivalTime or departureTime, not both. departureTime wins if both are present. | 2025-09-18T09:30:00Z |
departureTime | string | No | ISO 8601 departure time. Z for UTC, an offset like +01:00 (encode + as %2B), or no zone for origin-local time. Send departureTime or arrivalTime, not both. departureTime wins if both are present. | 2025-09-18T09:00:00Z |
transfers | integer | No | Maximum number of transfers (range 0-6) | 2 |
transport | string | No | Return routes using only specified transport types, comma-separated | bus,subway,train,tram |
barrierMode | integer | No | Wheelchair routing filter: 0 no filter, 1 require explicitly accessible stops and trips, 2 require explicitly accessible stops only, 3 require explicitly accessible trips only. Unknown accessibility fails each requirement selected by the mode | 1 |
maxRoutes | integer | No | Search effort and maximum alternatives requested from the routing engine (range 1-6) | 3 |
lang | string | No | Language code for translated stop/route names (IETF BCP 47 format) | en |
Time format
Time parameters use ISO 8601. The zone designator at the end of the value determines its interpretation.
| Form | Example | Meaning |
|---|---|---|
| No zone | 2025-09-18T10:00:00 | Local time at the queried location: the origin for /compact/v1/routes or the stop or location for /compact/v1/nextDepartures. The caller does not need the location's UTC offset. |
| UTC | 2025-09-18T14:00:00Z | A fixed instant. The Z suffix marks UTC. |
| Explicit offset | 2025-09-18T10:00:00-04:00 | A fixed instant. Encode + as %2B in the query string. |
- The UTC and offset forms denote the same instant regardless of caller location; only the no-zone form is location-relative. 09:00:00Z and 10:00:00+01:00 are equivalent.
- If omitted, the current time is used.
- Seconds are rounded up to the next minute.
- When present, localDate and localTime report the request time in the resolved region. nextDepartures v1 times use ISO 8601 and may include a UTC offset or omit a zone designator.
Real-time vs scheduled times
Times come in two flavours: the schedule (always present) and the real-time/live value (available only when the operator feeds live data). When a real-time value is available it is the actual expected time - use it instead of the scheduled one. The field names differ per endpoint:
| Endpoint | Scheduled field | Real-time field (live only) |
|---|---|---|
/compact/v1/routes | legs columns departureTime / arrivalTime (full ISO 8601) | legs columns realtimeDepartureTime / realtimeArrivalTime (live only) |
/compact/v1/nextDepartures | departures column scheduledDepartureTime (ISO 8601) | departures column realtimeDepartureTime (ISO 8601; live only) |
- The fixed-width /compact/v1/nextDepartures row keeps its real-time column and uses null.
- nextDepartures times use ISO 8601 and may include a UTC offset or omit a zone designator.
- Delay = real-time minus scheduled (positive = running late). A live/delay badge is the typical UI.
- Service disruptions come as a top-level alerts[] array (header, description, cause, effect, validFrom/validUntil, and the affected route/stop via informedEntity / sectionIds).
Wheelchair accessibility
wheelchairBoarding: wheelchairBoarding describes a stop.
wheelchairAccessible: wheelchairAccessible describes a trip.
| Value | Meaning |
|---|---|
field absent | Unknown (GTFS value 0). |
1 | Accessible. |
2 | Not accessible. |
Try It Out
Required parameters only
curl -H "capi-key: Bearer YOUR_API_KEY" \
-H "capi-host: busmaps.com" \
"https://capi.busmaps.com:8443/compact/v1/routes?origin=51.537511,-0.152208&destination=51.531921,-0.082569" Popular parameters
curl -H "capi-key: Bearer YOUR_API_KEY" \
-H "capi-host: busmaps.com" \
"https://capi.busmaps.com:8443/compact/v1/routes?origin=51.537511,-0.152208&destination=51.531921,-0.082569&arrivalTime=2025-09-18T09:30:00Z&transfers=2&transport=bus,subway,train,tram&barrierMode=1&maxRoutes=3&lang=en"Response Example
{
"regionName": "uk_ireland",
"placeFields": [
"stopId",
"countryIso",
"name",
"description",
"lat",
"lon",
"wheelchairBoarding"
],
"places": [
[
null,
null,
null,
null,
51.537511,
-0.152208,
null
],
[
"12749834648374944315",
"GBR",
"Camden Town Underground Station",
null,
51.539258,
-0.142972,
2
],
[
"15596762607412162429",
"GBR",
"Old Street Underground Station",
null,
51.524987,
-0.087547,
2
],
[
null,
null,
null,
null,
51.531921,
-0.082569,
null
],
[
"16900768855175614933",
"GBR",
"Regent's Park Road",
"Stop K",
51.538191,
-0.152258,
null
],
[
"11974292288902583902",
"GBR",
"Camden High Street Camden Town",
"Stop CX",
51.538744,
-0.143454,
null
]
],
"serviceFields": [
"routeId",
"countryIso",
"line",
"headsign",
"operator"
],
"services": [
[
"3173742969-2726050097",
"GBR",
"Northern",
"Morden via Bank",
"London Underground (TfL)"
],
[
"3565009689-2914759404",
"GBR",
"274",
"Islington, Angel",
"Metroline Travel"
]
],
"legFields": [
"id",
"mode",
"serviceRef",
"wheelchairAccessible",
"fromPlaceRef",
"toPlaceRef",
"departureTime",
"realtimeDepartureTime",
"arrivalTime",
"realtimeArrivalTime",
"departurePlatform",
"arrivalPlatform",
"durationMinutes",
"distanceMeters",
"intermediateStopCount"
],
"legs": [
[
"C0-S0",
"pedestrian",
null,
null,
0,
1,
"2026-08-11T12:50:00+01:00",
null,
"2026-08-11T13:05:00+01:00",
null,
null,
null,
15,
880,
null
],
[
"C0-S1",
"subway",
0,
1,
1,
2,
"2026-08-11T13:04:00+01:00",
"2026-08-11T13:05:00+01:00",
"2026-08-11T13:13:00+01:00",
"2026-08-11T13:14:00+01:00",
"2",
null,
9,
5132,
3
],
[
"C0-S2",
"pedestrian",
null,
null,
2,
3,
"2026-08-11T13:14:00+01:00",
null,
"2026-08-11T13:31:00+01:00",
null,
null,
null,
17,
983,
null
],
[
"C1-S0",
"pedestrian",
null,
null,
0,
4,
"2026-08-11T12:47:00+01:00",
null,
"2026-08-11T12:49:00+01:00",
null,
null,
null,
2,
115,
null
],
[
"C1-S1",
"bus",
1,
1,
4,
5,
"2026-08-11T12:49:00+01:00",
"2026-08-11T12:49:00+01:00",
"2026-08-11T12:54:00+01:00",
"2026-08-11T12:54:00+01:00",
null,
null,
5,
677,
2
],
[
"C1-S2",
"pedestrian",
null,
null,
5,
1,
"2026-08-11T12:54:00+01:00",
null,
"2026-08-11T12:56:00+01:00",
null,
null,
null,
2,
120,
null
],
[
"C1-S3",
"subway",
0,
1,
1,
2,
"2026-08-11T12:58:00+01:00",
"2026-08-11T12:59:00+01:00",
"2026-08-11T13:07:00+01:00",
"2026-08-11T13:08:00+01:00",
"2",
null,
9,
5132,
3
],
[
"C1-S4",
"pedestrian",
null,
null,
2,
3,
"2026-08-11T13:08:00+01:00",
null,
"2026-08-11T13:25:00+01:00",
null,
null,
null,
17,
983,
null
]
],
"routeFields": [
"id",
"durationMinutes",
"transfers",
"walkingDurationMinutes",
"walkingDistanceMeters",
"legRefs"
],
"routes": [
[
"C0",
41,
0,
32,
1863,
[
0,
1,
2
]
],
[
"C1",
38,
1,
21,
1218,
[
3,
4,
5,
6,
7
]
]
],
"imperial": true
}Response Schema
View JSON Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Compact Routes Response",
"type": "object",
"properties": {
"regionName": {
"type": "string",
"description": "Transit data region that served the request"
},
"imperial": {
"type": "boolean",
"description": "Optional flag, present as true for US/UK; numeric distance fields remain in meters"
},
"placeFields": {
"type": "array",
"items": [
{
"const": "stopId"
},
{
"const": "countryIso"
},
{
"const": "name"
},
{
"const": "description"
},
{
"const": "lat"
},
{
"const": "lon"
},
{
"const": "wheelchairBoarding"
}
],
"additionalItems": false,
"minItems": 7,
"maxItems": 7,
"description": "Column order for places rows"
},
"places": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": [
"string",
"null"
],
"description": "Stop identifier for an exact departure request"
},
{
"type": [
"string",
"null"
],
"description": "ISO 3166-1 alpha-3 country code"
},
{
"type": [
"string",
"null"
],
"description": "Place or stop name"
},
{
"type": [
"string",
"null"
],
"description": "Additional place or stop description"
},
{
"type": [
"number",
"null"
],
"description": "Latitude in decimal degrees"
},
{
"type": [
"number",
"null"
],
"description": "Longitude in decimal degrees"
},
{
"enum": [
1,
2,
null
],
"description": "Wheelchair accessibility of the stop"
}
],
"additionalItems": false,
"minItems": 7,
"maxItems": 7
},
"description": "Globally deduplicated leg endpoints"
},
"serviceFields": {
"type": "array",
"items": [
{
"const": "routeId"
},
{
"const": "countryIso"
},
{
"const": "line"
},
{
"const": "headsign"
},
{
"const": "operator"
}
],
"additionalItems": false,
"minItems": 5,
"maxItems": 5,
"description": "Column order for services rows"
},
"services": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": [
"string",
"null"
],
"description": "Route identifier for /line and departure matching"
},
{
"type": [
"string",
"null"
],
"description": "ISO 3166-1 alpha-3 country code"
},
{
"type": [
"string",
"null"
],
"description": "Public-facing route name"
},
{
"type": [
"string",
"null"
],
"description": "Destination shown on the vehicle"
},
{
"type": [
"string",
"null"
],
"description": "Operating agency name"
}
],
"additionalItems": false,
"minItems": 5,
"maxItems": 5
},
"description": "Globally deduplicated route and direction metadata"
},
"legFields": {
"type": "array",
"items": [
{
"const": "id"
},
{
"const": "mode"
},
{
"const": "serviceRef"
},
{
"const": "wheelchairAccessible"
},
{
"const": "fromPlaceRef"
},
{
"const": "toPlaceRef"
},
{
"const": "departureTime"
},
{
"const": "realtimeDepartureTime"
},
{
"const": "arrivalTime"
},
{
"const": "realtimeArrivalTime"
},
{
"const": "departurePlatform"
},
{
"const": "arrivalPlatform"
},
{
"const": "durationMinutes"
},
{
"const": "distanceMeters"
},
{
"const": "intermediateStopCount"
}
],
"additionalItems": false,
"minItems": 15,
"maxItems": 15,
"description": "Column order for legs rows"
},
"legs": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": [
"string",
"null"
],
"description": "Journey leg identifier"
},
{
"type": "string",
"description": "Travel mode"
},
{
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Index into services; null for walking legs"
},
{
"enum": [
1,
2,
null
],
"description": "Wheelchair accessibility of the trip"
},
{
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Index into places for the leg origin"
},
{
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Index into places for the leg destination"
},
{
"type": [
"string",
"null"
],
"description": "Scheduled departure time in ISO 8601"
},
{
"type": [
"string",
"null"
],
"description": "Real-time departure time in ISO 8601"
},
{
"type": [
"string",
"null"
],
"description": "Scheduled arrival time in ISO 8601"
},
{
"type": [
"string",
"null"
],
"description": "Real-time arrival time in ISO 8601"
},
{
"type": [
"string",
"null"
],
"description": "Departure platform or stand"
},
{
"type": [
"string",
"null"
],
"description": "Arrival platform or stand"
},
{
"type": [
"integer",
"null"
],
"description": "Rounded leg duration in minutes"
},
{
"type": [
"integer",
"null"
],
"description": "Leg distance in meters"
},
{
"type": [
"integer",
"null"
],
"description": "Number of intermediate stops"
}
],
"additionalItems": false,
"minItems": 15,
"maxItems": 15
},
"description": "Journey legs referenced by route alternatives"
},
"routeFields": {
"type": "array",
"items": [
{
"const": "id"
},
{
"const": "durationMinutes"
},
{
"const": "transfers"
},
{
"const": "walkingDurationMinutes"
},
{
"const": "walkingDistanceMeters"
},
{
"const": "legRefs"
}
],
"additionalItems": false,
"minItems": 6,
"maxItems": 6,
"description": "Column order for routes rows"
},
"routes": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": [
"string",
"null"
],
"description": "Route alternative identifier"
},
{
"type": [
"integer",
"null"
],
"description": "Rounded total journey time in minutes"
},
{
"type": [
"integer",
"null"
],
"description": "Number of transfers"
},
{
"type": [
"integer",
"null"
],
"description": "Rounded walking time in minutes"
},
{
"type": [
"integer",
"null"
],
"description": "Walking distance in meters"
},
{
"type": "array",
"items": {
"type": "integer",
"minimum": 0
},
"description": "Ordered indexes into legs"
}
],
"additionalItems": false,
"minItems": 6,
"maxItems": 6
},
"description": "Up to the first two route alternatives with unique transit patterns",
"maxItems": 2
},
"noticeFields": {
"type": "array",
"items": [
{
"const": "code"
},
{
"const": "title"
},
{
"const": "regionOrigin"
},
{
"const": "regionDestination"
}
],
"additionalItems": false,
"minItems": 4,
"maxItems": 4,
"description": "Column order for notices rows"
},
"notices": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": [
"string",
"null"
],
"description": "Status code"
},
{
"type": [
"string",
"null"
],
"description": "Notice title"
},
{
"type": [
"string",
"null"
],
"description": "Origin region"
},
{
"type": [
"string",
"null"
],
"description": "Destination region"
}
],
"additionalItems": false,
"minItems": 4,
"maxItems": 4
},
"description": "Informational notices (e.g. noRouteFound, noCoverage)"
},
"alertFields": {
"type": "array",
"items": [
{
"const": "id"
},
{
"const": "cause"
},
{
"const": "effect"
},
{
"const": "header"
},
{
"const": "description"
},
{
"const": "operator"
},
{
"const": "validFrom"
},
{
"const": "validUntil"
},
{
"const": "legRefs"
}
],
"additionalItems": false,
"minItems": 9,
"maxItems": 9,
"description": "Column order for alerts rows"
},
"alerts": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": [
"string",
"null"
],
"description": "Alert identifier"
},
{
"type": [
"string",
"null"
],
"description": "GTFS-RT alert cause"
},
{
"type": [
"string",
"null"
],
"description": "GTFS-RT alert effect"
},
{
"type": [
"string",
"null"
],
"description": "Short alert headline"
},
{
"type": [
"string",
"null"
],
"description": "Full alert text"
},
{
"type": [
"string",
"null"
],
"description": "Operator identifier"
},
{
"type": [
"string",
"null"
],
"description": "Alert start time"
},
{
"type": [
"string",
"null"
],
"description": "Alert end time"
},
{
"type": [
"array",
"null"
],
"items": {
"type": "integer",
"minimum": 0
},
"description": "Indexes into legs affected by the alert"
}
],
"additionalItems": false,
"minItems": 9,
"maxItems": 9
},
"description": "Service alerts/disruptions affecting the result"
}
},
"required": [
"regionName",
"placeFields",
"places",
"serviceFields",
"services",
"legFields",
"legs",
"routeFields",
"routes"
]
}Response Codes
200
Compact routes calculated successfully (or noCoverage notice if region not supported)400
Invalid parameters or coordinates500
Internal server error