Operations
Poll long-running async operations (year-end closing, imports, currency revaluation).
Endpoints
GET/api/v1/operations/:id— Poll a long-running operation by id.
GET /api/v1/operations/:id {#get-operations-get}
operations.get · scope operations:read
Poll a long-running operation by id.
Returns the current snapshot of a v1 async operation: status (queued / running / succeeded / failed / cancelled), progress (jsonb, free-form), result (on success), and error (on failure). The operation_id is returned by the POST endpoints that initiate async work (period close, year-end, currency revaluation, SIE import).
Use when: You started an async operation and need to know whether it has finished. Poll every 5–30 seconds; switch to the operation.completed webhook for production integrations.
Don't use for: Fetching the resource the operation produced — once status=succeeded, read the result field or call the resource-specific GET endpoint. Cancelling a running operation (no cancel endpoint exists in v1).
Pitfalls
- Terminal statuses (
succeeded,failed,cancelled) are final; the row never transitions out of them. - progress is free-form jsonb; agents should treat it as opaque except for the documented fields
phase(string),current/total(numbers for percent calculation). - started_at is null while status=queued (the work has not begun yet); completed_at is null until a terminal status is reached.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Example response
{
"data": {
"operation_id": "0e9c-…",
"type": "fiscal_periods.year_end",
"status": "succeeded",
"progress": {
"phase": "committed",
"current": 142,
"total": 142
},
"result": {
"journal_entries_created": 4,
"opening_balances_set": 138
},
"error": null,
"started_at": "2026-05-12T10:01:23Z",
"completed_at": "2026-05-12T10:01:48Z",
"poll_url": "/api/v1/operations/0e9c-…",
"webhook_event": "operation.completed"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}