Traffic Volume
Important Note
Explore ready-to-use traffic reports and data visualizations immediately by signing up for a 30-day free trial on the MOVE Portal. Once registered, you'll receive an API key to start using the Traffic Analytics APIs right away. Alternatively, you may contact our Sales team for a tailored solution.
Purpose
The Traffic Stats API Traffic Volume service provides estimated historical vehicle counts for road segments within an area. This service is asynchronous.
Unlike Traffic Density, which reports the number of observed probe samples, Traffic Volume uses a statistical model to estimate the total number of vehicle passages — including vehicles not captured by probe data. The result represents a model-based estimate of all historical traffic, not just the sampled portion.
There are two endpoints consuming two types of requests. The first one is only for ordering jobs with POST requests.
In its response the user receives a jobId, which should be used in the second endpoint with a GET request to
the check job's status. When the job is successfully finished, the user will receive links in the response to
download the results.
Using this service
There are some important notes about using this API service:
- The latitude and longitude coordinates are in EPSG4326 / WGS84 format for both input and output. Other coordinate systems are not supported.
- The current API version is 1.
- The maximum length of date range is 366 days.
- The maximum number of time sets is 24.
- Network size, calculated as the size of the convex hull of a defined geometry, cannot be greater than 20000 km².
- As the service is asynchronous it can take a while before results are available, depending on how busy the service is. Do not repost your request multiple times if you do not get feedback within minutes, we will ensure that the results are delivered.
- At the same time you can have only 5 jobs in CALCULATIONS and SCHEDULED statuses per each developer key. When you reach this limit you can still create new jobs as they will be queued until at least one of currently running jobs is processed.
- The map version is always selected automatically by the system based on the requested date range.
- Traffic Volume data always covers all vehicle types — both passenger and fleet vehicles combined. The data composition cannot be changed.
- Segment results in the GeoJSON output may include optional third-party ID mappings (
openLr,gersIdMapping,osmIdMapping). These fields are only present when enabled at the contract level and are not available in SHAPE format.
Traffic Volume Coverage
Traffic Volume data is available on the Orbis map only. Coverage is limited to the countries listed below.
Americas
Market | Country code | Available from |
|---|---|---|
| United States | US | 2023 |
Asia Pacific
Market | Country code | Available from |
|---|---|---|
| Australia | AU | 2024 |
Europe
Market | Country code | Available from |
|---|---|---|
| Belgium | BE | 2024 |
| Netherlands | NL | 2024 |
| Norway | NO | 2024 |
| Sweden | SE | 2024 |
| United Kingdom | GB | 2024 |
Request data
HTTPS method: POST
Constants and parameters enclosed in curly brackets { } must be replaced with their values.
URL format
https://api.tomtom.com/traffic/trafficstats/trafficvolume/1?key={Your_API_Key}
curl format
curl -X POST -H"Content-type: application/json" -d'{request body here}' 'https://api.tomtom.com/traffic/trafficstats/trafficvolume/1?key={Your_API_Key}'
Required headers
| Header | Value |
|---|---|
| Content-Type |
|
Request parameters
The following table describes all of the parameters that can be used in a request. Required parameters must be used or the call will fail. Optional parameters may be used.
| Required parameters | Description |
|---|---|
| Authorization key for access to the API. |
Request POST body example - JSON
1{2 "jobName": "Test job",3 "distanceUnit": "KILOMETERS",4 "acceptMode": "MANUAL",5 "network": {6 "name": "City of London",7 "geometry": {8 "type": "Polygon",9 "coordinates": [10 [11 [-0.1004, 51.5123],12 [-0.0932, 51.5123],13 [-0.0932, 51.5178],14 [-0.1004, 51.5178],15 [-0.1004, 51.5123]16 ]17 ]18 },19 "timeZoneId": "Europe/London",20 "frcs": [0, 1, 2, 3, 4]21 },22 "dateRange": {23 "name": "Wednesday 15 January 2025",24 "from": "2025-01-15",25 "to": "2025-01-15"26 },27 "timeSets": [28 {29 "name": "Wednesday morning peak",30 "timeGroups": [31 {32 "days": ["WED"],33 "times": ["7:00-9:00"]34 }35 ]36 }37 ]38}
Request POST body parameters - JSON
The following JSON parameters refer to the POST request body.
| Required parameters | Description |
|---|---|
| Job name. Given for the user's convenience. |
| Base unit used for distance and speed values.
|
| Network for calculations. See the Structure of network section. |
| Range of dates for calculations. See the Structure of dateRange section. |
| Time sets for calculations.
See the Structure of timeSets section. |
| Optional parameters | Description |
|---|---|
| Defines whether the job should be accepted manually or automatically.
Default value: |
Structure of network
| Required parameters | Description |
|---|---|
| Name of the network. |
| In which time zone all times are given.
Value: A time zone like: |
| Functional road classes. |
| Geometry of the network in GeoJSON format. Supported geometry types are
|
Structure of dateRange
| Required parameters | Description |
|---|---|
| Date range name. Given for the user's convenience. |
| The date from (inclusive). |
| The date to (inclusive). |
| Optional parameters | Description |
|---|---|
| List of days excluded from the date range. |
| List of days of the week to be excluded.
|
Structure of timeSets
| Required parameters | Description |
|---|---|
| Time set name. |
| List of time groups. See the Structure of timeGroups section. |
Structure of timeGroups
| Required parameters | Description |
|---|---|
| Days of week for the time group. List of values selected from:
|
| Time ranges for the time group.
A list of values in the format: |
Response data
In the response to the request a jobId is provided, which is required for further communication about
the query. A JSON response content example:
1{2 "jobId": "677",3 "responseStatus": "OK",4 "messages": ["Job created. Processing started."]5}
Check job status
When a job has been initiated via the API request, it is possible to check the status.
Job status request
https://api.tomtom.com/traffic/trafficstats/status/1/{job_id}?key={Your_API_Key}
Job status request parameters
The following table describes all of the parameters that can be used in a request. Required parameters must be used or the call will fail. Optional parameters may be used.
| Required parameters | Description |
|---|---|
| The job ID. |
| Authorization key for access to the API. |
JSON response
1{2 "jobId": "{job_id}",3 "jobState": "{job_status}",4 "responseStatus": "OK"5}
Job status flow
During the process there are different stages applicable. Via the get state request you can see what the state of your job is. The following table shows the different stages of the process.
| Status | Description |
|---|---|
NEW | The job is waiting for scheduling. |
SCHEDULED | Job is scheduled for processing. |
MAPMATCHING | Mapmatching is in progress. |
MAPMATCHED | Mapmatching is done and the job is waiting for Geobase reading. |
READING_GEOBASE | Geobase reading is in progress. |
CALCULATIONS | Calculations are in progress. |
NEED_CONFIRMATION | Occurs only if manual acceptance mode was used. The results are waiting to be accepted or rejected. In this state network coverage summaries for the job are provided when checking the job status. |
DONE | The results are waiting to be downloaded. |
ERROR | Processing failed. This can occur at any place in the flow. |
REJECTED | The job is rejected. During processing it turned out that the job exceeds set limits, or geometry cannot be processed (it is effectively empty because there are no roads with selected frcs or it is defined on an area which is not supported). This can occur at any place in the flow. |
CANCELLED | The job is cancelled. The owner of the job stopped processing it. It can be done at any time before the job is processed. |
EXPIRED | The job is older than 2 years and all data has been removed. |
Confirming job results
When the job's state is NEED_CONFIRMATION, then a summary URL will be available in the response.
1{2 "jobId": "{job_id}",3 "jobState": "NEED_CONFIRMATION",4 "sampleDetailsUrl": "{url_for_network_coverage_summary_file}",5 "responseStatus": "OK",6 "messages": ["For more details see: {url_for_network_coverage_summary_file}"]7}
A network coverage summary file looks like this:
1{2 "summaries": [3 {4 "locationName": "City of London",5 "dateRangeName": "Wednesday 15 January 2025",6 "timeSetName": "Wednesday morning peak",7 "networkLength": 12.53,8 "coveredNetworkLength": 11.11,9 "distanceUnit": "KILOMETERS",10 "frcDetails": [11 {12 "frc": 0,13 "networkLength": 0.0,14 "coveredNetworkLength": 0.0,15 "distanceUnit": "KILOMETERS"16 },17 {18 "frc": 1,19 "networkLength": 3.25,20 "coveredNetworkLength": 3.25,21 "distanceUnit": "KILOMETERS"22 },23 {24 "frc": 2,25 "networkLength": 1.92,26 "coveredNetworkLength": 1.92,27 "distanceUnit": "KILOMETERS"28 },29 {30 "frc": 3,31 "networkLength": 0.31,32 "coveredNetworkLength": 0.31,33 "distanceUnit": "KILOMETERS"34 },35 {36 "frc": 4,37 "networkLength": 0.51,38 "coveredNetworkLength": 0.51,39 "distanceUnit": "KILOMETERS"40 },41 {42 "frc": 5,43 "networkLength": 0.0,44 "coveredNetworkLength": 0.0,45 "distanceUnit": "KILOMETERS"46 },47 {48 "frc": 6,49 "networkLength": 0.97,50 "coveredNetworkLength": 0.87,51 "distanceUnit": "KILOMETERS"52 },53 {54 "frc": 7,55 "networkLength": 5.56,56 "coveredNetworkLength": 4.24,57 "distanceUnit": "KILOMETERS"58 }59 ]60 }61 ]62}
If you wish to accept the job, make the following request:
https://api.tomtom.com/traffic/trafficstats/status/1/{job_id}/accept?key={Your_API_Key}
Otherwise reject the job with the following request:
https://api.tomtom.com/traffic/trafficstats/status/1/{job_id}/reject?key={Your_API_Key}
Response data
Final DONE response
1{2 "jobId": "{job_id}",3 "jobState": "DONE",4 "responseStatus": "OK",5 "urls": [6 "{url_for_geojson_result_file}",7 "{url_for_shape_result_file}"8 ]9}
Results
Output of Traffic Volume is available in the following formats:
- GeoJSON
- SHAPE
GeoJSON results are provided in a gzip compressed format. SHAPE files are packed into zip archives.
GeoJSON result description
The GeoJSON result is a FeatureCollection. The first feature contains job-level metadata in its
properties, with geometry set to null. Each subsequent feature represents a single road segment.
1{2 "type": "FeatureCollection",3 "features": [4 {5 "type": "Feature",6 "geometry": null,7 "properties": {8 "jobName": "Copy of BARCELONA",9 "creationTime": "2026-04-01T07:57:57.108025573Z",10 "userPreference": {11 "distanceUnit": "KILOMETERS"12 },13 "dateRanges": [14 {15 "@id": 1,16 "name": "FWB",17 "from": "2025-10-01",18 "to": "2025-10-31",19 "exclusions": [],20 "excludedDaysOfWeek": []21 }22 ],23 "timeSets": [24 {25 "@id": 2,26 "name": "0:00-24:00",27 "dayToTimeRanges": [28 { "dayOfWeek": "MONDAY", "timeRanges": ["00:00-24:00"] },29 { "dayOfWeek": "TUESDAY", "timeRanges": ["00:00-24:00"] },30 { "dayOfWeek": "WEDNESDAY", "timeRanges": ["00:00-24:00"] },31 { "dayOfWeek": "THURSDAY", "timeRanges": ["00:00-24:00"] },32 { "dayOfWeek": "FRIDAY", "timeRanges": ["00:00-24:00"] },33 { "dayOfWeek": "SATURDAY", "timeRanges": ["00:00-24:00"] },34 { "dayOfWeek": "SUNDAY", "timeRanges": ["00:00-24:00"] }35 ]36 }37 ],38 "networkName": "BARCELONA",39 "zoneId": "Europe/Madrid",40 "probeSource": "ALL",41 "mapsVersions": ["SouthWestEurope_eur2025.12.1800-23.125-0 OPEN_DSEG"]42 }43 },44 {45 "type": "Feature",46 "geometry": {47 "type": "LineString",48 "coordinates": [49 [2.12857, 41.37935],50 [2.12853, 41.37937],51 [2.12847, 41.37941],52 [2.12840, 41.37946],53 [2.12834, 41.37952],54 [2.12829, 41.37958],55 [2.12828, 41.37964],56 [2.12828, 41.37970],57 [2.12831, 41.37976]58 ]59 },60 "properties": {61 "segmentId": 1156333907664011264,62 "newSegmentId": "1156333907664011264",63 "speedLimit": 50,64 "frc": 2,65 "streetName": "Gran Via de Carles III",66 "distance": 54.99,67 "openLr": "CwGDfx1s4hZbAP/nACkWEA==",68 "gersIdMapping": {69 "id": "ca10e7c8-3502-4f11-80a7-bbc39004ff84",70 "startOffset": 0.0,71 "endOffset": 0.072 },73 "osmIdMapping": [74 { "osmId": "86163010", "length": 54.99, "offset": 0.0 }75 ],76 "segmentVolumes": [77 { "timeSet": 2, "dateRange": 1, "volume": 160129 }78 ]79 }80 }81 ]82}
Job metadata feature
| Field | Description |
|---|---|
| From the request. |
| The job creation time. |
| Requested preference. |
| From the request. Value: See the Structure of dateRanges section. |
| From the request. |
| From and as in the request. |
| From and as in the request. |
| Always |
| Version(s) of maps used for map matching. Selected automatically by the |
Structure of dateRanges
| Field | Description |
|---|---|
| Helper reference for further use (in |
| From and as in the request. |
| From and as in the request. |
| From and as in the request. |
| Based on request values from:
|
Structure of timeSets
| Field | Description |
|---|---|
| Helper reference for further use (in
|
| From and as in the request. |
| Time ranges from the request, grouped per day of the week:
|
Segment features
Each segment feature has a LineString geometry and the following properties:
| Field | Description |
|---|---|
| A unique numeric identifier for the road segment. |
| A string representation of the unique segment identifier. |
| Speed limit (in kmph or mph according to userPreference). |
| Functional Road Class. |
| The street name. |
| The length of a segment (in meters or feet according to |
| See the Structure of segmentVolumes |
| The geometry of the segment encoded in OpenLR |
| Mapping from this segment to a |
| Mapping from this segment to one or more OpenStreetMap ways. |
Structure of segmentVolumes
Field | Description |
|---|---|
timeSet integer | Reference to TimeSet in which calculations were made. |
dateRange integer | Reference to DateRange in which calculations were made. |
volume integer | The estimated number of vehicle passages on the segment for the given |
Structure of gersIdMapping
Field | Description |
|---|---|
id string | The GERS ID of the Overture Maps feature this segment maps to. Formatted |
startOffset float | Distance in meters or feet (according to |
endOffset float | Distance in meters or feet (according to |
Example: understanding startOffset and endOffset
startOffset is the gap between the GERS feature start and this segment's start.
endOffset is the gap between this segment's end and the GERS feature end.
The invariant is: startOffset + segmentLength + endOffset ≈ total GERS feature length.
Three segments tile GERS feature 3ccf363f-6b9b-4a01-b3ac-4dd110c7b9b4 end-to-end:
1GERS feature 3ccf363f-6b9b-4a01-b3ac-4dd110c7b9b4 (total ~105.168 m):2|←——————————————————————— —————————————————————————→|34Segment A — covers [0 → 50 m] (segmentLength = 50.0 m):5|←——————————————————————→ |6 startOffset = 0.0 endOffset = 55.16878Segment B — covers [50 → 77.58 m] (segmentLength = 27.58 m):9| ←———————————→ |10 startOffset = 50.0 endOffset = 27.5841112Segment C — covers [77.584 → 105.168 m] (segmentLength = 27.58 m):13| ←———————————→|14 startOffset = 77.584 endOffset = 0.0
JSON example (Segment A):
1{2 "segmentId": 1161128122481737730,3 "gersIdMapping": {4 "id": "3ccf363f-6b9b-4a01-b3ac-4dd110c7b9b4",5 "startOffset": 0.0,6 "endOffset": 55.1687 }8}
JSON example (Segment B):
1{2 "segmentId": 1161128122481737732,3 "gersIdMapping": {4 "id": "3ccf363f-6b9b-4a01-b3ac-4dd110c7b9b4",5 "startOffset": 50.0,6 "endOffset": 27.5847 }8}
JSON example (Segment C):
1{2 "segmentId": 1161128122481737734,3 "gersIdMapping": {4 "id": "3ccf363f-6b9b-4a01-b3ac-4dd110c7b9b4",5 "startOffset": 77.584,6 "endOffset": 0.07 }8}
Example: reversed segments and GERS geometry direction
A GERS feature has a fixed geometry direction (from its defined start to its defined end). TomTom road segments mapped to the same GERS feature can run in either direction — with or against the GERS feature's direction. This is common for bidirectional roads, where both travel directions share the same GERS feature.
For a segment running in the same direction as the GERS feature ("forward"):
startOffset= distance from GERS start to the segment's startendOffset= distance from the segment's end to GERS end
For a segment running opposite to the GERS feature ("reversed"):
startOffset= distance from GERS end to the segment's startendOffset= distance from GERS start to the segment's end
The invariant startOffset + segmentLength + endOffset ≈ total GERS length holds in both cases.
1GERS feature (total ~1225.191 m, direction →):2A (0 m) B (500 m) E (1225.191 m)3|←————————————————————————→|←————————————————————————————→|45Forward segment A→B (runs with GERS direction):6 startOffset = 0.0 endOffset = 725.1917 Sub-geometry: GERS[A → B] = GERS[0 → 500 m] ← already in correct direction89Reversed segment B→A (runs against GERS direction):10 startOffset = 725.191 endOffset = 0.011 Sub-geometry: GERS[endOffset → total−startOffset] = GERS[0 → 500 m], then reverse
To detect whether a segment is reversed: compare the segment's first coordinate with the
GERS feature geometry (fetched from Overture Maps by id). If it is near the GERS end
rather than the GERS start, the segment is reversed.
JSON example — forward segment (A→B):
1{2 "segmentId": 1160846647740727298,3 "gersIdMapping": {4 "id": "3495e20b-7ad6-4348-b2b5-66dd5d9690f2",5 "startOffset": 0.0,6 "endOffset": 725.1917 }8}
JSON example — reversed segment (B→A), same physical road section:
1{2 "segmentId": 1160846647740727299,3 "gersIdMapping": {4 "id": "3495e20b-7ad6-4348-b2b5-66dd5d9690f2",5 "startOffset": 725.191,6 "endOffset": 0.07 }8}
Both segments cover the same 500 m stretch of road. The reversed segment's offsets are
"mirrored" relative to the GERS feature ends. To apply the GERS geometry for the reversed
segment, extract the sub-geometry from endOffset (0 m) to total − startOffset (500 m),
then reverse it to match the segment's travel direction.
Structure of osmIdMapping
Each entry in the osmIdMapping array describes the relationship between this segment and one
OpenStreetMap way.
Field | Description |
|---|---|
osmId string | The OpenStreetMap way ID. |
length float | The total length of the OSM way, in meters or feet (according to |
offset float | Position of the OSM way relative to the start of this segment, in meters |
Example: understanding the offset field
The offset field answers one question: where does the OSM way start, relative to this
segment's start?
- Positive offset — the OSM way starts ahead of the segment start. The segment begins
before the OSM way and enters it after
offsetmeters or feet. - Negative offset — the OSM way starts behind the segment start. The segment starts
already inside the OSM way, at position
−offsetfrom the OSM way start.
The formula is: position_of_segment_start_along_OSM_way = −offset
The following three segments all run along the same OSM way (131023305, 388.698 m). Their
offsets chain together — each segment starts exactly where the previous one ends on the OSM way.
1OSM way 131023305 (388.698 m):2 |←———————————————————————————————————————————————————————————————————————————→|34Seg 204 (200.0 m, offset = +122.137):5|←—————————————————————————————————————→|6|←————— 122.137 m —————→|78Seg 206 (155.4 m, offset = −77.863):9 |←————————————————————————————→|10 |←— 77.863 m ——→|1112Seg 208 (155.43 m, offset = −233.267):13 |←————————————————————————————→|14 |←———————————————— 233.267 m —————————————————→|
Reading the diagram:
- Seg 204 starts 122.137 m before the OSM way. It enters the OSM way 122.137 m into its own journey and covers the first 77.863 m of the OSM way (200.0 − 122.137 = 77.863 m).
- Seg 206 starts right where Seg 204 ends on the OSM way (77.863 m from the OSM start) and covers the next 155.4 m.
- Seg 208 starts at 233.267 m into the OSM way and runs to its end (233.267 + 155.43 ≈ 388.7 m).
JSON examples:
{ "osmId": "131023305", "length": 388.698, "offset": 122.137 }
Seg 204 starts 122.137 m before the OSM way start.
{ "osmId": "131023305", "length": 388.698, "offset": -77.863 }
Seg 206 starts 77.863 m into the OSM way.
{ "osmId": "131023305", "length": 388.698, "offset": -233.267 }
Seg 208 starts 233.267 m into the OSM way.
Example: reversed segments and OSM way direction
An OSM way has a fixed geometry direction (from its defined start to its defined end). TomTom road segments mapped to the same OSM way can run in either direction — with or against the OSM way's direction. This is common for bidirectional roads, where both travel directions share the same OSM way.
For a segment running in the same direction as the OSM way ("forward"):
segment_start_position_in_OSM_way = −offset
For a segment running opposite to the OSM way ("reversed"):
segment_start_position_in_OSM_way = length + offset
The sub-geometry to extract differs accordingly:
- Forward: extract OSM geometry from
(−offset)to(−offset + segmentLength) - Reversed: extract OSM geometry from
(length + offset − segmentLength)to(length + offset), then reverse it
1OSM way 7390012 (total ~1206.45 m, direction →):2A (0 m) B (500 m) E (1206.45 m)3|←————————————————————————→|←————————————————————————————→|45Forward segment A→B (runs with OSM direction):6 offset = 0.0 → start = −offset = 0 m from OSM start7 Extract OSM[A → B] = OSM[0 → 500 m] ← already in correct direction89Reversed segment B→A (runs against OSM direction):10 offset = −706.4511 end = length + offset = 1206.45 + (−706.45) = 500 m12 start = length + offset − segLength = 1206.45 + (−706.45) − 500 = 0 m13 Extract OSM[A → B] = OSM[0 → 500 m], then reverse
To detect whether a segment is reversed: compare the segment's first coordinate with the OSM
way geometry (fetched from OpenStreetMap by osmId). If it is near the OSM way's end
rather than its start, the segment is reversed.
JSON example — forward segment (A→B):
{ "osmId": "7390012", "length": 1206.45, "offset": 0.0 }
JSON example — reversed segment (B→A), same physical road section:
{ "osmId": "7390012", "length": 1206.45, "offset": -706.45 }
Both segments cover the same 500 m stretch of road. For the reversed segment,
length + offset gives the sub-geometry end (500 m from OSM start), and
length + offset − segmentLength gives its start (0 m). Extract OSM[0 → 500 m],
then reverse it to match the segment's travel direction.