StabisoDocs

API reference

Close

Period-end: depreciation, FX revaluation, deferred tax, checklist, close, reopen.

Operation Summary Scope Idempotency-Key
PUT /v1/documents/{document_id}/doubtful Mark an invoice doubtful draft
DELETE /v1/documents/{document_id}/doubtful Unmark a doubtful invoice draft
GET /v1/entities/{entity}/receivable-allowance/settings Get the general allowance percents read
PUT /v1/entities/{entity}/receivable-allowance/settings Set the general allowance percents post
POST /v1/periods/{period_id}/close Close a period approve
GET /v1/periods/{period_id}/close-checklist Get the close checklist of a period read
POST /v1/periods/{period_id}/deferred-tax Run deferred tax for a period draft
POST /v1/periods/{period_id}/depreciation Run depreciation for a period draft
POST /v1/periods/{period_id}/fx-revaluation Run FX revaluation for a period draft
GET /v1/periods/{period_id}/receivable-allowance Calculate the allowance for doubtful receivables read
POST /v1/periods/{period_id}/receivable-allowance Run the allowance for doubtful receivables draft
POST /v1/periods/{period_id}/reopen Reopen a period approve

PUT /v1/documents/{document_id}/doubtful

Mark an invoice doubtful

Mark a posted customer invoice doubtful, or change its percent: the allowance run covers that share of what is open on it (a specific allowance) instead of its aging bucket's percent. Posts nothing by itself. Refused: 404 for an unknown invoice, 422 when it is not a posted customer invoice (doubtful_not_invoice).

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id mark_doubtful_v1_documents__document_id__doubtful_put

Parameters

In Name Type Required Description
path document_id string yes Document id (uuid) or number, e.g. INV-2026-000001.

Request body

application/json (required): DoubtfulInput

Field Type Required Description
percent decimal string yes The share of what is open on the invoice the specific allowance covers (100: nothing is expected to come in). (max 100; greater than 0)
note string or null Why the invoice is doubtful (optional). (max length 500)

Example request

curl -X PUT "$ERP_URL/v1/documents/INV-2026-000001/doubtful" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "Dispute",
  "percent": "50"
}'

Responses

Status Meaning Body
200 OK DoubtfulOut
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
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)

{
  "note": "Dispute",
  "percent": "50"
}

DELETE /v1/documents/{document_id}/doubtful

Unmark a doubtful invoice

The invoice is no longer doubtful: the general allowance covers it again. 404 when it is not marked.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id unmark_doubtful_v1_documents__document_id__doubtful_delete

Parameters

In Name Type Required Description
path document_id string yes Document id (uuid) or number, e.g. INV-2026-000001.

Example request

curl -X DELETE "$ERP_URL/v1/documents/INV-2026-000001/doubtful" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
204 No content
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
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

GET /v1/entities/{entity}/receivable-allowance/settings

Get the general allowance percents

The company's general allowance: a percent for each aging bucket and whether it is taken with VAT. default is true while the suggested ones apply (0 % not yet due, 5 % overdue; with VAT for Swiss and Liechtenstein companies).

Required scope read (admin implies every scope)
Operation id allowance_settings_v1_entities__entity__receivable_allowance_settings_get

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).

Example request

curl "$ERP_URL/v1/entities/CH01/receivable-allowance/settings" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK AllowanceSettingsOut
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)

{
  "include_vat": true,
  "percents": [
    {
      "bucket": "current",
      "percent": "0"
    },
    {
      "bucket": "1-30",
      "percent": "5"
    },
    {
      "bucket": "31-60",
      "percent": "5"
    },
    {
      "bucket": "61-90",
      "percent": "5"
    },
    {
      "bucket": "90+",
      "percent": "5"
    }
  ]
}

PUT /v1/entities/{entity}/receivable-allowance/settings

Set the general allowance percents

Set the percent for each of the five aging buckets (each once; 422 allowance_buckets otherwise) and whether it is taken with VAT. The next allowance run uses them; audited.

Required scope post (admin implies every scope)
Idempotency-Key not used
Operation id update_allowance_settings_v1_entities__entity__receivable_allowance_settings_put

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).

Request body

application/json (required): AllowanceSettingsInput

Field Type Required Description
percents array of BucketPercent-Input yes The general allowance in percent for each of the five aging buckets, each bucket once. (min items 5; max items 5)
include_vat boolean yes Whether the percent is taken on the receivable with VAT (Swiss practice for the del credere) or on its amount without VAT (the VAT comes back when the loss is final, so German practice takes the net).

Example request

curl -X PUT "$ERP_URL/v1/entities/CH01/receivable-allowance/settings" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "include_vat": true,
  "percents": [
    {
      "bucket": "current",
      "percent": "0"
    },
    {
      "bucket": "1-30",
      "percent": "5"
    },
    {
      "bucket": "31-60",
      "percent": "5"
    },
    {
      "bucket": "61-90",
      "percent": "5"
    },
    {
      "bucket": "90+",
      "percent": "5"
    }
  ]
}'

Responses

Status Meaning Body
200 OK AllowanceSettingsOut
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
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)

{
  "include_vat": true,
  "percents": [
    {
      "bucket": "current",
      "percent": "0"
    },
    {
      "bucket": "1-30",
      "percent": "5"
    },
    {
      "bucket": "31-60",
      "percent": "5"
    },
    {
      "bucket": "61-90",
      "percent": "5"
    },
    {
      "bucket": "90+",
      "percent": "5"
    }
  ]
}

POST /v1/periods/{period_id}/close

Close a period

Lock the period once every check passes. Humans only (policy).

Evaluates the close checklist and, when no check fails, sets the period to closed so nothing can be posted into it; the response is the checklist afterwards. Reopen with POST /v1/periods/{period_id}/reopen. Refused: 403 when the policy or the caller's scopes do not allow closing periods; 409 when the period is already closed or a check fails (the message names the failing check ids). The entity's own close tasks do not hold the close (the checks decide it, ADR-0034): a task not done by then stays not done, and is recorded only after the period is reopened.

Required scope approve (admin implies every scope)
Idempotency-Key not used
Operation id close_period_v1_periods__period_id__close_post

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

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

Responses

Status Meaning Body
200 OK Checklist
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
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)

{
  "entity": "string",
  "period": "string",
  "period_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "period_status": "string",
  "ready": true,
  "checks": [
    {
      "id": "string",
      "title": "string",
      "status": "fail",
      "detail": "string",
      "code": "string",
      "details": {}
    }
  ]
}

GET /v1/periods/{period_id}/close-checklist

Get the close checklist of a period

Evaluate the conditions for closing a period, without changing anything.

Each check has a status of pass, fail, warn or n/a: pending approvals, drafts, depreciation, FX revaluation, deferred tax, receivables and payables control accounts, bank reconciliation and balances, trial balance, ledger hash chain and earlier periods. ready is true when no check fails (warnings do not block).

Required scope read (admin implies every scope)
Operation id close_checklist_v1_periods__period_id__close_checklist_get

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

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

Responses

Status Meaning Body
200 OK Checklist
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)

{
  "entity": "string",
  "period": "string",
  "period_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "period_status": "string",
  "ready": true,
  "checks": [
    {
      "id": "string",
      "title": "string",
      "status": "fail",
      "detail": "string",
      "code": "string",
      "details": {}
    }
  ]
}

POST /v1/periods/{period_id}/deferred-tax

Run deferred tax for a period

Post the change in deferred tax since the last run (after depreciation).

Measures the temporary differences of the book that carries deferred tax at the period end and posts the movement against the deferred tax liability and asset accounts and the deferred tax expense account, through the approval policy (submit; null when there is nothing to post). items are the per-asset differences and total the movement. Refused: 409 when deferred tax already ran for the period, when the period has not started yet (period_not_started), or when depreciation is due but has not run; 422 when no tax book of the entity carries deferred tax.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id run_deferred_tax_v1_periods__period_id__deferred_tax_post

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

curl -X POST "$ERP_URL/v1/periods/3fa85f64-5717-4562-b3fc-2c963f66afa6/deferred-tax" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK RunSummary
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
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)

{
  "run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "period": "string",
  "items": [
    {}
  ],
  "total": "string",
  "submit": {
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "string",
    "number": "string",
    "policy": {
      "decision": null,
      "reason": null,
      "rule_id": null,
      "table_id": null
    },
    "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "reason": "string"
  }
}

POST /v1/periods/{period_id}/depreciation

Run depreciation for a period

Post the period's book depreciation for every active asset in service.

The asset's fiscal-year amount is spread over the regular periods of the year (evenly per month, by days on a week-based calendar) and capped at what is left to depreciate. One entry dated at the period end is posted (Dr depreciation expense / Cr accumulated depreciation per asset) through the approval policy; submit is null when nothing is due. Adjustment periods get no depreciation; an asset whose disposal waits for approval is skipped (the disposal books its depreciation to its date). On the fiscal year's last regular period a run that stands can be made again as a top-up that books only the difference to the year's schedule (what is missing, or the excess taken back). Refused: 404 for an unknown period; 409 when depreciation already ran for the period (on the last period: and nothing differs), the period is closed, or it has not started yet (period_not_started: a period-end run is for the current period or an earlier one).

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id run_depreciation_v1_periods__period_id__depreciation_post

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

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

Responses

Status Meaning Body
200 OK RunSummary
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
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)

{
  "run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "period": "string",
  "items": [
    {}
  ],
  "total": "string",
  "submit": {
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "string",
    "number": "string",
    "policy": {
      "decision": null,
      "reason": null,
      "rule_id": null,
      "table_id": null
    },
    "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "reason": "string"
  }
}

POST /v1/periods/{period_id}/fx-revaluation

Run FX revaluation for a period

Revalue open foreign-currency items at the closing ECB rate (auto-reversing).

Open receivables and payables in a foreign currency and foreign-currency bank accounts are remeasured at the period-end rate. The unrealised difference is posted at the period end (against the unrealised FX account) through the approval policy and reversed on the first day of the next period once posted. items lists each remeasured item with its result (a gain positive, a loss negative) and total is the result posted, in functional currency.

It can run again after a posting dated in the period changed what it remeasured (a payment of a revalued invoice or an invoice entered after the run; the close check fx_revaluation then fails with fx_changed): the run again books only the change, at the same closing rate, also auto-reversing; each item then also has booked (what the earlier entries booked for it). Refused: 409 when the revaluation already ran and nothing changed (fx_revaluation_done), while its entry waits for approval (fx_revaluation_pending) or the period has not started yet (period_not_started); 422 for an adjustment period or when the next fiscal year is not opened.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id run_fx_revaluation_v1_periods__period_id__fx_revaluation_post

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

curl -X POST "$ERP_URL/v1/periods/3fa85f64-5717-4562-b3fc-2c963f66afa6/fx-revaluation" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK RunSummary
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
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)

{
  "run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "string",
  "period": "string",
  "items": [
    {}
  ],
  "total": "string",
  "submit": {
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "string",
    "number": "string",
    "policy": {
      "decision": null,
      "reason": null,
      "rule_id": null,
      "table_id": null
    },
    "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "reason": "string"
  }
}

GET /v1/periods/{period_id}/receivable-allowance

Calculate the allowance for doubtful receivables

What the allowance should be at the period end, invoice by invoice: the open customer invoices (not those of group companies), each with its bucket or doubtful percent, the base it is taken on and the allowance; the totals per bucket; and adjustment, the difference to what the allowance account holds, which the run posts. Once run, run_id is set and booked is what the account held before the run. Posts nothing.

Required scope read (admin implies every scope)
Operation id allowance_proposal_v1_periods__period_id__receivable_allowance_get

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

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

Responses

Status Meaning Body
200 OK AllowanceProposal
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)

{
  "entity": "string",
  "period_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "period": "string",
  "as_of": "2026-09-21",
  "currency": "string",
  "include_vat": true,
  "items": [
    {
      "document_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "document_number": "string",
      "party": "string",
      "due_date": "2026-09-21",
      "days_overdue": 1,
      "bucket": "1-30",
      "currency": "string",
      "open": "string",
      "base": "string",
      "kind": "general",
      "percent": "string",
      "allowance": "string",
      "note": "string"
    }
  ],
  "buckets": [
    {
      "bucket": "1-30",
      "percent": "string",
      "base": "string",
      "allowance": "string"
    }
  ],
  "specific": "string",
  "general": "string",
  "target": "string",
  "booked": "string",
  "adjustment": "string",
  "allowance_account": "string",
  "expense_account": "string",
  "run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "run_status": "string"
}

POST /v1/periods/{period_id}/receivable-allowance

Run the allowance for doubtful receivables

Adjust the allowance account (role receivable_allowance) to the allowance the open invoices call for at the period end: one entry dated the period end, Dr allowance expense / Cr allowance to raise it or the reverse to release part of it, through the approval policy (submit null when nothing differs). Not reversed: the next period's run adjusts it again. Refused: 404 for an unknown period; 409 when the period's run stands (allowance_done; a rejected one is made again), the period is closed or has not started (period_not_started); 422 when the chart lacks the accounts (role_missing).

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id run_allowance_v1_periods__period_id__receivable_allowance_post

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Example request

curl -X POST "$ERP_URL/v1/periods/3fa85f64-5717-4562-b3fc-2c963f66afa6/receivable-allowance" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK AllowanceRunResult
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
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)

{
  "run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "period": "string",
  "target": "string",
  "booked": "string",
  "adjustment": "string",
  "submit": {
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "string",
    "number": "string",
    "policy": {
      "decision": null,
      "reason": null,
      "rule_id": null,
      "table_id": null
    },
    "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "reason": "string"
  }
}

POST /v1/periods/{period_id}/reopen

Reopen a period

Set a closed period back to open so entries can be posted to it again. Needs the approve scope and a human: the approval policy's reopen_period action denies agents. The reason is mandatory and recorded in the audit trail (period.reopen). Returns the period; reopening an open period changes nothing but the audit trail.

Required scope approve (admin implies every scope)
Idempotency-Key not used
Operation id reopen_period_v1_periods__period_id__reopen_post

Parameters

In Name Type Required Description
path period_id string (uuid) yes Fiscal period id (GET /v1/entities/{entity}/periods).

Request body

application/json (required): ReopenInput

Field Type Required Description
reason string yes Why the period is reopened (audit trail). (min length 3; max length 1000)

Example request

curl -X POST "$ERP_URL/v1/periods/3fa85f64-5717-4562-b3fc-2c963f66afa6/reopen" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Late audit adjustment to the September accruals"
}'

Responses

Status Meaning Body
200 OK PeriodOut
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
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",
  "fiscal_year": 1,
  "number": 1,
  "kind": "string",
  "start_date": "2026-09-21",
  "end_date": "2026-09-21",
  "status": "string",
  "closed_at": "2026-09-21T09:30:00Z",
  "closed_by": "string"
}

Schemas

AllowanceItem

One open invoice and the allowance it calls for.

Field Type Required Description
document_id string (uuid) yes Id of the invoice.
document_number string or null yes Number of the invoice.
party string yes Name of the customer.
due_date string (date) yes Due date of the invoice.
days_overdue integer yes Days past the due date at the period end (0: not due).
bucket "1-30" | "31-60" | "61-90" | "90+" | "current" yes Its aging bucket at the period end.
currency string yes Currency of the invoice.
open string yes What is open on it at the period end, in its currency.
base string yes What the allowance is taken on, in the functional currency: what the books carry for it, with or without VAT as the settings say.
kind "general" | "specific" yes specific: the invoice is marked doubtful; general: the bucket's percent.
percent string yes The percent applied.
allowance string yes The allowance it calls for, in the functional currency.
note string or null Why it is doubtful, for a specific one.

AllowanceProposal

What the allowance should be at a period end, and the entry that brings the allowance account there.

Field Type Required Description
entity string yes Code of the company.
period_id string (uuid) yes The period.
period string yes The period as 2026-09.
as_of string (date) yes The period end the receivables are taken at.
currency string yes The functional currency of the amounts.
include_vat boolean yes Whether the base includes VAT.
items array of AllowanceItem yes The open invoices, oldest due date first.
buckets array of BucketTotal yes The general allowance per aging bucket.
specific string yes The specific allowance on the doubtful invoices.
general string yes The general allowance on the others.
target string yes The allowance needed: specific plus general.
booked string yes What the allowance account holds at the period end (posted entries).
adjustment string yes What the run posts: positive raises the allowance (an expense), negative releases part of it; 0 posts nothing.
allowance_account string or null yes The allowance account (role receivable_allowance); none when the chart lacks it.
expense_account string or null yes The account the change goes to (role allowance_expense, else bad_debt_expense).
run_id string (uuid) or null The period's run when it was made (then nothing more is run).
run_status string or null Status of the run's entry: posted, pending_approval; none when not run or when it posted nothing.

AllowanceRunResult

Field Type Required Description
run_id string (uuid) yes The run.
period string yes The period as 2026-09.
target string yes The allowance needed at the period end.
booked string yes What the allowance account held before the run.
adjustment string yes What the run posted (0: nothing).
submit SubmitResult or null yes How the entry was submitted (the approval policy decides); none when nothing was posted.

AllowanceSettingsInput

Field Type Required Description
percents array of BucketPercent-Input yes The general allowance in percent for each of the five aging buckets, each bucket once. (min items 5; max items 5)
include_vat boolean yes Whether the percent is taken on the receivable with VAT (Swiss practice for the del credere) or on its amount without VAT (the VAT comes back when the loss is final, so German practice takes the net).

AllowanceSettingsOut

Field Type Required Description
percents array of BucketPercent-Output yes The general allowance in percent for each of the five aging buckets, each bucket once. (min items 5; max items 5)
include_vat boolean yes Whether the percent is taken on the receivable with VAT (Swiss practice for the del credere) or on its amount without VAT (the VAT comes back when the loss is final, so German practice takes the net).
entity string yes Code of the company.
default boolean yes True while the company has not set its own: these are the suggested ones (0 % for receivables not yet due, 5 % for overdue ones).

BucketPercent-Input

Field Type Required Description
bucket "1-30" | "31-60" | "61-90" | "90+" | "current" yes The aging bucket: current (not yet due) or days past due (1-30, 31-60, 61-90, 90+).
percent decimal string yes The share of these receivables the general allowance covers. (min 0; max 100)

BucketPercent-Output

Field Type Required Description
bucket "1-30" | "31-60" | "61-90" | "90+" | "current" yes The aging bucket: current (not yet due) or days past due (1-30, 31-60, 61-90, 90+).
percent string yes The share of these receivables the general allowance covers.

BucketTotal

Field Type Required Description
bucket "1-30" | "31-60" | "61-90" | "90+" | "current" yes The aging bucket.
percent string yes The general allowance's percent for it.
base string yes The receivables of the bucket not marked doubtful.
allowance string yes Their general allowance.

DoubtfulInput

Field Type Required Description
percent decimal string yes The share of what is open on the invoice the specific allowance covers (100: nothing is expected to come in). (max 100; greater than 0)
note string or null Why the invoice is doubtful (optional). (max length 500)

DoubtfulOut

Field Type Required Description
percent string yes The share of what is open on the invoice the specific allowance covers (100: nothing is expected to come in).
note string or null Why the invoice is doubtful (optional). (max length 500)
document_id string (uuid) yes Id of the invoice.
document_number string or null yes Number of the invoice.
marked_at string (date-time) yes When it was marked doubtful (UTC).

ReopenInput

Field Type Required Description
reason string yes Why the period is reopened (audit trail). (min length 3; max length 1000)

RunSummary

Field Type Required Description
run_id string (uuid) yes Id of the recorded run (one per kind and period).
kind string yes depreciation, fx_revaluation or deferred_tax.
period string yes The period as YYYY-NN, e.g. 2026-09.
items array of object yes What was processed. Depreciation: asset, amount, dataset_version. FX revaluation: item (document number or bank account), currency, open, carrying, closing, difference (closing less carrying), result (what the entry books to profit and loss: a gain positive, a loss negative) and, on a run again, booked (what the earlier entries booked). Deferred tax: the per-asset differences of the book (see DifferenceLine).
total string yes Depreciation: the amount posted. FX revaluation: the result posted (a gain positive, a loss negative). Deferred tax: the movement posted. In the entity's functional currency.
submit SubmitResult or null yes The posted entry with the approval policy decision (allow, require_approval, deny); null when there was nothing to post.
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 20b7dd5b0c4d