# Fetch order records

> fetch_order_records: Returns a page of an order's delivered records (50 by default, up to 100) with the licence block on every page, as JSON or, on request, as CSV.

Source: https://emailmovers.com/mydatahub/docs/reference/mcp/fetch_order_records

Returns a page of an order's delivered records (50 by default, up to 100) with the licence block on every page, as JSON or, on request, as CSV. Pages stay under about 8,000 tokens, with approx_tokens on each; pass next_cursor to continue. Fetching again under licence costs 0 credits; it needs records:read. Call check_suppression before any send, and get_compliance_receipt for proof of screening. Lawful basis is UK GDPR Article 6(1)(f) legitimate interests; email audiences include corporate subscribers only by default (PECR), so sole traders and ordinary partnerships are left out unless the toggle is changed.

| Property | Value |
| --- | --- |
| Tool name | `fetch_order_records` |
| Position in tools/list | 16 of 22 |
| Cost | Free under licence |
| Scope | `records:read` |
| Annotations | readOnlyHint true, destructiveHint false, idempotentHint true, openWorldHint false |
| Kind | Read only; idempotent, not destructive, closed world |
| REST equivalent | [`GET /v1/orders/{id}/records`](https://emailmovers.com/mydatahub/docs/reference/rest/list-order-records.md) |

> **Not yet live.** MyDataHub v2 is built and tested locally and is not yet live. The v2 hosts open at launch, date to confirm. This is what `tools/list` returns from https://mydatahub.emailmovers.com/mcp once v2 launches.

## Input

The schema sets `additionalProperties` to false, so a member that is not listed is refused.

| Member | Type | Required | Description |
| --- | --- | --- | --- |
| `order_id` | string | yes | The order whose records to fetch. It must be ready. |
| `cursor` | string | no | An opaque cursor from next_cursor. Pass it back unchanged. |
| `limit` | integer (1 to 100) | no | Records per page, 1 to 100 over MCP so a result stays under about 8,000 tokens. Default 50. Default `50`. |
| `format` | enum: `json`, `csv` | no | json (default) or csv. Default `json`. |
| `fields` | array of string | no | Columns to return; default the order's field set. |

## Example call

The `params` of a `tools/call` request:

```json
{
  "name": "fetch_order_records",
  "arguments": {
    "order_id": "ord_01JB4N9S3W2X6Y7Z8A1B2C3D4E"
  }
}
```

## Output

The result carries `structuredContent` that matches this schema, and one line of text that leads with the number.

### RecordsPage

| Member | Type | Always present | Description |
| --- | --- | --- | --- |
| `order_id` | string | yes | Format: an order id: ord_ followed by a 26 character ULID in upper case Crockford base32, such as ord_01JB4N9S3W2X6Y7Z8A1B2C3D4E. |
| `format` | `json` | yes |  |
| `fields` | array of string | yes | The field set's columns in this page. |
| `data` | array of `ContactRecord` | yes |  |
| `data[].id` | string | yes | The record id, pushed to CRMs as mydatahub_record_id. |
| `data[].dataset_version` | string | yes | The immutable weekly build a count is bound to, such as 2026-W39. The last 52 stay queryable. |
| `data[].contact` | object | yes |  |
| `data[].email` | object or null | yes |  |
| `data[].phone` | object or null | yes | Present when the field set includes telephone and a number is held. |
| `data[].company` | object | yes |  |
| `data[].site` | object | yes |  |
| `data[].compliance` | `ComplianceObject` | yes | Carried by every preview row, order record, lookup and enrichment, and repeated as CSV columns and as the MyDataHub property group on CRM push. |
| `data[].licence_expires_at` | string (date) or null | yes |  |
| `has_more` | boolean | yes |  |
| `next_cursor` | string or null | yes |  |
| `remaining` | integer (0 or more) | yes | Records after this page. |
| `approx_tokens` | integer (0 or more) | no | A rough token size of this page; pages stay under about 8,000 tokens. |
| `licence` | `Licence` | yes | Licence terms as data, on every quote, order, records page and receipt. Records stay usable, pushable and re-downloadable free until reuse_until. |
| `licence.type` | enum: `multi_use_12m`, `outright` | yes | multi_use_12m (12 month multi-use, every plan) or outright (1.8 credits a record, proposed). |
| `licence.reuse_until` | string (date) or null | yes | Order date plus 12 months; null for outright. |
| `licence.resale_prohibited` | boolean | yes |  |
| `licence.permitted_channels` | array of enum: `email`, `telephone`, `post` | yes | email, telephone and post on standard terms. |
| `licence.warranty_url` | string (uri) | yes |  |
| `licence.terms_version` | string | yes | The version of the Data Licence and Sharing Agreement the licence is under, such as 1.0. |
| `licence.terms_url` | string (uri) | no | Where that version of the Data Licence and Sharing Agreement is published. |

### RecordsCsvPage

| Member | Type | Always present | Description |
| --- | --- | --- | --- |
| `order_id` | string | yes | Format: an order id: ord_ followed by a 26 character ULID in upper case Crockford base32, such as ord_01JB4N9S3W2X6Y7Z8A1B2C3D4E. |
| `format` | `csv` | yes |  |
| `fields` | array of string | yes | The columns, in the order of the header. |
| `rows` | integer (0 or more) | yes | Records in this page, not counting the header. |
| `csv` | string | yes | The page as CSV with a header row and compliance fields as columns: the text GET /v1/orders/{id}/records returns with format=csv. |
| `has_more` | boolean | yes |  |
| `next_cursor` | string or null | yes |  |
| `remaining` | integer (0 or more) | yes | Records after this page. |
| `approx_tokens` | integer (0 or more) | no |  |
| `licence` | `Licence` | yes | Licence terms as data, on every quote, order, records page and receipt. Records stay usable, pushable and re-downloadable free until reuse_until. |
| `licence.type` | enum: `multi_use_12m`, `outright` | yes | multi_use_12m (12 month multi-use, every plan) or outright (1.8 credits a record, proposed). |
| `licence.reuse_until` | string (date) or null | yes | Order date plus 12 months; null for outright. |
| `licence.resale_prohibited` | boolean | yes |  |
| `licence.permitted_channels` | array of enum: `email`, `telephone`, `post` | yes | email, telephone and post on standard terms. |
| `licence.warranty_url` | string (uri) | yes |  |
| `licence.terms_version` | string | yes | The version of the Data Licence and Sharing Agreement the licence is under, such as 1.0. |
| `licence.terms_url` | string (uri) | no | Where that version of the Data Licence and Sharing Agreement is published. |

## Errors

A failed call returns `isError` true. The text content leads with the sentence a person acts on, then the whole problem as JSON, with `code`, `detail`, `next_step` and `did_you_mean`. A 401 and a step-up 403 are answered at HTTP level so the client can start authorisation. See [Errors](https://emailmovers.com/mydatahub/docs/errors.md).
