Start with an update timestamp
On your first request, supply updated_since as an RFC3339 timestamp, such as
2026-01-01T00:00:00Z. This is an inclusive check update timestamp, not a
filter on when the check opened or closed. An older check that changes after
your starting timestamp can be returned.
Confirm available historical coverage with Chompy before a large import. V1 uses the same paginated endpoint for history and updates; there is no separate bulk-export endpoint.
The default page size is 100; limit accepts 1 through 200. Use 200 for
historical imports. Always send exactly one of updated_since or cursor.
Continue with the cursor
Every successful checks response includes:
| Field | What to do |
|---|---|
checks |
Process these complete snapshots. The array can be empty. |
has_more: true |
Request the next page immediately using next_cursor. |
has_more: false |
You’ve finished this polling window. Save next_cursor and use it on the next scheduled poll. |
next_cursor |
Treat this as an opaque string. Don’t decode, edit, or construct it yourself. |
After processing the page from the quickstart, request the next page:
CHOMPY_CURSOR="$(printf '%s' "$chompy_checks_page" | jq -er '.next_cursor')" &&
chompy_checks_page="$(
curl --fail-with-body --silent --show-error --max-time 20 --get \
--header "Authorization: Bearer ${CHOMPY_ACCESS_TOKEN:?Get an access token first}" \
--data-urlencode "cursor=$CHOMPY_CURSOR" \
--data-urlencode 'limit=200' \
"$CHOMPY_API_BASE_URL/v1/locations/$CHOMPY_LOCATION_ID/checks"
)" &&
printf '%s' "$chompy_checks_page" | jq
Use --data-urlencode (or your HTTP client’s query-parameter encoder) so the
cursor arrives unchanged. Keep a separate saved cursor for each credential
pair, environment, and location. A newly issued access token for the same
credentials can continue using the saved cursor.
Save sync state
- Fetch a page using your saved cursor, or
updated_sincefor a new import. - Upsert every check by
id, keeping the newestversionyou have seen. - Durably save
next_cursoronly after all checks in the page are processed. - If
has_moreistrue, continue immediately. Otherwise, wait for your next poll.
If processing fails, retry from your last saved cursor. Where supported, save check updates and the cursor in one transaction. Run one pagination chain at a time per location to avoid overwriting checkpoints.
The feed returns snapshots, not every intermediate edit. Checks are ordered by
update time and ID. Updates made while you are paging may appear later or in a
subsequent poll. Recent snapshots are deliberately replayed, so receiving a
check more than once is normal—even after has_more was false.
Ignore an older version of a check you already stored. Reprocessing the same
version must be safe; don’t add its sales or payments to your totals again. For
a newer snapshot, replace the previous snapshot, including its arrays. Treat
status: deleted as a deletion marker in your copy, not as a new sale.
Reading a check
- Identity:
idis the stable check identifier.check_numberis a display reference, not a globally unique key. - Times: timestamps use RFC3339 with a UTC offset. Use
opened_atandclosed_atfor the check’s lifecycle; useupdated_atfor change tracking.closed_atis omitted when unavailable. Use the location’s IANAtimezonewhen displaying restaurant-local time. - Tables and server:
tablescontains names or numbers captured on the check and can be empty.serveris optional; its name may be unavailable. A server name is a current display label. Name changes alone don’t trigger check updates. - Money: amounts are integer cents and the current currency is
USD. For example,1299means $12.99. Usetotalsfor check-level amounts. - Line items: each row represents one item (
quantity: 1). Identical products can occupy separate rows with different IDs. Modifiers include their labels and prices. Voided rows remain visible but must not be counted as sales; their amounts describe the item before the void. - Discounts and comps:
adjustmentsincludestype, a reason name, a nonnegativeamount_cents, and aneffectofdecreaseorincrease.line_item_idlinks an item-specific adjustment; its absence means a check-level adjustment. Itemnet_amount_centsalready includes its item adjustment; don’t subtract it a second time. Check-level adjustments are reflected intotals, not distributed across the returned line items.totals.discounts_centsincludes comps and other price decreases, not only adjustments whose type isdiscount. Adjustments linked to voided items can remain in the snapshot; don’t treat them as discounts on an active sale. - Payments: inspect
status, captured amounts, and refunded amounts rather than treating every listed payment as successful. Payment amounts can include card surcharges and related tax, so summing payments need not equal the check total. Refunds are reported separately from captured amounts.
V1 does not include guest email, phone, or loyalty identifiers; card details; or split-level accounting. It provides read-only checks, not endpoints to post discounts or comps. See the reference for the exact schema.
Rate limits and retries
The default limits are 300 API requests per minute per credential pair,
shared across locations, and 30 token requests per minute per client ID and,
independently, per source IP. Reuse access tokens rather than requesting one for every API call.
Use the returned X-RateLimit-Limit and X-RateLimit-Remaining headers as the
runtime limits. Choose your polling interval based on your location count and
latency needs, leaving room for pagination and retries.
| Response | Recommended handling |
|---|---|
400 invalid_request |
Correct the timestamp, page limit, or query parameters before retrying. |
400 invalid_cursor |
Check the cursor’s location and credentials. If it cannot be recovered, start a new import from a safe earlier updated_since and deduplicate. |
401 invalid_token |
Obtain a new access token and retry once. If it persists, check credentials and access with Chompy. |
403 insufficient_scope |
Your credentials need checks:read; contact Chompy. |
404 not_found |
The location does not exist or is not authorized. Recheck /v1/locations. |
429 rate_limit_exceeded |
Wait at least the Retry-After number of seconds, then retry the same request. |
5xx or network timeout |
Retry the same page with bounded exponential backoff and jitter. Do not advance your saved cursor. |
API errors contain an error object with code, message, and, when available,
request_id. OAuth validation errors instead use an error string and
error_description. For invalid_client, check the credential pair and the
selected environment before retrying.
When emailing support@chompypos.com, include the environment, endpoint, HTTP status, and request ID. Never include client secrets, access tokens, or unredacted check data.