API reference/Logistics
POST/api/v1/logistics/dispatch

Dispatch 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

FieldTypeDescription
pickup
required
objectPickup 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
objectDropoff point — same shape as `pickup`.
e.g. { "lat": 6.6018, "lng": 3.3515, "address": "Allen Avenue, Ikeja", "city": "Lagos", "country": "NG" }
parcels
required
objectArray 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
numberPer-parcel longest side in cm. Filters providers whose vehicle class can't carry it.
e.g. 35
widthCm
optional
numberPer-parcel width in cm. Filters providers whose max-girth (L+W+H) limit rejects the parcel.
e.g. 25
heightCm
optional
numberPer-parcel height in cm. Filters providers whose max-girth (L+W+H) limit rejects the parcel.
e.g. 15
fragile
optional
booleanWhen true, only book carriers that handle fragile goods. 'Fragile — handle with care' is appended to driver notes.
e.g. false
signedDelivery
optional
booleanWhen 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
stringVertical hint — "documents", "food", "pharmacy", "electronics", "fashion", "general".
e.g. pharmacy
insuredValueKobo
optional
numberDeclared value for insurance, in kobo. Defaults to `valueKobo`.
e.g. 1250000
merchantReference
optional
stringYour own tracking reference. Persisted verbatim on the Shipment.
e.g. PHR-1242
notes
optional
stringFree-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
objectPickup contact — { name, phone }. Defaults to your merchant profile if omitted.
e.g. { "name": "HealthPlus VI", "phone": "+2348012345678" }
dropoffContact
optional
objectDropoff 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
stringExplicit carrier override — "uber", "fez", or "indrive". Skips selection strategy.
e.g. fez

Headers

FieldTypeDescription
Idempotency-Key
optional
stringClient-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.