Developers

MapsBox API v1

Read, create and update the road incidents in your workspace over HTTPS, and parse plain-English reports into structured data.

The base URL is https://mapbox.cc/v1. Requests and responses are JSON, except when you ask for GeoJSON. The API sends Access-Control-Allow-Origin: * and answers OPTIONS preflight requests with 204, so it can be called from a browser. It does not use cookies.

You need a workspace to get a token. Start a free trial

Authentication

Create a token in the console under API tokens (admins and owners can create them). Choose a name and at least one scope. The secret starts with mbx_ and is shown once, so copy it when it appears. Only a hash is stored. Revoke a token from the same screen.

Send the token as a Bearer header. You can also pass it as the access_token query parameter, but a header keeps it out of URLs and logs.

Request
curl https://mapbox.cc/v1/incidents \
  -H "Authorization: Bearer mbx_YOUR_TOKEN"

# or
curl "https://mapbox.cc/v1/incidents?access_token=mbx_YOUR_TOKEN"

Scopes

ScopeAllows
incidents:readList and retrieve incidents.
incidents:writeCreate and update incidents.

POST /v1/reports/parse accepts any valid token.

Incidents

An incident is one road event at one point: a crash, closure, construction zone, hazard or stretch of congestion.

The incident object

FieldTypeDescription
idstringIdentifier, prefixed inc_.
roadstringRoad name, for example I-35.
directionstring | nullNorthbound, Southbound, Eastbound, Westbound or Both directions.
typestringcrash, closure, construction, hazard or congestion.
severitystringmajor, moderate or minor.
statusstringactive or cleared.
lanesstringLanes affected, for example two right lanes.
locationstringNearby cross street or landmark.
descriptionstringFree-text notes.
lng, latnumberLongitude and latitude in decimal degrees.
sourcestringconsole, ai, api or sample.
createdAt, updatedAtstringISO 8601 UTC timestamps.
clearedAtstring | nullWhen the incident was cleared. null while active.
Incident
{
  "id": "inc_…",
  "road": "I-35",
  "direction": "Southbound",
  "type": "crash",
  "severity": "moderate",
  "status": "active",
  "lanes": "two right lanes",
  "location": "Riverside Dr",
  "description": "",
  "lng": -97.73,
  "lat": 30.25,
  "source": "api",
  "createdAt": "2026-11-01T10:15:00Z",
  "updatedAt": "2026-11-01T10:15:00Z",
  "clearedAt": null
}

List incidents

GET /v1/incidents Scope: incidents:read

ParameterDescription
statusactive, cleared or all. Defaults to active.
severityComma-separated list, for example major,moderate.
typeIncident type, for example crash.
bboxBounding box as minLng,minLat,maxLng,maxLat.
sinceISO 8601 timestamp. Returns incidents with updatedAt at or after it.
limitMaximum incidents to return. Default 100, maximum 500.
formatjson (default) or geojson.
Request
curl "https://mapbox.cc/v1/incidents?severity=major,moderate&bbox=-97.95,30.10,-97.55,30.50" \
  -H "Authorization: Bearer mbx_YOUR_TOKEN"
Response · 200
{
  "incidents": [ { "id": "inc_…", "road": "I-35", /* … */ } ],
  "count": 1
}

Retrieve an incident

GET /v1/incidents/:id Scope: incidents:read

Returns the incident object, or 404 not_found.

Create an incident

POST /v1/incidents Scope: incidents:write

Send a structured incident, or a plain-English report with a location. The response is 201 with the incident. The source is always set to api.

Structured

FieldRequiredNotes
roadYes1 to 80 characters.
typeYesOne of the incident types.
severityYesmajor, moderate or minor.
lng, latYesValid longitude (-180 to 180) and latitude (-90 to 90).
directionNoOne of the direction values.
lanesNoUp to 80 characters.
locationNoUp to 120 characters.
descriptionNoUp to 1000 characters.
Request
curl -X POST https://mapbox.cc/v1/incidents \
  -H "Authorization: Bearer mbx_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "road": "I-35",
    "direction": "Southbound",
    "type": "crash",
    "severity": "moderate",
    "lanes": "two right lanes",
    "location": "Riverside Dr",
    "lng": -97.73,
    "lat": 30.25
  }'

From a plain-English report

Send report, lng and lat. The report is parsed like Parse a report. If no road or incident type is detected, the API returns 422 validation_failed.

Request
curl -X POST https://mapbox.cc/v1/incidents \
  -H "Authorization: Bearer mbx_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "report": "Crash on I-35 southbound near Riverside Dr, two right lanes blocked", "lng": -97.73, "lat": 30.25 }'

Update an incident

PATCH /v1/incidents/:id Scope: incidents:write

Send any subset of the structured fields, plus status. Setting status to cleared sets clearedAt; setting it back to active clears it.

Request
curl -X PATCH https://mapbox.cc/v1/incidents/inc_… \
  -H "Authorization: Bearer mbx_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "cleared" }'

Parse a report

POST /v1/reports/parse Any valid token

Turns a plain-English road report into structured fields without creating an incident. Use it to pre-fill your own forms.

Request
curl -X POST https://mapbox.cc/v1/reports/parse \
  -H "Authorization: Bearer mbx_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Crash on I-35 southbound near Riverside Dr, two right lanes blocked" }'
Response · 200
{
  "parsed": {
    "road": "I-35",
    "direction": "Southbound",
    "event": "crash",
    "severity": "moderate",
    "lanes": "two right lanes",
    "location": "Riverside Dr",
    "confidence": 0.95
  }
}

event can also be cleared for messages such as “I-35 SB cleared”, or null when nothing is detected. confidence is between 0 and 1.

GeoJSON format

Add format=geojson to the list request to receive a FeatureCollection. Each incident is a Point feature at [lng, lat], and its properties are the incident fields without lng and lat.

Response · 200
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [-97.73, 30.25] },
      "properties": {
        "id": "inc_…",
        "road": "I-35",
        "direction": "Southbound",
        "type": "crash",
        "severity": "moderate",
        "status": "active"
        /* lanes, location, description, source, createdAt, updatedAt, clearedAt */
      }
    }
  ]
}

Errors

Errors use a standard HTTP status and this body:

Error · 401
{ "error": { "code": "invalid_token", "message": "…" } }
StatusCodeMeaning
401invalid_tokenThe token is missing, malformed or revoked.
403insufficient_scopeThe token does not have the scope this endpoint needs.
403trial_expiredThe workspace trial has ended. Contact us to move to a paid plan.
404not_foundThe incident does not exist in your workspace.
422validation_failedThe body is invalid, or a report did not contain a detectable road and type.
429quota_exceededThe monthly API quota for your plan is used up.

Quotas & usage

Every authenticated call counts toward your workspace’s monthly usage, which you can see in the console. Limits depend on the plan.

PlanAPI calls per month
Trial10,000
Business2,000,000
EnterpriseUnlimited

Responses include X-Quota-Limit and X-Quota-Remaining. Both are omitted when the plan is unlimited. After the quota is used up, requests return 429 quota_exceeded.

Example: show live incidents on a map

This script loads active incidents as GeoJSON into a MapLibre GL JS map and colors them by severity. A token placed in browser code is visible to anyone who opens the page, so use a token that only has incidents:read and revoke it if it leaks.

live-incidents.js
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://tiles.openfreemap.org/styles/positron',
  center: [-97.7431, 30.2672],
  zoom: 10,
});

map.on('load', async () => {
  const response = await fetch(
    'https://mapbox.cc/v1/incidents?format=geojson&status=active',
    { headers: { Authorization: 'Bearer mbx_YOUR_READ_TOKEN' } },
  );
  map.addSource('incidents', { type: 'geojson', data: await response.json() });
  map.addLayer({
    id: 'incidents',
    type: 'circle',
    source: 'incidents',
    paint: {
      'circle-radius': 7,
      'circle-stroke-width': 2,
      'circle-stroke-color': '#ffffff',
      'circle-color': ['match', ['get', 'severity'],
        'major', '#f04438', 'moderate', '#f79009', '#fac515'],
    },
  });
});