Skip to content
§ API referencev0.1 · preview

Scan, route, deliver.

Ship parcels into the Relayed mesh from your own dispatch. Track every hop. Receive webhooks on scan events. REST over HTTPS, JSON bodies, simple auth.

Preview — endpoints stabilise at first-paying-partner launch

Overview

The Relayed API is a REST interface for creating parcels, querying routes, and receiving scan-event webhooks. It is intended for delivery companies integrating their existing dispatch software with the Relayed mesh.

Base URL: https://api.userelayed.com. All responses are JSON. All request bodies must be JSON. All timestamps are ISO 8601 UTC.

◦ This is a preview — endpoints will stabilise at v1 when the first paying partner goes live. Breaking changes will be announced in the changelog and by email to all API key holders at least 30 days in advance.

Authentication

Every request requires an API key passed as a Bearer token in the Authorization header. Keys are issued per delivery-company partner and rotated on request.

Example · fetch your accountbash
curl https://api.userelayed.com/v0/me \
  -H "Authorization: Bearer sk_live_..."

Lost key? Email api@userelayed.com from the contact on file — we rotate within 1 business hour.

Rate limits

Current ceilings, per API key:

  • 100 requests / minute burst — read endpoints
  • 60 requests / minute sustained — write endpoints
  • 10,000 parcels / day create — contact us for higher allowances

Every response includes X-RateLimit-Remaining and X-RateLimit-Reset headers. Going over returns a 429 Too Many Requests.

Parcels

Create a parcel

POST /v0/parcels

Request bodyjson
{
  "from": {
    "station": "GH-ACC-0142",
    "partner_ref": "WG-2026-04-19-00123"
  },
  "to": {
    "station": "GH-KUM-0037"
  },
  "parcel": {
    "weight_g": 1800,
    "declared_value_ghs": 450,
    "contents": "Clothing · 1 dress"
  },
  "cod_ghs": 0,
  "recipient": {
    "name": "Afia K.",
    "phone": "+233..."
  }
}
Response · 201 Createdjson
{
  "id": "prc_01HXYZ...",
  "tracking_code": "GH-AC-0142",
  "status": "scanned_in",
  "route": [
    { "station": "GH-ACC-0142", "type": "drop" },
    { "station": "GH-CORR-N04", "type": "corridor" },
    { "station": "GH-KUM-0037", "type": "final" }
  ],
  "fee_ghs": 5,
  "created_at": "2026-04-19T08:24:13Z"
}

Retrieve a parcel

GET /v0/parcels/{id}

Returns the full parcel object, including scan-event history.

Scan events

Every physical handoff — drop-in, mesh relay, final-leg pickup, delivered — generates a scan event. Events are append-only and timestamped server-side.

Scan event schemajson
{
  "id": "scn_01HXYZ...",
  "parcel_id": "prc_01HXYZ...",
  "type": "scan_in" | "relay" | "pickup" | "delivered" | "staged",
  "station": "GH-ACC-0142",
  "actor": {
    "type": "courier" | "partner" | "system",
    "id": "crr_01HXYZ..."
  },
  "lat": 5.6358,
  "lng": -0.1614,
  "timestamp": "2026-04-19T08:24:13Z"
}

Query with GET /v0/parcels/{id}/scans or subscribe to them via webhooks — see below.

Webhooks

Configure a webhook endpoint in the partner dashboard. Relayed POSTs JSON to it whenever a parcel changes state. All webhook deliveries are signed — verify the X-Relayed-Signature header before trusting the body.

Webhook payload · parcel.deliveredjson
{
  "event": "parcel.delivered",
  "id": "evt_01HXYZ...",
  "created_at": "2026-04-19T14:03:01Z",
  "data": {
    "parcel_id": "prc_01HXYZ...",
    "tracking_code": "GH-AC-0142",
    "delivered_at": "2026-04-19T14:02:48Z",
    "recipient_name": "Afia K.",
    "signature_url": "https://cdn.userelayed.com/sig/..."
  }
}

Event types available in v0:

  • parcel.created — parcel scanned in at origin
  • parcel.relayed — parcel changed stations
  • parcel.picked_up — final-leg courier assigned
  • parcel.delivered — recipient received
  • parcel.staged — delivery failed, parcel in locker awaiting redelivery
  • parcel.claim_opened — damage/loss claim filed

Relayed retries failed webhook deliveries with exponential back-off for up to 24 hours.

Errors

The API uses conventional HTTP status codes. Error responses include a machine-readable code and a human-readable message.

Error response shapejson
{
  "error": {
    "code": "station_not_found",
    "message": "No station with code 'GH-ACC-9999'.",
    "docs": "https://userelayed.com/docs#errors"
  }
}
  • 400 · bad request — malformed body or invalid field
  • 401 · missing or invalid API key
  • 402 · partner account suspended for billing
  • 404 · parcel, station, or courier not found
  • 409 · conflict — e.g. scan event for an already-delivered parcel
  • 422 · prohibited item or rule violation
  • 429 · rate-limited — see rate limits
  • 5xx · Relayed-side error — safe to retry

Changelog

  • v0.1 · 2026-04-19

    Initial preview. Parcels (create, retrieve), scan events, 6 webhook event types. No breaking-change guarantees yet.

◦ Want early API access? Email api@userelayed.com with your company name and expected monthly volume.