The TravelTime API says which hexagons you can reach within a travel time. The Data API says what is in them. You make both requests with your own keys and pass the cells across.
What you need: a TravelTime application id and key from your account page. The same pair calls both APIs; each API has its own rate limits.
Ask for resolution 9: every Data API dataset has it, and cells takes it by default. This request returns the hexagons within 45 minutes of King's Cross by public transport on a weekday morning. travel_time is in seconds.
Request
curl -X POST "https://api.traveltimeapp.com/v4/h3/fast" \
-H "Content-Type: application/json" \
-H "X-Application-Id: YOUR_APP_ID" \
-H "X-Api-Key: YOUR_APP_KEY" \
-d '{
"resolution": 9,
"properties": ["min"],
"arrival_searches": {
"one_to_many": [
{
"id": "kings-cross",
"coords": { "lat": 51.5307, "lng": -0.1238 },
"transportation": { "type": "public_transport" },
"arrival_time_period": "weekday_morning",
"travel_time": 2700
}
]
}
}'Response
{
"results": [
{
"search_id": "kings-cross",
"cells": [
{ "id": "89195db5377ffff", "properties": { "min": 2229 } },
{ "id": "89195da538bffff", "properties": { "min": 2231 } },
"… 8,524 more"
]
}
]
}One entry in results per search. Each cell has an id and properties.min, its shortest travel time in seconds (mean and max are also available). The H3 Fast reference lists every parameter and the other transport types.
Send the id values from step 1 as cells. A 45-minute search returns thousands of them, so use the POST form: every route that takes cells also takes POST with the same fields as JSON, up to the cap in Long requests. For totals, compact them first with h3.compact_cells: a 90-minute drive from Manchester Piccadilly is 138,190 hexagons, sent as 14,980 ids with group_by=all.
The 8,526 hexagons from step 1 hold 3,173 places in the gym category, 100 a page. The body is elided here.
Request
curl -X POST -H "X-Application-Id: YOUR_APP_ID" -H "X-Api-Key: YOUR_APP_KEY" -H "Content-Type: application/json" \
-d '{"cells": ["89195db5377ffff", "89195da538bffff", "… 8,524 more"], "category": "gym"}' \
"https://data.traveltimeapp.com/v1/places"Response
{
"results": [
{
"id": "pl_gb_eebe766f-0e5b-4f8d-aa39-d309de4622c9",
"name": "Northolt Leisure Centre",
"category": "swimming_pool",
"brand": null,
"lat": 51.5491,
"lng": -0.36757,
"cell": "89195daea3bffff",
"verified": true
},
{
"id": "pl_gb_711c6900-311f-4932-8cf9-f538e026d478",
"name": "PureGym",
"category": "gym",
"brand": "PureGym",
"lat": 51.51235,
"lng": -0.0369,
"cell": "89194ad35abffff",
"verified": false
},
"… 98 more on this page"
],
"next_cursor": "eyJxIjoiNDI3NDU5YWVh…"
}Every per-hexagon route takes the same list. All but /v1/boundaries/cells and /v1/custom-scores/cells give one total with group_by=all, and /v1/proximity/cells keeps only the hexagons that meet a condition with within.
6,441,313 people in 2,419,928 households, 48% of them without a car.
Request
curl -X POST -H "X-Application-Id: YOUR_APP_ID" -H "X-Api-Key: YOUR_APP_KEY" -H "Content-Type: application/json" \
-d '{"cells": ["89195db5377ffff", "89195da538bffff", "… 8,524 more"], "group_by": "all"}' \
"https://data.traveltimeapp.com/v1/demographics/cells"Response
{
"results": [
{
"population": 6441313,
"cell_count": 8526,
"census": {
"residents": 6075716,
"households": 2419928,
"no_car_share": 0.484,
"…": "5 more"
}
}
],
"next_cursor": null,
"rollup": {
"cell_count": "sum",
"population": "sum",
"census.residents": "sum",
"census.households": "sum",
"census.no_car_share": "household_weighted_mean",
"…": "5 more"
},
"sources": {
"population": "worldpop_2020",
"census": ["ons_census_2021_ew", "ons_income_fye2020_msoa"]
}
}1,912 of the 8,526 hexagons, 100 a page.
Request
curl -X POST -H "X-Application-Id: YOUR_APP_ID" -H "X-Api-Key: YOUR_APP_KEY" -H "Content-Type: application/json" \
-d '{"cells": ["89195db5377ffff", "89195da538bffff", "… 8,524 more"], "within": "walk.supermarket:300"}' \
"https://data.traveltimeapp.com/v1/proximity/cells"Response
{
"within": "walk.supermarket:300",
"resolution": 9,
"results": [
{
"cell": "89194ad35abffff",
"ratings": { "walk": 96, "transit": 82, "drive": 90 },
"walk_s": { "supermarket": 238, "…": "7 more" },
"drive_s": "…"
},
"… 99 more on this page"
],
"next_cursor": "eyJxIjoiNTA3YWRhNzFj…"
}| Route | What each hexagon gets |
|---|---|
POST /v1/places/cells | Number of places; category_counts with include=categories. |
POST /v1/demographics/cells | People (WorldPop) and the census block: residents, households, age and renter shares, no_car_share, income. |
POST /v1/proximity/cells | Walk, transit and drive ratings; walk_s and drive_s to eight everyday places; within as a sieve. |
POST /v1/neighbourhood/cells | Noise, air quality, flood zone, crime, deprivation, broadband. |
POST /v1/open-spaces/cells | Open space and green m², green share, land cover, and the open spaces by name. |
POST /v1/boundaries/cells | Every boundary the hexagon is in, ward to country; no group_by. |
POST /v1/transport/transit/stations/cells, POST /v1/transport/transit/lines/cells | Stations and lines, with a count per mode. |
Per-hexagon answers have a cap: past it, use group_by=all (not on /boundaries/cells), which takes more res-9 hexagons (Limits). Totals says how each field is added up.