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/v1Authentication
All requests require a bearer token in the Authorization header:
curl -H "Authorization: Bearer crx_live_xxxxxxxxxxxx" \
https://api.courrex.com/v1/stopsTokens 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
| Event | When |
|---|---|
stop.created | A stop is created (via API or dashboard). |
stop.assigned | A stop is assigned to a driver. |
stop.completed | Driver marks the stop delivered. |
stop.failed | Driver marks the stop failed (with reason). |
driver.online | A driver starts an active route. |
driver.offline | A 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:
| Status | Meaning |
|---|---|
400 | Validation error — see error.details for the field. |
401 | Missing or invalid API key. |
403 | Key valid but lacks permission for the requested resource. |
404 | Resource not found. |
409 | Conflict — e.g. trying to assign a stop to a driver in the wrong zone. |
429 | Rate limit exceeded; retry with exponential backoff. |
500 | Internal 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.