Pricing a parcel
Quote before your customer pays, so the delivery fee you charge is the one you will be charged.
POST
/v1/quotesRequires quotes:read. Creates nothing — safe to call as often as you like.
Request
| Field | Required | Notes |
|---|---|---|
delivery_mode | yes | STATION to a pickup town, DOOR inside Nairobi. |
origin_lat, origin_lng | yes | Where a rider collects — your shop. |
dest_town_id | either | From /v1/towns. |
dest_lat, dest_lng | either | Use instead of a town for door delivery. |
package_size | no | S, M, ML, L, BULKY. |
weight_kg | no | Billed at the larger of size and weight. |
declared_value | no | Drives insurance. |
is_fragile | no | Adds a handling surcharge. |
Supply either dest_town_id or both destination coordinates. Neither gives missing_destination.
Response
json
{
"object": "quote",
"currency": "KES",
"delivery_fee": 515,
"insurance": 0,
"total": 515,
"distance_km": 245.3,
"package_size": "S",
"distance_band": "FAR",
"requires_pickup_station": false,
"breakdown": [
"S package · FAR distance",
"Long-distance tail +215",
"Pickup-station collection (discounted)"
]
}Charge total. The breakdown is there so you can explain a price to a customer who asks, rather than showing a number with no story.
How size and weight interact
Send both. A parcel is billed at whichever implies the larger tier, so a small box declared at 25 kg is priced as bulky, not small.
| Size | Up to |
|---|---|
S | 2 kg |
M | 5 kg |
ML | 10 kg |
L | 20 kg |
BULKY | over 20 kg, or oversized |
If you leave weight out entirely we price on the size you declare. Shops that ship heavy items and send no weight will under-charge their customers and pay the difference, so send it where you have it.
When a route cannot be priced
A 422 with not_quotable means the route is outside the network — usually a destination we do not serve. Fall back to your own shipping method rather than blocking the checkout.
Next: booking the parcel.
