---
title: "Update Event Block"
method: POST
path: "/extensions/roboledger/{graph_id}/operations/update-event-block"
tags: ["RoboLedger: Ledger & Events"]
---

# Update Event Block

`POST /extensions/roboledger/{graph_id}/operations/update-event-block`

## 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-event-block`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Apply a status transition (captured → classified | committed | voided) and/or field corrections (description, effective_at, metadata_patch) to an existing event block. Only supplied fields are updated. captured → classified records an account choice without posting — for a bank-feed line, patch metadata.classified_element_id (or accept_suggestion: true) in the same call. When the transition is captured/classified → committed, the registered Python handler fires against the captured metadata to produce the GL rows, unless it already wrote them when the event was created; a bank-feed line with no account chosen and no matching rule is refused. Errors from the handler (validation, element resolution, closed period, unbalanced lines) surface as 422 here so the inbox UI can display the failure reason without retry. A bank line's flow is a second classification beside its account, overriding the account's default flow on the cash flow and equity statements: patch `classified_flow_qname` (or `flow_qname` on each `classified_allocations` part) with an rs-gaap flow concept such as `rs-gaap:ProceedsFromIssuanceOfLongTermDebt`. On a line that has already posted, this re-tags its lines in place, in a closed month too, since no balance moves; an empty string clears 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

- UpdateEventBlockRequest: Status transitions and field corrections for an event block. All fields except event_id are optional — only supplied fields are updated.
  - `event_id` string, required: Target event ID.
  - `transition_to` 'classified' | 'committed' | 'pending' | 'fulfilled' | 'voided' | 'superseded', nullable: Status transition. Valid moves depend on current status: captured → classified | committed | voided | superseded; classified → committed | pending | fulfilled | voided | superseded; committed → pending | fulfilled | voided | superseded; pending → fulfilled | voided | superseded; fulfilled → voided | superseded. A retraction (voided, superseded) is final and is refused from any status once the event's ledger rows have posted or it has published to QuickBooks — reverse the posted entries instead. captured → classified records an account choice without posting (bank-feed lines: patch classified_element_id, or accept_suggestion: true, in the same call); the later commit fires the handler. Note: classified and fulfilled are otherwise set by handlers, not by callers, but the transition is allowed for corrections.
  - `superseded_by_id` string, nullable: New event id that replaces this one. Required when transition_to='superseded'.
  - `description` string, nullable: Replacement free-text summary. Unset = unchanged; pass an empty string to clear.
  - `effective_at` string, date-time, nullable: New accounting recognition date. Unset = unchanged. Useful when an event was captured against the wrong period.
  - `metadata_patch` object: Key-value pairs merged into existing metadata (additive patch, not replace).
  - `event_action` 'produce' | 'raise' | 'consume' | 'lower' | 'use' | 'cite' | 'work' | 'deliverService' | 'pickup' | 'dropoff' | 'accept' | 'transferCustody' | 'transferAllRights' | 'transfer' | 'move' | 'modify' | 'combine' | 'separate' | 'copy', nullable: Set or correct the canonical action verb. Unset = unchanged. Useful when an adapter improvement makes a previously-NULL verb fillable, or when reclassifying after the fact.
  - `obligated_by_event_id` string, nullable: Set/update the forward-materialization link.
  - `discharges_event_id` string, nullable: Set/update the settlement link.
  - `document_id` string, nullable: Set or replace the stored document the event rests on; an empty string detaches it. Must be a document on this graph. Unset = unchanged.

## Response `200`

Successful Response

- OperationEnvelopeEventBlockEnvelope
  - `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` EventBlockEnvelope: Read projection for a single event block. Returned by `create-event-block`, `update-event-block`, `preview-event-block`, and the read-side `get-event-block`. Mirrors the request shape plus server-assigned fields (id, status, audit timestamps) and the four nullable correction/duality links.
    - `id` string, required: Event ID (`evt_*` ULID).
    - `event_type` string, required: Open-vocabulary event type (e.g. `invoice_issued`, `bank_transaction`, `control_executed`).
    - `event_category` string, required: REA category, scoped by `event_class` — economic (`sales`, `purchase`, `financing`, `payroll`, `treasury`, `adjustment`, `recognition`, `other`), support (`control`, `approval`, `reconciliation`, `inquiry`), or operational (`pipeline`, `engagement`, `schedule`, `other`) for occurrences that drive no GL — a lead, a lifecycle change, an outreach, a schedule setup.
    - `status` string, required: Lifecycle state. One of: `captured` (raw, pre-classification), `classified` (handler ran, GL pending), `committed` (GL entries posted), `pending` (committed but awaiting fulfillment of an obligation), `fulfilled` (obligation discharged — retractable while its ledger rows are still drafts), `voided` (canceled — terminal), `superseded` (replaced by a corrected event — terminal). See `UpdateEventBlockRequest.transition_to` for the valid transition graph.
    - `occurred_at` string, date-time, required: When the event happened in the real world (UTC).
    - `effective_at` string, date-time, nullable: Accounting recognition date, when different from `occurred_at`.
    - `source` string, required: Capture source: `manual`, `system`, `schedule`, a connected provider name (e.g. `quickbooks`), or a registered external source_name. Used for adapter routing.
    - `external_id` string, nullable: Source-system dedup key. Unique with `source` when set, so adapter retries are idempotent.
    - `external_url` string, nullable: Deep link back to the source-system record.
    - `amount` integer, nullable: Economic value in **cents** of `currency`, signed (inflows positive, outflows negative). `null` for non-economic events.
    - `currency` string, required: ISO 4217 currency code for `amount`.
    - `description` string, nullable: Free-text human-readable summary.
    - `metadata` object, required: Free-form payload — handler-specific keys when the event ran through a handler, otherwise whatever the adapter captured.
    - `is_reconciling_item` boolean: True when this event is a reconciling item: a source re-sync surfaced a changed upstream payload for an event whose GL is already posted (committed/fulfilled are immutable to sync) — the local books legitimately no longer mirror the source, and the difference awaits an explicit disposition (restate the affected months, or book a catch-up entry in the open period). The live payload and GL are untouched; the incoming payload is stashed in `metadata.drift_payload` with `metadata.drift_detected_at`.
    - `dimension_ids` string[], required: Dimension-member IDs tagging this event (department, fund, project). Propagate to GL entries produced by the handler.
    - `event_class` string, required: REA event class — `economic` (drives GL postings) or `support` (audit-trail / value-chain primitive, no GL impact).
    - `event_action` 'produce' | 'raise' | 'consume' | 'lower' | 'use' | 'cite' | 'work' | 'deliverService' | 'pickup' | 'dropoff' | 'accept' | 'transferCustody' | 'transferAllRights' | 'transfer' | 'move' | 'modify' | 'combine' | 'separate' | 'copy', nullable: Canonical action verb refining `event_category`. Null when the source adapter or capture path didn't supply one.
    - `agent_id` string, nullable: Counterparty agent ID, when the event involves one.
    - `resource_type` string, nullable: REA resource kind being exchanged (`goods`, `services`, `money`, `right`, `obligation`, `information`, `labor`).
    - `resource_element_id` string, nullable: Specific element ID being exchanged, when known.
    - `replaced_by_event_id` string, nullable: ID of the event that replaces this one. Set when this event was superseded (`status='superseded'`); points forward in the correction chain.
    - `replaces_event_id` string, nullable: ID of the event this one replaces, when applicable. Points backward in the correction chain. Mirror of `replaced_by_event_id` on the predecessor.
    - `obligated_by_event_id` string, nullable: Forward-materialization link — the event that scheduled or obligated this one (e.g. depreciation entries point at the originating `asset_acquired` event).
    - `discharges_event_id` string, nullable: Settlement link — the obligation this event discharges (e.g. `cash_received` pointing at the originating `sale_invoiced`).
    - `document_id` string, nullable: The stored document the event rests on (an invoice, a bill, a receipt, a statement); read it with get-document.
    - `created_at` string, date-time, required: Row creation timestamp (UTC).
    - `created_by` string, required: ID of the user who captured the event. For adapter-sourced events, the system actor associated with the adapter.
  - `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)
