Endpoints and scopes
| Request | Scope |
|---|---|
GET /orders |
orders:read |
GET /orders/{order_id} |
orders:read |
POST /orders/{order_id}/accept |
orders:write |
POST /orders/{order_id}/reject |
orders:write |
POST /orders/{order_id}/status |
orders:write |
POST /orders/{order_id}/cancel |
orders:write |
| the customer’s full number in orders and events | customer:contact |
Who does what
| Party | Role |
|---|---|
| Customer | orders and pays in the AurMap app |
| AurMap | charges the card or records cash, refunds on cancellation, pays the merchant |
| Your system | accepts the order, prepares it, and updates it until hand-over |
Your system never charges or refunds the customer for AurMap orders.
At launch every order is pickup (pickup). Delivery is coming soon.
Statuses
received ──accept──▶ accepted ──▶ preparing ──▶ ready ──▶ completed
│ │ │ │
│ reject └─────────────┴────────────┴── cancel ─▶ cancelled (merchant)
▼
rejected
received ── customer cancels ──▶ cancelled (customer)
received ── accept_by passes ──▶ cancelled (timeout)
ready ── customer_no_show ──▶ cancelled (merchant)| Status | Set by | Meaning |
|---|---|---|
received |
AurMap | a new order waiting for your decision |
accepted |
you | you accepted it |
preparing |
you | being prepared |
ready |
you | ready for pickup |
out_for_delivery |
you | on its way Coming soon |
completed |
you | handed to the customer |
rejected |
you | refused before acceptance |
cancelled |
depends | cancelled; the reason is in cancel.reason |
- You can jump forward: from
acceptedstraight toreadyorcompleted. - You cannot go back; that answers
409 INVALID_TRANSITION.
Cancellation and refund rules
- Before acceptance the customer may cancel. They get a full refund automatically, and you receive
order.cancelledwith reasoncustomer. - After acceptance only the merchant cancels, from your system. AurMap refunds the customer in full, once, except for a customer no-show (below).
- Accept window: you set it between 2 and 15 minutes, 5 by default. Change it with pause ordering. If you neither accept nor reject before
accept_by, the order is cancelled with reasontimeoutand the customer is refunded. - AurMap support may cancel an open order with reason
aurmap_refund. - Customer no-show: the merchant decides within 24 hours of the order reaching
ready. A full refund is the default; a partial refund goes throughmerchant_refund. - Changing items after acceptance, and partial refunds other than for a no-show, are not available yet.
Accepting, a customer cancel and the window ending can happen in the same instant. We apply only the first to arrive. The others answer 409 ORDER_CLOSED with the final status, or 409 ALREADY_ACCEPTED.
How an order reaches you
- You receive
order.createdon your webhook the moment the order is placed. See Events. - Verify the signature and answer
200within 10 seconds. That answer is receipt, not acceptance. - Show the order in the kitchen, then accept or reject it before
accept_by.
If your server is down, the window keeps running. When you are back, ask for waiting orders:
aurmap GET '/v1/orders?status=received&place_id=plc_9q3w7e'The order object
{
"order_id": "ord_7m1x9c",
"number": "M-1043",
"mode": "live",
"link_id": "lnk_2h6j4n",
"place_id": "plc_9q3w7e",
"external_location_id": "pos-branch-17",
"type": "pickup",
"status": "received",
"version": 1,
"placed_at": "2026-10-14T12:30:05Z",
"accept_by": "2026-10-14T12:35:05Z",
"menu_version": 15,
"priced_by": "aurmap",
"quote_id": null,
"customer": { "name": "Sara", "phone_masked": "+9665••••••01", "phone_e164": null, "marketing_opt_in": false },
"items": [
{
"line_id": "1",
"item_id": "chicken-burger",
"size_id": "l",
"name": { "ar": "برجر دجاج", "en": "Chicken burger" },
"qty": 1,
"unit_price_minor": 2990,
"options": [
{ "group_id": "sauce", "option_id": "hot", "qty": 1, "price_minor": 230 },
{ "group_id": "extras", "option_id": "cheese", "qty": 1, "price_minor": 345 }
],
"notes": "No pickles",
"line_total_minor": 3565
},
{
"line_id": "2", "item_id": "orange-juice", "size_id": "s",
"name": { "ar": "عصير برتقال", "en": "Orange juice" },
"qty": 2, "unit_price_minor": 920, "options": [], "notes": null, "line_total_minor": 1840
}
],
"totals": { "currency": "SAR", "subtotal_minor": 5405, "discount_minor": 0, "service_charge_minor": 0, "tax_minor": 705, "total_minor": 5405, "prices_include_tax": true },
"payment": { "method": "card", "status": "paid", "amount_minor": 5405 },
"notes": null,
"cancel": null
}| Field | Description |
|---|---|
number |
a short number the customer says at pickup |
accept_by |
the last moment to accept or reject |
version |
grows with every change; ignore any event older than what you hold |
menu_version |
the menu version the order was priced from |
priced_by |
aurmap when priced from your published menu, partner when your system priced it |
item_id, size_id, group_id, option_id |
your own ids from the menu |
customer.phone_masked |
the customer’s number, masked: country code and first digit, one dot per hidden digit, last two digits |
customer.phone_e164 |
the full number, only when the link holds customer:contact; otherwise null |
customer.marketing_opt_in |
whether the customer agreed to marketing from this merchant |
payment.method |
card paid in advance, or cash paid at pickup |
payment.status |
paid, unpaid, refunded or partially_refunded |
payment.refunded_minor |
the amount refunded to the customer, after a refund only |
The full number is for the order and the merchant’s loyalty points only. Do not use it for marketing unless marketing_opt_in is true. The same rule applies in events, the events log and the quote request.
A cash order arrives with "method": "cash" and "status": "unpaid". The branch collects at hand-over, then you set completed.
Accept an order
POST /orders/{order_id}/accept with orders:write.
aurmap POST /v1/orders/ord_7m1x9c/accept '{"prep_minutes":15,"external_order_id":"POS-88231"}'{ "order_id": "ord_7m1x9c", "status": "accepted", "version": 2, "ready_estimate": "2026-10-14T12:46:00Z", "external_order_id": "POS-88231" }await aurmap('POST', `/v1/orders/${orderId}/accept`, { prep_minutes: 15, external_order_id: posId }, `accept-${orderId}`);aurmap('POST', "/v1/orders/{$orderId}/accept", ['prep_minutes' => 15, 'external_order_id' => $posId], "accept-{$orderId}");Use a fixed idempotency key per command, like accept-<order_id>. A retry then never accepts twice.
Reject an order
POST /orders/{order_id}/reject, from received only.
aurmap POST /v1/orders/ord_7m1x9c/reject '{"reason":"item_unavailable","note":"Kunafa sold out"}'{ "order_id": "ord_7m1x9c", "status": "rejected", "version": 2 }Reasons: busy, closed, item_unavailable, cannot_fulfil, other (a note is required with other). The customer gets a full refund.
Update the status
POST /orders/{order_id}/status
aurmap POST /v1/orders/ord_7m1x9c/status '{"status":"ready"}'{ "order_id": "ord_7m1x9c", "status": "ready", "version": 3 }Values: preparing, ready, completed, and out_for_delivery once delivery opens.
Merchant cancel after acceptance
POST /orders/{order_id}/cancel, from accepted, preparing or ready.
aurmap POST /v1/orders/ord_7m1x9c/cancel '{"reason":"kitchen_issue","note":"Oven failure"}'{ "order_id": "ord_7m1x9c", "status": "cancelled", "version": 4, "cancel": { "reason": "merchant", "detail": "kitchen_issue", "by": "partner" }, "payment": { "method": "card", "status": "refunded", "amount_minor": 5405 } }Reasons: kitchen_issue, item_unavailable, customer_no_show, other. customer_no_show is allowed from ready only; its rules are in the next section. AurMap refunds the customer at once. Do not refund anything on your side. You then receive order.cancelled and order.payment_updated with status refunded.
Customer no-show
The order is ready and the customer never came. The merchant decides within 24 hours of the order reaching ready, with the same call: POST /orders/{order_id}/cancel with reason customer_no_show.
- Without
merchant_refund: AurMap refunds the customer in full. This is the default. - With
merchant_refund: the merchant declares the amount to refund and the reason. AurMap refunds that amount to the customer.
aurmap POST /v1/orders/ord_7m1x9c/cancel '{"reason":"customer_no_show","merchant_refund":{"amount_minor":2700,"reason":"Order prepared, customer did not come"}}'{ "order_id": "ord_7m1x9c", "status": "cancelled", "version": 5, "cancel": { "reason": "merchant", "detail": "customer_no_show", "by": "partner" }, "payment": { "method": "card", "status": "partially_refunded", "amount_minor": 5405, "refunded_minor": 2700 } }| Field | Description |
|---|---|
merchant_refund.amount_minor |
the amount refunded to the customer, in halalas; more than zero and less than the amount paid |
merchant_refund.reason |
the reason for the amount; a short text, required |
- If the merchant does not decide within 24 hours, AurMap closes the order with
customer_no_showand refunds the customer in full. So setcompletedas soon as you hand the order over. - After 24 hours the cancel answers
409 ORDER_CLOSED. merchant_refundis accepted only withcustomer_no_show, and only on a card order. Otherwise it answers400 VALIDATION_FAILED.- A cash order is not paid yet, so there is nothing to refund. Cancel it with
customer_no_showand nomerchant_refund. - You then receive
order.cancelledandorder.payment_updatedwith statusrefundedorpartially_refunded.
Reading orders
| Request | Description |
|---|---|
GET /orders/{order_id} |
one order |
GET /orders?place_id=&status=&updated_after=&cursor= |
a list; status=open covers every open order |
GET /orders?ids=ord_a,ord_b |
up to 100 orders, for reconciling |
Pricing from your system Coming soon
Some systems price their own menus: service charges, loyalty prices, promotions. For them there is an optional capability: at checkout we ask your system for the price, and the customer pays exactly what you answer.
- Register a
quote_urlin the developer dashboard and turn on “pricing from my system” for the link. It must be a publichttpsaddress, under the same rules as webhook endpoints in Events. - At checkout we send
quote_urla request signed with your webhook secret. The timeout is 3 seconds.
{
"request_id": "qr_01JA9X",
"place_id": "plc_9q3w7e",
"external_location_id": "pos-branch-17",
"type": "pickup",
"payment_method": "card",
"menu_version": 15,
"customer": { "phone_masked": "+9665••••••01", "phone_e164": null },
"items": [
{ "line_id": "1", "item_id": "chicken-burger", "size_id": "l", "qty": 1, "options": [ { "group_id": "sauce", "option_id": "hot", "qty": 1 } ], "notes": null }
]
}Your system answers 200:
{
"quote_id": "pq_55120",
"expires_at": "2026-10-14T12:45:00Z",
"currency": "SAR",
"lines": [ { "line_id": "1", "unit_price_minor": 2990, "options_minor": 230, "line_total_minor": 3220 } ],
"subtotal_minor": 3220, "discount_minor": 0, "service_charge_minor": 0, "tax_minor": 420, "total_minor": 3220,
"cash_allowed": true, "prep_min": 10, "prep_max": 20
}Or 409 when the order cannot be made:
{ "code": "SOLD_OUT", "errors": [ { "line_id": "1", "code": "SOLD_OUT" } ] }| Code | Meaning |
|---|---|
MENU_CLOSED |
the menu is closed now |
PICKUP_OFF |
pickup is not available |
ITEM_UNAVAILABLE |
the item is not available |
SOLD_OUT |
sold out |
INVALID_OPTIONS |
the add-on choice breaks the rules |
CASH_NOT_ACCEPTED |
cash is not accepted |
expires_atis between 5 and 15 minutes from now.- If your system does not answer in time, the customer sees “cannot price right now”. We never use an old price.
- The order then arrives with
"priced_by": "partner"and thequote_id. Honour the price you answered.