# Skip, resume or confirm an onboarding step

> The onboarding.steps.update operation: POST /api/v1/onboarding/steps/{step} in the REST API and the onboarding_steps_update tool in the MCP server.

Changes one step of the organization's onboarding checklist and returns the checklist:

- `skip`: the step is set aside (`skipped`) and the checklist moves on. It counts as done as soon as the
  organization's data shows it done;
- `resume`: a skipped step is open again (and a confirmed registrations review is open again);
- `complete`: confirms the registrations review (`registrations`): the home registration numbers are right,
  existing OSS, UK or other registrations are entered, and the blocked jurisdictions were reviewed. The other
  steps follow the organization's data and can't be marked done (`onboarding_step_not_manual`).

Needs `org:write` (organization owners and admins).

## At a glance

- **REST:** `POST /api/v1/onboarding/steps/{step}`
- **MCP tool:** `onboarding_steps_update`
- **Operation ID:** `onboarding.steps.update`
- **Scope:** Organization
- **Permission:** `org:write`
- **Risk tier:** `write`
- **Dry run:** Supported (send `Ownrecord-Dry-Run: true`)
- **Idempotency:** `Idempotency-Key` required
- **Modes:** Test and live
- **Authentication:** API key with the `org:write` scope
- **Since:** M12

## Request

### Path parameters

| Field  | Type                                                                                                | Description |
| ------ | --------------------------------------------------------------------------------------------------- | ----------- |
| `step` | one of `legal_entity`, `brand`, `processor`, `registrations`, `catalog`, `test_checkout`, `go_live` |             |

### Body

A JSON object (`Content-Type: application/json`):

| Field             | Type                                | Required | Description                                                                                        |
| ----------------- | ----------------------------------- | -------- | -------------------------------------------------------------------------------------------------- |
| `action`          | one of `skip`, `resume`, `complete` | Yes      | `skip` a step, `resume` a skipped (or confirmed) one, or `complete` the registrations review.      |
| `expectedVersion` | integer (at least 0)                | No       | The checklist's `version` you read (0 before the first change); a stale one is `version_conflict`. |

## Response

`200 OK` with a JSON object:

| Field                 | Type                                                                                                        | Description                                                                              |
| --------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `object`              | `"onboarding_checklist"`                                                                                    |                                                                                          |
| `orgId`               | `org_…` ID                                                                                                  |                                                                                          |
| `complete`            | boolean                                                                                                     | Every step is done or skipped.                                                           |
| `next`                | one of `legal_entity`, `brand`, `processor`, `registrations`, `catalog`, `test_checkout`, `go_live` or null | The first step that is neither done nor skipped.                                         |
| `done`                | integer                                                                                                     |                                                                                          |
| `total`               | integer                                                                                                     |                                                                                          |
| `steps`               | array of object                                                                                             |                                                                                          |
| `steps[].step`        | one of `legal_entity`, `brand`, `processor`, `registrations`, `catalog`, `test_checkout`, `go_live`         |                                                                                          |
| `steps[].status`      | one of `todo`, `in_progress`, `done`, `skipped`                                                             |                                                                                          |
| `steps[].doneBy`      | one of `data`, `person` or null                                                                             | How a done step is known: from the organization's data, or from a person's confirmation. |
| `steps[].skippedAt`   | date-time or null                                                                                           |                                                                                          |
| `steps[].completedAt` | date-time or null                                                                                           | When a person confirmed the step (the registrations review only).                        |
| `completedAt`         | date-time or null                                                                                           | When the checklist was first complete.                                                   |
| `version`             | integer                                                                                                     | 0 until a step was first skipped or confirmed.                                           |

## Examples

### Confirm the registrations review

```http
POST /api/v1/onboarding/steps/registrations
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json

{
  "action": "complete"
}
```

Response (`200`):

```json
{
  "object": "onboarding_checklist",
  "orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
  "complete": false,
  "next": "catalog",
  "done": 4,
  "total": 7,
  "steps": [
    {
      "step": "legal_entity",
      "status": "done",
      "doneBy": "data",
      "skippedAt": null,
      "completedAt": null
    },
    {
      "step": "brand",
      "status": "done",
      "doneBy": "data",
      "skippedAt": null,
      "completedAt": null
    },
    {
      "step": "processor",
      "status": "done",
      "doneBy": "data",
      "skippedAt": null,
      "completedAt": null
    },
    {
      "step": "registrations",
      "status": "done",
      "doneBy": "person",
      "skippedAt": null,
      "completedAt": "2026-10-26T09:00:00.000Z"
    },
    {
      "step": "catalog",
      "status": "todo",
      "doneBy": null,
      "skippedAt": null,
      "completedAt": null
    },
    {
      "step": "test_checkout",
      "status": "todo",
      "doneBy": null,
      "skippedAt": null,
      "completedAt": null
    },
    {
      "step": "go_live",
      "status": "todo",
      "doneBy": null,
      "skippedAt": null,
      "completedAt": null
    }
  ],
  "completedAt": null,
  "version": 1
}
```

## Errors

| Code                                                                                                     | HTTP status | When                                                          | What to do                                                                                             |
| -------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed)                   | 400         | The step or action is unknown.                                | Fix the fields listed in `details.issues` and send the request again.                                  |
| [`onboarding_step_not_manual`](https://ownrecord.io/docs/reference/errors.md#onboarding_step_not_manual) | 400         | `complete` on a step the organization's data decides.         | Do the step (for example, create the brand), or skip it. Only the registrations review is marked done. |
| [`onboarding_step_done`](https://ownrecord.io/docs/reference/errors.md#onboarding_step_done)             | 409         | `skip` or `complete` on a step that is already done.          | Nothing to do. A done step can't be skipped or marked again.                                           |
| [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict)                     | 409         | The checklist changed since `expectedVersion`; read it again. | Fetch the object again and retry the change.                                                           |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)                   | 403         | You can't change this organization's onboarding.              | 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), [`invalid_json`](https://ownrecord.io/docs/reference/errors.md#invalid_json), [`unsupported_media_type`](https://ownrecord.io/docs/reference/errors.md#unsupported_media_type), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found), [`idempotency_key_required`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_required), [`idempotency_key_reused`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_reused), [`idempotency_in_progress`](https://ownrecord.io/docs/reference/errors.md#idempotency_in_progress), [`approval_required`](https://ownrecord.io/docs/reference/errors.md#approval_required), [`approval_rejected`](https://ownrecord.io/docs/reference/errors.md#approval_rejected), [`approval_expired`](https://ownrecord.io/docs/reference/errors.md#approval_expired), [`stale_approval`](https://ownrecord.io/docs/reference/errors.md#stale_approval), [`approval_policy_denied`](https://ownrecord.io/docs/reference/errors.md#approval_policy_denied), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
