app
app.deploy
Ship files in one call: commit the units and removals (as version.commit takes them), check the version's functions (unless check is false), make it live where to names (live, or a sandbox), test it there with app.test (unless test is false), and, with promote and a sandbox in to, make it live on the app once the test is green. Stops at the first step that fails: a refused commit, check or live answers that step's own error with stage; a failed test answers ok false, stage test and the test's failures with their fixes, and promotes nothing. Answers ok, stage, deployed {commit, live}, test and promote, each the answer of that step's own tool. Over HTTP it runs the commit, the check and live; test and promote run in the MCP tool.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
message | body | string | Yes | What this commit did. |
units | body | array of object | No | The units this commit writes, as version.commit takes them. |
removals | body | array of string | No | The paths this commit removes. |
branch | body | string | No | The branch to commit on (default: main). |
mode | body | "changes" | "snapshot" | No | changes applies units and removals to the parent version (default); snapshot makes the units the whole content. |
expected | body | string | No | The version the branch must still point at (64 hex, or an empty string for a branch with no version yet). 409 when it moved: nothing is written. |
checks_green | body | boolean | No | true says the branch's required checks are green, which a protected branch needs. |
to | body | string | Yes | Where the version goes live: live for the app, or a sandbox name from sandbox.list. |
check | body | boolean | No | false skips function.check over the version's functions before it goes live. Default true. |
test | body | boolean | No | true runs app.test on where the version went live, with its defaults; a failure stops the deploy there. Default true. |
promote | body | boolean | No | With a sandbox in to: once the test is green, make what the sandbox runs live on the app (live.set from the sandbox). Default false. |
backup | body | boolean | No | false skips the data backup a version going live on the app takes first. Default true. |
direct | body | "refuse" | "replace" | "keep" | No | As live.set: what to do with a function deployed outside a version that this would overwrite. Default "refuse". |
Response
| Field | Type | Present | Description |
|---|---|---|---|
ok | boolean | Always | true when every step asked for passed. |
stage | "done" | "test" | "promote" | Always | done, or the step that stopped the deploy (a refused commit, check or live answers its own error, stage commit, check or live). |
deployed | object | Always | |
test | object or null | Always | app.test's answer; null when test was false. |
promote | object or null | Always | live.set's answer on the app (its url the app's address); null when promote was not asked or the test failed. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_app/deploy" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"message":"message","to":"to"}'
app.diagnose
What is wrong with the app (or a sandbox) and how to fix it, in one call: which version each environment runs against main's head, function.check over the version that runs where the call looks (its diagnostics), its newest function errors, and app.test of its website and GET routes, each finding with its fix. Answers ok, sandbox, live {main, environments}, check, errors {recent, fix}, test and fixes, every fix in order. Read only; the MCP server runs it.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
sandbox | body | string | No | A sandbox name from sandbox.list: look at what it runs instead of the app. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
ok | boolean | Always | something is live where the call looks, its functions pass function.check and app.test passed. |
sandbox | string or null | Always | |
live | object | Always | |
check | object | Always | |
errors | object | Always | |
test | object or null | Always | app.test's answer; null when nothing runs there. |
fixes | array of string | Always | every finding's fix, in order; empty when ok. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_app/diagnose" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
app.scaffold
Start an app from a template compiled into the release: commits the app's first version on main, one snapshot of the template's units, each of which passes app.test. site is a page with its stylesheet and script; site-api adds a function route (GET /api/hello) the page calls; site-data-auth is a notes page anyone reads and a signed-in person adds to (GET /api/notes, POST /api/notes auth, GET /api/me auth). Refused with 409 when main already holds a version: change an app that has one with version.commit or app.deploy. Answers version.commit's answer and template; make it live with live.set (with sandbox to try it first).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
template | body | "site" | "site-api" | "site-data-auth" | Yes | site: a page, its stylesheet and script; site-api: that and a function route, GET /api/hello, the page calls; site-data-auth: a notes page anyone reads, a signed-in person adds to (GET /api/notes, POST /api/notes auth, GET /api/me auth). |
message | body | string | No | The commit's message (default: app.scaffold: and the template). |
Response
| Field | Type | Present | Description |
|---|---|---|---|
branch | string | Always | |
version | string | Always | the version's id (64 hex). |
root | string | When set | |
number | integer | Always | the version number, promotable at once with live.set (with sandbox to run it there first). |
generation | integer | When set | |
blobs_written | integer | When set | |
trees_written | integer | When set | |
template | "site" | "site-api" | "site-data-auth" | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_app/scaffold" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"template":"site"}'
app.test
Test the app's website (or a sandbox's) as a browser loads it, in one call: each page of paths (default /) and every same-site page it links, every stylesheet, script, image, icon and CSS url() or @import they name, and every GET function route with no parameter, each fetched in process as route.call does, as a visitor with no credentials. Each is checked for its status, its content type (a stylesheet must be text/css, a script JavaScript, an image image/*, never the site's page in their place) and its size. Answers ok, the table of every resource (path, kind, from, status, type, bytes, ok) and each failure with its problem and its fix. References to another origin are counted, never fetched.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
sandbox | body | string | No | A sandbox name from sandbox.list: test what it runs instead of the app. |
paths | body | array of string | No | The pages to start from (default ["/"]); every same-site <a href> page they link is tested too, up to max_pages. |
routes | body | boolean | No | true also calls every GET function route that has no parameter, as a visitor with no credentials, and fails one answering 500 or above. Default true. |
max_pages | body | integer | No | Pages fetched at most, paths and links together. Minimum 1. Maximum 1000. Default 20. |
max_fetches | body | integer | No | Requests made at most; a run that stops there answers truncated: true. Minimum 1. Maximum 5000. Default 200. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
ok | boolean | Always | true when no resource failed. |
sandbox | string or null | Always | |
pages | integer | Always | |
checked | integer | Always | requests made. |
failed | integer | Always | |
external | integer | Always | references to another origin, not fetched. |
skipped_routes | integer | Always | function routes with a parameter, a * or a method other than GET, not called. |
truncated | boolean | Always | max_pages or max_fetches stopped the run. |
resources | array of object | Always | |
failures | array of object | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_app/test" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
env
env.host.list
List the app's hosts, each with its environment and the version it runs, and the enabled root domains a host may be bound under.
Parameters
No parameters.
Response
| Field | Type | Present | Description |
|---|---|---|---|
hosts | array of object | Always | |
roots | array of string | Always | the enabled root domains a host may be bound under. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_env_hosts" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
env.host.remove
Remove one of the app's hosts: it answers nothing from then on and its label is free. ENV_HOST_NOT_FOUND when the app holds no such host. Answers 204.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
host | path | string | Yes | A host env.host.list names. |
Response
204 No Content: success has no body.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_env_hosts/$HOST" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
env.host.set
Bind a host of the app's choosing, <label>.<root> under an enabled root domain (my-app-v2.substrio.com), to one of its environments: live, or a sandbox (with version, a new sandbox running that version). The host answers exactly what that environment runs, with its data. A label has one owner across the platform: HOST_TAKEN when another app holds it, HOST_RESERVED for a reserved name or an app host, HOST_INVALID (with suggestion) for a label that is not a hostname label, ROOT_DOMAIN_UNKNOWN or ROOT_DOMAIN_DISABLED for the root. Binding a host the app holds again moves it. version.live.set with from: <host> pushes what it runs live.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
host | body | string | Yes | <label>.<root>: one DNS label (lowercase letters, digits, inner hyphens, 1 to 63) under a root domain env.host.list names, such as my-app-v2.substrio.com. |
environment | body | string | Yes | live (the app itself), or a sandbox name from sandbox.list; with version, a sandbox that does not exist yet is made and runs that version. |
version | body | integer | No | A version number from version.list to run in the environment (a sandbox) before the host is bound; absent: the environment runs what it runs. Minimum 1. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
host | string | Always | |
label | string | Always | |
root | string | Always | |
environment | string | Always | live or the sandbox's name. |
version | integer | Always | the version the environment runs now; 0: none. |
created_at | integer | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_env_hosts" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"host":"host","environment":"environment"}'
route
route.call
Send one HTTP request to a route of the app or of one of its sandboxes and return the response.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
method | body | string | Yes | GET, POST, PUT, PATCH, DELETE, ... |
path | body | string | Yes | The route's path; a ?query here is kept. Matches ^/. |
query | body | string | No | a=1&b=2, added to any query in path. |
headers | body | object | No | |
body | body | string | No | The request body as text (send JSON as its text). |
body_base64 | body | string | No | The request body as base64, instead of body. |
sandbox | body | string | No | Call this sandbox of the app (for example dev) instead of the app; its outbound fence applies. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_route" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"method":"method","path":"path"}'
route.list
List the HTTP routes the deployed functions answer: method, pattern, function and version; routes are declared in each function's manifest at deploy, there is no separate edit.
Parameters
No parameters.
Response
| Field | Type | Present | Description |
|---|---|---|---|
routes | array of object | Always | |
count | integer | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_routes" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox
sandbox.allow.add
Let a sandbox send outbound requests to hosts matching a pattern.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes | |
pattern | body | 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/_sandboxes/$NAME/allow" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"pattern":"pattern"}'
sandbox.allow.list
List the host patterns a sandbox may send outbound requests to.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_sandboxes/$NAME/allow" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.allow.remove
Stop letting a sandbox send outbound requests to hosts matching a pattern.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes | |
pattern | path | string | Yes |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_sandboxes/$NAME/allow/$PATTERN" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.create
Create a sandbox: a copy of the app's data running the app's live version.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | body | string | No | |
outbound | body | "live" | "fenced" | No | live: a dev environment, its requests go out as the app's do (it has its own secrets); fenced (the default): kept in its outbox. |
Response
A JSON object.
Errors
TENANT_ALREADY_EXISTS: callsandbox.resetto find the right one.
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_sandboxes" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.delete
Delete one sandbox by name together with its data; the app itself is not touched. To keep the sandbox and only copy the app's data into it again, use sandbox.reset.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_sandboxes/$NAME" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.list
List the app's sandboxes, their hosts and live versions.
Parameters
No parameters.
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_sandboxes" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.outbox
Read the outbound requests a sandbox's fence captured instead of sending.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_sandboxes/$NAME/outbox" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.reset
Copy the app's data into a sandbox again, keeping its live version.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | 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/_sandboxes/$NAME/reset" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.stub.clear
Forget a test tenant's stubs and the recorded fetches; answers how many of each.
Parameters
No parameters.
Response
| Field | Type | Present | Description |
|---|---|---|---|
cleared_stubs | integer | Always | |
cleared_calls | integer | Always |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X DELETE "$SUBSTRIO_URL/v1/_stubs" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.stub.list
Read a test tenant's stubs, with how often each answered, and every fetch its functions made since the last clear (method, URL, headers, body, the tenant's clock, stubbed or unmatched).
Parameters
No parameters.
Response
| Field | Type | Present | Description |
|---|---|---|---|
stubs | array of object | Always | |
calls | array of object | Always | Every fetch the tenant's functions made since the last clear, oldest first, stubbed or not. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_stubs" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
sandbox.stub.set
Stub one outbound request of a test tenant: its functions' fetch() of the given method, origin and path resolves with the stub's status, headers and body instead of going out. Only a test tenant takes stubs, any other is refused with TEST_TENANT_REQUIRED. The newest matching stub that is not spent answers; a fetch no stub matches is rejected. Answers {id}.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
method | body | "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD" | No | The request method this stub answers; absent: any method. |
url | body | string | Yes | The http or https URL a function's fetch() calls, without a query: the scheme, host, port and path are the stub's key. |
path_match | body | "exact" | "prefix" | No | prefix: the path and everything below it, on whole segments. Default "exact". |
status | body | integer | No | The status the fetch resolves with. Minimum 100. Maximum 599. Default 200. |
headers | body | object | No | The response headers. |
body | body | string | No | The response body. Default "". |
times | body | integer | No | How many answers the stub gives before it is spent; 0: no limit. Minimum 0. Default 0. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
id | integer | Always | The stub's id, as sandbox.stub.list names it. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_stubs" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"url"}'
tenant
tenant.clock.set
Set a test tenant's clock: Date.now() and new Date() in its functions read it. real, frozen at an instant, or real time plus an offset; setTimeout and cron stay on real time. Only a test tenant has a clock, any other is refused with TEST_TENANT_REQUIRED. Answers the setting and the clock's reading.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
mode | body | "real" | "frozen" | "offset" | Yes | real: the clock runs on real time; frozen: Date.now() is the instant at, whatever the real time; offset: real time plus offset_ms. |
at | body | integer | No | frozen only: the instant, in Unix milliseconds. |
offset_ms | body | integer | No | offset only: milliseconds added to real time (negative: earlier). |
Response
| Field | Type | Present | Description |
|---|---|---|---|
mode | "real" | "frozen" | "offset" | Always | |
at | integer or null | Always | |
offset_ms | integer or null | Always | |
now_ms | integer | Always | The clock's reading when this answer was made, in Unix milliseconds. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_clock" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"mode":"real"}'
version
version.check
Check an app version before it is pushed or made live: the body is the version.create body, or {version} naming one already committed (a number, an id, a branch, live or a sandbox's name; no manifest). Runs function.check over every function whose source is uploaded (parsed as script, CommonJS or ES module, with deploy's require() refusal) and answers ok, diagnostics (function, severity, message, line, column) and the blobs still missing. Nothing is stored or run. version.create and version.live.set run this same check unless they are sent check:false.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
functions | body | array of object | No | Every function of the app. A function not listed here is not part of the version. |
rules | body | object or null | No | The security rules document (the body security.rules.set takes), by hash. |
mcp | body | object or null | No | The app's MCP tool manifest (the body mcp.tools.set takes), by hash. |
site | body | object or null | No | The static site: its files by path. |
cron | body | array of object | No | Schedules made when the version goes live. |
queues | body | array of object | No | Durable queues made when the version goes live (a send to a queue not listed is refused). Messages of a queue the version drops stay stored. |
triggers | body | array of object | No | Collection triggers made when the version goes live. |
plans | body | object or null | No | The plans file POST /v1/_plans takes, set on the target when the version goes live; absent leaves its plans as they are. |
auth | body | object or null | No | The auth settings PUT /v1/_auth/settings takes, over the defaults, set on the target when the version goes live; absent leaves them as they are. |
login | body | object or null | No | The login settings PUT /v1/_auth/login takes, set on the target when the version goes live; absent leaves them as they are. |
permissions | body | object or null | No | The permission catalog permissions.set takes ([permissions]: names, all, implies), declared on the target first when the version goes live, append only; absent leaves it as it is. |
ledger | body | object or null | No | The ledger catalog ledger.catalog.set takes ([ledger]: kinds, categories), declared on the target first when the version goes live, append only; absent leaves it as it is. |
collections | body | array or null | No | The declared collections, as the calls substrio deploy makes, run in order on the target when the version goes live, before any part switches: a collection that exists is kept, an index already declared the same way changes nothing; absent leaves them as they are. |
version | body | any | No | Instead of a manifest: the committed version to check, a number from version.list, an id (64 hex digits), a branch, live or a sandbox's name. The answer then names its number in version. |
message | body | string | No | Ignored; kept so a version.create body can be sent as it is. |
Response
| Field | Type | Present | Description |
|---|---|---|---|
ok | boolean | Always | true when no diagnostic has severity error. |
diagnostics | array of object | Always | |
missing | array of string | Always | hashes of blobs (any part of the version) not uploaded yet. |
version | integer | When set | the number of the committed version checked, when the call named one. |
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_versions/_check" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
version.create
Push an app version: the functions (each by the SHA-256 of its source), rules, MCP manifest, site files, cron, triggers, plans, auth and login settings, and the permission and ledger catalogs (declared first when it goes live, append only). Answers 201 {version, missing, existed}: missing lists the blobs you still have to upload with site.blob.upload, and existed is true when the same content was pushed before. Pushing does not change what is live: make it live with version.live.set. The version is committed on the branch named by branch (main when none is), which is created at this version when it has no version yet. Sources already uploaded are checked like function.check unless check is false; a failing one refuses the push with 400 and its diagnostics.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
functions | body | array of object | Yes | Every function of the app. A function not listed here is not part of the version. |
rules | body | object or null | No | The security rules document (the body security.rules.set takes), by hash. |
mcp | body | object or null | No | The app's MCP tool manifest (the body mcp.tools.set takes), by hash. |
site | body | object or null | No | The static site: its files by path. |
cron | body | array of object | No | Schedules made when the version goes live. |
queues | body | array of object | No | Durable queues made when the version goes live (a send to a queue not listed is refused). Messages of a queue the version drops stay stored. |
triggers | body | array of object | No | Collection triggers made when the version goes live. |
plans | body | object or null | No | The plans file POST /v1/_plans takes, set on the target when the version goes live; absent leaves its plans as they are. |
auth | body | object or null | No | The auth settings PUT /v1/_auth/settings takes, over the defaults, set on the target when the version goes live; absent leaves them as they are. |
login | body | object or null | No | The login settings PUT /v1/_auth/login takes, set on the target when the version goes live; absent leaves them as they are. |
permissions | body | object or null | No | The permission catalog permissions.set takes ([permissions]: names, all, implies), declared on the target first when the version goes live, append only; absent leaves it as it is. |
ledger | body | object or null | No | The ledger catalog ledger.catalog.set takes ([ledger]: kinds, categories), declared on the target first when the version goes live, append only; absent leaves it as it is. |
collections | body | array or null | No | The declared collections, as the calls substrio deploy makes, run in order on the target when the version goes live, before any part switches: a collection that exists is kept, an index already declared the same way changes nothing; absent leaves them as they are. |
message | body | string | No | A note kept with the version (version.list shows it). |
check | body | boolean | No | true (the default) runs function.check over every function whose source is already uploaded and refuses the push, with the diagnostics, when one has an error; sources not uploaded yet are checked by version.live.set, which refuses the same way. false skips the check. Default true. |
branch | body | string | No | The branch of the app's history this version is committed on (branch.list names them); the branch is created, pointing at this version, when it has no version yet. Absent: main, where every push lands. Default "main". |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_versions" \
-H "Authorization: Bearer $SUBSTRIO_KEY" \
-H "Content-Type: application/json" \
-d '{"functions":[]}'
version.diff
Show what changes between two app versions (the route's {from} and {to}): the parts added, removed and changed; 404 when either does not exist.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
from | path | integer | Yes | Minimum 1. |
to | path | integer | Yes | Minimum 1. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_versions/$FROM/diff/$TO" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
version.get
Read one app version by number (the route's {number}): its functions, rules, MCP manifest, site, cron, triggers and message, and in missing the blobs it still lacks. 404 when no such version.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
number | path | integer | Yes | Minimum 1. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_versions/$NUMBER" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
version.list
List the app's versions, newest first, with the live version number (live), the version a rollback would restore (rollback_to), the live history with the backup each promote took, and each sandbox's live version. direct_changes lists, for the app and each sandbox, any function deployed directly (outside a version) since its live version was recorded. limit pages the versions and next_cursor (null on the last page) is the cursor the next page passes.
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. |
Response
A JSON object.
Errors
A failed call answers the error envelope with a typed code.
Example
curl "$SUBSTRIO_URL/v1/_versions" \
-H "Authorization: Bearer $SUBSTRIO_KEY"
version.live.set
Make an app version live, or roll back with version: previous; from instead of version promotes what a sandbox or a test host runs. Before anything changes it backs the app's data up (unless backup is false) and, unless check is false or this is a rollback, runs function.check over the version's functions and refuses with 400 and the diagnostics when one has an error. A version with a blob not uploaded cannot go live (upload what version.get lists in missing). When a function was deployed directly since the version now live was recorded and this would overwrite or delete it, direct controls what happens: refuse (the default) answers 409 DIRECT_CHANGES with direct_changes instead; replace applies the version anyway (reporting replaced); keep applies it except those functions, left as deployed (reporting kept). With sandbox it acts on that sandbox instead. With plan true it answers the plan of the change (each collection's shape change, the retypes and the documents they would read) and applies nothing. Answers live, previous, rollback_to, sandbox and backup_id, and direct_changes, replaced or kept when relevant.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version | body | any | No | A version number from version.list, or previous to roll back to the version live before this one (a rollback is never checked). |
from | body | string | No | Instead of version: the environment whose running version goes live, a sandbox name from sandbox.list or a host from env.host.list (my-app-v2.substrio.com); an unknown one, or one running no version, is ENVIRONMENT_NOT_FOUND. |
sandbox | body | string | No | A sandbox name from sandbox.list: make the version live there instead of on the app. |
backup | body | boolean | No | false skips the data backup an app promote takes first (version.restore needs it). Default true. |
check | body | boolean | No | true (the default) runs function.check over every function of the version before anything changes, and refuses with the diagnostics when one has an error; false skips the check. Not applied to a rollback. Default true. |
plan | body | boolean | No | true answers what this change would do to each collection's declared shape and what it would cost, and applies nothing: no check, no backup, no write, and the version now live keeps serving. Answers plan, version, live and collections, each entry naming the collection, whether the change adds, removes or changes its shape, its fields (field, change: added, removed or retyped, with from and to for a retype), retypes (the fields whose new type asks something of the stored documents) and documents (what those retypes would read). Default false. |
direct | body | "refuse" | "replace" | "keep" | No | What to do when a function was deployed directly (function.deploy, substrio deploy NAME, function.environment.set, function.delete) since the version now live was recorded, and this promote would overwrite or delete it with something else: refuse (the default) answers 409 DIRECT_CHANGES with direct_changes instead of applying anything; replace applies the version anyway, reporting what it overwrote in replaced; keep applies the version except those functions, left exactly as deployed, reported in kept. Default "refuse". |
Response
A JSON object.
Errors
INVALID_ARGUMENT: callversion.checkto find the right one.KEY_NOT_FOUND: callversion.listto find the right one.KEY_EXISTS: callversion.getto find the right one.TENANT_NOT_FOUND: callsandbox.createto find the right one.CONSTRAINT_VIOLATION: callversion.listto find the right one.DIRECT_CHANGES: callfunction.listto find the right one.
A failed call answers the error envelope with a typed code.
Example
curl -X POST "$SUBSTRIO_URL/v1/_live" \
-H "Authorization: Bearer $SUBSTRIO_KEY"