courrex· Docs
For developers

REST API

The Courrex API lets you create stops, query driver state, and receive real-time event notifications via webhooks.

Status: v1 of the API is in private beta. Contact hello@courrex.com for an API key. Rate-limited to 100 requests per minute per key during beta.

Base URL

https://api.courrex.com/v1

Authentication

All requests require a bearer token in the Authorization header:

curl -H "Authorization: Bearer crx_live_xxxxxxxxxxxx" \
  https://api.courrex.com/v1/stops

Tokens are scoped to a single Courrex deployment. Rotate them from Dashboard → Settings → API keys.

Stops

Create a stop

POST /v1/stops

{
  "address": "Pikk 19, 10123 Tallinn, Estonia",
  "customer_name": "Mia Lindqvist",
  "phone": "+4521345678",
  "order_amount": 245.00,
  "payment_method": "prepaid",
  "time_window": {
    "from": "2026-05-08T09:00:00+02:00",
    "to":   "2026-05-08T12:00:00+02:00"
  },
  "notes": "Use back entrance via courtyard",
  "external_ref": "order-2026-04812"
}

Response:

{
  "id": "stop_01HZTABCDEF",
  "status": "pending",
  "geocoded": {
    "lat": 55.6717,
    "lng": 12.5444,
    "confidence": "high"
  },
  "created_at": "2026-05-07T14:23:11Z"
}

List stops

GET /v1/stops?status=pending&driver_id=drv_xxx

Returns up to 100 stops per page; use cursor for pagination.

Update a stop

PATCH /v1/stops/:id — partial update of any field.

Bulk import

POST /v1/stops/bulk — accepts a JSON array of up to 500 stop objects, processed atomically.

Drivers

List drivers

GET /v1/drivers

Get driver live state

GET /v1/drivers/:id/live

{
  "driver_id": "drv_01HZAAA",
  "lat": 55.6712,
  "lng": 12.5440,
  "speed_mps": 8.4,
  "heading": 184.0,
  "current_stop_id": "stop_01HZTABCDEF",
  "eta_minutes": 7,
  "battery_pct": 64,
  "updated_at": "2026-05-07T14:32:09Z"
}

Webhooks

Subscribe to real-time events at Dashboard → Settings → Webhooks. Each event POSTs JSON to your configured endpoint, signed with HMAC-SHA256 in the X-Courrex-Signature header.

Event types

EventWhen
stop.createdA stop is created (via API or dashboard).
stop.assignedA stop is assigned to a driver.
stop.completedDriver marks the stop delivered.
stop.failedDriver marks the stop failed (with reason).
driver.onlineA driver starts an active route.
driver.offlineA driver finishes a route or signs out.

Verifying signatures

import crypto from 'crypto';

function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature),
  );
}

Errors

Standard HTTP status codes:

StatusMeaning
400Validation error — see error.details for the field.
401Missing or invalid API key.
403Key valid but lacks permission for the requested resource.
404Resource not found.
409Conflict — e.g. trying to assign a stop to a driver in the wrong zone.
429Rate limit exceeded; retry with exponential backoff.
500Internal error; safe to retry.

Error body shape:

{
  "error": {
    "code": "validation_error",
    "message": "phone is not a valid E.164 number",
    "details": { "field": "phone", "value": "21345678" }
  }
}

Need help?

Email hello@courrex.com to request beta access, get a key, or ask integration questions. We aim to respond within one business day.