# Reconcile a processor connection now

> The reconciliation.runs.create operation: POST /api/v1/reconciliation/runs in the REST API and the reconciliation_runs_create tool in the MCP server.

Asks for a reconciliation run of one processor connection now, besides the daily one. The run happens in the
background within a minute (`runRequestedAt` is set until it finishes): it reads the connection's balance
transactions since its cursor, matches them to payments, refunds and disputes, posts the processor fees and
payouts not posted yet (each once), puts what doesn't match in the queue and raises RECON_UNMATCHED when it
queued something new. Poll `reconciliation.connections.list` for the result (`lastRun`). Asking again while a
run is pending runs it again; that is harmless.

## At a glance

- **REST:** `POST /api/v1/reconciliation/runs`
- **MCP tool:** `reconciliation_runs_create`
- **Operation ID:** `reconciliation.runs.create`
- **Scope:** Legal entity
- **Permission:** `ledger: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 `ledger:write` scope
- **Since:** M8

## Request

### Body

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

| Field                   | Type        | Required | Description                                 |
| ----------------------- | ----------- | -------- | ------------------------------------------- |
| `processorConnectionId` | `pcon_…` ID | Yes      | The connection to reconcile now (`pcon_…`). |

## Response

`202 Accepted` with a JSON object:

| Field                   | Type                                        | Description                                                                                          |
| ----------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `object`                | `"reconciliation_connection"`               |                                                                                                      |
| `processorConnectionId` | `pcon_…` ID                                 |                                                                                                      |
| `livemode`              | boolean                                     |                                                                                                      |
| `processor`             | one of `stripe`, `mollie`, `fake`           |                                                                                                      |
| `label`                 | string                                      |                                                                                                      |
| `status`                | one of `active`, `degraded`, `disconnected` | The connection's status: disconnected ones aren't read.                                              |
| `cursor`                | date-time or null                           | The creation time of the latest balance transaction read; the next run reads from an hour before it. |
| `lastRun`               | object or null                              |                                                                                                      |
| `lastSucceededAt`       | date-time or null                           |                                                                                                      |
| `runRequestedAt`        | date-time or null                           | A run asked for that hasn't finished yet (the job runs it within a minute).                          |
| `openItems`             | integer                                     | Open items of this connection in the queue.                                                          |

## Examples

### Reconcile the Stripe connection now

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

{
  "processorConnectionId": "pcon_01m4vyt4mxe0s9zzk90373z6p6"
}
```

Response (`202`):

```json
{
  "object": "reconciliation_connection",
  "processorConnectionId": "pcon_01m4vyt4mxe0s9zzk90373z6p6",
  "livemode": false,
  "processor": "stripe",
  "label": "Stripe (test)",
  "status": "active",
  "cursor": "2026-11-05T00:10:00.000Z",
  "lastRun": {
    "trigger": "schedule",
    "startedAt": "2026-11-05T04:00:00.000Z",
    "finishedAt": "2026-11-05T04:00:12.000Z",
    "status": "succeeded",
    "readFrom": "2026-11-03T23:59:00.000Z",
    "counts": {
      "read": 42,
      "recorded": 40,
      "matched": 39,
      "opened": 1,
      "posted": 35,
      "rechecked": 0,
      "bankConfirmed": 1
    },
    "error": null
  },
  "lastSucceededAt": "2026-11-05T04:00:12.000Z",
  "runRequestedAt": "2026-11-05T10:00:00.000Z",
  "openItems": 1
}
```

## Errors

| Code                                                                                                                           | HTTP status | When                                                                                                                             | What to do                                                                                                                                                                              |
| ------------------------------------------------------------------------------------------------------------------------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed)                                         | 400         | `processorConnectionId` isn't a processor connection 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 processor connection in this mode.                                                                       | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                                                                                    |
| [`reconciliation_connection_unsupported`](https://ownrecord.io/docs/reference/errors.md#reconciliation_connection_unsupported) | 400         | The connection is disconnected: its balance transactions can't be read any more.                                                 | Reconciliation reads a connection's balance transactions: the connection must be active (not disconnected) and in the mode of the request. `details.status` is the connection's status. |
| [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict)                                           | 409         | Another run was asked for at the same moment; retry.                                                                             | Fetch the object again and retry the change.                                                                                                                                            |
| [`scope_required`](https://ownrecord.io/docs/reference/errors.md#scope_required)                                               | 400         | The request names no legal entity (an org key without `Ownrecord-Entity`, or a brand key: reconciliation belongs to the 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 work this entity's reconciliation (`ledger:write`: finance, owners and admins).                                        | Ask an organization owner or admin for a role or scope that allows this action.                                                                                                         |
| [`livemode_not_allowed`](https://ownrecord.io/docs/reference/errors.md#livemode_not_allowed)                                   | 403         | You have no live-mode access, so you can't use live reconciliation.                                                              | Use test mode, or credentials for the target's mode. Developers need live access granted by an organization owner or admin.                                                             |

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), [`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).
