---
title: "Update Journal Entry"
method: POST
path: "/extensions/roboledger/{graph_id}/operations/update-journal-entry"
tags: ["RoboLedger: Ledger & Events"]
---

# Update Journal Entry

`POST /extensions/roboledger/{graph_id}/operations/update-journal-entry`

## 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/update-journal-entry`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Update a draft journal entry, or re-tag any entry's flows. If line_items is provided, existing line items are replaced atomically, the new set must balance, and a line on a retired (`is_active=false`) account is refused. `line_flows` sets the cash flow row of the named lines in place, on a posted entry too, closed month included, since a flow moves no balance; the lines on the other side of the entry that were in step with it follow. Posted entries accept nothing else and are corrected via `create-event-block(event_type='journal_entry_reversed')`.

**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

- UpdateJournalEntryRequest: Update a draft journal entry, or re-tag any entry's flows. Posted entries accept only `line_flows`: a flow moves no balance, so it changes in place, closed month or not. Anything else on a posted entry is a reversal and a corrected entry. Omitted fields are left unchanged. If `line_items` is provided, the existing line items are replaced entirely (atomic delete + insert) and the new set must still balance. If `line_items` is omitted, the existing line items are left untouched.
  - `entry_id` string, required: The draft entry to update.
  - `posting_date` string, date, nullable: New posting date.
  - `memo` string, nullable: New entry-level memo.
  - `type` 'standard' | 'adjusting' | 'closing' | 'reversing', nullable: New entry type. `closing` should normally only be set by close-period.
  - `line_items` JournalEntryLineItemInput[], nullable: Replacement line items. Whole-list replacement (not patch). The new set must still balance (total_debit == total_credit). Omit to leave existing lines untouched.
    - `element_id` string, required: Element ULID identifying the account to post to.
    - `debit_amount` integer: Debit amount in cents. Must be 0 if `credit_amount` > 0.
    - `credit_amount` integer: Credit amount in cents. Must be 0 if `debit_amount` > 0.
    - `description` string, nullable: Per-line memo (overrides the entry-level memo on this line).
    - `flow_qname` string, nullable: The cash flow row this line's cash belongs to, an rs-gaap flow qname (`flowCandidates(entityId)` lists the rows this company's statement offers). Only for a loan drawn or repaid, capital put in or taken out, an asset bought or sold; omitted, the account's default flow applies. A flow set on one side of the entry tags the untagged lines on the other: the cash flow statement reads the cash line and the roll-forwards read the account line. On the group's consolidation entity, which moves no cash, every tagged line counts on its own, cash-effect signed (a credit is an inflow), so an elimination offsets the flow a member's line produced, and a tag does not spread to the other side. Refused when it is not a row of the entity's cash flow statement.
    - `metadata` object, nullable: Optional per-line metadata stamped on `LineItem.metadata_`. Used to carry source-system fields the standard columns don't cover — e.g. an external flow-tag code that drives rollforward attribution (`transaction_description_code`), an external memo, or a cost-center hint. Pass-through is non-validating; the renderer / filter engine reads keys it knows about and ignores the rest. `None` is normalized to `{}` at persist time.
  - `line_flows` JournalEntryLineFlow[], nullable: Re-tag lines in place: each named line takes its `flow_qname` (null clears it), and when every line on that side of the entry then carries one flow, the lines on the other side not named here follow when they were in step with it — untagged, or carrying the flow the named lines carried before — so the cash line and the account line agree; a line tagged differently on purpose keeps its tag. Allowed on a posted entry, closed month included, and the only change one accepts; recorded on the entry as `flow_retags`, with what each changed line carried before. Not combinable with `line_items`, which replaces the lines (set `flow_qname` on them).
    - `line_id` string, required: The line to re-tag, by id.
    - `flow_qname` string, nullable: The rs-gaap flow qname the line takes; null clears it, back to the account's default flow.

## 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)
