Browse the API reference

Reopen Fiscal Period

post/extensions/roboledger/{graph_id}/operations/reopen-period

Part of Extensions: RoboLedger.

Reopen a closed period for adjustment. Only the latest closed period (closed_through) can be reopened; it decrements by one and the period's entries become writable again. To reach an earlier month, reopen latest-first down to it, then re-close forward — an out-of-order reopen is refused (422) with the ordered list, because every later closed month carries statements stamped from the earlier month's numbers. Retracts the month's canonical statement FactSets (a reopened month is no longer a closed assertion; re-closing restamps them). The required reason is captured in the audit log. Use sparingly — reopen invalidates downstream artifacts that trusted the closed state (reports, shared filings).

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.

Authentication

Authenticate in any one of these ways — not all of them:

  • API key in the X-API-Key header.
  • Bearer token in the Authorization header.

Path parameters

NameTypeDescription
graph_idrequiredstringGraph Id

Header parameters

NameTypeDescription
Idempotency-KeyoptionalstringIdempotency-Key

Request body

Required, application/json.

FieldTypeDescription
reasonrequiredstring

Required reason for the reopen (captured in audit log)

noteoptionalstring

Additional free-form note

periodrequiredstring

Period to reopen, in YYYY-MM. Any closed period may be reopened. Reopening the current `closed_through` retreats it by one month; reopening an earlier period leaves `closed_through` where it is (a prior-period adjustment), and its re-close restores the period without moving the pointer.

Example request

curl
curl -X POST "https://api.robosystems.ai/extensions/roboledger/{graph_id}/operations/reopen-period" \
  -H "X-API-Key: $ROBOSYSTEMS_API_KEY" \
  -H "Idempotency-Key: <Idempotency-Key>" \
  -H "Content-Type: application/json" \
  -d '{
  "period": "2026-03",
  "reason": "Discovered late vendor invoice — needs to land in March."
}'

Responses

200 Successful Response

FieldTypeDescription
operationrequiredstring

Kebab-case operation name

operationIdrequiredstring

op_-prefixed ULID for audit and SSE correlation

statusrequiredstring

Operation lifecycle state

One of: completed, pending, failed

resultoptionalFiscalCalendarResponse

Command-specific result payload

FiscalCalendarResponse fields
FieldTypeDescription
graph_idrequiredstring
fiscal_year_start_monthrequiredinteger
closed_throughoptionalstring

Latest closed period (YYYY-MM), or null if nothing closed

close_targetoptionalstring

Target period the user wants closed through (YYYY-MM)

gap_periodsoptionalinteger

Number of periods between closed_through and close_target (inclusive of close_target). 0 means caught up.

Default: 0

catch_up_sequenceoptionalstring[]

Ordered list of periods that a close run would process

closeable_nowoptionalboolean

Whether the next period in the catch-up sequence passes all closeable gates

Default: false

blockersoptionalstring[]

Structured blocker codes when closeable_now is False: 'sequence_violation', 'period_incomplete', 'sync_stale', 'calendar_not_initialized', 'period_already_closed', 'pending_obligations', 'stranded_obligations'

pending_obligation_countoptionalinteger

Number of pending schedule_entry_due events blocking close. Non-zero only when `pending_obligations` is in `blockers`.

Default: 0

pending_obligation_sampleoptionalPendingObligationDetailResponse[]

Sample of up to 5 pending obligations (schedule_id, schedule_name, period, event_id) ordered by occurred_at. Use `list-event-blocks` with event_type=schedule_entry_due&status=pending for the full set.

PendingObligationDetailResponse fields
FieldTypeDescription
event_idrequiredstring
schedule_idoptionalstring
schedule_nameoptionalstring
periodrequiredstring

Period in YYYY-MM format

earliest_pending_periodoptionalstring

Earliest period (YYYY-MM) with a pending obligation blocking close. Null when no pending_obligations blocker is active.

sync_stale_daysoptionalinteger

Days the most recent sync is stale relative to the period to close. Populated only when `sync_stale` is in `blockers` and last_sync_at exists (null when there's a connection but no sync has ever run).

stranded_obligation_countoptionalinteger

Matured schedule_entry_due events already at 'classified' with no drafted closing entry for their (schedule, period) — adjusting entries a close would silently omit. Resolve by running promote-obligations with dispatch_handlers=true (which reaches them) or voiding the obligation.

Default: 0

stranded_obligation_sampleoptionalPendingObligationDetailResponse[]

Sample of up to 5 stranded obligations (schedule_id, schedule_name, period, event_id) ordered by occurred_at.

PendingObligationDetailResponse fields
FieldTypeDescription
event_idrequiredstring
schedule_idoptionalstring
schedule_nameoptionalstring
periodrequiredstring

Period in YYYY-MM format

reconciling_item_countoptionalinteger

Posted events in or before this period whose source payload changed afterwards and that nobody has dispositioned — differences between the books and the source system. Resolve each with resolve-reconciling-item, or close over them knowingly with allow_reconciling_items.

Default: 0

reconciling_item_sampleoptionalstring[]

Source identifiers (or event ids) of up to 5 unresolved reconciling items, so the blocker names what is holding the close.

last_close_atoptionalstring (date-time)
initialized_atoptionalstring (date-time)
last_sync_atoptionalstring (date-time)

Most recent QB sync timestamp (if connected)

periodsoptionalFiscalPeriodSummary[]

Fiscal period rows for this graph

FiscalPeriodSummary fields
FieldTypeDescription
namerequiredstring

Period name (YYYY-MM)

start_daterequiredstring (date)
end_daterequiredstring (date)
statusrequiredstring

'open' | 'closing' | 'closed'

closed_atoptionalstring (date-time)
has_close_receiptoptionalboolean

Whether this period carries a close receipt. A flag rather than the receipt itself keeps the calendar listing compact; fetch the receipt from `get-period-close-status` for the period. False on open periods and on periods closed before receipts shipped.

Default: false

atrequiredstring

ISO-8601 UTC timestamp

createdByoptionalstring

User ID that initiated the operation (null for legacy callers)

idempotentReplayoptionalboolean

True when this envelope came from the idempotency cache — the underlying command did not execute again. False on fresh executions.

Default: false

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