API reference

The RouteKey driver app and your dispatch integrations talk to one REST endpoint. Drivers pull their route on launch, then stream location and upload proof of delivery as they work the stops.

Base URL

All requests are made against your account's region. This deployment is us-central-1.

https://routekey.io/v1

Requests authenticate with an API key as a bearer token. Keys are scoped per account; a driver-app key can read routes and post stop events but cannot change billing or org settings.

Authorization: Bearer rk_live_9f2c81a4d7e0b365

Endpoints

Method Path Purpose
GET /v1/routes/:driver_id Fetch the driver's optimized stop sequence for the shift.
POST /v1/stops/:stop_id/proof Upload proof of delivery — photo and/or signature. This is where the bytes are.
POST /v1/drivers/:driver_id/location Report a live GPS position (batched every few seconds while moving).
GET /v1/manifest Pull the dispatch manifest for a depot and date.

Fetch a route

Called by the driver app on launch and on resume. Small and cheap — it's the only call that needs to be fresh, so a reassignment shows up on the driver's next poll.

GET /v1/routes/drv_7f3c9a21?date=2026-07-21
// 200 OK
{
  "route_id": "rt_2026_07_21_a41f",
  "driver_id": "drv_7f3c9a21",
  "depot": "atx-north",
  "stops": [
    {
      "stop_id": "stp_88a1",
      "seq": 1,
      "address": "1200 W 6th St, Austin, TX",
      "window": ["09:00", "11:00"],
      "lat": 30.2711,
      "lng": -97.7566
    },
    {
      "stop_id": "stp_9c02",
      "seq": 2,
      "address": "2100 S Lamar Blvd, Austin, TX",
      "window": ["09:30", "12:00"],
      "lat": 30.2470,
      "lng": -97.7880
    }
  ]
}

Upload proof of delivery

Posted at each completed stop. The photo is the largest thing the app sends all day, which is why the SDK compresses on-device and retries on a flaky connection rather than blocking the driver.

POST /v1/stops/stp_88a1/proof
Content-Type: multipart/form-data
// fields
photo:      <binary jpeg, ~1–3 MB>
signature:  <binary png, optional>
outcome:    "delivered"
lat:        30.2711
lng:        -97.7566
captured_at: "2026-07-21T09:14:08Z"
// 201 Created
{ "proof_id": "pod_5f21c9", "stop_id": "stp_88a1", "stored": true }

A busy route is 60–120 stops a day, each with a 1–3 MB photo, per driver — so a mid-size fleet moves several GB a day up to the endpoint, all from phones on cellular. Size your plan by fleet, not by seats.

Report live location

The app batches GPS points and posts them every few seconds while the driver is moving, so dispatch sees an accurate ETA without draining the phone.

POST /v1/drivers/drv_7f3c9a21/location
Content-Type: application/json

{
  "points": [
    { "lat": 30.2679, "lng": -97.7731, "t": "2026-07-21T09:11:02Z" },
    { "lat": 30.2691, "lng": -97.7702, "t": "2026-07-21T09:11:07Z" }
  ]
}
// 202 Accepted

Driver SDK quickstart

Android (Kotlin). The iOS SDK exposes the same calls.

val client = RouteKey.init(
    apiKey   = "rk_live_9f2c81a4d7e0b365",
    endpoint = "https://routekey.io"
)

// Pull today's route and hand it to the map.
val route = client.routes.today(driverId)

// At each stop: compress + upload, retry in the background.
client.stops.submitProof(stopId, photo, outcome = "delivered")

Errors

Code Meaning What to do
401 API key missing, malformed, or revoked. Check the bearer token. Driver keys are issued per account.
404 No route for that driver and date. Usually a driver with no assigned stops yet. Show an empty-day state.
413 Proof payload too large. The SDK compresses to fit; if you post raw, keep photos under 8 MB.
429 Too many requests from one key. Honour Retry-After; the SDK backs off on its own.

Service health for this region is published at /status.