Manage Shipments
Once a shipment is created, use these endpoints to list, inspect, and cancel.
List shipments
GET /merchant/shipments
Returns your shipments, most recent first.
curl "https://api.dodo.co.tz/api/v1/merchant/shipments?status=delivered&page=1&per_page=20" \
-H "X-API-Key: $DODO_API_KEY"
Query parameters:
| Param | Type | Description |
|---|---|---|
status | string | Filter by shipment status — pending, confirmed, pickup_dispatched, picked_up, in_transit, out_for_delivery, delivered, cancelled, failed |
type | string | same_city or regional |
search | string | Match against shipment_number, tracking_code, or merchant_reference |
page | integer | Page number (default: 1) |
per_page | integer | Page size (default: 20, max: 100) |
Response (200 OK):
[
{
"id": 12345,
"shipment_number": "SHP-20260515-A1B2C3",
"tracking_code": "DODO7K9M2P4QR8",
"merchant_reference": "your-internal-order-id-123",
"type": "same_city",
"status": "delivered",
"sender_name": "Malaika Restaurant",
"receiver_name": "Jane Doe",
"pickup_address": "Samora Ave, Dar es Salaam",
"dropoff_address": "Apartment 4B, Msasani, Dar es Salaam",
"total_amount": 4100,
"payment_status": "paid",
"estimated_delivery_at": "2026-05-15T11:30:00Z",
"created_at": "2026-05-15T10:30:00Z"
}
]
The list endpoint returns the trimmed list-view object — call Get details for items, legs, and the event log.
Get shipment details
GET /merchant/shipments/{id}
Full shipment record including items, journey legs, and the complete event log.
curl https://api.dodo.co.tz/api/v1/merchant/shipments/12345 \
-H "X-API-Key: $DODO_API_KEY"
The response shape matches the POST /merchant/shipments response, but with up-to-date status and a populated events array.
Event log
events is the timeline of what happened to this shipment. Use it to display delivery progress in your UI when you can't easily wire up webhooks.
"events": [
{
"id": 102,
"status": "delivered",
"leg_type": "first_mile",
"description": "Package delivered to Jane Doe",
"location_address": null,
"actor_type": "rider",
"occurred_at": "2026-05-15T11:28:14Z"
},
{
"id": 101,
"status": "out_for_delivery",
"leg_type": "first_mile",
"description": "Rider James M. heading to receiver",
"actor_type": "rider",
"occurred_at": "2026-05-15T11:05:42Z"
},
{
"id": 100,
"status": "picked_up",
"leg_type": "first_mile",
"description": "Package collected from Malaika Restaurant",
"actor_type": "rider",
"occurred_at": "2026-05-15T10:48:09Z"
}
]
Events are ordered newest first.
Cancel a shipment
POST /merchant/shipments/{id}/cancel
Cancel a shipment before pickup. Refunds the wallet immediately.
curl -X POST https://api.dodo.co.tz/api/v1/merchant/shipments/12345/cancel \
-H "X-API-Key: $DODO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Customer changed their mind" }'
Request:
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | yes | Why you're cancelling (5–500 chars) — appears in admin reports |
Response: the updated shipment record with status: "cancelled" and the wallet credit reflected.
Cancellation is only allowed in pending, confirmed, or pickup_dispatched status. Once the rider has the package (picked_up and beyond), the API returns:
{ "detail": "Shipment in status 'picked_up' cannot be cancelled." }
For post-pickup issues, contact support — we'll work with the rider and refund where appropriate.
What happens on cancel
- Shipment status flips to
cancelled - Wallet credit posted for the full
total_amount - Webhook
shipment.cancelledfires - If a rider was already dispatched, they're notified
Related
- Webhooks — get status updates pushed to your server instead of polling
- Shipment Lifecycle — full state machine including which transitions can cancel
- Errors — error codes and retry strategy