Skip to main content

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>
note
Why /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

NameTypeNotes
venueIdstringMozrest venue identifier (must be in token scope)
tableIdUUIDMozrest 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.

FieldTypeNotes
idstring or nullPOS-side item identifier when the POS provides one; null otherwise (the sandbox simulator provides none). Not a Mozrest ID.
namestringLine-item label as the POS reports it.
quantityintegerQuantity for the line.
unitPricedecimalPer-unit price.
pricedecimalAlias of unitPrice, retained for partners integrated before the contract was formalised.
totaldecimalLine total (unit price × quantity, minus line discounts where the POS reports them).

Order-level totals

FieldNotes
subtotalItems total before tax/tip/discount.
taxTax amount. May be 0 on POS systems with inclusive VAT - the VAT is already inside subtotal.
tipTip already on the check, if any.
discountDiscount applied to the check.
totalGross check total (subtotal + tax + tip - discount). Equals the original bill amount.
prepaymentAmount already paid against this order via the deposit / reservation prepayment flow. 0.00 when none.
paidSum 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.
totalDueAmount 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.
tip
Always charge totalDue, not total

Reservations 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

StatusWhen
401 UnauthorizedToken invalid or revoked. OAuth-style body, not the standard envelope - see Errors
403 ForbiddenMissing Authorization header, token does not have partner access, or venue not in scope
404 Not FoundThe 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