API conventions
Six rules hold everywhere on this API. Learn them once and every operation reads the same.
One path per operation, everything in the body
Every operation is a POST to a fixed, verb-first path with a typed JSON request object. No path parameters, no query strings. A request is therefore fully described by its URL and its body, which is what makes it trivial to log, replay and diff.
No version segment
The base path carries no /v1. Evolution here is additive — new optional fields and new operations, never removals or narrowing — so there is no cutover a version segment would ever mark. Ignore fields you do not recognise and your client survives every release.
Money is an integer in the currency's minor unit
1250 is $12.50. A decimal amount cannot survive a round trip through every language's default number type, so the API never emits one. All Phase 0 order amounts are USD; a currency field will be added additively before non-USD markets onboard.
Times are ISO-8601 in UTC
A store's local time is a rendering decision, and the API does not make it for you — resolve it from the location's IANA timezone. Fields carrying an instant are typed string<date-time> in the reference.
Unknown fields are your problem to ignore, not ours to withhold
We add optional fields to existing request and response objects at any time. A new field always has a defined meaning when absent, so an older client is never wrong — only less informed.
Every response carries a transaction id
Every response — a 200 exactly as much as a 400, 401 or 500 — carries the x-mealco-tx-id response header. It is the identifier we use to follow one call end to end.
Log it against every call you make. Store it beside your own record of the request and you have a durable record of every transaction you have ever sent us. On its own it costs you one header read; the day you need it, it is the difference between a question we can answer in minutes and one we cannot answer at all.
Quote it to support. "Your API returned a 500 at about 3pm" is not something we can look up. One transaction id is: hand it over and we can pull the complete record of that single call.
It also appears as txId in any error body, so whichever half of the response you already log — headers or bodies — you end up holding it. When both are present they are the same value.
You may send your own. Set x-mealco-tx-id on a request and we adopt it: it is what we record against the call and what comes back on the response, so your correlation id and ours are the same string. Send a value that is unique per request — reusing one makes several calls indistinguishable to us and to you. Keep it to 200 characters or fewer of ordinary printable text; anything longer or containing control characters is ignored and we use our own id instead. If you send nothing, we generate one for you.
It is a label and nothing more. It carries no authorization and no access of any kind — sending someone else's transaction id grants nothing, and it is never used to decide what a request may see. Do not put customer names, email addresses, card data or any other personal information in it, and do not read meaning into the format: it is opaque, and it may change shape without notice.
One case has no id, and it is worth knowing: a request whose body is not valid JSON is rejected before we have looked at it, so that response carries neither the header nor a txId in the body. Every other response has one. See Getting Started → Errors and retries.