Checkout quotes
At checkout you need a price fast, and you don't want to save addresses first. Send the pickup and drop-off inline in a single POST /quotes. Reeds saves both addresses and returns a quote.
Quote at checkout
Each of pickup and dropoff takes the same fields as POST /addresses: name, phone, address (text), place_id, latitude and longitude, and notes. Send package.description too. See Quotes for every field.
Aggregators already hold coordinates or a place id after validating an address. Send them. A text-only address that matches only approximately makes the quote unavailable, and Reeds drops out of that checkout.
- cURL
- Node.js
- PHP
- Python
curl https://api.getreeds.co/shipping/v1/quotes \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"pickup": {
"name": "Kemi Adebayo", "phone": "08051234567",
"address": "12 Allen Avenue, Ikeja, Lagos",
"latitude": 6.6018, "longitude": 3.3515
},
"dropoff": {
"name": "Chidi Okafor", "phone": "08031234567",
"address": "Admiralty Way, Lekki, Lagos",
"latitude": 6.4474, "longitude": 3.4723
},
"package": { "description": "2 pairs of sneakers", "weight_kg": 1.5 }
}'
const res = await fetch('https://api.getreeds.co/shipping/v1/quotes', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REEDS_ACCESS_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
pickup: {
name: 'Kemi Adebayo', phone: '08051234567',
address: '12 Allen Avenue, Ikeja, Lagos',
latitude: 6.6018, longitude: 3.3515,
},
dropoff: {
name: 'Chidi Okafor', phone: '08031234567',
address: 'Admiralty Way, Lekki, Lagos',
latitude: 6.4474, longitude: 3.4723,
},
package: { description: '2 pairs of sneakers', weight_kg: 1.5 },
}),
});
const { data } = await res.json();
if (data.available) {
console.log(data.id, data.fee.total, data.schedule.deliver_by);
} // otherwise: leave Reeds out of the checkout
<?php
$ch = curl_init('https://api.getreeds.co/shipping/v1/quotes');
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([
'pickup' => [
'name' => 'Kemi Adebayo', 'phone' => '08051234567',
'address' => '12 Allen Avenue, Ikeja, Lagos',
'latitude' => 6.6018, 'longitude' => 3.3515,
],
'dropoff' => [
'name' => 'Chidi Okafor', 'phone' => '08031234567',
'address' => 'Admiralty Way, Lekki, Lagos',
'latitude' => 6.4474, 'longitude' => 3.4723,
],
'package' => ['description' => '2 pairs of sneakers', 'weight_kg' => 1.5],
]),
]);
$data = json_decode(curl_exec($ch), true)['data'];
curl_close($ch);
if ($data['available']) {
echo $data['id'], ' ', $data['fee']['total'];
} // otherwise: leave Reeds out of the checkout
import os
import requests
res = requests.post(
"https://api.getreeds.co/shipping/v1/quotes",
headers={"Authorization": f"Bearer {os.environ['REEDS_ACCESS_TOKEN']}"},
json={
"pickup": {
"name": "Kemi Adebayo", "phone": "08051234567",
"address": "12 Allen Avenue, Ikeja, Lagos",
"latitude": 6.6018, "longitude": 3.3515,
},
"dropoff": {
"name": "Chidi Okafor", "phone": "08031234567",
"address": "Admiralty Way, Lekki, Lagos",
"latitude": 6.4474, "longitude": 3.4723,
},
"package": {"description": "2 pairs of sneakers", "weight_kg": 1.5},
},
)
data = res.json()["data"]
if data["available"]:
print(data["id"], data["fee"]["total"])
# otherwise: leave Reeds out of the checkout
{
"status": "success",
"data": {
"id": "qt_2bX9Wn4K",
"available": true,
"expires_at": "2026-10-27T10:20:00+01:00",
"service": "standard",
"fee": { "delivery_fee": 255000, "vat": 19125, "service_charge": 5875, "discount": 0, "total": 280000, "currency": "NGN" },
"schedule": {
"pickup_by": "2026-10-26T19:00:00+01:00",
"deliver_by": "2026-10-27T19:00:00+01:00",
"earliest_delivery": "2026-10-26T19:00:00+01:00"
},
"...": "other quote fields"
}
}
The price is your rate-card price. Show fee.total (kobo, so 280000 is ₦2,800) and the schedule at checkout.
When Reeds can't serve the route
available: false is a normal 200 response, not an error. Ask every courier at once and leave Reeds out of this checkout.
{
"status": "success",
"data": {
"available": false,
"reason": { "code": "ADDRESS_NOT_SERVICEABLE", "message": "The drop-off is outside Reeds' coverage" },
"pickup_address_id": "adr_7Hq2Lk9P",
"dropoff_address_id": "adr_6Tn3Wd5R"
}
}
reason.code | When |
|---|---|
ADDRESS_NEEDS_CONFIRMATION | An address matched only approximately, or not at all. data.suggestion is Reeds' best match (null if there is none). Quote again with coordinates or a place id. |
ADDRESS_NOT_SERVICEABLE | An address is outside Reeds' coverage, or there is no road route between the two. |
INTERSTATE_NOT_AVAILABLE | The drop-off is in another state. Inter-state delivery is not available through the API. |
Speed and caching
The target is an answer within 2 seconds for 95% of quotes. A quote lasts 24 hours and books one delivery, with the price locked, so you can cache it for up to 24 hours, for example against the cart. If the cart changes (address or package), ask for a new quote.
Book when the order is placed
When the customer pays, book with the quote_id and the shipper. Idempotency-Key is required.
- cURL
- Node.js
- PHP
- Python
curl https://api.getreeds.co/shipping/v1/deliveries \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN" \
-H "Idempotency-Key: order-10045-book" \
-H "Content-Type: application/json" \
-d '{
"quote_id": "qt_2bX9Wn4K",
"reference": "ORDER-10045",
"shipper": { "business_name": "Tola Fabrics", "phone": "08051234567", "merchant_id": "m_8812" }
}'
const res = await fetch('https://api.getreeds.co/shipping/v1/deliveries', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REEDS_ACCESS_TOKEN}`,
'Idempotency-Key': 'order-10045-book',
'Content-Type': 'application/json',
},
body: JSON.stringify({
quote_id: 'qt_2bX9Wn4K',
reference: 'ORDER-10045',
shipper: { business_name: 'Tola Fabrics', phone: '08051234567', merchant_id: 'm_8812' },
}),
});
const { data } = await res.json();
console.log(data.id, data.tracking_code);
<?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-10045-book',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'quote_id' => 'qt_2bX9Wn4K',
'reference' => 'ORDER-10045',
'shipper' => ['business_name' => 'Tola Fabrics', 'phone' => '08051234567', 'merchant_id' => 'm_8812'],
]),
]);
$data = json_decode(curl_exec($ch), true)['data'];
curl_close($ch);
echo $data['id'], ' ', $data['tracking_code'];
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-10045-book",
},
json={
"quote_id": "qt_2bX9Wn4K",
"reference": "ORDER-10045",
"shipper": {"business_name": "Tola Fabrics", "phone": "08051234567", "merchant_id": "m_8812"},
},
)
data = res.json()["data"]
print(data["id"], data["tracking_code"])
If the quote has expired you get 409 QUOTE_EXPIRED: quote again and book with the new id. See QUOTE_EXPIRED.