The cutover API turns a hard-cutover weekend from a manual SQL playbook into a sequenced run of HTTP calls. Every step writes to an append-only audit log so a future operator can reconstruct exactly what happened. This guide covers the production cutover flow. For the data-load that runs in the days leading up to cutover, see Migrating Data into Arcus and the bulk import + jobs cluster.Documentation Index
Fetch the complete documentation index at: https://docs.arcuserp.com/llms.txt
Use this file to discover all available pages before exploring further.
When to use this API
Use the cutover cluster when you have already finished:- Migration loads complete via
POST /v1/entities/{eid}/migration/{resource}/bulkfor accounts, products, orders, journal-entries, vendor-bills, ap-payments. - Reconciliation checks pass. Trial balance ties; AR aging matches the source; AP aging matches the source; resource counts within tolerance. See Reconciliation API.
- Pilot slices verified. At minimum one named customer, then a wider slice, then a single fiscal year, then a full dry run into a clean entity. Each slice walked end to end in the Arcus UI.
Required scope
Cutover endpoints are gated on two elevated scopes:| Scope | Endpoints that require it |
|---|---|
migration:admin + migration:write | freeze, snapshot, swap, unfreeze, rollback |
migration:write | verify (runs the reconciliation suite) |
migration:read | status, log (read-only) |
migration:admin is intentionally restricted. Grant it only to the operator who will execute the cutover window. Both migration:admin and migration:write must be present on the same key for the destructive endpoints. Issue the key from Settings > Developers > API Keys, tick both elevated-scope checkboxes, acknowledge the elevated-permission warning, and store the secret in your password manager. Revoke the key immediately after cutover is complete.
The state machine
Every cutover entity is in one of seven states, visible viaGET /v1/entities/{eid}/migration/cutover/status:
rolling_back via POST .../rollback. Rollback emits operator commands; it does NOT auto-execute a snapshot restore.
Step 1: freeze the entity
freeze_token. You need it for every subsequent step until unfreeze.
After freeze, all non-migration writes return HTTP 423 Locked with a migration_in_progress envelope. Browser users continue to see read-only data; write attempts surface a clear banner. Migration write endpoints (the bulk cluster) continue to function, so a soft-cutover top-up sync is still possible.
If you call freeze on an already-frozen entity, you get the existing freeze_token back. The call is idempotent.
Step 2: take the database snapshot
GET .../cutover/status until percent_progress: 100 and status: "available". Snapshots typically complete in 10 to 25 minutes for a small-to-medium database tier.
The snapshot is the rollback target. Do not proceed to swap until the snapshot is available. Snapshot retention is unlimited by default; sweep manually post-cutover-window if you no longer need it.
Step 3: emit swap commands
Step 4: verify
- Trial balance debits and credits balance to the penny.
- AR aging total equals the AR control account.
- AP aging total equals the AP control account.
- Inventory valuation snapshot matches the inventory subledger.
- Cash balances match each bank reconciliation row.
- Resource counts are within tolerance (default 0; configurable per call).
status is failed, the response includes per-check deltas, and unfreeze is blocked. Either rollback (Step 6) or fix the data and re-run verify.
verify_log_id is valid for 4 hours. After that it expires and you must re-verify before unfreezing.
Step 5: unfreeze
idle. Revoke the API key.
Step 6 (only if needed): rollback
Rollback emits the operator commands required to restore the pre-cutover snapshot and re-point traffic at the legacy ERP. It does not auto-execute anything destructive.confirm field MUST equal {entity_id}:rollback. The API rejects any other value with HTTP 422. This is the same pattern Stripe Connect uses for destructive operations.
Response:
Status and log
At any point during cutover you can read the current state:migration:read. The log is append-only and includes every action with timestamp, performed-by, status, and the JSON payload that initiated it.
Webhook events
If you have a webhook endpoint subscribed to the cutover event family, the API emits the following during a cutover:migration.freeze_engagedmigration.snapshot_takenmigration.swap_initiatedmigration.cutover_verifiedmigration.unfreeze_engagedmigration.cutover_completedmigration.cutover_rolled_back(only on rollback path)
Operational notes
- Run cutover during a planned freeze window. Customers and operators see read-only data for the duration. Targets are typically a Friday EOD freeze, Saturday snapshot + swap + verify, Sunday final tests, Monday go-live.
- Have the rollback playbook open in another tab. If verify fails on Saturday evening, you want zero ambiguity about how to back out.
- Snapshots are not free. Cloud database snapshots are billed by GB-month; keep the snapshot for 30 to 90 days as your safety net, then delete it.
- Do not skip the verify step. Unfreeze is gated on a successful verify within the last 4 hours. There is no override.
- Capture the
freeze_tokenon Step 1. It is the only path through Steps 2 to 5. If you lose it, you must call freeze again (which returns the existing token; safe). - Keep the snapshot retention long enough. Once the snapshot expires, rollback is no longer possible from this snapshot. Take a manual snapshot before deletion if you want a longer safety window.
Related
- Migrating Data into Arcus - the bulk-load pass that populates the entity before cutover.
- Reconciliation API - the read endpoints that prove the data is correct before you flip the switch.
- Webhooks - subscribe to cutover events for observability.
- Idempotency -
Idempotency-Keyheader semantics across all endpoints.

