---
title: "Record Opening Balance"
method: POST
path: "/extensions/roboledger/{graph_id}/operations/record-opening-balance"
tags: ["RoboLedger: Ledger & Events"]
---

# Record Opening Balance

`POST /extensions/roboledger/{graph_id}/operations/record-opening-balance`

## Request

- Base URL: `https://api.robosystems.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.robosystems.ai/extensions/roboledger/{graph_id}/operations/record-opening-balance`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Record the balance sheet an entity's books start from, when its history does not come with them: one balance per balance-sheet account (assets, liabilities, equity), in cents, debit or credit in the account's normal direction. It posts as one `opening` entry dated the day before the entity's first fiscal month, so every month's opening balances include it and no month's activity does: the cash flow and the equity statement start from it rather than counting it. Name the equity account that takes any difference between debits and credits (`equity_element_id`, usually Opening Balance Equity); unbalanced balances without one are refused, and an income or expense account is refused, since income before the books begin is in retained earnings. One per entity: recording it again replaces it, until the entity's first close, after which a correction is an adjusting entry in an open month. Set up the fiscal calendar first; moving its start (change-calendar-start) moves the opening with it.

**Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

## Path parameters

- `graph_id` string, required

## Headers

- `Idempotency-Key` string, nullable

## Request body

- RecordOpeningBalanceRequest: The balance sheet a ledger starts from.
  - `entity_id` string, nullable: The entity whose books start here; omit for the group parent.
  - `balances` OpeningBalanceInput[], required: One balance per balance-sheet account (assets, liabilities, equity). An income or expense account is refused: income before the books begin is already in retained earnings.
    - `element_id` string, required: The balance-sheet account, by id.
    - `debit_amount` integer: Debit balance in cents.
    - `credit_amount` integer: Credit balance in cents.
  - `equity_element_id` string, nullable: The equity account that takes any difference between debits and credits, usually Opening Balance Equity. Required when the balances do not balance; a non-zero balance left there is a review item.
  - `memo` string, nullable: The entry's memo; defaults to 'Opening balances'.

## Response `200`

Successful Response

- OperationEnvelopeJournalEntryResponse
  - `operation` string, required: Kebab-case operation name
  - `operationId` string, required: op_-prefixed ULID for audit and SSE correlation
  - `status` 'completed' | 'pending' | 'failed', required: Operation lifecycle state
  - `result` JournalEntryResponse: The common response shape for journal entry write operations.
    - `id` string, required
    - `transaction_id` string, nullable
    - `type` string, required
    - `status` string, required
    - `posting_date` string, date, required
    - `memo` string, nullable
    - `provenance` string, nullable
    - `reversal_of` string, nullable
    - `posted_at` string, date-time, nullable
    - `line_items` JournalEntryLineItemResponse[], required
      - `id` string, required
      - `element_id` string, required
      - `debit_amount` integer, required
      - `credit_amount` integer, required
      - `description` string, nullable
      - `line_order` integer, required
      - `flow_qname` string, nullable: The cash flow row this line carries, when tagged; null means the account's default flow.
    - `total_debit` integer, required
    - `total_credit` integer, required
    - `adjustment_kind` string, nullable
    - `adjusts_entity_id` string, nullable
  - `at` string, required: ISO-8601 UTC timestamp
  - `createdBy` string, nullable: User ID that initiated the operation
  - `idempotentReplay` boolean: True when this envelope came from the idempotency cache — the underlying command did not execute again. False on fresh executions.

## Other responses

- `400`: Invalid request
- `401`: Authentication required
- `403`: Access denied
- `404`: Resource not found
- `409`: Idempotency-Key conflict — key reused with different body
- `422`: Validation error
- `429`: Rate limit exceeded
- `500`: Internal server error

---

[API](https://skmtc.dev/robosystems/apis/robosystems-api.md) · [All operations](https://skmtc.dev/robosystems/apis/robosystems-api/llms.txt) · [OpenAPI document](https://skmtc.dev/robosystems/apis/robosystems-api/revisions/e661e2d5ca6a?raw)
