API reference
Machines
The virtual machines behind an app: create, read, start, stop, suspend, destroy, migrate; logs, snapshots, files and shell sessions.
A machine is one virtual machine of an app. A deploy creates machines for you; this family is for reading them, acting on one, and for the machines you create yourself (a computer, an agent’s workspace). A machine is requested, scheduled, starting, running, suspending, suspended, stopping, stopped, deleted or failed.
The shell routes (ry exec, ry ssh, ry proxy) upgrade the connection to a WebSocket and are not plain JSON calls; use the CLI for them.
Endpoints
Section titled “Endpoints”POST /v1/apps/:name/machines: Creates a machine in the app and waits until it runs. Add?wait=falsefor202right away and pollGET /v1/machines/:id/waitGET /v1/apps/:name/machines: The app’s machinesGET /v1/machines/:id: One machineGET /v1/machines/:id/wait: Holds the request until the machine reaches a state (?state=), at most?timeout=seconds;408when it runs outPOST /v1/machines/:id/:action: Acts on a machine:start,stop,suspendordestroyPOST /v1/machines/:id/migrate: Moves the machine to another hostGET /v1/apps/:name/logs: The console output of the app’s machines, with a cursor per machine for the next callPOST /v1/machines/:id/checkpoints: Takes a named snapshot of the machine: its disk, and withmemory: trueits running memory tooGET /v1/machines/:id/checkpoints: The machine’s named snapshots. Add?auto=1to include the automatic onesDELETE /v1/machines/:id/checkpoints/:label: Forgets a snapshotPOST /v1/machines/:id/checkpoints/:label/restore: Brings the machine back to that snapshot. WithkeepCurrent: true(the default) the current state is saved firstGET /v1/machines/:id/files: Reads one file of the machine (?path=), as raw bytesPUT /v1/machines/:id/files: Writes one file of the machine (?path=); the body is the file’s bytesGET /v1/machines/:id/files/list: Lists a directory of the machine (?path=)GET /v1/machines/:id/screenshot: A screenshot of the machine’s desktop, for a machine that has oneGET /v1/machines/:id/exec: Opens a shell session over a WebSocket. This is whatry execandry sshuse; it is not a plain JSON callGET /v1/machines/:id/exec-sessions: The shell sessions open on the machine
POST /v1/apps/:name/machines
Section titled “POST /v1/apps/:name/machines”Creates a machine in the app and waits until it runs. Add ?wait=false for 202 right away and poll GET /v1/machines/:id/wait.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
name |
The app’s name. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
wait |
false answers 202 as soon as the row exists, before the boot; the default waits for the running machine. |
Request body
Section titled “Request body”JSON, the shape CreateMachineRequest of the contract.
| Field | Type | Required | Description |
|---|---|---|---|
image |
string | required | An OCI reference such as nginx:alpine, or build:<id> for a build of your organization. 1 to 512 characters. |
class |
shared-cpu-1x | shared-cpu-2x | shared-cpu-4x | shared-cpu-8x | performance-1x | performance-2x | performance-4x | performance-8x |
optional | A named size instead of vcpus; the two must not contradict each other. |
vcpus |
integer | optional | Virtual CPUs. 1 to 16, default 1. |
memoryMb |
integer | optional | Memory in MB. 128 to 16384, default 512. |
env |
object of string | optional | Plain environment variables. Use secrets for credentials. |
diskMb |
integer | optional | The machine’s disk in MB. Without it, the image’s size plus headroom. 512 to 131072. |
volumeGb |
integer | optional | A volume of this size, attached to the machine. 1 to 500. |
start |
string | optional | The start command, run through /bin/sh -c. It replaces what detection chose or the image’s CMD. 1 to 2000 characters. |
internalPort |
integer | optional | The port the app listens on. 1 to 65535, default 3000. |
suspendPolicy |
object | optional | When the machine sleeps. Without it, a new app never sleeps; a deploy without it keeps the app’s rule. |
suspendPolicy.mode |
suspend | stop | off |
optional | suspend keeps the memory and resumes fast (machines up to 2048 MB; larger ones stop instead), stop shuts down, off never sleeps. default "suspend". |
suspendPolicy.idleSeconds |
integer | optional | Seconds without requests and without CPU load before the machine sleeps. 10 to 86400, default 300. |
suspendPolicy.stopAfterSeconds |
integer | optional | Second stage: after this many seconds since the last activity a suspended machine is stopped (its memory snapshot dropped, its disk kept). Only with mode: "suspend", and greater than idleSeconds. 10 to 604800. |
healthCheck |
object | optional | An HTTP check a new machine must pass before it gets traffic. |
healthCheck.path |
string | optional | The path to call; empty means the port alone. default "". |
healthCheck.timeoutMs |
integer | optional | How long one probe may take. 100 to 30000, default 2000. |
healthCheck.intervalMs |
integer | optional | Time between probes. 100 to 10000, default 500. |
healthCheck.healthyThreshold |
integer | optional | Probes that must pass in a row. 1 to 10, default 1. |
healthCheck.maxWaitMs |
integer | optional | How long a new machine may take in total before the deploy gives up on it. 1000 to 300000. |
restart |
object | optional | What happens when the process ends. Without it, a crashed machine is restarted. |
restart.policy |
never | on-failure |
optional | never or on-failure. default "never". |
restart.retries |
integer | optional | Restarts before the machine stays down. 1 to 10, default 3. |
killSignal |
SIGTERM | SIGINT | SIGQUIT | SIGHUP | SIGUSR1 | SIGUSR2 | SIGWINCH | SIGKILL |
optional | The signal sent before a machine is stopped or replaced. Default: the image’s STOPSIGNAL, else SIGTERM. |
killTimeoutS |
integer | optional | Seconds between that signal and SIGKILL. 1 to 300. |
durableCheckpoint |
boolean | optional | Agent machine: the whole state (memory and disk) is checkpointed and survives a host failure. default false. |
checkpointIntervalS |
integer | optional | 5 to 3600. |
console |
boolean | optional | default false. |
command |
array of string | optional | Runs on a machine of its own, as an argument list. 1 to 64 items. |
diskIsCache |
boolean | optional | |
readiness |
port | boot |
optional | boot: ready when the machine boots. port: ready when internalPort answers. |
exposePorts |
array of integer | optional | 0 to 8 items. |
egress |
object | optional | Outbound network: allow-all, deny-all, or allowlist with domains and cidrs. |
egress.mode |
deny-all | allowlist |
required | view to watch, control to take keyboard and mouse. |
egress.domains |
array of string | required | 0 to 100 items. |
egress.cidrs |
array of string | required | 0 to 10 items. |
region |
string | optional | The region to place the machine in. Without it, the organization’s region. 2 to 12 characters. |
Example request
Section titled “Example request”curl -X POST "https://api.rytiv.app/v1/apps/<name>/machines" \ -H "Authorization: Bearer $RYTIV_TOKEN" \ -H "Content-Type: application/json" \ -d '{"image":"rytiv/computer:0.1.0"}'Response
Section titled “Response”201 with the machine (plus bootMs, the time the boot took):
{ "id": "<id>", "appName": "my-app", "config": { "image": "nginx:alpine", "vcpus": 1, "memoryMb": 512, "env": { "<key>": "<value>" }, "internalPort": 3000, "suspendPolicy": { "mode": "suspend", "idleSeconds": 300 }, "durableCheckpoint": false, "console": false }, "desiredState": "requested", "observedState": "requested", "region": "<region>", "createdAt": "2026-10-21T09:00:00Z"}| Field | Type | Present | Description |
|---|---|---|---|
id |
string | always | The machine’s id. |
appName |
string | always | The app it belongs to. |
config |
object | always | What it runs: image, size, environment and the settings of a deploy request. |
config.image |
string | always | An OCI reference such as nginx:alpine, or build:<id> for a build of your organization. 1 to 512 characters. |
config.class |
shared-cpu-1x | shared-cpu-2x | shared-cpu-4x | shared-cpu-8x | performance-1x | performance-2x | performance-4x | performance-8x |
if set | A named size instead of vcpus; the two must not contradict each other. |
config.vcpus |
integer | always | Virtual CPUs. 1 to 16, default 1. |
config.memoryMb |
integer | always | Memory in MB. 128 to 16384, default 512. |
config.env |
object of string | always | Plain environment variables. Use secrets for credentials. |
config.diskMb |
integer | if set | The machine’s disk in MB. Without it, the image’s size plus headroom. 512 to 131072. |
config.volumeGb |
integer | if set | A volume of this size, attached to the machine. 1 to 500. |
config.start |
string | if set | The start command, run through /bin/sh -c. It replaces what detection chose or the image’s CMD. 1 to 2000 characters. |
config.internalPort |
integer | always | The port the app listens on. 1 to 65535, default 3000. |
config.suspendPolicy |
object | always | When the machine sleeps. Without it, a new app never sleeps; a deploy without it keeps the app’s rule. |
config.healthCheck |
object | if set | An HTTP check a new machine must pass before it gets traffic. |
config.restart |
object | if set | What happens when the process ends. Without it, a crashed machine is restarted. |
config.killSignal |
SIGTERM | SIGINT | SIGQUIT | SIGHUP | SIGUSR1 | SIGUSR2 | SIGWINCH | SIGKILL |
if set | The signal sent before a machine is stopped or replaced. Default: the image’s STOPSIGNAL, else SIGTERM. |
config.killTimeoutS |
integer | if set | Seconds between that signal and SIGKILL. 1 to 300. |
config.durableCheckpoint |
boolean | always | Agent machine: the whole state (memory and disk) is checkpointed and survives a host failure. default false. |
config.checkpointIntervalS |
integer | if set | 5 to 3600. |
config.console |
boolean | always | default false. |
config.command |
array of string | if set | Runs on a machine of its own, as an argument list. 1 to 64 items. |
config.diskIsCache |
boolean | if set | |
config.readiness |
port | boot |
if set | boot: ready when the machine boots. port: ready when internalPort answers. |
config.exposePorts |
array of integer | if set | 0 to 8 items. |
config.egress |
object | if set | Outbound network: allow-all, deny-all, or allowlist with domains and cidrs. |
desiredState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What the platform wants the machine to be. |
observedState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What it is right now. |
host |
string | if set | Internal; not shown to a customer. |
privateIp |
string | if set | The machine’s address on the private network. |
role |
primary | standby |
if set | primary or standby, for a redundant database only. |
region |
string | always | Where it runs. Fixed for the machine’s lifetime. 2 to 12 characters. |
checkpointAt |
string (ISO 8601) | if set | Agent machines: when the last durable checkpoint was taken. |
zone |
string | if set | The availability zone, where the host reports one. |
diskUsedMb |
integer | if set | How full the disk is, an upper bound. 0 to 9007199254740991. |
diskTotalMb |
integer | if set | The disk’s size. 0 to 9007199254740991. |
diskAt |
string (ISO 8601) | if set | When the disk numbers were reported. |
restoreChunksDone |
integer | if set | 0 to 9007199254740991. |
restoreChunksTotal |
integer | if set | 0 to 9007199254740991. |
restoreAt |
string (ISO 8601) | if set | |
readyAt |
string (ISO 8601) | if set | |
net |
object or null | if set | |
liveness |
listening | not-listening | no-signal |
if set | |
livenessReason |
string | if set | |
livenessSince |
string (ISO 8601) | if set | |
livenessAt |
string (ISO 8601) | if set | |
createError |
string | if set | |
createErrorCode |
string | if set | |
createBootLog |
string | if set | |
createWarning |
string | if set | |
createdAt |
string (ISO 8601) | always | When it was created. |
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 400 | bad-request |
The request is malformed or a field is out of range. error names every field; issues lists them. |
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | build-not-found |
build:<id> is not a build of your organization. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 409 | conflict |
The request conflicts with the current state. |
| 409 | volume-needs-single-machine |
An app with a volume runs exactly one machine. |
| 503 | create-failed |
The host could not create the machine (image, start command or port). The sentence says which. |
| 503 | no-capacity |
No host in the region has room for the machine right now; try again. |
GET /v1/apps/:name/machines
Section titled “GET /v1/apps/:name/machines”The app’s machines.
Auth: API key with full access or the scope deploy or deploy:<app> for this app, or the scope read. Every class of agent token may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
name |
The app’s name. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/apps/<name>/machines" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a list of machines, each:
[ { "id": "<id>", "appName": "my-app", "config": { "image": "nginx:alpine", "vcpus": 1, "memoryMb": 512, "env": { "<key>": "<value>" }, "internalPort": 3000, "suspendPolicy": { "mode": "suspend", "idleSeconds": 300 }, "durableCheckpoint": false, "console": false }, "desiredState": "requested", "observedState": "requested", "region": "<region>", "createdAt": "2026-10-21T09:00:00Z" }]| Field | Type | Present | Description |
|---|---|---|---|
id |
string | always | The machine’s id. |
appName |
string | always | The app it belongs to. |
config |
object | always | What it runs: image, size, environment and the settings of a deploy request. |
config.image |
string | always | An OCI reference such as nginx:alpine, or build:<id> for a build of your organization. 1 to 512 characters. |
config.class |
shared-cpu-1x | shared-cpu-2x | shared-cpu-4x | shared-cpu-8x | performance-1x | performance-2x | performance-4x | performance-8x |
if set | A named size instead of vcpus; the two must not contradict each other. |
config.vcpus |
integer | always | Virtual CPUs. 1 to 16, default 1. |
config.memoryMb |
integer | always | Memory in MB. 128 to 16384, default 512. |
config.env |
object of string | always | Plain environment variables. Use secrets for credentials. |
config.diskMb |
integer | if set | The machine’s disk in MB. Without it, the image’s size plus headroom. 512 to 131072. |
config.volumeGb |
integer | if set | A volume of this size, attached to the machine. 1 to 500. |
config.start |
string | if set | The start command, run through /bin/sh -c. It replaces what detection chose or the image’s CMD. 1 to 2000 characters. |
config.internalPort |
integer | always | The port the app listens on. 1 to 65535, default 3000. |
config.suspendPolicy |
object | always | When the machine sleeps. Without it, a new app never sleeps; a deploy without it keeps the app’s rule. |
config.healthCheck |
object | if set | An HTTP check a new machine must pass before it gets traffic. |
config.restart |
object | if set | What happens when the process ends. Without it, a crashed machine is restarted. |
config.killSignal |
SIGTERM | SIGINT | SIGQUIT | SIGHUP | SIGUSR1 | SIGUSR2 | SIGWINCH | SIGKILL |
if set | The signal sent before a machine is stopped or replaced. Default: the image’s STOPSIGNAL, else SIGTERM. |
config.killTimeoutS |
integer | if set | Seconds between that signal and SIGKILL. 1 to 300. |
config.durableCheckpoint |
boolean | always | Agent machine: the whole state (memory and disk) is checkpointed and survives a host failure. default false. |
config.checkpointIntervalS |
integer | if set | 5 to 3600. |
config.console |
boolean | always | default false. |
config.command |
array of string | if set | Runs on a machine of its own, as an argument list. 1 to 64 items. |
config.diskIsCache |
boolean | if set | |
config.readiness |
port | boot |
if set | boot: ready when the machine boots. port: ready when internalPort answers. |
config.exposePorts |
array of integer | if set | 0 to 8 items. |
config.egress |
object | if set | Outbound network: allow-all, deny-all, or allowlist with domains and cidrs. |
desiredState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What the platform wants the machine to be. |
observedState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What it is right now. |
host |
string | if set | Internal; not shown to a customer. |
privateIp |
string | if set | The machine’s address on the private network. |
role |
primary | standby |
if set | primary or standby, for a redundant database only. |
region |
string | always | Where it runs. Fixed for the machine’s lifetime. 2 to 12 characters. |
checkpointAt |
string (ISO 8601) | if set | Agent machines: when the last durable checkpoint was taken. |
zone |
string | if set | The availability zone, where the host reports one. |
diskUsedMb |
integer | if set | How full the disk is, an upper bound. 0 to 9007199254740991. |
diskTotalMb |
integer | if set | The disk’s size. 0 to 9007199254740991. |
diskAt |
string (ISO 8601) | if set | When the disk numbers were reported. |
restoreChunksDone |
integer | if set | 0 to 9007199254740991. |
restoreChunksTotal |
integer | if set | 0 to 9007199254740991. |
restoreAt |
string (ISO 8601) | if set | |
readyAt |
string (ISO 8601) | if set | |
net |
object or null | if set | |
liveness |
listening | not-listening | no-signal |
if set | |
livenessReason |
string | if set | |
livenessSince |
string (ISO 8601) | if set | |
livenessAt |
string (ISO 8601) | if set | |
createError |
string | if set | |
createErrorCode |
string | if set | |
createBootLog |
string | if set | |
createWarning |
string | if set | |
createdAt |
string (ISO 8601) | always | When it was created. |
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
GET /v1/machines/:id
Section titled “GET /v1/machines/:id”One machine.
Auth: API key with full access or the scope read. Every class of agent token may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The machine’s id. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with the machine:
{ "id": "<id>", "appName": "my-app", "config": { "image": "nginx:alpine", "vcpus": 1, "memoryMb": 512, "env": { "<key>": "<value>" }, "internalPort": 3000, "suspendPolicy": { "mode": "suspend", "idleSeconds": 300 }, "durableCheckpoint": false, "console": false }, "desiredState": "requested", "observedState": "requested", "region": "<region>", "createdAt": "2026-10-21T09:00:00Z"}| Field | Type | Present | Description |
|---|---|---|---|
id |
string | always | The machine’s id. |
appName |
string | always | The app it belongs to. |
config |
object | always | What it runs: image, size, environment and the settings of a deploy request. |
config.image |
string | always | An OCI reference such as nginx:alpine, or build:<id> for a build of your organization. 1 to 512 characters. |
config.class |
shared-cpu-1x | shared-cpu-2x | shared-cpu-4x | shared-cpu-8x | performance-1x | performance-2x | performance-4x | performance-8x |
if set | A named size instead of vcpus; the two must not contradict each other. |
config.vcpus |
integer | always | Virtual CPUs. 1 to 16, default 1. |
config.memoryMb |
integer | always | Memory in MB. 128 to 16384, default 512. |
config.env |
object of string | always | Plain environment variables. Use secrets for credentials. |
config.diskMb |
integer | if set | The machine’s disk in MB. Without it, the image’s size plus headroom. 512 to 131072. |
config.volumeGb |
integer | if set | A volume of this size, attached to the machine. 1 to 500. |
config.start |
string | if set | The start command, run through /bin/sh -c. It replaces what detection chose or the image’s CMD. 1 to 2000 characters. |
config.internalPort |
integer | always | The port the app listens on. 1 to 65535, default 3000. |
config.suspendPolicy |
object | always | When the machine sleeps. Without it, a new app never sleeps; a deploy without it keeps the app’s rule. |
config.healthCheck |
object | if set | An HTTP check a new machine must pass before it gets traffic. |
config.restart |
object | if set | What happens when the process ends. Without it, a crashed machine is restarted. |
config.killSignal |
SIGTERM | SIGINT | SIGQUIT | SIGHUP | SIGUSR1 | SIGUSR2 | SIGWINCH | SIGKILL |
if set | The signal sent before a machine is stopped or replaced. Default: the image’s STOPSIGNAL, else SIGTERM. |
config.killTimeoutS |
integer | if set | Seconds between that signal and SIGKILL. 1 to 300. |
config.durableCheckpoint |
boolean | always | Agent machine: the whole state (memory and disk) is checkpointed and survives a host failure. default false. |
config.checkpointIntervalS |
integer | if set | 5 to 3600. |
config.console |
boolean | always | default false. |
config.command |
array of string | if set | Runs on a machine of its own, as an argument list. 1 to 64 items. |
config.diskIsCache |
boolean | if set | |
config.readiness |
port | boot |
if set | boot: ready when the machine boots. port: ready when internalPort answers. |
config.exposePorts |
array of integer | if set | 0 to 8 items. |
config.egress |
object | if set | Outbound network: allow-all, deny-all, or allowlist with domains and cidrs. |
desiredState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What the platform wants the machine to be. |
observedState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What it is right now. |
host |
string | if set | Internal; not shown to a customer. |
privateIp |
string | if set | The machine’s address on the private network. |
role |
primary | standby |
if set | primary or standby, for a redundant database only. |
region |
string | always | Where it runs. Fixed for the machine’s lifetime. 2 to 12 characters. |
checkpointAt |
string (ISO 8601) | if set | Agent machines: when the last durable checkpoint was taken. |
zone |
string | if set | The availability zone, where the host reports one. |
diskUsedMb |
integer | if set | How full the disk is, an upper bound. 0 to 9007199254740991. |
diskTotalMb |
integer | if set | The disk’s size. 0 to 9007199254740991. |
diskAt |
string (ISO 8601) | if set | When the disk numbers were reported. |
restoreChunksDone |
integer | if set | 0 to 9007199254740991. |
restoreChunksTotal |
integer | if set | 0 to 9007199254740991. |
restoreAt |
string (ISO 8601) | if set | |
readyAt |
string (ISO 8601) | if set | |
net |
object or null | if set | |
liveness |
listening | not-listening | no-signal |
if set | |
livenessReason |
string | if set | |
livenessSince |
string (ISO 8601) | if set | |
livenessAt |
string (ISO 8601) | if set | |
createError |
string | if set | |
createErrorCode |
string | if set | |
createBootLog |
string | if set | |
createWarning |
string | if set | |
createdAt |
string (ISO 8601) | always | When it was created. |
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
GET /v1/machines/:id/wait
Section titled “GET /v1/machines/:id/wait”Holds the request until the machine reaches a state (?state=), at most ?timeout= seconds; 408 when it runs out.
Auth: API key with full access or the scope read. Every class of agent token may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
state |
The state to wait for, for example running or stopped. |
timeout |
Seconds to hold the request, at most 60. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/wait" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with the machine, once it is in the state:
{ "id": "<id>", "appName": "my-app", "config": { "image": "nginx:alpine", "vcpus": 1, "memoryMb": 512, "env": { "<key>": "<value>" }, "internalPort": 3000, "suspendPolicy": { "mode": "suspend", "idleSeconds": 300 }, "durableCheckpoint": false, "console": false }, "desiredState": "requested", "observedState": "requested", "region": "<region>", "createdAt": "2026-10-21T09:00:00Z"}| Field | Type | Present | Description |
|---|---|---|---|
id |
string | always | The machine’s id. |
appName |
string | always | The app it belongs to. |
config |
object | always | What it runs: image, size, environment and the settings of a deploy request. |
config.image |
string | always | An OCI reference such as nginx:alpine, or build:<id> for a build of your organization. 1 to 512 characters. |
config.class |
shared-cpu-1x | shared-cpu-2x | shared-cpu-4x | shared-cpu-8x | performance-1x | performance-2x | performance-4x | performance-8x |
if set | A named size instead of vcpus; the two must not contradict each other. |
config.vcpus |
integer | always | Virtual CPUs. 1 to 16, default 1. |
config.memoryMb |
integer | always | Memory in MB. 128 to 16384, default 512. |
config.env |
object of string | always | Plain environment variables. Use secrets for credentials. |
config.diskMb |
integer | if set | The machine’s disk in MB. Without it, the image’s size plus headroom. 512 to 131072. |
config.volumeGb |
integer | if set | A volume of this size, attached to the machine. 1 to 500. |
config.start |
string | if set | The start command, run through /bin/sh -c. It replaces what detection chose or the image’s CMD. 1 to 2000 characters. |
config.internalPort |
integer | always | The port the app listens on. 1 to 65535, default 3000. |
config.suspendPolicy |
object | always | When the machine sleeps. Without it, a new app never sleeps; a deploy without it keeps the app’s rule. |
config.healthCheck |
object | if set | An HTTP check a new machine must pass before it gets traffic. |
config.restart |
object | if set | What happens when the process ends. Without it, a crashed machine is restarted. |
config.killSignal |
SIGTERM | SIGINT | SIGQUIT | SIGHUP | SIGUSR1 | SIGUSR2 | SIGWINCH | SIGKILL |
if set | The signal sent before a machine is stopped or replaced. Default: the image’s STOPSIGNAL, else SIGTERM. |
config.killTimeoutS |
integer | if set | Seconds between that signal and SIGKILL. 1 to 300. |
config.durableCheckpoint |
boolean | always | Agent machine: the whole state (memory and disk) is checkpointed and survives a host failure. default false. |
config.checkpointIntervalS |
integer | if set | 5 to 3600. |
config.console |
boolean | always | default false. |
config.command |
array of string | if set | Runs on a machine of its own, as an argument list. 1 to 64 items. |
config.diskIsCache |
boolean | if set | |
config.readiness |
port | boot |
if set | boot: ready when the machine boots. port: ready when internalPort answers. |
config.exposePorts |
array of integer | if set | 0 to 8 items. |
config.egress |
object | if set | Outbound network: allow-all, deny-all, or allowlist with domains and cidrs. |
desiredState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What the platform wants the machine to be. |
observedState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What it is right now. |
host |
string | if set | Internal; not shown to a customer. |
privateIp |
string | if set | The machine’s address on the private network. |
role |
primary | standby |
if set | primary or standby, for a redundant database only. |
region |
string | always | Where it runs. Fixed for the machine’s lifetime. 2 to 12 characters. |
checkpointAt |
string (ISO 8601) | if set | Agent machines: when the last durable checkpoint was taken. |
zone |
string | if set | The availability zone, where the host reports one. |
diskUsedMb |
integer | if set | How full the disk is, an upper bound. 0 to 9007199254740991. |
diskTotalMb |
integer | if set | The disk’s size. 0 to 9007199254740991. |
diskAt |
string (ISO 8601) | if set | When the disk numbers were reported. |
restoreChunksDone |
integer | if set | 0 to 9007199254740991. |
restoreChunksTotal |
integer | if set | 0 to 9007199254740991. |
restoreAt |
string (ISO 8601) | if set | |
readyAt |
string (ISO 8601) | if set | |
net |
object or null | if set | |
liveness |
listening | not-listening | no-signal |
if set | |
livenessReason |
string | if set | |
livenessSince |
string (ISO 8601) | if set | |
livenessAt |
string (ISO 8601) | if set | |
createError |
string | if set | |
createErrorCode |
string | if set | |
createBootLog |
string | if set | |
createWarning |
string | if set | |
createdAt |
string (ISO 8601) | always | When it was created. |
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 400 | bad-request |
The request is malformed or a field is out of range. error names every field; issues lists them. |
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 408 | wait-timeout |
The wait ran out before the machine reached the state; ask again. |
| 410 | gone |
The object existed and is gone. |
POST /v1/machines/:id/:action
Section titled “POST /v1/machines/:id/:action”Acts on a machine: start, stop, suspend or destroy.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
action |
start, stop, suspend or destroy. |
Example request
Section titled “Example request”curl -X POST "https://api.rytiv.app/v1/machines/<id>/<action>" \ -H "Authorization: Bearer $RYTIV_TOKEN" \ -H "Content-Type: application/json" \ -d '{}'Response
Section titled “Response”200 with the machine after the action:
{ "id": "<id>", "appName": "my-app", "config": { "image": "nginx:alpine", "vcpus": 1, "memoryMb": 512, "env": { "<key>": "<value>" }, "internalPort": 3000, "suspendPolicy": { "mode": "suspend", "idleSeconds": 300 }, "durableCheckpoint": false, "console": false }, "desiredState": "requested", "observedState": "requested", "region": "<region>", "createdAt": "2026-10-21T09:00:00Z"}| Field | Type | Present | Description |
|---|---|---|---|
id |
string | always | The machine’s id. |
appName |
string | always | The app it belongs to. |
config |
object | always | What it runs: image, size, environment and the settings of a deploy request. |
config.image |
string | always | An OCI reference such as nginx:alpine, or build:<id> for a build of your organization. 1 to 512 characters. |
config.class |
shared-cpu-1x | shared-cpu-2x | shared-cpu-4x | shared-cpu-8x | performance-1x | performance-2x | performance-4x | performance-8x |
if set | A named size instead of vcpus; the two must not contradict each other. |
config.vcpus |
integer | always | Virtual CPUs. 1 to 16, default 1. |
config.memoryMb |
integer | always | Memory in MB. 128 to 16384, default 512. |
config.env |
object of string | always | Plain environment variables. Use secrets for credentials. |
config.diskMb |
integer | if set | The machine’s disk in MB. Without it, the image’s size plus headroom. 512 to 131072. |
config.volumeGb |
integer | if set | A volume of this size, attached to the machine. 1 to 500. |
config.start |
string | if set | The start command, run through /bin/sh -c. It replaces what detection chose or the image’s CMD. 1 to 2000 characters. |
config.internalPort |
integer | always | The port the app listens on. 1 to 65535, default 3000. |
config.suspendPolicy |
object | always | When the machine sleeps. Without it, a new app never sleeps; a deploy without it keeps the app’s rule. |
config.healthCheck |
object | if set | An HTTP check a new machine must pass before it gets traffic. |
config.restart |
object | if set | What happens when the process ends. Without it, a crashed machine is restarted. |
config.killSignal |
SIGTERM | SIGINT | SIGQUIT | SIGHUP | SIGUSR1 | SIGUSR2 | SIGWINCH | SIGKILL |
if set | The signal sent before a machine is stopped or replaced. Default: the image’s STOPSIGNAL, else SIGTERM. |
config.killTimeoutS |
integer | if set | Seconds between that signal and SIGKILL. 1 to 300. |
config.durableCheckpoint |
boolean | always | Agent machine: the whole state (memory and disk) is checkpointed and survives a host failure. default false. |
config.checkpointIntervalS |
integer | if set | 5 to 3600. |
config.console |
boolean | always | default false. |
config.command |
array of string | if set | Runs on a machine of its own, as an argument list. 1 to 64 items. |
config.diskIsCache |
boolean | if set | |
config.readiness |
port | boot |
if set | boot: ready when the machine boots. port: ready when internalPort answers. |
config.exposePorts |
array of integer | if set | 0 to 8 items. |
config.egress |
object | if set | Outbound network: allow-all, deny-all, or allowlist with domains and cidrs. |
desiredState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What the platform wants the machine to be. |
observedState |
requested | scheduled | starting | running | suspending | suspended | stopping | stopped | deleted | failed |
always | What it is right now. |
host |
string | if set | Internal; not shown to a customer. |
privateIp |
string | if set | The machine’s address on the private network. |
role |
primary | standby |
if set | primary or standby, for a redundant database only. |
region |
string | always | Where it runs. Fixed for the machine’s lifetime. 2 to 12 characters. |
checkpointAt |
string (ISO 8601) | if set | Agent machines: when the last durable checkpoint was taken. |
zone |
string | if set | The availability zone, where the host reports one. |
diskUsedMb |
integer | if set | How full the disk is, an upper bound. 0 to 9007199254740991. |
diskTotalMb |
integer | if set | The disk’s size. 0 to 9007199254740991. |
diskAt |
string (ISO 8601) | if set | When the disk numbers were reported. |
restoreChunksDone |
integer | if set | 0 to 9007199254740991. |
restoreChunksTotal |
integer | if set | 0 to 9007199254740991. |
restoreAt |
string (ISO 8601) | if set | |
readyAt |
string (ISO 8601) | if set | |
net |
object or null | if set | |
liveness |
listening | not-listening | no-signal |
if set | |
livenessReason |
string | if set | |
livenessSince |
string (ISO 8601) | if set | |
livenessAt |
string (ISO 8601) | if set | |
createError |
string | if set | |
createErrorCode |
string | if set | |
createBootLog |
string | if set | |
createWarning |
string | if set | |
createdAt |
string (ISO 8601) | always | When it was created. |
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 409 | machine-busy |
Another operation on the machine is in progress; try again. |
| 503 | create-failed |
The host could not create the machine (image, start command or port). The sentence says which. |
| 503 | guest-exited |
The machine’s process ended during the start. |
| 503 | host-refused |
The host refused the action. |
| 503 | host-unreachable |
The host did not answer. |
| 503 | no-capacity |
No host in the region has room for the machine right now; try again. |
| 503 | port-timeout |
The machine did not answer on its port in time. |
| 503 | start-interrupted |
The start was interrupted on the host. |
POST /v1/machines/:id/migrate
Section titled “POST /v1/machines/:id/migrate”Moves the machine to another host.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Example request
Section titled “Example request”curl -X POST "https://api.rytiv.app/v1/machines/<id>/migrate" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a JSON object and the fields of the object the handler builds.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 409 | conflict |
The request conflicts with the current state. |
| 409 | create-failed |
The host could not create the machine (image, start command or port). The sentence says which. |
| 409 | ephemeral |
|
| 503 | no-capacity |
No host in the region has room for the machine right now; try again. |
GET /v1/apps/:name/logs
Section titled “GET /v1/apps/:name/logs”The console output of the app’s machines, with a cursor per machine for the next call.
Auth: API key with full access or the scope deploy or deploy:<app> for this app, or the scope read. Every class of agent token may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
name |
The app’s name. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
machine |
Only this machine. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/apps/<name>/logs" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a JSON body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
POST /v1/machines/:id/checkpoints
Section titled “POST /v1/machines/:id/checkpoints”Takes a named snapshot of the machine: its disk, and with memory: true its running memory too.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Request body
Section titled “Request body”JSON, the shape CreateCheckpointRequest of the contract.
| Field | Type | Required | Description |
|---|---|---|---|
label |
string | required | A name for the snapshot: letters, digits, ., - and _, starting with a letter or digit. auto- is reserved. |
comment |
string | optional | A note kept with the snapshot. at most 500 characters. |
memory |
boolean | optional | true snapshots the running memory as well, so a restore resumes the very processes. default false. |
Example request
Section titled “Example request”curl -X POST "https://api.rytiv.app/v1/machines/<id>/checkpoints" \ -H "Authorization: Bearer $RYTIV_TOKEN" \ -H "Content-Type: application/json" \ -d '{"label":"before-migration"}'Response
Section titled “Response”201 with a JSON body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 400 | bad-request |
The request is malformed or a field is out of range. error names every field; issues lists them. |
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
GET /v1/machines/:id/checkpoints
Section titled “GET /v1/machines/:id/checkpoints”The machine’s named snapshots. Add ?auto=1 to include the automatic ones.
Auth: API key with full access or the scope read. Every class of agent token may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
includeAuto |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/checkpoints" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a JSON body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
DELETE /v1/machines/:id/checkpoints/:label
Section titled “DELETE /v1/machines/:id/checkpoints/:label”Forgets a snapshot.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
label |
The snapshot’s label. |
Example request
Section titled “Example request”curl -X DELETE "https://api.rytiv.app/v1/machines/<id>/checkpoints/<label>" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”204 with no body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
POST /v1/machines/:id/checkpoints/:label/restore
Section titled “POST /v1/machines/:id/checkpoints/:label/restore”Brings the machine back to that snapshot. With keepCurrent: true (the default) the current state is saved first.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
label |
The snapshot’s label. |
Request body
Section titled “Request body”JSON, the shape RestoreCheckpointRequest of the contract.
| Field | Type | Required | Description |
|---|---|---|---|
keepCurrent |
boolean | optional | Save the current state as a snapshot before restoring (default true). default true. |
Example request
Section titled “Example request”curl -X POST "https://api.rytiv.app/v1/machines/<id>/checkpoints/<label>/restore" \ -H "Authorization: Bearer $RYTIV_TOKEN" \ -H "Content-Type: application/json" \ -d '{"keepCurrent":true}'Response
Section titled “Response”200 with a JSON object carrying machineId, restored, manifest, memory, savedAs.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 400 | bad-request |
The request is malformed or a field is out of range. error names every field; issues lists them. |
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
GET /v1/machines/:id/files
Section titled “GET /v1/machines/:id/files”Reads one file of the machine (?path=), as raw bytes.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class production needs prodDataRead for it; sandbox and twin may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/files" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a JSON body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 502 | transport |
PUT /v1/machines/:id/files
Section titled “PUT /v1/machines/:id/files”Writes one file of the machine (?path=); the body is the file’s bytes.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused (agent-token-production-readonly).
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
mode |
The file mode, default 0644. |
mkdirs |
1 creates missing directories. |
Request body
Section titled “Request body”The raw bytes of the file.
Example request
Section titled “Example request”curl -X PUT "https://api.rytiv.app/v1/machines/<id>/files" \ -H "Authorization: Bearer $RYTIV_TOKEN" \ -H "Content-Type: application/octet-stream" \ --data-binary @hello.txtResponse
Section titled “Response”200 with a JSON object carrying path, bytes, sha256.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 400 | bad-request |
The request is malformed or a field is out of range. error names every field; issues lists them. |
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 413 | too-large |
The body is larger than the route accepts. |
| 502 | transport |
GET /v1/machines/:id/files/list
Section titled “GET /v1/machines/:id/files/list”Lists a directory of the machine (?path=).
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class production needs prodDataRead for it; sandbox and twin may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/files/list" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a JSON object carrying path, entries.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 502 | transport |
GET /v1/machines/:id/screenshot
Section titled “GET /v1/machines/:id/screenshot”A screenshot of the machine’s desktop, for a machine that has one.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class production needs prodDataRead for it; sandbox and twin may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
display |
Request body
Section titled “Request body”JSON, the shape ExecScreenshot of the contract.
| Field | Type | Required | Description |
|---|---|---|---|
display |
string | optional | default ":0". |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/screenshot" \ -H "Authorization: Bearer $RYTIV_TOKEN" \ -H "Content-Type: application/json" \ -d '{"display":"<display>"}'Response
Section titled “Response”200 with a JSON body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 400 | bad-request |
The request is malformed or a field is out of range. error names every field; issues lists them. |
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
GET /v1/machines/:id/exec
Section titled “GET /v1/machines/:id/exec”Opens a shell session over a WebSocket. This is what ry exec and ry ssh use; it is not a plain JSON call.
Auth: API key with full access (a key with scopes cannot call this route). An agent token of class sandbox or twin may call it; class production is refused.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/exec" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”A JSON body on success.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |
| 426 | upgrade-required |
The route needs a WebSocket upgrade; use the CLI. |
GET /v1/machines/:id/exec-sessions
Section titled “GET /v1/machines/:id/exec-sessions”The shell sessions open on the machine.
Auth: API key with full access or the scope read. Every class of agent token may call it.
Path parameters
Section titled “Path parameters”| Name | Description |
|---|---|
id |
The object’s id. |
Query parameters
Section titled “Query parameters”| Name | Description |
|---|---|
limit |
How many entries, at most. |
Example request
Section titled “Example request”curl -X GET "https://api.rytiv.app/v1/machines/<id>/exec-sessions" \ -H "Authorization: Bearer $RYTIV_TOKEN"Response
Section titled “Response”200 with a JSON body.
Errors
Section titled “Errors”| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No API key, or one that does not work. |
| 403 | token-scope |
The key’s scopes do not cover this route. |
| 404 | not-found |
Not found, or not yours. An object of another organization answers like one that does not exist. |