app
app.archive
Download the app as one .substrio.zip, its backup and its portable export: every collection as NDJSON (data/<collection>.ndjson), its users (users.ndjson), versions, config and site files, and manifest.json with each entry's SHA-256. Optional body passphrase seals secret values, password hashes, TOTP enrolments and passkeys into sealed.bin; without it they are left out. Optional backup_id archives that backup instead. app.restore or app.import reads it back on any server version.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
passphrase | body | string | No | Seals secret values, users' password hashes, TOTP enrolments and passkeys into sealed.bin (Argon2id, AES-256-GCM), so a restore with the same passphrase keeps sign-ins and secrets; without it they are left out. |
backup_id | body | string | No | Archive this backup (an id from backup.list) instead of the app as it is now. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_archive/download" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
app.export
Stream the app as one bundle (versions, blobs, live stack, views, AI config, database, secrets), sealed whole to seal_to, for that server's POST /v1/_import.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
seal_to | query | string | No | the importing server's seal key (GET /v1/_seal-key); required. |
seal_to | query | string | Yes | The importing server's seal key (GET /v1/_seal-key there); the whole bundle is sealed to it, so only that server can read it. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_export" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
app.restore
Restore a .substrio.zip (the request body, as app.archive made it) into this app through the normal write paths: users, data, versions, site files, config, and with the X-Substrio-Passphrase header the sealed secrets and sign-ins. Every entry is checked against manifest.json before anything is written. An app that holds data is refused unless replace=true. Answers the counts restored and what was left out.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
replace | query | boolean | No | true replaces an existing app of that slug (app.restore: the caller's own app) that holds data. |
replace | body | boolean | No | Replace what the app holds; without it an app that holds data is refused. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_archive" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
app.seal_key.get
Read the X25519 public key bundles this server imports are sealed to (seal_to of an export).
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_seal-key"
backup
backup.clone_into
Replace another tenant's database (body target_slug) with a backup of this app (the route's {id} from backup.list), then catch it up with this app's history from the backup's point to now, so it ends up current, not frozen at the backup. Everything target_slug held is lost; it must be a different tenant. Answers {status:'cloned', backup_id, target_slug, history_position, history_through, history_applied}.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | |
target_slug | body | string | Yes | The slug of another tenant to clone this backup into, caught up to this app's current history (its own database is replaced). |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_backups/$ID/clone_into" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"target_slug":"target_slug"}'
backup.create
Start a backup of the app's database as a background job: optional body description. Answers 202 {job_id, status:'running'} at once; backup.get with that job id shows the progress and, when it completes, the backup id that backup.restore takes.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
description | body | string | No | A note kept with the backup. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_backups" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
backup.delete
Delete one backup by its id (the route's {id}, as backup.list shows it).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string or integer | Yes | The backup's id, as backup.list or backup.create 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/_backups/$ID" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
backup.get
Read one backup or backup job by id: the job_id backup.create answered (its status and progress) or a backup id from backup.list (its details); 404 when neither exists.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string or integer | Yes | The backup's id, as backup.list or backup.create returned it. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_backups/$ID" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
backup.list
List the app's backups, oldest first, a page at a time (limit, cursor; next_cursor): their ids are what backup.restore, backup.get and backup.delete take.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
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. |
limit | query | integer | No | Rows a page: 100 by default, capped at 1000. Minimum 1. |
cursor | query | string | No | The next_cursor of the page before: the walk resumes past it. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_backups" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
backup.restore
Replace the app's database with a backup: the route's {id} from backup.list. Everything written since the backup is lost, so take a backup first (backup.create). Answers {status:'restored', backup_id}. To go back to a promote's state together with its version use version.restore.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_backups/$ID/restore" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
system
system.reset
Drop the app's whole database and start a fresh empty one: every collection, SQL table, row, index and the change history are destroyed and this cannot be undone. Functions, versions, secrets and settings are kept. Answers {status: reset, file_size_bytes}; take a backup first.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_reset" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
version
version.restore
Restore the app's data from the backup a promote took (the latest when none is named) and make live again the version that was live then.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
backup_id | body | string | No | A backup a promote took; the latest when omitted. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_restore" \
-H "Authorization: Bearer $SUBSTRIO_KEY"