Drafts and required actions
A draft is a delivery created without a quote. Use one when an address still needs confirmation, when the item isn't packed yet, or when you want Reeds to price and book in a single call. Nothing is charged until the delivery is booked.
Create a draft
POST /deliveries without quote_id. Send the saved addresses and the package instead. Idempotency-Key is required, as for any booking.
| Field | Type | Description |
|---|---|---|
pickup_address_id | string | required. A saved address, verified or needs_confirmation. |
dropoff_address_id | string | required. A saved address, verified or needs_confirmation. |
package | object | required. description (required), quantity, weight_kg, declared_value (kobo), dimensions_cm. See What Reeds carries. |
pickup_date | date | Default today; up to 7 days ahead. |
auto_book | boolean | Default false. If true, Reeds books the delivery as soon as both addresses are confirmed and your account can pay (the wallet covers the price, or an invoice account has room under its credit limit). No further call from you. |
max_total | integer | Optional, in kobo. With auto_book, Reeds books only if the price is at or below this. Otherwise the draft waits with the BOOK action. Confirming an address in another area can change the price. |
ready, reference, shipper, pickup_instructions, dropoff_instructions, metadata | As in Book a delivery. |
- cURL
- Node.js
- PHP
- Python
curl https://api.getreeds.co/shipping/v1/deliveries \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN" \
-H "Idempotency-Key: order-10046-draft" \
-H "Content-Type: application/json" \
-d '{
"pickup_address_id": "adr_3Mz8Rt1Q",
"dropoff_address_id": "adr_5Vb1Jc8D",
"package": { "description": "2 pairs of sneakers", "weight_kg": 1.5 },
"auto_book": true,
"max_total": 300000,
"reference": "ORDER-10046"
}'
const res = await fetch('https://api.getreeds.co/shipping/v1/deliveries', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REEDS_ACCESS_TOKEN}`,
'Idempotency-Key': 'order-10046-draft',
'Content-Type': 'application/json',
},
body: JSON.stringify({
pickup_address_id: 'adr_3Mz8Rt1Q',
dropoff_address_id: 'adr_5Vb1Jc8D',
package: { description: '2 pairs of sneakers', weight_kg: 1.5 },
auto_book: true,
max_total: 300000,
reference: 'ORDER-10046',
}),
});
const { data } = await res.json();
console.log(data.status, data.required_actions);
<?php
$ch = curl_init('https://api.getreeds.co/shipping/v1/deliveries');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REEDS_ACCESS_TOKEN'),
'Idempotency-Key: order-10046-draft',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'pickup_address_id' => 'adr_3Mz8Rt1Q',
'dropoff_address_id' => 'adr_5Vb1Jc8D',
'package' => ['description' => '2 pairs of sneakers', 'weight_kg' => 1.5],
'auto_book' => true,
'max_total' => 300000,
'reference' => 'ORDER-10046',
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($body['data']['required_actions']);
import os
import requests
res = requests.post(
"https://api.getreeds.co/shipping/v1/deliveries",
headers={
"Authorization": f"Bearer {os.environ['REEDS_ACCESS_TOKEN']}",
"Idempotency-Key": "order-10046-draft",
},
json={
"pickup_address_id": "adr_3Mz8Rt1Q",
"dropoff_address_id": "adr_5Vb1Jc8D",
"package": {"description": "2 pairs of sneakers", "weight_kg": 1.5},
"auto_book": True,
"max_total": 300000,
"reference": "ORDER-10046",
},
)
data = res.json()["data"]
print(data["status"], data["required_actions"])
Reeds prices the draft as soon as both addresses are verified. If they are verified when you create it, that happens at once, and with auto_book: true the draft books itself in the same request.
When both addresses are already verified, Reeds also checks coverage at once: a pair it can't serve gets 422 ADDRESS_NOT_SERVICEABLE (or 422 INTERSTATE_NOT_AVAILABLE for Lagos to the FCT), and no draft is created. If an address is confirmed later and turns out to be outside coverage, the draft stays unpriced and asks you to confirm that address again.
{
"status": "success",
"data": {
"id": "dlv_8Pq4Ns2L",
"status": "requires_action",
"required_actions": [
{
"type": "CONFIRM_PICKUP_ADDRESS",
"address_id": "adr_3Mz8Rt1Q",
"message": "Pickup address needs confirmation"
}
],
"auto_book": true,
"fee": null,
"...": "other delivery fields"
}
}
Required actions
required_actions lists only what is still outstanding. A completed action disappears from the list and appears in events. A delivery.requires_action webhook fires each time one is added.
type | Meaning | How to clear it |
|---|---|---|
CONFIRM_PICKUP_ADDRESS | The pickup address needs confirmation. | Dashboard, or POST /addresses/{id}/confirm. |
CONFIRM_DROPOFF_ADDRESS | The drop-off address needs confirmation. | Dashboard, or POST /addresses/{id}/confirm. |
BOOK | Priced, and waiting for you to accept the price and book. Also used when the price is above max_total. | Dashboard, or POST /deliveries/{id}/book. |
FUND_WALLET | auto_book is on but the wallet doesn't cover the price. | Fund the wallet. Reeds retries the booking automatically when the money lands. |
PAY_INVOICE | auto_book is on but your invoice account has no room under its credit limit. | Pay the issued invoice, or ask Reeds to raise the limit. Reeds retries automatically. |
MARK_READY | The item isn't ready for pickup. | Dashboard, or POST /deliveries/{id}/ready. |
AWAITING_PRICE | Reeds couldn't price the delivery because its maps service was unavailable. | Nothing. Reeds tries again every 5 minutes. Once it is priced, the action becomes BOOK, or the draft books itself with auto_book. |
For address confirmation, see Addresses.
Book a priced draft
POST /deliveries/{id}/book charges the quoted price and books the draft. Idempotency-Key is required.
curl -X POST https://api.getreeds.co/shipping/v1/deliveries/dlv_8Pq4Ns2L/book \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN" \
-H "Idempotency-Key: order-10046-book"
Mark an item ready
POST /deliveries/{id}/ready tells Reeds the item is packed. The pickup is scheduled from that moment, so the delivery promise clock starts here.
curl -X POST https://api.getreeds.co/shipping/v1/deliveries/dlv_8Pq4Ns2L/ready \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN"
Nothing waits forever
A draft that isn't booked within 7 days, and a booked delivery that isn't marked ready within 7 days, are cancelled. A charged delivery is refunded in full.
Reeds reminds you on day 3 and day 6, in the dashboard, by email and through the delivery.expiring webhook (it carries expires_at). An expired delivery is cancelled with the reason expired.
Worked flow
- You create a draft with
auto_book: true. The pickup addressadr_3Mz8Rt1Qneeds confirmation, so the draft comes backrequires_actionwithCONFIRM_PICKUP_ADDRESS, andfeeisnull. - You confirm the address with
POST /addresses/adr_3Mz8Rt1Q/confirm. Anaddress.confirmedwebhook fires. - Both addresses are now verified, so Reeds prices the draft. The price is within your
max_totaland the wallet covers it, so Reeds books it.delivery.bookedfires, the status becomesscheduled, and the tracking code is set. - If the wallet had been short, the draft would show
FUND_WALLETinstead, and book itself once you fund the wallet.