/api/v1/logistics/dispatchDispatch a shipment (with auto-failover)
Quotes every carrier, picks one per your configured selection strategy (cheapest by default), and books it. Providers that can't handle the parcel (weight too high, no cold chain, no signed delivery, dimensions too large) are filtered before quoting and surfaced in the `excluded` array. If the winning carrier rejects the booking (no driver, rate limit, network error) the orchestrator automatically falls back to the next-best quote — capped at 3 attempts. Every attempt is recorded in the response's `failoverAttempts`. Pass an explicit `carrier` to skip the strategy and force a specific provider. Supports `Idempotency-Key` — retry the same call with the same key inside 24h to get the cached response instead of double-booking.
Authorization
Requires the logistics:write scope. See the auth guide for how to mint a token with the right scopes.
Parameters
Body parameters
| Field | Type | Description |
|---|---|---|
pickup required | object | Pickup point — { lat, lng, address, city?, state?, country? }. e.g. { "lat": 6.4419, "lng": 3.4710, "address": "15 Adeola Odeku, Victoria Island", "city": "Lagos", "country": "NG" } |
dropoff required | object | Dropoff point — same shape as `pickup`. e.g. { "lat": 6.6018, "lng": 3.3515, "address": "Allen Avenue, Ikeja", "city": "Lagos", "country": "NG" } |
parcels required | object | Array of parcels — [{ weightKg, valueKobo, description?, lengthCm?, widthCm?, heightCm?, fragile?, signedDelivery?, temperature?, category?, insuredValueKobo? }]. e.g. [{ "weightKg": 0.8, "valueKobo": 1250000, "description": "Pharmacy order #PHR-1242", "temperature": "chilled", "category": "pharmacy" }] |
lengthCm optional | number | Per-parcel longest side in cm. Filters providers whose vehicle class can't carry it. e.g. 35 |
widthCm optional | number | Per-parcel width in cm. Filters providers whose max-girth (L+W+H) limit rejects the parcel. e.g. 25 |
heightCm optional | number | Per-parcel height in cm. Filters providers whose max-girth (L+W+H) limit rejects the parcel. e.g. 15 |
fragile optional | boolean | When true, only book carriers that handle fragile goods. 'Fragile — handle with care' is appended to driver notes. e.g. false |
signedDelivery optional | boolean | When true, only book carriers that capture a recipient signature at dropoff. e.g. false |
temperature optional | string | "ambient" (default), "chilled" (2-8°C), or "frozen". Cold-chain class — filters to providers with matching support. e.g. chilled |
category optional | string | Vertical hint — "documents", "food", "pharmacy", "electronics", "fashion", "general". e.g. pharmacy |
insuredValueKobo optional | number | Declared value for insurance, in kobo. Defaults to `valueKobo`. e.g. 1250000 |
merchantReference optional | string | Your own tracking reference. Persisted verbatim on the Shipment. e.g. PHR-1242 |
notes optional | string | Free-form dispatch note shown to the driver. Merged with parcel-aware flags (cold chain, fragile, signed delivery). e.g. Ring buzzer twice on arrival. |
pickupContact optional | object | Pickup contact — { name, phone }. Defaults to your merchant profile if omitted. e.g. { "name": "HealthPlus VI", "phone": "+2348012345678" } |
dropoffContact optional | object | Dropoff contact — { name, phone }. e.g. { "name": "Adaeze Okonkwo", "phone": "+2348098765432" } |
serviceLevel optional | string | "express" (same-day, default) or "standard" (next-day). e.g. express |
carrier optional | string | Explicit carrier override — "uber", "fez", or "indrive". Skips selection strategy. e.g. fez |
Headers
| Field | Type | Description |
|---|---|---|
Idempotency-Key optional | string | Client-supplied retry key. Same value in 24h = same response, never double-books. e.g. dispatch_idem_PHR-1242 |
Response
A successful call returns 200 OK with the body shown to the right. Errors follow the standard envelope.