POS v1
This API is Live and ready to use in production.
TableCheck has specialized integrations with Oracle MICROS (Simphony), Shiji Infrasys (HERO), Agilisys (InfoGenesis), and many more. Please contact your TableCheck Sales Representative to check if your desired integration already exists.
For further inquiries and assistance, please contact api@Tablecheck.com.
The POS API is used to connect Point-of-Sale systems to the TableCheck platform.
Target Audience
The POS API is recommended for use exclusively by POS vendors. It cannot be used by restaurant booking sites, etc.
Endpoint
The POS API allows the implementer to modify data.
https://api.tablecheck.com/api/pos/v1/...
Interactive API console
https://api.tablecheck.com/api/pos/v1/docs
Refer to Using the API Console for help.
Data Model
This section describes TableCheck’s object relational structure exposed by the API.
The POS API provides multi-tenant access: with a single API key you can manage data across multiple end-user accounts and even multiple POS systems. End-user tenancy is controlled with the following objects:
A “Franchise” is a merchant account, typically a restaurant group company or a hotel property.
A “Shop” is a restaurant venue. One Franchise has many Shops.
Depending on the end-user’s POS setup, a Franchise or Shop will correspond to the POS client account, and a Shop will correspond to one or more POS revenue centers.
A Shop has a one-to-many relationship with each of the following objects:
A “Table” corresponds to any physical location for seating, including tables, counter stools, and private rooms. In order for mapping logic to work, it is important that the table names within the POS exactly match the names used in TableCheck.
A “Reservation” corresponds to the POS party or table status. A Reservation will be assigned to one or more Tables. Note that multiple Reservations may be assigned to the same Table, so long as their seating times are not overlapping.
A “PosJournal” corresponds to the POS guest check. A Reservation may have multiple PosJournals, e.g. in the case that checks are split within the party. As described in the logic section below, there are cases where creating a PosJournal object (i.e. “opening a check”) will automatically create an associated Reservation object.
Lastly, a PosJournal has three sub-object types, each being a one-to-many relationship:
A “PosOrder” corresponds to a single food/beverage order line-item, for example: “3 x Chicken Salad @ $10.99”. The PosOrder includes the menu item name as a text field, as well as the quantity and unit price.
A “PosDiscount” corresponds to a discount such as a coupon or voucher which is subtracted from the check subtotal.
A “PosPayment” corresponds a money payment to settle the check, and includes information about the payment method such as cash or credit card.
API Setup
Please perform the following process for each new Shop which would like which is setup in the system.
Request access to the Shops to enable POS integration by contacting api@tablecheck.com
Verify you can access the Shop via the API
Confirm the table names are matched between TableCheck and the POS system
Setup: Requesting Access to a Shop
In the future we plan to automate the Shop access request process.
Please request access to specific Shops (restaurants) by contacting api@tablecheck.com. Please include:
The Shop name
Your reference ID code to use for the Shop (will appear as
Shop.ref
in our API)The Shop parent company (to help match)
The Shop address (to help match)
Setup: Browsing the Accessible Shop List
The /shops
endpoint will return all restaurants for which you have been granted access.
GET /shops
Setup: Confirming Table Names
The POS API uses table names to automatically match Checks to existing Reservations. We recommend POS vendors to implement an automatic check process which is run periodically to ensure both systems remain in-sync.
The /shops/{shop_id}/tables
endpoint returns all tables associated with the shop.
GET /shops/{shop_id}/tables
We recommend to pass time
param to get all tables available for specific time.
Warning: POS API integration will NOT work properly if table names do not match between TableCheck and your POS system.
Live API Workflow
Overview
When a user opens or modifies a guest check, transmit it to TableCheck's “PosJournal” API
TableCheck will match the PosJournal to a Reservation (or create a new Reservation)
When Reservations change in TableCheck, either via API or via user actions, TableCheck will notify the POS System of the change.
According to the change, the POS system should retrieve the Reservation object and update the Table Status within the POS accordingly.
Transmitting Guest Checks (PosJournals)
You may fetch info for a single shop by either the id
or slug
.
GET /shops/{shop_id}/pos_journals
Create PosJournal
You can create PosJournal using the following URL:
POST /shops/{shop_id}/pos_journals
Special params:
Name | Comment |
---|---|
| Required field and represent Check ID |
| TableCheck Reservation ID |
| Reservation ‘status’ that should be updated on associated Reservation record. See status mapping below |
| Table names could be fetched from https://api.tablecheck.com/api/pos/v1/docs#/table_names/listTables |
| Params that will be used for Reservation creation if reservation not found. |
| Arrays of PosJournal associated records. |
Update PosJournal
Update URL:
PUT /shops/{shop_id}/pos_journals/{pos_journal_id}
We allow to update all the same params as listed for :create PosJournal action except receipt_num param since it considered as unchangeable.
Linking Reservations and Setting Reservation Status
In the aforementioned PUT /shops/{shop_id}/pos_journals/{pos_journal_id}
API endpoint, you may use the PosJournal.reservation_status
parameter to automate Reservation status actions. In each case a Reservation will attempted to be linked as follows:
If a Reservation was already created by or linked to the PosJournal as a result of a previous action (as per below), use that Reservation.
If either of the
PosJournal.reservation_id
orreservation_ref
parameters are set, attempt to use those to lookup the Reservation by itsid
orref
Attempt to automatch the reservation according to the
pax
,table_names
, andopened_at
parameters.Create a new Reservation
| Reservation Action | Reservation.status |
---|---|---|
| Guest has been seated at a table. |
|
| Bill has been printed |
|
| The bill has been paid by the guest. |
|
| The guest has left the table, |
|
| The table is cleaned and ready for the next guest. |
|
Setting Rich Data on PosJournals
While it is possible to implement the API by only setting basic fields such as opened_at
, total_amt
, etc., we recommend to transmit as many of the available fields as possible, including:
PosOrders
- Includes menu item and order price details.PosDiscounts
- Promotional discount codes applied to the sales amount.PosPayments
- Payment method (credit card, cashless, etc.) and card brand / issuer.
Restaurant end users can see data in TableCheck Manager and use it to generate detailed reports and analytics. Refer to the API Console for further details.
Receiving Reservation Sync Events
Please refer to the Sync API for instructions on how receive SyncEvent messages which indicate that a Reservation has changed on the TableCheck side as per the below example.
Note that you will receive all SyncEvents for all Shops to a single API callback URL. (If you require handling SyncEvents on a per-Shop basis, please refer to the polling instructions in the Sync API.)
// SyncEvent object
{
"id": "ae5355ca1fd337ed5d6893e2",
"event_type": "created"
"syncable_type": "reservation",
"syncable_id": "ca1fd893e2Zae5355337ed5d6", // The reservation ID
"syncable_ref": "your_id_here" // PosJournal.reservation_ref, if set
}
Fetching a Reservation based on a Webhook Event
When you receive the SyncEvent, you may fetch the Reservation (including any associated PosJournals) using the following endpoint:
GET /shops/{shop_id}/reservations/{syncable_id or syncable_ref}
Pre-loading Reservations
Certain POS systems may wish to pre-load Reservations and open PosJournals in advance. This may be done using the Reservations list endpoint follows:
// Load all reservations starting between Nov 26, 2018 19:00 and 20:00 UTC
GET /shops/{shop_id}/reservations?start_at_min=2018-11-26T19:00:00Z&start_at_max=2018-11-26T20:00:00Z
Update Reservations
Certain Reservation could be updated without updating PosJournal
PUT /shops/{shop_id}/reservations/{syncable_id or syncable_ref}
Table Status API
For certain POS systems and mobile ordering use cases, it may be easier to work with tables (i.e. identified by table name) rather than reservations. To do this, use the table_status
endpoint.
Updating Status at a Table
The following example will find the reservation at table “A1” an change its status to seated:
PUT /shops/{shop_id}/table_status/update
Body:
{
table_name: "A1",
status: "seated",
allow_create_reservation: true
}
Response:
{
table_status: {
table_id: "5071d35765a26aa79f465e70",
table_name: "A1",
reservation_id: "65e70356071daa79f4765a25",
reservation_start_at: "2024-01-01T17:00:00.000+09:00",
reservation_end_at: "2024-01-01T19:00:00.000+09:00",
status: "seated"
}
}
Updating Status by Reservation ID
After an initially fetching or updating table status as per the above example, you should store the reservation_id
returned and used it for subsequent updates. This will guarantee you are updating the same diner’s reservation status, even if the current time exceeds their reservation period, or they move to a different table.
PUT /shops/{shop_id}/table_status/update
Body:
{
reservation_id: "65e70356071daa79f4765a25",
status: "paid"
}
Response:
{
table_status: {
table_id: "5071d35765a26aa79f465e70",
table_name: "A1",
reservation_id: "65e70356071daa79f4765a25",
reservation_start_at: "2024-01-01T17:00:00.000+09:00",
reservation_end_at: "2024-01-01T19:00:00.000+09:00",
status: "paid"
}
}
Clearing a Table
To clear a reservation from a table at the current time, set the status value to "vacant"
. This will cause the end time of the reservation to shift to be before the current time. Note that in this case, the API will return status "vacant"
because there is no longer a reservation at the current time, however, the reservation object itself will have status "turned_over"
.
PUT /shops/{shop_id}/table_status/update
Body:
{
reservation_id: "65e70356071daa79f4765a25",
status: "vacant"
}
Response:
{
table_status: {
table_id: "5071d35765a26aa79f465e70",
table_name: "A1",
reservation_id: "65e70356071daa79f4765a25",
reservation_start_at: "2024-01-01T17:00:00.000+09:00",
reservation_end_at: "2024-01-01T18:30:00.000+09:00", // changed
status: "vacant"
}
}
Refer to the API documentation for further details.
TODO
Voiding Orders
Discounts (surcharges?) coupon code, etc.?