StabisoDocs

API reference

Exports

The complete package of the organization's own data for its archive: every table as CSV and JSON, reports, stored files, hash-chain verification and hashes. Started by an administrator, built asynchronously, downloaded or fetched through a signed link.

Operation Summary Scope Idempotency-Key
GET /v1/exports List the organization's exports audit
POST /v1/exports Export the organization's data audit required
GET /v1/exports/{run_id} Get an export's status audit
GET /v1/exports/{run_id}/download Download the package of an export audit
GET /v1/exports/{run_id}/link Get a link to download the package of an export audit

GET /v1/exports

List the organization's exports

The organization's exports, newest first, with their status. Pages of limit: pass the last id as after for the next one. Needs the admin and audit scopes.

Required scope audit (admin implies every scope)
Operation id list_exports_v1_exports_get

Parameters

In Name Type Required Description
query limit integer Most exports returned, 1 to 100. (min 1; max 100; default 25)
query after string (uuid) or null Continue after this export (its id, the last of the previous page); omit for the first page.

Example request

curl "$ERP_URL/v1/exports" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of ExportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "expired",
    "via": "platform",
    "language": "de",
    "note": "string",
    "requested_by": {},
    "requested_at": "2026-09-21T09:30:00Z",
    "started_at": "2026-09-21T09:30:00Z",
    "finished_at": "2026-09-21T09:30:00Z",
    "stage": "string",
    "progress": {},
    "error": "string",
    "cutoff": "2026-09-21T09:30:00Z",
    "file_name": "string",
    "size_bytes": 1,
    "sha256": "string",
    "manifest_sha256": "string",
    "file_count": 1,
    "row_count": 1,
    "complete": true,
    "statement": {},
    "expires_at": "2026-09-21T09:30:00Z"
  }
]

POST /v1/exports

Export the organization's data

Ask for the complete package of the organization's data, for its own archive: every table of every entity and year as CSV (UTF-8, documented schema) and JSON, the reports of every entity and fiscal year as PDF and CSV, every stored file checked against its SHA-256, the verification of every entity's hash chain, a manifest with the hash of every file (manifest.sha256, for sha256sum -c), the index.xml of the German Beschreibungsstandard where an entity is German, a program that verifies the package, and a README in the requested language with the legal references. Nothing secret is in it (no API key hash, no session token).

The export is built asynchronously from one consistent snapshot of the database, so it can be large: the answer is 202 with the export in status queued; follow it with GET /v1/exports/{id} until it is succeeded, then download it (GET /v1/exports/{id}/download, or a link with GET /v1/exports/{id}/link). The package is kept for 30 days. One export at a time: 409 export_in_progress while another is queued or running. Allowed also while the organization is suspended (it changes none of the books). Needs the admin and audit scopes and a person's key, not an agent's. Starting is an audit event (export.start).

A retry with the same Idempotency-Key returns the first answer and starts nothing more.

Required scope audit (admin implies every scope)
Idempotency-Key required
Operation id start_export_v1_exports_post

Request body

application/json (required): ExportRequest

Field Type Required Description
language "de" | "en" | "fr" | "it" | "sv" or null The language of the package's README: en, de, fr, it or sv. Default: the language of the person who asks, else the country of the organization's first entity (de for CH and DE, fr for FR, it for IT, sv for SE), else en.
note string or null Why the export is made, up to 500 characters; kept with the request and in the audit trail. (max length 500)

Example request

curl -X POST "$ERP_URL/v1/exports" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "language": "de",
  "note": "Archive copy at contract end"
}'

Responses

Status Meaning Body
202 Successful Response ExportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "status": "expired",
  "via": "platform",
  "language": "de",
  "note": "string",
  "requested_by": {},
  "requested_at": "2026-09-21T09:30:00Z",
  "started_at": "2026-09-21T09:30:00Z",
  "finished_at": "2026-09-21T09:30:00Z",
  "stage": "string",
  "progress": {},
  "error": "string",
  "cutoff": "2026-09-21T09:30:00Z",
  "file_name": "string",
  "size_bytes": 1,
  "sha256": "string",
  "manifest_sha256": "string",
  "file_count": 1,
  "row_count": 1,
  "complete": true,
  "statement": {},
  "expires_at": "2026-09-21T09:30:00Z"
}

GET /v1/exports/{run_id}

Get an export's status

One export: queued, running (with the stage it is in and its progress), succeeded (with the file's name, size and SHA-256, the hash of the package's own checksum list, the number of files and rows, whether it is complete, and the hand-over statement), failed (with the reason), or expired (the package was deleted after its 30 days). 404 for an unknown export or one of another organization. Needs the admin and audit scopes.

Required scope audit (admin implies every scope)
Operation id get_export_v1_exports__run_id__get

Parameters

In Name Type Required Description
path run_id string (uuid) yes Id of an export (GET /v1/exports).

Example request

curl "$ERP_URL/v1/exports/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ExportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "status": "expired",
  "via": "platform",
  "language": "de",
  "note": "string",
  "requested_by": {},
  "requested_at": "2026-09-21T09:30:00Z",
  "started_at": "2026-09-21T09:30:00Z",
  "finished_at": "2026-09-21T09:30:00Z",
  "stage": "string",
  "progress": {},
  "error": "string",
  "cutoff": "2026-09-21T09:30:00Z",
  "file_name": "string",
  "size_bytes": 1,
  "sha256": "string",
  "manifest_sha256": "string",
  "file_count": 1,
  "row_count": 1,
  "complete": true,
  "statement": {},
  "expires_at": "2026-09-21T09:30:00Z"
}

GET /v1/exports/{run_id}/download

Download the package of an export

The package of a succeeded export, as a ZIP, streamed (it can be many gigabytes: use a client that writes to a file, and compare the SHA-256 with sha256 of the export or with the X-Content-SHA256 header). For a large package, GET /v1/exports/{id}/link gives a link that downloads straight from the store. Every download is an audit event (export.download). 409 export_not_ready while the export has not succeeded or after it has expired, 404 for an unknown export or one of another organization. Needs the admin and audit scopes.

Required scope audit (admin implies every scope)
Operation id download_export_v1_exports__run_id__download_get

Parameters

In Name Type Required Description
path run_id string (uuid) yes Id of an export (GET /v1/exports).

Example request

curl "$ERP_URL/v1/exports/3fa85f64-5717-4562-b3fc-2c963f66afa6/download" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 The package: a ZIP, streamed (SHA-256 in X-Content-SHA256). application/zip
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Get a link to download the package of an export

A signed link that downloads the package straight from the store, without credentials, for seven days at most (and never beyond the package's own expiry). Anyone who holds the link can download until it ends: treat it like a password. Giving the link is an audit event (export.link). 409 export_not_ready while the export has not succeeded or after it has expired, and 409 no_signed_link on a deployment that cannot sign links (use /download). Needs the admin and audit scopes.

Required scope audit (admin implies every scope)
Operation id export_link_v1_exports__run_id__link_get

Parameters

In Name Type Required Description
path run_id string (uuid) yes Id of an export (GET /v1/exports).

Example request

curl "$ERP_URL/v1/exports/3fa85f64-5717-4562-b3fc-2c963f66afa6/link" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ExportLink
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "url": "string",
  "expires_at": "2026-09-21T09:30:00Z",
  "file_name": "string",
  "size_bytes": 1,
  "sha256": "string"
}
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 20b7dd5b0c4d