Sandbox
Test mode is a full copy of the Shipping API that never reaches Reeds operations. Use it to build and test every path before you go live.
How the sandbox behaves
- Use test credentials (
rci_test_...andrcs_test_...). They use the same token endpoint and base URL as live credentials. - Every object they create has
livemode: false. - Live credentials get
403 TEST_MODE_ONLYfrom the sandbox endpoints (/sandbox/...). - Test deliveries never reach Reeds' riders or hubs, and no SMS is sent.
- Addresses and quotes use the real geocoder and the real price rules, so test prices match live. The same rate limits apply.
- There are no special test addresses. Test addresses shows what to send to reach each outcome.
- The test wallet starts with ₦100,000.
- Test data is kept for 90 days.
Top up the test wallet
POST /sandbox/wallet/fund tops up the test wallet instantly. There is no payment page. (POST /wallet/fund works in Live mode only.)
curl -X POST https://api.getreeds.co/shipping/v1/sandbox/wallet/fund \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "amount": 5000000 }'
Advance a delivery
No rider will pick up a test delivery, so you move it yourself. POST /sandbox/deliveries/{id}/advance sets the next status and sends the same webhooks a live delivery would.
status | Simulates |
|---|---|
rider_assigned | A rider has been given the pickup |
picked_up | The parcel was collected |
at_hub | The parcel is at a Reeds hub |
out_for_delivery | The rider is heading to the receiver |
delivered | The delivery is complete |
failed_attempt | The rider couldn't deliver |
on_hold | Reeds paused the delivery. Send hold_reason with it. |
Send deliver_by (date-time) and reason instead of status to simulate a schedule change. deliver_by must be in the future and after pickup_by. delivery.schedule_changed fires.
- cURL
- Node.js
- PHP
- Python
curl -X POST https://api.getreeds.co/shipping/v1/sandbox/deliveries/dlv_9Kd3Qx7M/advance \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "status": "picked_up" }'
const res = await fetch(
'https://api.getreeds.co/shipping/v1/sandbox/deliveries/dlv_9Kd3Qx7M/advance',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REEDS_ACCESS_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: 'picked_up' }),
},
);
console.log(await res.json());
<?php
$ch = curl_init('https://api.getreeds.co/shipping/v1/sandbox/deliveries/dlv_9Kd3Qx7M/advance');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REEDS_ACCESS_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['status' => 'picked_up']),
]);
echo curl_exec($ch);
curl_close($ch);
import os
import requests
res = requests.post(
"https://api.getreeds.co/shipping/v1/sandbox/deliveries/dlv_9Kd3Qx7M/advance",
headers={"Authorization": f"Bearer {os.environ['REEDS_ACCESS_TOKEN']}"},
json={"status": "picked_up"},
timeout=30,
)
print(res.json())
The webhook for each step goes to your Test-mode endpoint. Add one in Dashboard → Developers with the Test switch on.
Test every path
Before you go live, check each of these in Test mode:
- Verified pickup and drop-off, then a quote and a booking
- A needs-confirmation address: draft,
requires_action, thenPOST /addresses/{id}/confirm - A not-serviceable address:
available: falseon the quote - An inter-state route:
INTERSTATE_NOT_AVAILABLE - An expired quote:
QUOTE_EXPIRED, then a fresh quote - A short wallet:
402 INSUFFICIENT_BALANCE, fund, retry with the sameIdempotency-Key - A cancellation before pickup, and the refund
- Every status through
advance, includingfailed_attemptandon_hold - A schedule change and the
delivery.schedule_changedwebhook - Your webhook receiver: signature check, duplicates, unknown event types
- A retried request with the same
Idempotency-Key