StabisoDocs

API reference

Audit

The audit trail, the hash chain verification and the archive export for auditors.

Operation Summary Scope Idempotency-Key
GET /v1/access-log List what external auditors opened admin
GET /v1/audit-events Audit Events read
GET /v1/entities/{entity}/chain-verification Chain Verification read

GET /v1/access-log

List what external auditors opened

Every request of the organization's external auditors, newest first: when, who, what they opened (method, path and query: a screen's data, a report, a downloaded file) and the answer's status (403 for what was refused them). An external auditor is a person invited with an end to their access (access_until) or with the rights to read and to audit only (the auditor role). The log is append-only; nobody can change or delete it. Only a person with the admin scope reads it (403 otherwise).

Required scope admin (admin implies every scope)
Operation id access_log_v1_access_log_get

Parameters

In Name Type Required Description
query user_id string (uuid) or null Only the requests of this auditor (a user id from GET /v1/users).
query limit integer Most entries returned, 1 to 1000. (min 1; max 1000; default 100)
query before integer or null Continue before this entry (its id, the last of the previous page); omit for the newest.

Example request

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

Responses

Status Meaning Body
200 OK array of AccessLogEntry
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": 1,
    "at": "2026-09-21T09:30:00Z",
    "user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "email": "string",
    "via": "string",
    "method": "string",
    "path": "string",
    "query": "string",
    "status": 1,
    "address": "string",
    "request_id": "string"
  }
]

GET /v1/audit-events

Audit Events

The audit trail, newest first: who (actor) did what (action, e.g. journal.post) to which object, with the request id and idempotency key of the call and event-specific data. Events are append-only and cannot be changed. Narrow it with object_type and object_id.

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

Parameters

In Name Type Required Description
query object_type string or null Only events about this kind of object, e.g. journal_entry, entity, account, period, api_key, app_user, organization.
query object_id string or null Only events about the object with this id (as text, usually a uuid).
query limit integer How many events to return, newest first; at most 1000. (max 1000; default 100)

Example request

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

Responses

Status Meaning Body
200 OK array of AuditEventOut
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": 1,
    "at": "2026-09-21T09:30:00Z",
    "actor": {},
    "action": "string",
    "object_type": "string",
    "object_id": "string",
    "request_id": "string",
    "idempotency_key": "string",
    "data": {}
  }
]

GET /v1/entities/{entity}/chain-verification

Chain Verification

Recompute the hash chain of all posted entries of the entity to detect tampering. Every posted entry holds a hash of its content and of its predecessor. The answer is valid with the number of entries, or not valid with the number of the first entry that breaks the chain (first_invalid) and why (reason: a gap in the sequence, a wrong previous hash, or changed content).

Required scope read (admin implies every scope)
Operation id chain_verification_v1_entities__entity__chain_verification_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/chain-verification" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ChainCheck
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",
  "entries": 1,
  "valid": true,
  "first_invalid": "string",
  "reason": "string",
  "hash_versions": {}
}

Schemas

AccessLogEntry

One request an external auditor made.

Field Type Required Description
id integer yes Sequence number of the entry; increases with time.
at string (date-time) yes When the request was made (ISO 8601, UTC).
user_id string (uuid) or null yes The auditor's user id.
email string yes The auditor's sign-in address.
via string or null yes The app the auditor connected over MCP that made the request (e.g. Claude (connected app)); null for the auditor's own session.
method string yes GET for a read or a download, MCP for a tool their app called; any other method asked to change something.
path string yes What was opened, e.g. /v1/entities/CH01/trial-balance, or the tool's name, e.g. trial_balance.
query string or null yes The query string of the request, or the tool's arguments as JSON; null for none.
status integer or null yes The answer's HTTP status: 2xx served, 403 refused (for example a change an auditor may not make).
address string or null yes The client address the request came from.
request_id string or null yes The request's id, as in the audit trail.

ChainCheck

Field Type Required Description
entity string yes Code of the entity that was checked.
entries integer yes Number of posted entries in the chain.
valid boolean yes True when every entry's sequence number, previous hash and content hash check out.
first_invalid string or null Number of the first entry that breaks the chain; null when valid.
reason string or null gap in chain sequence, previous hash mismatch or content hash mismatch; null when valid.
hash_versions map of integer Entries verified per hash version (1: content; 2: every column).
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 6f03a5e846b3