Incident Details

The Incident Details service provides real-time and scheduled traffic incident data for a geographic area or a list of known incident IDs. Each incident is a GeoJSON Feature with a Point or LineString geometry, making results easy to display on a map or process server-side.

import { TomTomConfig } from '@tomtom-org/maps-sdk/core';
import { geocodeOne, trafficIncidentDetails } from '@tomtom-org/maps-sdk/services';
import { API_KEY } from './config';

TomTomConfig.instance.put({ apiKey: API_KEY });

(async () => {
    const place = await geocodeOne('Amsterdam');

    const result = await trafficIncidentDetails({
        bbox: place,
        timeValidityFilter: ['present'],
    });

    console.log(`Found ${result.features.length} incident(s)\n`);

    for (const incident of result.features) {
        console.log(JSON.stringify(incident.properties, null, 4));
    }
})();

Core Concepts

Traffic incidents are described by:

  • Category (category): the type of incident — accident, roadworks, jam, road-closed, etc.
  • Delay magnitude: how severe the delay is — minor, moderate, major, or indefinite (road closures).
  • Geometry: a Point for localised incidents, or a LineString for incidents spanning a road stretch.
  • Time validity: whether the incident is present (active now) or future (scheduled).
  • Events: one or more descriptions of what is happening at the incident location.

Basic Usage

Query by Bounding Box

The bbox parameter accepts a raw [minLon, minLat, maxLon, maxLat] tuple, or any GeoJSON object — the bounding box is calculated automatically from the geometry:

import { TomTomConfig } from '@tomtom-org/maps-sdk/core';
import { geocodeOne, trafficIncidentDetails } from '@tomtom-org/maps-sdk/services';
TomTomConfig.instance.put({ apiKey: 'your-api-key' });
// Pass a geocoded place directly — no manual bbox extraction needed
const place = await geocodeOne('Amsterdam');
const result = await trafficIncidentDetails({ bbox: place });
result.features.forEach(incident => {
const { category, magnitudeOfDelay, from, to } = incident.properties;
console.log(`${category} — ${magnitudeOfDelay} delay: ${from} → ${to}`);
});

You can also pass a raw tuple when you already have the coordinates:

const result = await trafficIncidentDetails({
bbox: [4.728, 52.278, 5.08, 52.479] // [minLon, minLat, maxLon, maxLat]
});

Query by Incident IDs

When you already know the IDs of the incidents you are interested in, look them up directly:

const result = await trafficIncidentDetails({
ids: ['incident-id-1', 'incident-id-2', 'incident-id-3']
});

Filtering Results

By Category

Use categoryFilter to restrict results to specific incident types:

const result = await trafficIncidentDetails({
bbox: [4.728, 52.278, 5.08, 52.479],
categoryFilter: ['accident', 'road-closed']
});

Available category values:

ValueDescription
'accident'Traffic accident or collision
'animals-on-road'Animals present on the road
'broken-down-vehicle'Vehicle breakdown causing obstruction
'danger'Dangerous situation on the road
'flooding'Flooded road section
'fog'Fog reducing visibility
'frost'Frost or ice on the road
'jam'Traffic congestion or slow-moving traffic
'lane-closed'One or more lanes closed
'narrow-lanes'Lane narrowing reducing road capacity
'other'Other types of incidents
'rain'Heavy rain affecting driving conditions
'road-closed'Road is closed or blocked
'roadworks'Construction or maintenance work
'wind'Strong wind conditions affecting traffic

By Time Validity

By default only 'present' (currently active) incidents are returned. Include 'future' incidents to see planned works and scheduled events:

const result = await trafficIncidentDetails({
bbox: [4.728, 52.278, 5.08, 52.479],
timeValidityFilter: ['present', 'future']
});

Working with Incident Data

Reading Incident Properties

const incident = result.features[0];
// Geometry — Point or LineString
console.log(incident.geometry.type); // 'Point' | 'LineString'
console.log(incident.geometry.coordinates); // [lon, lat] or [[lon, lat], ...]
const {
id,
category, // 'accident' | 'jam' | 'roadworks' | 'road-closed' | …
magnitudeOfDelay, // 'minor' | 'moderate' | 'major' | 'indefinite' | 'unknown'
events,
from,
to,
lengthInMeters,
delayInSeconds,
roadNumbers,
timeValidity, // 'present' | 'future'
probabilityOfOccurrence, // 'certain' | 'probable' | 'risk_of' | 'improbable'
startTime, // Date | undefined
endTime, // Date | undefined
tmc, // TMC data | undefined
} = incident.properties;

Displaying on a Map

Incident results are standard GeoJSON features and integrate directly with the TomTom Maps SDK:

import maplibregl from 'maplibre-gl';
const result = await trafficIncidentDetails({
bbox: [4.728, 52.278, 5.08, 52.479]
});
// Add incidents as a GeoJSON source
map.addSource('incidents', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: result.features
}
});
// Style Point incidents as circles
map.addLayer({
id: 'incident-points',
type: 'circle',
source: 'incidents',
filter: ['==', ['geometry-type'], 'Point'],
paint: {
'circle-radius': 8,
'circle-color': [
'match', ['get', 'category'],
'accident', '#e74c3c',
'jam', '#e67e22',
'road-closed','#c0392b',
'roadworks', '#f39c12',
'#3498db' // default
]
}
});
// Style LineString incidents as lines
map.addLayer({
id: 'incident-lines',
type: 'line',
source: 'incidents',
filter: ['==', ['geometry-type'], 'LineString'],
paint: {
'line-width': 4,
'line-color': '#e74c3c'
}
});

Filtering by Severity

Focus on the most impactful incidents by filtering client-side on magnitudeOfDelay:

const severeIncidents = result.features.filter(incident =>
incident.properties.magnitudeOfDelay === 'major' ||
incident.properties.magnitudeOfDelay === 'indefinite'
);

Advanced Options

Traffic Model ID

For consistency across multiple traffic API calls made at the same time, pass the same trafficModelId. Obtain it from the Traffic Flow API:

const result = await trafficIncidentDetails({
bbox: [4.728, 52.278, 5.08, 52.479],
trafficModelId: '1234567890'
});

Custom Service Customization

The trafficIncidentDetails function accepts an optional second argument for advanced request/response customization, following the same pattern as other SDK services:

import { trafficIncidentDetails } from '@tomtom-org/maps-sdk/services';
const result = await trafficIncidentDetails(
{ bbox: [4.728, 52.278, 5.08, 52.479] },
{
// Override the request builder to add custom headers or modify the URL
buildRequest: (params) => {
const request = buildTrafficIncidentDetailsRequest(params);
// ... modify request
return request;
}
}
);

Error Handling

try {
const result = await trafficIncidentDetails({
bbox: [4.728, 52.278, 5.08, 52.479]
});
if (result.features.length === 0) {
console.log('No incidents in this area');
}
} catch (error) {
// SDKServiceError contains .status (HTTP code) and .service
console.error('Incident Details request failed:', error.message);
}