API Reference
Endpoints

Create batch orders

The batch endpoint is the primary way to create deliveries. Submit a whole batch in one call: one pickup with one drop, one pickup with many drops (multidrop), or any mix. Creation is synchronous — you get per-order accepted/rejected results at request time, with no polling to find out whether an order failed.

POST/orders/bulk

Create one or many delivery orders in a single synchronous call. Each order is one pickup with one or more drop-offs (a multidrop run). Valid orders are created immediately; invalid ones are returned with a specific reason and never persisted. Partial success is normal.

Headers
Authorizationstringrequired
Your API key: Bearer rly_live_... (or rly_test_... for sandbox).
Idempotency-Keystring (uuid)required
A unique key per batch. The same key + body replays the stored result; a different body returns 409.
Content-Typestringrequired
application/json.
Body parameters
client_batch_idstringrequired
Your reference for the batch. Unique per business + environment among live batches; reused keys replay the stored result.
ordersarrayrequired
One or more pickup groups. Each group is a single pickup plus 1..N drop-offs.
pickupobjectrequired
Pickup name, phone (E.164), and either lat/long or an address. Optional pickup_scheduled_at (ISO-UTC) to schedule; omit to dispatch now.
dropoffarrayrequired
One trackable order per drop. Each has your client_order_id (unique among active drops), an optional external_waybill, and a dropoff recipient (name, phone, coords or address).
curl -X POST https://dev-api.rely7.com/api/v1/orders/bulk \
  -H "Authorization: Bearer rly_live_xxx" \
  -H "Idempotency-Key: 8f2b1c9a-4e21-4c3a-9b77-2f0a1e6d5c44" \
  -H "Content-Type: application/json" \
  -d '{
  "client_batch_id": "batch-2026-07-19-001",
  "orders": [
    {
      "pickup": {
        "name": "Warehouse A",
        "phone": "+97455123456",
        "lat": 25.2854,
        "long": 51.531
      },
      "dropoff": [
        {
          "client_order_id": "order-9001",
          "external_waybill": "WB-9001",
          "dropoff": {
            "name": "Ahmed Hassan",
            "phone": "+97455998877",
            "address": {
              "complete_address": "West Bay Tower 3, Doha",
              "city": "Doha",
              "country": "Qatar"
            }
          }
        }
      ]
    }
  ]
}'
{
  "statusCode": 200,
  "success": true,
  "data": {
    "batch_id": "7c9e6a2b-1f34-4d21-a0b8-9e2c1d4f5a6b",
    "client_batch_id": "batch-2026-07-19-001",
    "counts": { "total": 1, "accepted": 1, "rejected": 0 },
    "orders": [
      {
        "client_order_id": "order-9001",
        "external_waybill": "WB-9001",
        "status": "accepted",
        "pass_order_id": "b1d2...",
        "drop_id": "c3e4..."
      }
    ],
    "poll_url": "https://dev-api.rely7.com/api/v1/batches/7c9e6a2b-1f34-4d21-a0b8-9e2c1d4f5a6b"
  }
}
Partial success is normal
Good orders are created; bad ones come back with a specific failure_reason and are never persisted, so their client_order_id stays free to resend. A single 200 can contain both accepted and rejected orders.

Failure reasons

A rejected order carries one of these failure_reason values:

failure_reason
OUT_OF_SERVICE_AREAINSUFFICIENT_BALANCEGEOCODE_FAILEDOUTSIDE_OPERATING_HOURSSCHEDULE_IN_PASTDUPLICATE_CLIENT_ORDER_IDINVALID_PHONEINVALID_COORDINATES

Batch status

The persisted batch carries a status: PROCESSING, COMPLETED (all accepted), PARTIAL (mixed), or FAILED (none accepted). Address-only drops are forward-geocoded and the resolved pin echoed back; coordinates are used as-is.

Settlement at creation
On a wallet account, accepted orders debit your balance at creation (an empty balance rejects with INSUFFICIENT_BALANCE and nothing persists). On an invoiced account, orders accrue to your monthly bill.