Authentication
Send both headers on every request:
| Header | Meaning |
|---|---|
x-api-key | Your partner API key, issued per organization. Treat it as a secret. |
x-mealco-org-id | The organization the call acts on behalf of. |
They are required together, and the organization id must be the organization the key belongs to. A mismatch is rejected with 401 — it is not silently reinterpreted as the key's own organization, because a caller that sent the wrong id is a caller whose next request is also wrong.
Scope
A credential is scoped to exactly one organization, and that scope is enforced at the data layer rather than by request validation. There is no request parameter that widens it, which is why organizationId never appears in a request body: an operation cannot be pointed at data the credential does not already reach.
Handling keys
- Keep the key server-side. It is a bearer credential — anyone holding it is you.
- Rotate by requesting a new key, moving traffic to it, then retiring the old one. Both are live during the overlap, so a rotation needs no downtime window.
- If a key is exposed, tell us immediately; a compromised key is revoked, not rotated on a schedule.
Rate limits
Limits are sized per contract, and this page does not publish a default table. That is a deliberate choice, not an omission: a number printed here is a commitment, and the only numbers worth printing are the ones the edge actually enforces for you. Yours are agreed with your OneTablet contact against your declared workload, and they are the ones that apply.
What does hold, whatever your numbers are:
- A limit is per organization, not per key. All of your keys draw on one budget, so adding keys never multiplies your throughput and rotating a key never resets your usage. Send
x-mealco-org-idon every request — it is required for authentication regardless, and a request we cannot attribute to an organization is one we cannot account for against yours. 429is part of the contract. Any operation may answer it. HonourRetry-Afterwhen it is present; when it is not, wait 60 seconds and add jitter. Either way, do not tight-loop. See Getting Started → Errors and retries.- A shared capacity ceiling protects the service independently of your own limits. It is not a per-partner allowance, it is not a number we publish, and a well-behaved integration should never meet it.
Two design decisions keep a polling integration comfortably inside any limit:
- Reads that reflect delivery-platform state are answered from OneTablet's own refreshed state, never proxied per request to the platforms. Your cadence is bounded by your limits alone, never by a platform's — see Concepts → Data freshness.
- Every read is bulk-shaped.
fetchStoreStatusescovers one storefront or an entire estate in the same call, andfetchStoresreturns the whole crosswalk. A status sweep across a large estate is a handful of calls, not one per store — which is what makes the limits generous enough not to need publishing as a per-endpoint grid.
If your expected volume does not fit what you have been given — a frequent status sweep across every store, say — tell us the cadence you need and we size it, rather than you discovering a ceiling in production.
What a failure looks like
401— the key is missing, unknown, revoked, or does not match the organization id.429— you are over your rate limit. See Rate limits above and Errors and retries.