Get bill by table
Returns the open order for a table, including all checks, items, and totals.
GET /v1/pat/venue/{venueId}/table/{tableId}/bill
Authorization: Bearer <token>
/bill when the body contains checks?A bill contains one or more open checks - splits within the same order. The URL is named for the partner's mental model ("the bill for this table"); checks is POS-side vocabulary that we surface inside the payload but keep off the path.
Path parameters
| Name | Type | Notes |
|---|---|---|
venueId | string | Mozrest venue identifier (must be in token scope) |
tableId | UUID | Mozrest canonical table ID (from the tables endpoint) |
Response - 200 OK
{
"orderId": "00ceefd4-8cc8-428b-985a-207b97cc3cba",
"venueId": "651f2c781027817e9f28e465",
"tableId": "8180b94f-e6ef-47b6-9d38-47b3459d06c9",
"tableName": "T 1",
"status": "open",
"partySize": 4,
"totals": {
"subtotal": 84.00,
"tax": 8.40,
"tip": 0.00,
"discount": 0.00,
"total": 92.40,
"prepayment": 20.00,
"paid": 30.00,
"totalDue": 42.40
},
"checks": [
{
"checkNumber": "1",
"status": "open",
"totals": {
"subtotal": 84.00,
"tax": 8.40,
"tip": 0.00,
"discount": 0.00,
"total": 92.40
},
"paymentMethod": null,
"items": [
{ "id": null, "name": "Tasting Menu", "quantity": 2, "unitPrice": 35.00, "price": 35.00, "total": 70.00 },
{ "id": null, "name": "Wine Pairing", "quantity": 2, "unitPrice": 7.00, "price": 7.00, "total": 14.00 }
]
}
]
}
partySize is null for orders opened directly on the POS (walk-ins) - it is only populated when the order originated from a reservation.
Item fields
Every item carries exactly these six fields, in the same shape for every POS - Mozrest normalises the line items regardless of which POS sits behind the venue.
| Field | Type | Notes |
|---|---|---|
id | string or null | POS-side item identifier when the POS provides one; null otherwise (the sandbox simulator provides none). Not a Mozrest ID. |
name | string | Line-item label as the POS reports it. |
quantity | integer | Quantity for the line. |
unitPrice | decimal | Per-unit price. |
price | decimal | Alias of unitPrice, retained for partners integrated before the contract was formalised. |
total | decimal | Line total (unit price × quantity, minus line discounts where the POS reports them). |
Order-level totals
| Field | Notes |
|---|---|
subtotal | Items total before tax/tip/discount. |
tax | Tax amount. May be 0 on POS systems with inclusive VAT - the VAT is already inside subtotal. |
tip | Tip already on the check, if any. |
discount | Discount applied to the check. |
total | Gross check total (subtotal + tax + tip - discount). Equals the original bill amount. |
prepayment | Amount already paid against this order via the deposit / reservation prepayment flow. 0.00 when none. |
paid | Sum of the bill portion (amount - tip) of every partner payment already recorded against this order via the payment endpoint. Only payments with status: "confirmed" count - pending and failed payments never contribute. Lets you reconcile what you've submitted so far without keeping your own running total. 0.00 when none. |
totalDue | Amount the guest still owes: total - prepayment - paid, floored at 0. Use this as the amount to submit on the payment endpoint when collecting the remaining balance without a tip. When the guest adds a tip, submit amount = totalDue + tip - the payment amount field is tip-inclusive. |
totalDue, not totalReservations with deposits arrive at the bill endpoint with the deposit already accounted for. Earlier partial payments come off totalDue automatically. Charging anything other than totalDue (e.g. the raw total) will over-tender on the POS and be rejected. Re-fetch /bill between partial payments to follow the moving balance. With a tip the guest pays totalDue + tip in total - the tip rides on top and never pays the bill down.
Freshness
When the venue's POS supports live bill retrieval (features.payAtTable.billRetrieval = true), Mozrest fetches the bill from the POS at request time and write-throughs the local cache. When it doesn't, Mozrest serves the last-known state from its own DB. Either way you get the same response shape - the freshness is exposed via /features.
Errors
| Status | When |
|---|---|
401 Unauthorized | Token invalid or revoked. OAuth-style body, not the standard envelope - see Errors |
403 Forbidden | Missing Authorization header, token does not have partner access, or venue not in scope |
404 Not Found | The table is unknown for the venue (message: No table "{tableId}" registered for venue "{venueId}".) or no open order exists for the table (message: No open order for venue "{venueId}" table "{tableId}".). Same status either way; the message states which case applies |