account
account.audit.list
Read an account's audit trail (its keys, members, invites, apps and clients), newest first; the filters, limit and cursor of audit.list.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | Minimum 1. |
order | query | "asc" | "desc" | No | asc lists oldest first; desc (the default) newest first. |
since | query | integer (0 or more) | No | only entries at or after this Unix time, in seconds. |
limit | query | integer (0 or more) | No | the most items per page (positive); absent returns every item. |
cursor | query | string | No | resume after the previous page: its next_cursor. |
until | query | integer (0 or more) | No | only entries at or before this Unix time, in seconds. |
action | query | string | No | only records of this action, such as function.deploy, secret.set, key.revoke or promote. |
actor_kind | query | string | No | only records made by this kind of actor (system_key, tenant_key, account_key, user, agent_token, agent_session, client_ipv4, client_ipv6, server); give actor with it. |
actor | query | string | No | only records made by this actor: a key id (16 hex digits), a user id, an agent session id or an address; give actor_kind with it. |
target_kind | query | string | No | only records that changed this kind of thing (function, secret, setting, key, token, hostname, collection, index, config, tenant, account, user, ...); give target with it. |
target | query | string | No | only records that changed this one thing, by its name (a function name, a setting key) or key id; give target_kind with it. |
outcome | query | string | No | only change records that ended this way: applied, refused, failed, interrupted or pending. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
records | array of object | When set | |
count | integer | When set | |
next_cursor | string or null | When set | pass it as cursor for the next page; null on the last. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_accounts/$ID/audit" \
-H "Authorization: Bearer $SUBSTRIO_ACCOUNT_KEY"
audit
audit.export
Stream the app's audit trail, oldest first, as one JSON object per line (application/x-ndjson): every record of audit.list plus its chained (whether it carries a digest) and digest (hex, when chained) fields, and a final {chain_head_seq, chain_head_digest} line on the last page. Filters: since and until (Unix seconds); limit (default 1000) and cursor (the X-Substrio-Next-Cursor response header) page it; a page keeps the chain order, so a customer can verify a kept export later without substrio.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
since | query | integer (0 or more) | No | only entries at or after this Unix time, in seconds. |
limit | query | integer (0 or more) | No | the most items per page (positive); absent returns every item. |
cursor | query | string | No | resume after the previous page: its next_cursor. |
until | query | integer (0 or more) | No | only entries at or before this Unix time, in seconds. |
since | query | integer | No | Unix seconds, at or after. Minimum 0. |
until | query | integer | No | Unix seconds, at or before. Minimum 0. |
limit | query | integer | No | the most records per page (default 1000). Minimum 1. |
cursor | query | string | No | the previous page's X-Substrio-Next-Cursor header; absent for the first page. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_audit/export" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
audit.get
Read one audit record of the app's trail by its seq (the number audit.list shows for it).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
seq | path | integer | Yes | Minimum 1. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
seq | integer | When set | orders the whole trail; never reused. |
time | integer | When set | Unix milliseconds. |
action | string | When set | |
operation | string | When set | the registry operation that made the change. |
scope | "tenant" | "account" | "platform" | When set | |
actor | object | When set | |
target | object | When set | |
before | string | When set | fingerprint of the state before, hex; absent when unknown. |
after | string | When set | fingerprint of the state after, hex; absent when unknown. |
outcome | "applied" | "refused" | "failed" | "interrupted" | "pending" | When set | |
status | integer | When set | the HTTP status the change answered. |
error | integer | When set | the substrio error code, 0 when none. |
client | string | When set | the caller's address when known. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_audit/$SEQ" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
audit.list
Read the app's audit trail, newest first: every deploy, promote, rollback, secret, key, token, setting, rule, collection, index and domain change, and every agent request, each with its actor, target, before and after fingerprints and outcome (applied, refused, failed, interrupted, or pending while it runs). Filters: action, actor_kind with actor, target_kind with target, outcome, since and until (Unix seconds), order; limit and cursor page it. Answers records, count and next_cursor. A record is never removed or changed; a change has its record before it runs.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
order | query | "asc" | "desc" | No | asc lists oldest first; desc (the default) newest first. |
since | query | integer (0 or more) | No | only entries at or after this Unix time, in seconds. |
limit | query | integer (0 or more) | No | the most items per page (positive); absent returns every item. |
cursor | query | string | No | resume after the previous page: its next_cursor. |
until | query | integer (0 or more) | No | only entries at or before this Unix time, in seconds. |
action | query | string | No | only records of this action, such as function.deploy, secret.set, key.revoke or promote. |
actor_kind | query | string | No | only records made by this kind of actor (system_key, tenant_key, account_key, user, agent_token, agent_session, client_ipv4, client_ipv6, server); give actor with it. |
actor | query | string | No | only records made by this actor: a key id (16 hex digits), a user id, an agent session id or an address; give actor_kind with it. |
target_kind | query | string | No | only records that changed this kind of thing (function, secret, setting, key, token, hostname, collection, index, config, tenant, account, user, ...); give target with it. |
target | query | string | No | only records that changed this one thing, by its name (a function name, a setting key) or key id; give target_kind with it. |
outcome | query | string | No | only change records that ended this way: applied, refused, failed, interrupted or pending. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
records | array of object | When set | |
count | integer | When set | |
next_cursor | string or null | When set | pass it as cursor for the next page; null on the last. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_audit" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
audit.verify
Walk the app's audit trail over [from, to] (default: the whole trail) and answer whether every record's digest chains from the one before it to the chain head: intact, or the first seq where it breaks and how (digest_mismatch, gap, or head_mismatch). Reads each record once, in order; records_read is the rows it touched.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
from | query | integer (0 or more) | No | the first seq to verify (default 1). |
to | query | integer (0 or more) | No | the last seq to verify (default the newest written). |
from | query | integer | No | the first seq to verify; default 1. Minimum 1. |
to | query | integer | No | the last seq to verify; default the newest written. Minimum 1. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
status | "intact" | "digest_mismatch" | "gap" | "head_mismatch" | Always | |
at | integer or null | Always | the first seq where it breaks; null when intact. |
records_read | integer | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_audit/verify" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
function
function.errors
Read the errors the app's functions threw, newest first: each has an id (also a cursor), function, revision (the function's newest revision when it threw), request_id, timestamp, error name, message and the stack as frames (function, file, line, column). Options: function, request_id, revision (only errors of one deploy), since and until (Unix seconds), limit and cursor. Answers errors, count and next_cursor. Check the revision against version.log with the function path: a deploy that fixed a bug stops adding errors under the new revision.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
since | query | integer (0 or more) | No | only entries at or after this Unix time, in seconds. |
function | query | string | No | only entries of this function (its id, tenant/name, or its name). |
limit | query | integer (0 or more) | No | the most items per page (positive); absent returns every item. |
cursor | query | string | No | resume after the previous page: its next_cursor. |
request_id | query | string | No | only entries of this function call (its request id). |
until | query | integer (0 or more) | No | only entries at or before this Unix time, in seconds. |
revision | query | integer (0 or more) | No | only errors thrown while this revision of the function was its newest (the deploy counter every entry carries, so this narrows a page to one deploy). |
Response
| Field | Type | Present | Description |
|---|---|---|---|
errors | array of object | Always | |
count | integer | Always | |
next_cursor | string or null | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_function_errors" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
function.logs
Read the app's function logs: options function (id, tenant/name or name), level, request_id (every line of one call), since and until (Unix seconds), limit, and cursor to continue after a next_cursor; wait_ms with a cursor long-polls for new lines (at most 30000 ms). Answers logs, count, next_cursor and latest_cursor. A line records no function revision, so to tell what a deploy changed use function.errors with its revision option, or version.log with the function path.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer (0 or more) | No | the most items to return. |
skip | query | integer (0 or more) | No | items to skip before the first one returned. |
since | query | integer (0 or more) | No | only entries at or after this Unix time, in seconds. |
q | query | string | No | the text to find: in the function source (function.source.search, required), or the words every returned log line's message holds (function.logs). |
level | query | string | No | only log entries of this level. |
function | query | string | No | only entries of this function (its id, tenant/name, or its name). |
cursor | query | string | No | resume after the previous page: its next_cursor. |
request_id | query | string | No | only entries of this function call (its request id). |
until | query | integer (0 or more) | No | only entries at or before this Unix time, in seconds. |
wait_ms | query | integer (0 or more) | No | function.logs long poll: with a cursor, and no matching line stored past it yet, wait up to this many milliseconds (at most 30000; more is refused) and answer with the first non-empty page, or empty at the deadline; an app holds at most 64 waits at once (the next is SERVER_BUSY). |
Response
| Field | Type | Present | Description |
|---|---|---|---|
logs | array of object | Always | |
count | integer | Always | |
has_more | boolean | When set | |
next_cursor | string | When set | present on a full page: pass it as cursor for the entries after it. |
latest_cursor | string | When set | the newest stored line when this was answered: tail from here with cursor and wait_ms; every line up to it was considered by this answer. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_logs" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
function.logs.clear
Purge the stored function log lines of the app; answers {success, purged}.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_logs" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
function.logs.stream
Tail function logs live over WebSocket: connect with ?function=, ?request_id=, ?level= (as function.logs) and ?cursor= (default: only new lines); the first frame is {type:connected,cursor}, then {type:logs,cursor,logs:[...]}; a slow socket gets {type:lagged,cursor} and continues from that cursor, or reconnect with it.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_logs/ws" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
log_alert
log_alert.create
Add a log alert that publishes the app event log.alert (scope: the alert's id) when its condition first holds in a window, once per window; the webhooks that take log.alert (webhook.create with event log.alert) store, sign, retry and dead-letter it: error_count (function errors reach threshold), error_rate (errors over calls reach rate_percent, with min_calls calls) or log_match (log lines whose message holds every word of match, optionally of one function and level, reach threshold). Windows are fixed slots of unix time of window_ms. Answers the alert with its id.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | body | string | No | a label shown in the notification. |
kind | body | "error_count" | "error_rate" | "log_match" | Yes | error_count: function errors in the window reach threshold; error_rate: errors / calls in the window reach rate_percent, with at least min_calls calls; log_match: log lines matching match (and function, level) in the window reach threshold. |
function | body | string | No | only this function (its name); empty: every function. |
level | body | string | No | log_match: only lines of this level. |
match | body | string | No | log_match: the words every counted line's message holds. |
window_ms | body | integer | No | the window length; windows are fixed slots of unix time (default 60000). Minimum 1. |
threshold | body | integer | No | error_count and log_match: the count that fires the alert (default 1). Minimum 1. |
rate_percent | body | number | No | error_rate: the error percentage that fires the alert. Maximum 100. |
min_calls | body | integer | No | error_rate: calls the window needs before the rate counts (default 1). Minimum 1. |
enabled | body | boolean | No | false pauses the alert (default true). |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_log_alerts" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"error_count"}'
log_alert.delete
Delete one log alert by its id (the route's {id}, as log_alert.list shows it).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | The log alert's id (16 hex digits), as log_alert.list returned it. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_log_alerts/$ID" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
log_alert.list
List the app's log alerts: each with its kind, filters, window, threshold, the window it last fired in, when, and how many webhooks took that notification.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_log_alerts" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
log_alert.update
Change one log alert by id: any of its settings; the window it last fired in is kept, so a change never notifies twice for one window.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | the alert's id (16 hex digits), as log_alert.list shows it. |
name | body | string | No | a label shown in the notification. |
kind | body | "error_count" | "error_rate" | "log_match" | No | error_count: function errors in the window reach threshold; error_rate: errors / calls in the window reach rate_percent, with at least min_calls calls; log_match: log lines matching match (and function, level) in the window reach threshold. |
function | body | string | No | only this function (its name); empty: every function. |
level | body | string | No | log_match: only lines of this level. |
match | body | string | No | log_match: the words every counted line's message holds. |
window_ms | body | integer | No | the window length; windows are fixed slots of unix time (default 60000). Minimum 1. |
threshold | body | integer | No | error_count and log_match: the count that fires the alert (default 1). Minimum 1. |
rate_percent | body | number | No | error_rate: the error percentage that fires the alert. Maximum 100. |
min_calls | body | integer | No | error_rate: calls the window needs before the rate counts (default 1). Minimum 1. |
enabled | body | boolean | No | false pauses the alert (default true). |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X PATCH "$SUBSTRIO_URL/v1/_log_alerts/$ID" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
log_drain
log_drain.create
Add a log drain: every log line and every function error is POSTed, as NDJSON in batches, in order and at least once (a line carries its log_seq, so a receiver can drop a repeat), signed like a webhook when a secret is set. Answers the drain with its id. start now (default) delivers lines stored from now on, start delivers everything stored.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
url | body | string | Yes | where the lines are POSTed: an http:// or https:// URL. |
secret | body | string | No | signs every delivery like a webhook's secret; empty: unsigned. |
headers | body | object | No | headers sent with every delivery. |
batch_lines | body | integer | No | lines per request, at most (default 500). Minimum 1. |
retry_ms | body | integer | No | wait after a failed delivery; doubles on each failure in a row (default 1000). Minimum 1. |
max_retry_ms | body | integer | No | the longest wait between attempts (default 60000). Minimum 1. |
enabled | body | boolean | No | false pauses the drain, which resumes from its cursor (default true). |
start | body | "now" | "start" | No | now (default): lines stored from now on; start: everything already stored too. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_log_drains" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"url"}'
log_drain.delete
Delete one log drain by its id (the route's {id}, as log_drain.list shows it); its undelivered lines are not delivered.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | The log drain's id (16 hex digits), as log_drain.list returned it. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_log_drains/$ID" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
log_drain.list
List the app's log drains: each with its url, settings, acked (the cursor of the last line its endpoint accepted), latest (the newest stored line's cursor), the failures in a row and the endpoint's last HTTP status. A drain whose endpoint is down shows acked behind latest and catches up in order when the endpoint answers.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_log_drains" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
log_drain.update
Change one log drain by id: any of url, secret, headers, batch_lines, retry_ms, max_retry_ms, enabled; its progress is kept. A disabled drain stops delivering and resumes from its cursor when enabled.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | the drain's id (16 hex digits), as log_drain.list shows it. |
url | body | string | No | where the lines are POSTed: an http:// or https:// URL. |
secret | body | string | No | signs every delivery like a webhook's secret; empty: unsigned. |
headers | body | object | No | headers sent with every delivery. |
batch_lines | body | integer | No | lines per request, at most (default 500). Minimum 1. |
retry_ms | body | integer | No | wait after a failed delivery; doubles on each failure in a row (default 1000). Minimum 1. |
max_retry_ms | body | integer | No | the longest wait between attempts (default 60000). Minimum 1. |
enabled | body | boolean | No | false pauses the drain, which resumes from its cursor (default true). |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X PATCH "$SUBSTRIO_URL/v1/_log_drains/$ID" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
meta
meta.gc
Inspect or reclaim the app database's deferred-free space. GET answers limbo_entries, allocated_bytes and file_size_bytes; POST drains the deferred frees into the allocator and answers {triggered: true}. It frees space for reuse and never deletes data, and the file does not shrink. Pick the method with http_method.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_meta/gc" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
observability
observability.metrics
Read process metrics.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
range | query | integer | No | seconds of history to report (default 3600, at most 604800). |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_metrics"
tenant
tenant.storage
Read what this app's folder holds on disk (disk_bytes, as of the last fold, each second) by kind (database, files, logs, backups, code, other), its storage limit and the room left (null while no limit is set). The storage limit is held against disk_bytes; tenant.usage's used_bytes and blob_bytes count only document and file bytes.
Parameters
No parameters.
Response
| Field | Type | Present | Description |
|---|---|---|---|
tenant_id | integer | Always | |
slug | string | Always | |
disk_bytes | integer | Always | what the app's folder holds on disk as of the last fold (each second): the figure the storage limit is held against. |
kinds | object | Always | disk_bytes by kind. |
limit_bytes | integer or null | Always | the app's storage limit; null while none is set. |
available_bytes | integer or null | Always | limit_bytes less disk_bytes, at least 0; null while no limit is set. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_storage" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
tenant.usage.history
Read this app's KPI history, oldest first: one point per finished minute (step=minute, the default; kept two days) or hour (step=hour; kept 90 days), each with what the app's function calls added in it (calls, status classes, latency buckets and percentiles, refusals, CPU and wall time) and its stored documents and bytes at its end. since and until are Unix seconds (default: the last hour of minutes, or the last two days of hours); limit caps the points. Counted on the node that answers.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer (0 or more) | No | the most items to return. |
since | query | integer (0 or more) | No | only entries at or after this Unix time, in seconds. |
until | query | integer (0 or more) | No | only entries at or before this Unix time, in seconds. |
step | query | "minute" | "hour" | No | minute (the default) or hour: one point per minute, or per hour. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
step | "minute" | "hour" | When set | |
since | integer | When set | Unix seconds, the start of the range asked. |
until | integer | When set | Unix seconds, the end of the range asked. |
points | array of object | When set | oldest first; a minute or hour with no point had no counter written (the database was closed). |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_usage/history" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
tenant.usage.self
Read this tenant's own exact usage and limits: storage bytes, documents, requests per minute (a limit is null until one is set) and the function limits (cpu, memory, concurrency, timeout, body and value sizes), for the tenant the key belongs to.
Parameters
No parameters.
Response
| Field | Type | Present | Description |
|---|---|---|---|
tenant_id | integer | Always | |
slug | string | Always | |
storage | object | Always | |
documents | object | Always | |
requests | object | Always | |
functions | object | Always | |
calls | object | Always | what the tenant's function calls used since the server counted them (in memory: a restart starts the window again). |
limits_explicit | boolean | Always | true once a storage, document or request limit was set; only then are they enforced. |
active | boolean | Always | |
mcp_tools | object | When set | tools/call runs of each of the app's own MCP tools on its /mcp, by tool name, kept in the app's database (APP-MCP). |
this_month | object | Always | the app's function calls, API requests and their 5xx this month (UTC, the plan's metering month): durable totals kept in the app's record, reset when the month turns. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_usage" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
webhook
webhook.logs
Read the delivery log of one webhook route by id: options limit.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string or integer | Yes | The webhook's id, as webhook.list returned it. |
limit | query | integer (0 or more) | No | the most items to return. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_webhooks/$ID/logs" \
-H "Authorization: Bearer $SUBSTRIO_KEY"