Sendway

Parcels

Booking a parcel adds it to the batch a rider will collect from you. Nothing is charged at this point.

Book a parcel

POST/v1/parcels

Requires parcels:write.

FieldRequiredNotes
recipient_nameyesWho collects it.
recipient_phoneyesGets the arrival SMS and the collection PIN.
recipient_emailnoEmailed the PIN as well.
descriptionyesWhat is inside. Agents see this.
package_sizeyesAs in quotes.
weight_kgnoSend it where you have it.
delivery_modeyesSTATION or DOOR.
dest_town_ideitherCollection town.
dest_lat, dest_lngeitherFor door delivery.
origin_lat, origin_lngyesWhere a rider collects.
origin_addressnoHelps the rider find you.
declared_valuenoDrives insurance.
referencenoYour own order id. Comes back on every webhook.
json
{
  "object": "parcel",
  "livemode": true,
  "id": "9f3a1c72-4b8e-4d1a-9c2f-7e5b0a6d3812",
  "parcel_number": "PCL-A1B2C3",
  "tracking_number": "SHP-8DD1D9",
  "status": "AWAITING_PICKUP",
  "payment_timing": "PAY_AT_PICKUP",
  "total_fee": 350,
  "currency": "KES",
  "pickup_run_id": "cbcb7d07-...",
  "reference": "order-1042",
  "message": "Booked. It will be settled with the rest of your batch when a rider collects."
}
Always send X-Idempotency-Key. Derive it from your order id — order-1042, not a random value. If the connection drops after we created the parcel, your retry returns the same parcel instead of booking and charging for a second one.

Parcel statuses

StatusMeans
AWAITING_PICKUPWaiting for a rider to collect it from you.
AWAITING_DROPOFFWaiting for you to drop it at a SendWay point.
IN_TRANSITCollected, moving through the network.
AT_PICKUP_STATIONArrived. Your customer has a PIN.
DELIVEREDCollected by your customer.
RETURNEDNot collected in time; coming back.
CANCELLEDCancelled before collection.

List your parcels

GET/v1/parcels?limit=25

Newest first, cursor-paginated. Requires parcels:read.

json
{
  "object": "list",
  "data": [{ "object": "parcel", "id": "...", "tracking_number": "SHP-8DD1D9" }],
  "has_more": true,
  "next_cursor": "9f3a1c72-4b8e-4d1a-9c2f-7e5b0a6d3812"
}

Pass next_cursor back as starting_after for the next page.

Read one

GET/v1/parcels/:id

Track by number

GET/v1/tracking/:tracking_number

Accepts either the tracking number or the parcel number. Returns status and destination without the recipient's contact details, so it is safe to render on a page your customer sees.

Cancel

POST/v1/parcels/:id/cancel

Possible while the parcel is still with you. Once a rider has scanned your batch the total is locked and you get 409 run_already_scanned — at that point the parcel is in the network and cancelling is a support conversation.

A cancelled parcel drops out of your batch, so it never becomes a charge.

Next: how you pay.