Sending us orders
One request, from your system to ours. When it arrives we answer it — we say yes or no, and we tell you why.
The address
POST https://api.cateringdeliverypartners.com/ordersThe key
We issue you one. It is shown once, when it is made, and we cannot show it again — if it is lost we issue another and revoke the old one. Send it as a bearer token:
Authorization: Bearer cdp_live_…The key belongs in your server, never in a browser or a mobile app. Anyone holding it can file orders as you.
An order
Copy this, change the values, and you are done. Every field below is either in it or optional.
{
"external_reference": "CLOVER-88120",
"delivery_date": "2026-10-02",
"pickup_time": "2026-10-02T10:45:00-04:00",
"delivery_time": "2026-10-02T11:30:00-04:00",
"order_price": "518.00",
"tip": "50.00",
"head_count": 25,
"recipient": {
"name": "Reception",
"ask_for": "Dana on the third floor",
"phone": "+12025550147"
},
"address": {
"line": "1000 Wilson Blvd",
"city": "Arlington",
"state": "VA",
"post_code": "22209"
},
"note": "Use the loading dock on H Street"
}What comes back
{
"id": "28213f55-…",
"status": "pending"
}An order is not booked when we answer 201. It is waiting for us to look at it. Every delivery this company carries is agreed rather than assumed, and that is as true of an order from a machine as of one from a telephone call.
The fields
| Field | Required | Example | |
|---|---|---|---|
external_reference | — | "CLOVER-88120" | Your own reference. We show it back to you and never interpret it. |
delivery_date | yes | "2026-10-02" | The day it is delivered, as a calendar date. |
pickup_time | yes | "2026-10-02T10:45:00-04:00" | When it is ready to collect. MUST carry a timezone offset. |
delivery_time | yes | "2026-10-02T11:30:00-04:00" | When it is wanted. Must be after the collection time. |
order_price | yes | "518.00" | What the customer paid, as a decimal string. Two places, no currency symbol. |
tip | — | "50.00" | What the customer left. |
head_count | — | 25 | How many people it feeds. |
recipient.name | yes | "Reception" | Who is receiving it. |
recipient.ask_for | — | "Dana on the third floor" | Who the driver should ask for on arrival. |
recipient.phone | — | "+12025550147" | Their number. |
address.line | yes | "1000 Wilson Blvd" | The street address. A desk or floor belongs in ask_for, not here. |
address.city | yes | "Arlington" | |
address.state | yes | "VA" | |
address.post_code | yes | "22209" | |
note | — | "Use the loading dock on H Street" | Anything the driver should know at their end. |
external_business_id | — | "CLOVER-STORE-9" | Only if your key serves several restaurants. A key cut for one restaurant ignores it. |
Two things worth reading twice
- Times must carry a timezone offset.
2026-10-02T11:30means a different moment in two places, and we will refuse it rather than guess which one you meant. - Amounts are strings, to two decimal places.
"518.00", not518and not518.004. Money that has been through a floating point number has already lost the argument.
The answers
| Code | What it means | Try again? |
|---|---|---|
201 | We have it. It is waiting for us to answer. | No. |
400 | Something in the order is wrong. `problems` names each field. | No — the same body will be refused again. |
401 | The key is missing, unknown or revoked. | No. Ask us for a key. |
422 | The order was understood and could not be stored. | No. Tell us. |
503 | We could not answer just now. | Yes, after a pause. Nothing was recorded. |
A 400 names every field it objected to at once, so you are not discovering them one round trip at a time.
Asking what happened to one
We answer your order in our own panel, usually within the hour. Ask us what we said, with the id we gave you:
GET https://api.cateringdeliverypartners.com/orders/<id>{
"id": "28213f55-1bb5-43c2-85db-bfb2c9fcc080",
"status": "rejected",
"reason": "that Saturday is full",
"external_reference": "CLOVER-88120"
}| Status | What it means |
|---|---|
pending | We have it and have not answered yet. |
accepted | We are carrying it. |
rejected | We are not. `reason` says why, always. |
withdrawn | The restaurant took it back before we answered. |
A rejection always carries its reason. "No" and "no, that Saturday is full" are different answers, and only one of them tells you what to do next.
An id that is not yours answers 404, exactly as an id that does not exist does.