---
title: "Save confirmed business setup progress"
method: PUT
path: "/bookkeeping/setup"
tags: ["Bookkeeping"]
---

# Save confirmed business setup progress

`PUT /bookkeeping/setup`

## Request

- Base URL: `https://ledgerhq.pro/api/v1`
- URL: `https://ledgerhq.pro/api/v1/bookkeeping/setup`
- Auth: one of:
  - HTTP bearer and API key in header `x-organization-id`
  - HTTP bearer and API key in header `x-organization-id`

Read/resume owner-led bookkeeping for the business selected by x-organization-id. Requires manage:banking, bank_transactions:read for GET and bank_transactions:read_write for PUT. Updates obey normal subscription permissions. Stored progress is assistant-reported, not evidence of a bank connection, posted accounting or an active external routine. No secrets. This endpoint does not create jobs or change books. Send the complete state and expectedRevision from GET (zero for first save). Stale edits return 409; reload and merge. An identical retry of the immediately preceding write returns reused=true. Active routines require provider ID, approved scope, schedule, timezone and approval/verification timestamps; opening balances marked confirmed require evidence. Mapped bank register IDs must belong to this business.

## Request body

- object
  - `expectedRevision` integer, required: Revision from get_business_bookkeeping_setup; zero for an unsaved setup. Reload after a conflict.
  - `state` object, required: Complete setup snapshot, preserving existing answers. Save only owner-supplied facts and observed results; no credentials.
    - `nextStep` 'business' | 'accounts' | 'history' | 'opening_balances' | 'backfill' | 'routine' | 'ongoing': Next unfinished conversational step, not an accounting gate
    - `businessActivity` string: Owner-confirmed description of what this business does
    - `accounts` object[]: Owner-selected business accounts, preserving existing mappings
      - `label` string, required: Business account label; never a full account number
      - `institution` string, required
      - `kind` 'checking' | 'savings' | 'credit_card' | 'loan' | 'processor' | 'other', required
      - `mask` string, nullable
      - `connectionStatus` 'not_connected' | 'connected' | 'needs_attention' | 'file_only'
      - `externalAccountId` string, nullable: Provider account identifier, never an access token
      - `bankAccountId` string, uuid, nullable: Mapped bank register UUID in this business
      - `availableFrom` string, date, nullable
      - `importedThrough` string, date, nullable
    - `history` object
      - `mode` 'undecided' | 'start_fresh' | 'bank_history' | 'existing_books'
      - `startDate` string, date, nullable
      - `cutoverDate` string, date, nullable: Last date covered by prior books; live activity must not overlap imported accounting
      - `notes` string
    - `openingBalances` object
      - `status` 'needed' | 'partial' | 'confirmed'
      - `evidence` string: Statement/report references and dates; confirmed requires evidence, including owner confirmation for a genuinely new zero-balance account
    - `backfill` object
      - `status` 'not_started' | 'in_progress' | 'complete'
      - `notes` string
      - `receiptReferences` string[]: Import/job/receipt references, not a copy of every transaction
    - `routine` object
      - `status` 'not_set' | 'planned' | 'active'
      - `provider` string
      - `externalId` string, nullable
      - `schedule` string
      - `timeZone` string
      - `approvedAt` string, date-time, nullable
      - `verifiedAt` string, date-time, nullable
      - `lastRunAt` string, date-time, nullable
      - `scope` string: Owner-approved accounts and actions; this record does not grant permission or schedule a job
    - `unresolved` string[]: Missing files, account access, owner decisions and other unfinished work

## Response `200`

Saved or identical retry

- object
  - `organizationId` string, uuid
  - `revision` integer
  - `state` object
    - `nextStep` 'business' | 'accounts' | 'history' | 'opening_balances' | 'backfill' | 'routine' | 'ongoing': Next unfinished conversational step, not an accounting gate
    - `businessActivity` string: Owner-confirmed description of what this business does
    - `accounts` object[]: Owner-selected business accounts, preserving existing mappings
      - `label` string, required: Business account label; never a full account number
      - `institution` string, required
      - `kind` 'checking' | 'savings' | 'credit_card' | 'loan' | 'processor' | 'other', required
      - `mask` string, nullable
      - `connectionStatus` 'not_connected' | 'connected' | 'needs_attention' | 'file_only'
      - `externalAccountId` string, nullable: Provider account identifier, never an access token
      - `bankAccountId` string, uuid, nullable: Mapped bank register UUID in this business
      - `availableFrom` string, date, nullable
      - `importedThrough` string, date, nullable
    - `history` object
      - `mode` 'undecided' | 'start_fresh' | 'bank_history' | 'existing_books'
      - `startDate` string, date, nullable
      - `cutoverDate` string, date, nullable: Last date covered by prior books; live activity must not overlap imported accounting
      - `notes` string
    - `openingBalances` object
      - `status` 'needed' | 'partial' | 'confirmed'
      - `evidence` string: Statement/report references and dates; confirmed requires evidence, including owner confirmation for a genuinely new zero-balance account
    - `backfill` object
      - `status` 'not_started' | 'in_progress' | 'complete'
      - `notes` string
      - `receiptReferences` string[]: Import/job/receipt references, not a copy of every transaction
    - `routine` object
      - `status` 'not_set' | 'planned' | 'active'
      - `provider` string
      - `externalId` string, nullable
      - `schedule` string
      - `timeZone` string
      - `approvedAt` string, date-time, nullable
      - `verifiedAt` string, date-time, nullable
      - `lastRunAt` string, date-time, nullable
      - `scope` string: Owner-approved accounts and actions; this record does not grant permission or schedule a job
    - `unresolved` string[]: Missing files, account access, owner decisions and other unfinished work
  - `updatedBy` string, uuid, nullable
  - `updatedAt` string, date-time
  - `reused` boolean

## Other responses

- `400`: Invalid state or bank register mapping
- `403`: Permission denied
- `409`: Revision conflict; reread and merge before retrying

---

[API](https://skmtc.dev/ledgerhq-pro/apis/ledgerhq-bookkeeping-api.md) · [All operations](https://skmtc.dev/ledgerhq-pro/apis/ledgerhq-bookkeeping-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ledgerhq-pro/apis/ledgerhq-bookkeeping-api/revisions/9a8269f0a586?raw)
