# Get a registration's history

> The registrations.history operation: GET /api/v1/registrations/{id}/history in the REST API and the registrations_history tool in the MCP server.

Returns a registration's history as one timeline, newest first:

- `state`: every state change, who made it, why and the operator's note (also on the registration);
- `audit`: what the audit log recorded about the registration: prerequisite updates with what changed,
  uploaded documents, and actions not tied to a state change. An audit entry made with a state change is
  listed in that entry's `audited` instead of on its own;
- `event`: deadline escalations (`registration.deadline_escalated`), with the level reached.

Each source is read up to its 200 most recent entries (`truncated` says when one had more).

## At a glance

- **REST:** `GET /api/v1/registrations/{id}/history`
- **MCP tool:** `registrations_history`
- **Operation ID:** `registrations.history`
- **Scope:** Legal entity
- **Permission:** `registrations:read`
- **Risk tier:** `read`
- **Dry run:** Not supported
- **Idempotency:** Not needed (read only)
- **Modes:** Test and live
- **Authentication:** API key with the `registrations:read` scope
- **Since:** M7

## Request

### Path parameters

| Field | Type   | Description                                                                               |
| ----- | ------ | ----------------------------------------------------------------------------------------- |
| `id`  | string | The registration (`regn_…`) or its regime's ID, e.g. `EU_OSS_UNION` or `US_SALES_TAX:TX`. |

### Query parameters

This operation takes no query parameters.

## Response

`200 OK` with a JSON object:

| Field               | Type                             | Description |
| ------------------- | -------------------------------- | ----------- |
| `object`            | `"registration_history"`         |             |
| `registrationId`    | string                           |             |
| `regimeId`          | string                           |             |
| `data`              | array of object                  |             |
| `data[].id`         | string                           |             |
| `data[].at`         | date-time                        |             |
| `data[].source`     | one of `state`, `audit`, `event` |             |
| `data[].type`       | string                           |             |
| `data[].actor`      | string                           |             |
| `data[].state`      | object or null                   |             |
| `data[].changes`    | object or null                   |             |
| `data[].escalation` | object or null                   |             |
| `data[].audited`    | array of string                  |             |
| `truncated`         | boolean                          |             |

## Examples

### Armed, in grace after the first sale, escalated, then submitted

```http
GET /api/v1/registrations/EU_OSS_NON_UNION/history
Authorization: Bearer or_test_…
```

Response (`200`):

```json
{
  "object": "registration_history",
  "registrationId": "regn_01m4tx5nj8emwbyf7y9vcf47xk",
  "regimeId": "EU_OSS_NON_UNION",
  "data": [
    {
      "id": "state:2",
      "at": "2026-10-20T08:15:00.000Z",
      "source": "state",
      "type": "state_changed",
      "actor": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
      "state": {
        "from": "grace",
        "to": "grace",
        "reason": "application_submitted",
        "note": null
      },
      "changes": null,
      "escalation": null,
      "audited": ["registrations.mark_application_submitted"]
    },
    {
      "id": "aud_01m4tx5nj8emwbyf7y9vcf47xt",
      "at": "2026-10-20T08:14:02.000Z",
      "source": "audit",
      "type": "registrations.documents.upload",
      "actor": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
      "state": null,
      "changes": {
        "before": null,
        "after": {
          "fileId": "file_01m4tx5nj8emwbyf7y9vcf47xq",
          "filename": "oss-submission-receipt.pdf",
          "contentType": "application/pdf",
          "size": 82,
          "sha256": "36dc4d8396e18eff67cf01ca1121f420465e698179be0d927351dbe6ac07884d"
        }
      },
      "escalation": null,
      "audited": []
    },
    {
      "id": "evt_01m4tx5nj8emwbyf7y9vcf47xv",
      "at": "2026-10-18T07:07:00.000Z",
      "source": "event",
      "type": "registration.deadline_escalated",
      "actor": "system",
      "state": null,
      "changes": null,
      "escalation": {
        "level": 1,
        "deadlineAt": "2026-11-10T22:59:59.000Z"
      },
      "audited": []
    },
    {
      "id": "state:1",
      "at": "2026-10-14T09:30:00.000Z",
      "source": "state",
      "type": "state_changed",
      "actor": "system",
      "state": {
        "from": "blocked_b2c",
        "to": "grace",
        "reason": "first_sale_after_arming",
        "note": null
      },
      "changes": null,
      "escalation": null,
      "audited": []
    },
    {
      "id": "state:0",
      "at": "2026-10-13T12:00:00.000Z",
      "source": "state",
      "type": "state_changed",
      "actor": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
      "state": {
        "from": "blocked_b2c",
        "to": "blocked_b2c",
        "reason": "armed",
        "note": "Ana files by the 10th"
      },
      "changes": null,
      "escalation": null,
      "audited": ["registrations.arm"]
    }
  ],
  "truncated": false
}
```

## Errors

| Code                                                                                     | HTTP status | When                                                                       | What to do                                                                                                                                         |
| ---------------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed)   | 400         | `id` is neither a registration ID nor a regime ID.                         | Fix the fields listed in `details.issues` and send the request again.                                                                              |
| [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found) | 404         | This entity has no such registration in this mode.                         | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                                               |
| [`scope_required`](https://ownrecord.io/docs/reference/errors.md#scope_required)         | 400         | The request names no legal entity (an org key without `Ownrecord-Entity`). | Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (`details.required_scope`). |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)   | 403         | You can't see this entity's registrations.                                 | Ask an organization owner or admin for a role or scope that allows this action.                                                                    |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`dry_run_not_supported`](https://ownrecord.io/docs/reference/errors.md#dry_run_not_supported), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
