> ## Documentation Index
> Fetch the complete documentation index at: https://storekit.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Response Format

> The merchant MCP data-and-meta envelope: how results, pagination, date ranges, timezones, currencies and images are returned, and how to parse them.

Every successful tool call returns one envelope, delivered twice in the MCP result: as `structuredContent`, and as the JSON text of the first `content` block. Read whichever your client exposes; they are identical. Every tool publishes a matching `outputSchema`, so a spec-compliant client validates `structuredContent` against it.

```json theme={null}
{
  "data": {
    "results": [
      { "id": 42, "name": "Soho", "timezone": "Europe/London", "currency": "GBP" }
    ]
  },
  "meta": {
    "schemaVersion": 2,
    "timezone": "Europe/London",
    "dateRange": {
      "from": "2026-09-11T23:00:00.000Z",
      "to": "2026-09-18T22:59:59.999Z",
      "basis": "fulfillment",
      "endInclusive": true
    },
    "pagination": {
      "page": 1,
      "limit": 50,
      "returned": 50,
      "total": 1240,
      "totalIsEstimate": true,
      "hasMore": true,
      "nextPage": 2,
      "truncated": true
    },
    "warnings": [],
    "currencyCodes": ["GBP"]
  }
}
```

## `data`

* **List tools** return `data.results`, an array.
* **Detail tools** (`get-venue`, `get-order`, `get-menu`, `get-payment-link`, `get-order-stats`, the two writes) return the record itself in `data`.
* `get-snooze-report` returns a summary, a time series and a paginated `items` array together.
* Fields are allowlisted per resource. Anything not in a tool's `outputSchema` is never sent, whatever the underlying record holds.

## `meta`

| Field           | Type                 | Meaning                                                                           |
| --------------- | -------------------- | --------------------------------------------------------------------------------- |
| `schemaVersion` | `2`                  | Bumped on any breaking change to the envelope or a resource shape                 |
| `timezone`      | IANA name or `null`  | The timezone the date range was interpreted in                                    |
| `dateRange`     | object or `null`     | The resolved, inclusive range actually applied, as UTC instants, plus its `basis` |
| `pagination`    | object or `null`     | Present on paginated results                                                      |
| `warnings`      | `string[]`           | Human-readable caveats, for example that stats are gross of refunds               |
| `currencyCodes` | `string[]`, optional | Distinct ISO 4217 codes present in the result                                     |

`meta` is strict: no undocumented keys appear, and new keys arrive with a version bump.

## Pagination

Pages start at **1**. `limit` is capped at 100 (25 for `list-top-products`) and silently reduced if you ask for more.

`hasMore` and `nextPage` come from fetching one row beyond the page, so they are always exact. `total` is `null` when the tool does not count, and may be flagged `totalIsEstimate: true` on large order lists where an exact count is too slow. Drive loops from `hasMore`, not from `total`:

```javascript theme={null}
let page = 1;
do {
  const { data, meta } = await call("list-orders", { venueId, from, to, page, limit: 100 });
  process(data.results);
  page = meta.pagination.nextPage;
} while (page !== null);
```

Lists are live; a record created between pages can shift subsequent pages.

## Dates and Timezones

**Inputs** (`from`, `to`) accept either:

* `YYYY-MM-DD` — a local calendar date in the effective timezone, inclusive at both ends (`to: "2026-09-18"` runs to `23:59:59.999` that day); or
* an ISO datetime with `Z` or a numeric offset and at most three fractional digits, e.g. `2026-09-18T14:00:00+01:00`. Offset-less datetimes are rejected.

The **effective timezone** is `timezone` if supplied, otherwise the venue's timezone when `venueId` is given, otherwise `UTC`. `meta.timezone` always states which was used.

Ranges may span at most **90 local calendar dates**; longer ranges are rejected with `INVALID_INPUT`. Each tool has a default range (7 or 30 dates) and a `basis` — `creation`, `fulfillment`, `refund` or `snooze_overlap` — that says which timestamp the range filters; see [Tools](/docs/developers/mcp/tools). `meta.dateRange` echoes the resolved range so a client can display exactly what was counted.

**Write inputs** (`startDate`, `endDate`, `expiresAt`) must be full ISO timestamps with an offset. Date-only values are not accepted for writes.

## Money

All amounts are integers in **minor currency units** (pence, cents) and are never converted. The currency travels with the data — as a `currency` field on venues, orders, bills and links, and as `meta.currencyCodes` for the result as a whole. `codeAmount` on a percentage discount is in tenths of a percent, not a currency amount.

Account-wide stats and top-product queries on an account whose venues use more than one currency are refused (`INVALID_INPUT`); pass `venueId`.

## Images

`get-payment-link-qr` is the only tool that returns binary data. Its `content` array holds the JSON text block followed by a native MCP image block:

```json theme={null}
{
  "type": "image",
  "mimeType": "image/png",
  "data": "<base64 PNG>"
}
```

`structuredContent` carries the checkout URL and link metadata only; there is no base64 field inside `data`.

## Errors

A failed call is **not** an envelope. It is an `isError: true` result whose single text block is an `{ error }` object, with no `structuredContent`. See [Errors](/docs/developers/mcp/errors).


## Related topics

- [Merchant MCP Overview](/docs/developers/mcp/overview.md)
- [Payload Format](/docs/developers/webhooks/payload-format.md)
- [Contact Support](/docs/getting-started/contact-support.md)
- [Testing Webhooks](/docs/developers/webhooks/testing-webhooks.md)
- [Lightspeed Troubleshooting](/docs/guides/integrations/pos/lightspeed/troubleshooting.md)
