Routerra LogoTeams
Browse articles· Team, driver & analytics endpoints
For ownersUpdated 2026-09-08 · 8 min read

Team, driver & analytics endpoints

The reference data behind every plan you build — team context, drivers, the address book and delivery statistics — plus the one call that edits a driver.

Before your integration can create a plan it needs three facts from the team: which drivers exist, where each of them actually starts, and how much of today's optimization quota is still yours to spend. These endpoints answer all of that, and one of them writes back.

Everything here lives under the production base URL:

https://teams-api.routerra.io/api/v1/external

Every request carries your key in the X-API-Key header — see API keys for creating one and API authentication & scopes for what each scope unlocks. Throughout the API, fields with no value are omitted from the response rather than returned as null: a driver with no shift simply has no shiftStartTime.

Team context

GET/api/v1/external/teamread200

One call for everything you need before dispatching: drivers with the locations the solver will really use, depots, zones, your team's defaults, and the remaining optimization quota.

The important field is drivers[].startLocation and finishLocation. These are the effective coordinates — the driver's own start point if they have one, otherwise their depot. This is what the solver builds from, so check it before you dispatch.

{
"team": { "id": 87, "name": "Hudson Bakery Supply" },
"timezone": "America/New_York",
"defaults": {
  "serviceTimeSeconds": 300,
  "stopSide": "ANY",
  "stopLimit": 200,
  "stopDeduplication": false,
  "liveNavTrackingEnabled": false
},
"optimizationQuota": { "capacity": 34, "available": 26, "availableForApi": 14 },
"depots": [
  { "id": 12, "name": "Greenpoint Depot", "address": "…", "latitude": 40.7297, "longitude": -73.9542 }
],
"zones": [ { "id": 3, "name": "East", "driverIds": [91, 93] } ],
"drivers": [ {
  "id": 91, "name": "Maya R.", "vehicleType": "VAN",
  "shiftStartTime": "08:00:00", "shiftEndTime": "17:00:00",
  "startDepotId": 12, "finishDepotId": 12,
  "startLocation": { "address": "…", "latitude": 40.7297, "longitude": -73.9542 },
  "finishLocation": { "…": "…" },
  "zoneIds": [3], "zoneRestricted": true
} ]
}

zones[].driverIds lists who may serve a zone: drivers with no zone restrictions at all, plus the ones explicitly admitted. On a driver, zoneRestricted: true means at least one zone rule applies to them and zoneIds is their allow-list.

optimizationQuota carries three numbers, and only the third decides whether an API key may dispatch. availableForApi is always at most available, because part of the daily quota is reserved for the dashboard — API limits & quotas has the arithmetic. Every POST …/dispatch response returns the quota too, so you rarely need to poll this endpoint for it.

Drivers

GET/api/v1/external/driversread200

The full driver cards: vehicle, capacity, stop ceiling and routing preferences. Use the id values here as driverIds when you optimize.

The response is a JSON array of driver objects — there is no wrapper and no pagination. One element looks like this:

[
{
  "id": 91, "name": "Maya R.", "vehicleType": "VAN", "vehicleCapacity": 40, "maxStops": 60,
  "shiftStartTime": "08:00", "shiftEndTime": "17:00",
  "startLocation": { "address": "…", "latitude": 40.73, "longitude": -73.95 },
  "liveRoadData": true, "avoidTolls": false, "avoidHighways": false
}
]
FieldTypeDescription
idnumberDriver ID — use in driverIds
namestringDriver name
vehicleTypestringCAR, VAN, TRUCK, BIKE, or SCOOTER
vehicleCapacitynumberCapacity in the same load units as a stop's load
maxStopsnumberMaximum stops per route
shiftStartTime, shiftEndTimestringWorking hours, HH:mm here — but the same driver's shift comes back as HH:mm:ss from GET /team
startLocationLocationThe driver's own start point
finishLocationLocationThe driver's own end point
liveRoadDatabooleanRouting uses live traffic
avoidTollsbooleanRouting avoids toll roads
avoidHighwaysbooleanRouting avoids highways

A Location is { "address", "latitude", "longitude" }.

Drivers are created, invited and removed from the dashboard — see Manage drivers.

PATCH/api/v1/external/drivers/{driverId}write200

A partial update of a driver's operational fields: anything you leave out is left alone. Name, e-mail and the start/finish locations are not editable over the API — changing an e-mail sends an invitation, and that belongs in the dashboard.

FieldTypeConstraints
vehicleTypeenumCAR, VAN, TRUCK, BIKE, SCOOTER
vehicleCapacityint1–10000, in the same units as a stop's load
maxStopsint1–1000
shiftStartTime / shiftEndTimeHH:mm
liveRoadData / avoidTolls / avoidHighwaysbool

Request

{ "vehicleCapacity": 25, "shiftStartTime": "08:00" }

Errors: 404 driver_not_found, 409 driver_route_in_progress, 403 insufficient_scope, 402 subscription_required. API error reference has the full list.

Address book

GET/api/v1/external/address-bookread200

Your team's saved addresses with their settings. An entry can be dropped into a stop by its addressBookEntryId, or matched automatically by name when matchAddressBook is on — see Plan endpoints for how a stop picks up an entry.

This endpoint is read-only. Entries are created and edited from the dashboard — see Address book.

ParameterTypeDescription
querystringCase-insensitive substring of the name or address
limitint1–50, default 20; most recent first
{
"id": 501, "name": "Dr. Lee Clinic", "address": "1 Clinic Rd, Brooklyn, NY",
"latitude": 40.69, "longitude": -73.99, "serviceTime": 900,
"arrivalRangeFrom": "09:00", "arrivalRangeTo": "11:00",
"email": "front.desk@leeclinic.example", "phone": "+13475550142",
"recipientName": "Dr. Lee"
}

email, phone and recipientName are the template recipient contacts: they are copied into a stop along with the coordinates, and customer notifications use them. Empty fields are omitted.

Analytics

GET/api/v1/external/statisticsread200

Delivery totals over a date range, counted across every route whose date falls inside it: overall and per driver, with failures broken down by reason. Cancelled plans are excluded.

ParameterTypeDescription
dateFrom / dateTodateDefault: the last 7 days up to today. The range may not exceed 92 days, or you get 400 invalid_date_range
{
"dateFrom": "2026-08-31", "dateTo": "2026-09-07",
"totals": {
  "routesCount": 14, "stopsCount": 412,
  "deliveredCount": 380, "failedCount": 9, "pendingCount": 23,
  "failedByReason": [
    { "failureReason": "CUSTOMER_NOT_AVAILABLE", "count": 5 },
    { "failureReason": "BUSINESS_CLOSED", "count": 3 },
    { "failureReason": null, "count": 1 }
  ]
},
"perDriver": [ {
  "driverId": 91, "driverName": "Maya R.", "routesCount": 5, "stopsCount": 150,
  "deliveredCount": 142, "failedCount": 2, "pendingCount": 6,
  "failedByReason": [ { "failureReason": "BUSINESS_CLOSED", "count": 2 } ]
} ]
}

A failureReason of null is a real bucket, not a gap in the data: the driver marked the stop as not delivered without picking a reason. Count it, don't drop it.

What's next

Was this article helpful?

Still stuck?

Write to us — a human reads every message.

Contact support