DirectionsResponse
Routing result. `geojson` (FeatureCollection) present when the upstream returned shape geometry. Upstream-emitted fields (`confidence`, `method`, `layer`, `source` on origin/destination resolution) are passed through unchanged. `traffic_provenance` states what traffic did to this specific result.
Properties
| Name | Type | Description |
|---|---|---|
| distance | number | |
| distance_units | string | |
| duration_seconds | number | |
| base_duration_seconds | number | The routing engine's duration with no traffic applied. Equal to duration_seconds. |
| effective_duration_seconds | number | What to plan against: base_duration_seconds adjusted by any computed traffic delay, else identical to base_duration_seconds. |
| traffic_delay_seconds | number | effective_duration_seconds minus base_duration_seconds. Positive means traffic made the ETA slower, negative means it made the ETA faster, and zero means the duration was unchanged. For truck costing, |
| traffic_adjusted_seconds | number | Computed traffic-adjusted duration in seconds when traffic produced an adjustment. Use effective_duration_seconds as the authoritative duration for this response. |
| base_arrival_utc | string | Arrival time assuming base_duration_seconds, in UTC. |
| base_arrival_local | stringnull | Same instant as base_arrival_utc, in the destination's local time. Null when no destination timezone was resolved. |
| effective_arrival_utc | string | Arrival time assuming effective_duration_seconds, in UTC. |
| effective_arrival_local | stringnull | Same instant as effective_arrival_utc, in the destination's local time. Null when no destination timezone was resolved. |
| has_toll | boolean | |
| has_highway | boolean | |
| has_ferry | boolean | |
| costing | string | |
| legs | array | |
| maneuvers | array | |
| maneuver_count | number | |
| timing | object | |
| origin | object | |
| destination | object | |
| geojson | object | |
| alternates | array | |
| traffic | object | Traffic observations consulted along this route. Sample span distances are always expressed in miles; provider-specific legacy extensions may also be present. |
| timezone_start | stringnull | IANA timezone at the route origin, or null when unresolved. Contains information from timezone-boundary-builder, which is made available under the Open Database License (ODbL) v1.0. Timezone boundarie |
| timezone_end | stringnull | IANA timezone at the route destination, or null when unresolved. Contains information from timezone-boundary-builder, which is made available under the Open Database License (ODbL) v1.0. Timezone boun |
| timezone_start_status | string | |
| timezone_end_status | string | |
| timezone_artifact_version | stringnull | |
| elevation_gain_m | numbernull | |
| elevation_loss_m | numbernull | |
| elevation_gain_ft | numbernull | |
| elevation_loss_ft | numbernull | |
| elevation_start_m | numbernull | |
| elevation_end_m | numbernull | |
| elevation_start_ft | numbernull | |
| elevation_end_ft | numbernull | |
| traffic_provenance | object | What traffic actually did to this response: whether it changed the roads chosen, whether it changed the duration, and how fresh the underlying observations were. Always present — when no traffic data |
| meta | object |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/thinair-co/json-schema/thinair-co-directions-response-schema.json",
"title": "DirectionsResponse",
"description": "Routing result. `geojson` (FeatureCollection) present when the upstream returned shape geometry. Upstream-emitted fields (`confidence`, `method`, `layer`, `source` on origin/destination resolution) are passed through unchanged. `traffic_provenance` states what traffic did to this specific result.",
"x-generated": "2026-10-30",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/geo-thinair-co-openapi.json#/components/schemas/DirectionsResponse",
"type": "object",
"properties": {
"distance": {
"type": "number"
},
"distance_units": {
"type": "string",
"enum": [
"miles",
"kilometers"
]
},
"duration_seconds": {
"type": "number"
},
"base_duration_seconds": {
"type": "number",
"description": "The routing engine's duration with no traffic applied. Equal to duration_seconds."
},
"effective_duration_seconds": {
"type": "number",
"description": "What to plan against: base_duration_seconds adjusted by any computed traffic delay, else identical to base_duration_seconds."
},
"traffic_delay_seconds": {
"type": "number",
"description": "effective_duration_seconds minus base_duration_seconds. Positive means traffic made the ETA slower, negative means it made the ETA faster, and zero means the duration was unchanged. For truck costing, general traffic evidence is slowdown-only, so this value is never negative."
},
"traffic_adjusted_seconds": {
"type": "number",
"description": "Computed traffic-adjusted duration in seconds when traffic produced an adjustment. Use effective_duration_seconds as the authoritative duration for this response."
},
"base_arrival_utc": {
"type": "string",
"description": "Arrival time assuming base_duration_seconds, in UTC."
},
"base_arrival_local": {
"type": [
"string",
"null"
],
"description": "Same instant as base_arrival_utc, in the destination's local time. Null when no destination timezone was resolved."
},
"effective_arrival_utc": {
"type": "string",
"description": "Arrival time assuming effective_duration_seconds, in UTC."
},
"effective_arrival_local": {
"type": [
"string",
"null"
],
"description": "Same instant as effective_arrival_utc, in the destination's local time. Null when no destination timezone was resolved."
},
"has_toll": {
"type": "boolean"
},
"has_highway": {
"type": "boolean"
},
"has_ferry": {
"type": "boolean"
},
"costing": {
"type": "string"
},
"legs": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": {}
}
},
"maneuvers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": {}
}
},
"maneuver_count": {
"type": "number"
},
"timing": {
"type": "object",
"properties": {
"departure_utc": {
"type": "string",
"description": "Departure instant, ISO-8601 UTC. Empty string when no route was produced."
},
"departure_local": {
"type": [
"string",
"null"
],
"description": "Departure in the ORIGIN's local time. Null when the origin timezone was not resolved — never a UTC instant relabelled as local."
},
"arrival_utc": {
"type": "string",
"description": "Arrival instant, ISO-8601 UTC. Empty string when no route was produced."
},
"arrival_local": {
"type": [
"string",
"null"
],
"description": "Arrival in the DESTINATION's local time. Null when the destination timezone was not resolved."
},
"origin_timezone": {
"type": [
"string",
"null"
],
"description": "IANA timezone at the origin, or null when unresolved. See origin_timezone_status."
},
"destination_timezone": {
"type": [
"string",
"null"
],
"description": "IANA timezone at the destination, or null when unresolved. See destination_timezone_status."
},
"origin_timezone_status": {
"type": "string",
"enum": [
"resolved",
"boundary_ambiguous",
"source_conflict",
"not_covered",
"unavailable"
],
"description": "Why origin_timezone is what it is. Only `resolved` carries a name; the rest explain the null rather than hiding it."
},
"destination_timezone_status": {
"type": "string",
"enum": [
"resolved",
"boundary_ambiguous",
"source_conflict",
"not_covered",
"unavailable"
],
"description": "Why destination_timezone is what it is."
},
"timezone_artifact_version": {
"type": [
"string",
"null"
],
"description": "Boundary artifact both timezones came from. Null when none is active."
},
"duration_seconds": {
"type": "number",
"description": "Routed duration in seconds. 0 when no route was produced."
},
"timezones_crossed": {
"type": "array",
"items": {
"type": "string"
},
"description": "Distinct IANA zones sampled along the route, present ONLY when the route crosses more than one. An unresolved sample is omitted rather than contributing a fabricated crossing."
}
},
"required": [
"departure_utc",
"departure_local",
"arrival_utc",
"arrival_local",
"origin_timezone",
"destination_timezone",
"origin_timezone_status",
"destination_timezone_status",
"timezone_artifact_version",
"duration_seconds"
],
"additionalProperties": {}
},
"origin": {
"type": "object",
"additionalProperties": {}
},
"destination": {
"type": "object",
"additionalProperties": {}
},
"geojson": {
"type": "object",
"additionalProperties": {}
},
"alternates": {
"type": "array",
"items": {
"type": "object",
"properties": {
"distance": {
"type": "number"
},
"distance_units": {
"type": "string",
"enum": [
"miles",
"kilometers"
]
},
"duration_seconds": {
"type": "number"
},
"legs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"leg": {
"type": "number"
},
"distance": {
"type": "number"
},
"duration_seconds": {
"type": "number"
},
"maneuvers": {
"type": "number"
}
},
"required": [
"leg",
"distance",
"duration_seconds",
"maneuvers"
],
"additionalProperties": {}
}
},
"maneuvers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"instruction": {
"type": "string"
},
"distance": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
"time": {
"type": "number"
},
"type": {
"type": "number"
},
"begin_shape_index": {
"type": "number"
}
},
"additionalProperties": {}
}
},
"geojson": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"FeatureCollection"
]
},
"features": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Feature"
]
},
"id": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
},
"geometry": {
"type": [
"object",
"null"
],
"properties": {
"type": {
"anyOf": [
{
"type": "string",
"enum": [
"Point",
"LineString",
"Polygon",
"MultiPoint",
"MultiLineString",
"MultiPolygon",
"GeometryCollection"
]
},
{
"type": "string"
}
]
},
"coordinates": {},
"geometries": {
"type": "array",
"items": {}
}
},
"required": [
"type"
],
"additionalProperties": {}
},
"properties": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"type",
"geometry"
],
"additionalProperties": {}
}
}
},
"required": [
"type",
"features"
],
"additionalProperties": {}
},
"geometry": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"distance",
"distance_units",
"duration_seconds",
"legs",
"maneuvers"
],
"additionalProperties": {}
}
},
"traffic": {
"type": "object",
"properties": {
"sample_count": {
"type": "integer",
"minimum": 0
},
"sample_spacing_mi": {
"type": "number",
"minimum": 0,
"description": "Nominal spacing between traffic observations, in miles, regardless of the route's display units."
},
"samples": {
"type": "array",
"items": {
"type": "object",
"properties": {
"mile": {
"type": "number",
"description": "Approximate mile marker along the route for this observation."
},
"lat": {
"type": "number"
},
"lon": {
"type": "number"
},
"current_speed": {
"type": "number"
},
"free_flow_speed": {
"type": "number"
},
"congestion": {
"type": "string"
},
"units": {
"type": "string"
},
"measured_mi": {
"type": "number",
"description": "Length of road actually measured by this observation, in miles. Omitted when the provider reported no measurable span."
},
"measured_start_mi": {
"type": "number",
"description": "Start of the measured span as distance along the route, in miles."
},
"measured_end_mi": {
"type": "number",
"description": "End of the measured span as distance along the route, in miles."
}
},
"required": [
"mile",
"lat",
"lon"
],
"additionalProperties": {}
}
},
"adjusted_time_factor": {
"type": "number"
},
"adjusted_eta_seconds": {
"type": "number"
},
"error": {
"type": "string"
}
},
"required": [
"sample_count",
"sample_spacing_mi",
"samples"
],
"additionalProperties": {},
"description": "Traffic observations consulted along this route. Sample span distances are always expressed in miles; provider-specific legacy extensions may also be present."
},
"timezone_start": {
"type": [
"string",
"null"
],
"description": "IANA timezone at the route origin, or null when unresolved. Contains information from timezone-boundary-builder, which is made available under the Open Database License (ODbL) v1.0. Timezone boundaries © OpenStreetMap contributors. US legal-zone cross-check: U.S. Department of Transportation, Bureau of Transportation Statistics (public domain)."
},
"timezone_end": {
"type": [
"string",
"null"
],
"description": "IANA timezone at the route destination, or null when unresolved. Contains information from timezone-boundary-builder, which is made available under the Open Database License (ODbL) v1.0. Timezone boundaries © OpenStreetMap contributors. US legal-zone cross-check: U.S. Department of Transportation, Bureau of Transportation Statistics (public domain)."
},
"timezone_start_status": {
"type": "string",
"enum": [
"resolved",
"boundary_ambiguous",
"source_conflict",
"not_covered",
"unavailable"
]
},
"timezone_end_status": {
"type": "string",
"enum": [
"resolved",
"boundary_ambiguous",
"source_conflict",
"not_covered",
"unavailable"
]
},
"timezone_artifact_version": {
"type": [
"string",
"null"
]
},
"elevation_gain_m": {
"type": [
"number",
"null"
]
},
"elevation_loss_m": {
"type": [
"number",
"null"
]
},
"elevation_gain_ft": {
"type": [
"number",
"null"
]
},
"elevation_loss_ft": {
"type": [
"number",
"null"
]
},
"elevation_start_m": {
"type": [
"number",
"null"
]
},
"elevation_end_m": {
"type": [
"number",
"null"
]
},
"elevation_start_ft": {
"type": [
"number",
"null"
]
},
"elevation_end_ft": {
"type": [
"number",
"null"
]
},
"traffic_provenance": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"none",
"eta_enrichment",
"candidate_ranking",
"native_live_routing",
"native_predicted_routing"
],
"description": "Which traffic-processing rung this request attempted. `none`: no traffic data was consulted. `eta_enrichment`: after the route was chosen, traffic evidence was sought only to adjust its estimated duration; the roads returned are unchanged. The attempt may fail or produce no adjustment, so inspect `outcome` and `duration_influenced` for what reached this answer. `candidate_ranking`: traffic re-ranked several candidate routes against each other. `native_live_routing`: live speeds were used to choose which roads to take. `native_predicted_routing`: as above, plus time-of-day predicted speeds for a future departure."
},
"outcome": {
"type": "string",
"enum": [
"TRAFFIC_DISABLED",
"PROVIDER_DISABLED",
"QUOTA_EXHAUSTED",
"NO_SEGMENT_MATCH",
"INSUFFICIENT_COVERAGE",
"STALE_EVIDENCE",
"UPSTREAM_ERROR",
"APPLIED"
],
"description": "Neutral, stable reason code for what happened to traffic evidence on this request. `TRAFFIC_DISABLED`: no traffic evidence was sought. `PROVIDER_DISABLED`: evidence was sought but the traffic backend was not configured. `QUOTA_EXHAUSTED`: the traffic backend's spend allotment was exhausted. `NO_SEGMENT_MATCH`: the backend answered but no sample matched a live road segment. `INSUFFICIENT_COVERAGE`: the backend reported no sensor coverage for the sampled area. `STALE_EVIDENCE`: an adjustment was computed, but the evidence behind it was fetched more than 30 minutes ago because the provider could not refresh it. `UPSTREAM_ERROR`: a configured backend or network failure prevented reading all requested traffic evidence. `APPLIED`: an adjustment was computed and reached this response; inspect `retrieved_at` / `retrieval_age_seconds` to see how old the evidence behind it is (acquisition age — this traffic source reports no observation time, see those fields' own descriptions). Material failure codes take precedence over `APPLIED` when only partial evidence adjusted the duration; `duration_influenced` remains true in that case."
},
"path_influenced": {
"type": "boolean",
"description": "Whether traffic could have changed WHICH roads were returned. False today: the route is selected from the road network's own speeds, so traffic never changes the path — only the estimated duration."
},
"duration_influenced": {
"type": "boolean",
"description": "Whether traffic actually changed the duration returned by THIS request. False when no traffic adjustment was applied, even if traffic was requested and fetched successfully."
},
"source_as_of": {
"type": [
"string",
"null"
],
"deprecated": true,
"description": "DEPRECATED since 2026-09-24, always null. The traffic source provides no observation timestamp, so this field can never be filled honestly. See `retrieved_at` for when ThinAir fetched the traffic evidence (not when it was observed). Will be removed in /v2."
},
"route_coverage_pct": {
"type": [
"number",
"null"
],
"description": "Percentage of the route's distance backed by a live traffic observation. This is a MEASURED figure, not an attributed one: it sums the length of road each traffic observation actually matched and divides by the route distance. Coverage can range from sparse observations to most of a corridor, depending on the evidence available for this request; use the returned value rather than assuming a sampling pattern. A low percentage does not mean the ETA is unreliable; it means most of the route's duration comes from the road network's own speeds rather than from live observation. Null when no live traffic observation carried a measurable length."
},
"freshness_seconds": {
"type": [
"number",
"null"
],
"deprecated": true,
"description": "DEPRECATED since 2026-09-24, always null — same reason as `source_as_of`. See `retrieval_age_seconds` for the acquisition age ThinAir CAN report honestly. Will be removed in /v2."
},
"retrieved_at": {
"type": [
"string",
"null"
],
"description": "ISO 8601 time when ThinAir fetched the traffic evidence behind this response (point or tile). This is acquisition metadata, not the time the traffic was observed — the traffic source reports no observation time (see `source_as_of`). Null when no consulted sample's acquisition time was determinable."
},
"retrieval_age_seconds": {
"type": [
"number",
"null"
],
"description": "Age, in seconds, of `retrieved_at` — how long ago ThinAir fetched the traffic evidence behind this response (point or tile). This is acquisition/cache age, not traffic-observation freshness. Null under the same condition as `retrieved_at`."
},
"routing_release_id": {
"type": [
"string",
"null"
],
"description": "Identifier of the road-network build that produced this route. Null today: the routing engine does not report one."
},
"overlay_epoch": {
"type": [
"string",
"null"
],
"description": "Identifier of the live-speed overlay applied to the road network. Null today: no live-speed overlay is in use."
}
},
"required": [
"mode",
"outcome",
"path_influenced",
"duration_influenced",
"source_as_of",
"route_coverage_pct",
"freshness_seconds",
"retrieved_at",
"retrieval_age_seconds",
"routing_release_id",
"overlay_epoch"
],
"additionalProperties": false,
"description": "What traffic actually did to this response: whether it changed the roads chosen, whether it changed the duration, and how fresh the underlying observations were. Always present — when no traffic data was consulted it reports mode `none` rather than being omitted."
},
"meta": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"distance",
"distance_units",
"duration_seconds",
"base_duration_seconds",
"effective_duration_seconds",
"traffic_delay_seconds",
"base_arrival_utc",
"base_arrival_local",
"effective_arrival_utc",
"effective_arrival_local",
"has_toll",
"has_highway",
"has_ferry",
"costing",
"legs",
"maneuvers",
"maneuver_count",
"timing",
"origin",
"destination",
"timezone_start",
"timezone_end",
"timezone_start_status",
"timezone_end_status",
"timezone_artifact_version",
"elevation_gain_m",
"elevation_loss_m",
"elevation_gain_ft",
"elevation_loss_ft",
"elevation_start_m",
"elevation_end_m",
"elevation_start_ft",
"elevation_end_ft",
"traffic_provenance",
"meta"
],
"additionalProperties": {}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/thinair-co-directions-response"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.