Quickstart

Make your first booking in six steps. You need an API key (Authentication).

1. Authenticate

GET /v1/parcel_lanes
X-Api-Key: <YOUR_API_KEY>

2. Retrieve available lanes

GET /v1/parcel_lanes
{ "data": [{ "code": "010", "origin": "China", "destination": "Nigeria" }] }

Lanes carry no prices. Currently only China → Nigeria is supported. Pass code as lane_code.

3. Retrieve supported commodities

GET /v1/parcel_commodities
{ "data": [{ "code": "010", "label": "Electronics" }] }

4. Get a rate

POST /v1/parcel_quotes
Content-Type: application/json
{
"lane_code": "010",
"transport_mode": "air",
"commodity_code": "010",
"weight": 25
}

Save the quote id and rate.id from the response. Rates expire after one hour.

5. Create a booking

POST /v1/parcel_bookings
Content-Type: application/json
{
"quote_id": "<quote_id>",
"rate_id": "<rate_id>",
"sender": { "customer_id": "<customer_id>" },
"recipient": {
"name": "Ada Example",
"phone": "+2348000000000",
"address": { "street": "10 Example Street", "city": "Lagos", "country": "NG" }
}
}

recipient is required when customer_as_recipient is omitted or false. Set customer_as_recipient: true with sender.customer_id only when that same customer is receiving the shipment. In that case, omit recipient because the backend loads the customer’s saved name, phone, email, and address and stores them in the booking’s recipient snapshot. The response still includes recipient. A complete customer profile in your account and API mode is required; no recipient details are guessed. Do not send non-empty recipient details together with the flag; this returns 422 INVALID_PARTY to avoid conflicting instructions.

The response is a booked quote with parcel_id: null — no parcel exists yet.

6. Track the parcel

After SEND receives the cargo, a parcel is created and linked to the quote (parcel_id, received_at). Track it:

GET /v1/packages/{parcel_id}/track

Warehouse receipt is a SEND operation, not a public endpoint. For notifications, set up Webhooks.