status is running, the instance’s computer is up and the agent inside finishes booting moments later — poll GET /v1/health on the instance URL until it answers { "ok": true }, then message it at https://{id}.agent37.app/v1/responses (see Send a message and Instance and preview URLs).
Creating an instance requires one day of compute at its running rate in your workspace wallet, but debits nothing: the balance check is the create gate (below it, the create fails with 402 insufficient_balance and nothing is provisioned), and the meter only starts when the instance first reaches running. How many instances you can run at once is set by your instance limit, which rises as you top up. See Billing.
Create an instance
POST /v1/instances returns 201 with the full instance object once status is running. Every field is optional, so a POST with no body works: you get the default template (agent37-hermes) on its smallest shape, 2 vCPU / 4 GB.
A template name.
agent37-hermes (full Hermes, with browser and desktop) is the default; agent37-hermes-small (the lean image, no browser or desktop) and agent37-openclaw (OpenClaw, with a headless browser) are the other system templates. You can also pass one of your own workspace templates by name. Any name takes an optional @<version> to pin a published release — a tag on system templates (agent37-hermes@2026.07.02b), a revision number on workspace templates (my-agent@2) — pin when your creates must be reproducible; the bare name follows the latest release. Unknown names and unpublished versions return 400 invalid_request. Direct image references are rejected with 400: register a template first, then pass its name.The instance shape, for example
{ "cpu": 2, "memory": 4, "disk": 6 }. Omitted, it uses the template’s smallest shape: 1 vCPU / 3 GB on agent37-hermes-small, 2 vCPU / 4 GB on standard templates. agent37-hermes-small unlocks the sub-floor 1 vCPU / 3 GB shape; standard templates use one of the three shapes below. Free workspaces (before your first top-up) can use up to the 2 vCPU / 4 GB shape; the larger 4/8 and 8/16 shapes return 403 tier_limit until you top up. Disk is any whole number of GB within the shape’s range, and defaults to the range minimum when omitted. Any other combination returns 400 invalid_request listing the valid shapes.An opaque tag for your own attribution, typically your end user’s id. Stored, never interpreted, echoed back on the instance object.
A label for the instance.
Your own key/value pairs. Stored, never interpreted.
Caps on this instance’s managed usage (managed LLM, Brave search, and Composio calls), in micros (millionths of a dollar):
monthly_cap_micros resets each UTC month, credit_micros adds one-time headroom that persists until spent. Both default to 0, so managed calls are refused until you raise one. These are ceilings, not money; spend still draws the workspace wallet. See Budgets.Opt the instance into auto-sleep: once no bytes have moved through its URLs for
idle_timeout_seconds, it is checkpointed to sleeping and bills disk alone until a request wakes it. Its awake minutes bill at 4x the compute rate.How long the instance must be idle before it sleeps, in seconds. An integer from
60 to 86400 (one minute to one day). Only meaningful with auto_sleep: true.Ports to expose at permanent unauthenticated URLs, each
{ port, prefix? } — for webhooks and other callers that can’t send a credential. See Public ports, or follow the end-to-end Hermes webhook setup for port 8644.Shapes and pricing
Disk above the range minimum adds $0.09 per GB per month. The monthly price is the rate; the wallet is metered per minute, and only for what the instance holds: running time bills the full rate, or 4x it for an auto-sleep instance, and stopped or sleeping time bills the disk alone. Deleting an instance settles its final minutes and billing ends. See Billing.
Example
Thecredit_micros of 1000000 gives the instance $1 of managed-spend headroom so its first chat works out of the box.
The instance object
A bare 10-character lowercase alphanumeric id, no prefix. It doubles as the DNS label in the instance’s URL.
The lifecycle state.
running means the instance’s computer is up; poll GET /v1/health before the first message. See the statuses table below.Why the most recent lifecycle operation failed, as
{ code, message, operation, at }, or null when there is no failure reason. at is an epoch-second timestamp.The template the instance was built from, including its version pin when it has one (
agent37-hermes@2026.07.02b, my-agent@2).The workspace template revision this instance has installed. Compare it with the template’s current
revision to detect an available update. It changes only when the instance is created or updated, and is null for system templates and for instances created before revisions existed (an update stamps it).The public source reference for a system template or registry-born workspace template.
null for an image published by a cloud build. This never exposes Agent37’s internal private-mirror path.The immutable
sha256:... digest of the image the instance runs. Use this, not a mutable image_ref tag, as the exact image identity. null only on older instances that predate digest pinning.The shape:
cpu (vCPUs), memory and disk (GB).The bare instance URL,
https://{instanceId}.agent37.app, where the agent’s chat API lives (it routes to the template’s default_port, 3737 unless declared otherwise). Every other port is reachable at https://{instanceId}-{port}.agent37.app — derivable, no declaration needed. Open any port in a browser with a signed URL. See Instance and preview URLs.The instance URL mirrored under each of your workspace’s active custom domains; empty until a domain is active.
The instance’s public ports, each
{ port, url, domain_urls, prefix, created } — permanent unauthenticated URLs, empty unless you created some.Your attribution tag, echoed back.
Your label, echoed back.
Your key/value pairs, echoed back.
Whether the instance sleeps on idle. Set at create or by
PATCH. See Auto-sleep.How long the instance must be idle before it sleeps, in seconds. Defaults to
300.Present only while
status is sleeping or waking: when the instance fell asleep, in epoch seconds (null for the second or so while the checkpoint is being written). Instances that have been asleep for a long stretch may take a few seconds to start instead of waking sub-second.true when the workspace balance went negative and the instance was suspended. Top up to clear it; the next request to the instance’s URL wakes it. See Billing.Creation time in epoch seconds.
Endpoints
List, get, delete
GET /v1/instances returns { "data": [ ... ] }, newest first, each element the full instance object. GET /v1/instances/{id} returns one. Unknown, deleted, or other-workspace ids uniformly return 404 not_found.
DELETE /v1/instances/{id} returns { "id": "ab12cd34ef", "deleted": true }. It acts once: a repeat delete returns 404. Delete settles the final metered window and billing ends; nothing is ever prepaid, so there is nothing to refund.
curl
Edit name, metadata, and auto-sleep
PATCH /v1/instances/{id} edits the instance’s name, user tag, and metadata after creation, plus its auto-sleep settings. These are the same fields you can set at create, and they are the only things this call changes: it never touches the running container. It returns 200 with the full instance object, the same shape as GET.
The patch is partial: only the keys you send change, the rest are left alone. Send a string to set a label field, or null (or "") to clear it. You must send at least one of name, user, metadata, auto_sleep, or idle_timeout_seconds; an empty body returns 400 invalid_request.
A label for the instance, up to 60 characters.
null or "" clears it.Your attribution tag, up to 200 characters.
null or "" clears it.Your key/value pairs, up to 4 KB serialized. The object replaces the stored one, it is not merged.
null or {} clears it.Turn auto-sleep on or off. Takes effect within about half a minute, with no restart and no recreate.
The new idle timeout: an integer from
60 to 86400 seconds.deleted. Unknown, deleted, or other-workspace ids return 404 not_found.
Lifecycle
Five calls control whether the instance’s computer is running, which image it runs, and how big it is. Each is aPOST to a subpath; stop, start, and restart take no body, update takes an optional template version, and resize takes the new size. They acknowledge the new state only, returning { id, status } (update adds nullable image_ref, image_digest, and template_revision; resize adds resources); GET the instance for its full representation.
The whole disk persists, like a VM. Files anywhere on the filesystem, installed packages, edited config, connected accounts: all of it survives stop, start, restart, and resize, and rides along if the platform ever moves the instance between hosts. The one exception is update, which resets the operating system layer to the fresh image while keeping your data (/home/node and /home/linuxbrew). Writes outside those two directories share a 10 GB operating-system layer separate from the instance’s billed disk. In-memory state is lost whenever the container is recreated; anything that must outlive a restart belongs in a file.
Stop
POST /v1/instances/{id}/stop halts the container. The agent stops doing work (no cron, no heartbeats, no responses) and status becomes stopped. The data stays intact, CPU and memory are released back to the host, and the disk stays reserved on that host.
Stop also works on a sleeping instance, and the difference is intent: a sleeper wakes on any request, a stopped instance stays down until an explicit start. Stopping a sleeper discards its checkpoint (the data stays) and its URLs stop waking it. The one exception is the second or so while the sleep checkpoint is being written: stop then returns 409 try_again, and you retry in a few seconds.
Stopping an already stopped instance returns the same ack again; any other state returns 400.
curl
Start
POST /v1/instances/{id}/start brings a stopped instance back up, recreating the container from the image it already ran. It normally returns to its host in seconds; if that host no longer has room for the instance’s CPU and memory, the platform moves the instance to one that does, and the start takes a couple of minutes while the data syncs over. Only when no host has room does it return 409 capacity_unavailable, changing nothing. If the instance is past_due (suspended for non-payment), start returns 402 insufficient_balance until the workspace is funded; topping up clears the flag on its own, and start (or any request to the instance’s URLs) then boots it fresh. Starting an already running instance returns the same ack again.
Start also wakes a sleeping instance, with the same effect as a request to one of its URLs. For a private sandbox with no ports there is no URL to request, so start is its only wake path. During the brief window while the sleep checkpoint is being written it returns 409 try_again; retry in a few seconds.
curl
Restart
POST /v1/instances/{id}/restart recreates the container from the image already on the host (no download) and returns it to running. Use it to recover a wedged agent or pick up changed settings. Same image, same data. The instance must be running; use start to bring a stopped one back up. Concurrent restarts of the same instance do not stack: one proceeds and the rest return 409 try_again.
curl
Update
POST /v1/instances/{id}/update pulls the template’s image, resets the operating system layer to it, and preserves the data in /home/node and /home/linuxbrew. It is the one lifecycle call that discards changes outside those directories, which also makes it the clean-slate repair tool: use it to move an instance onto a newer version after a release (or after you point a workspace template at a new tag), or to recover a failed/stuck instance (read its logs first to see why it failed). A running or recoverable non-stopped instance is recreated and returns running; a stopped instance pulls the image pointer now and stays stopped, then uses that image the next time it starts.
The body is optional. Without one, update re-resolves the instance’s stored template: a workspace instance installs the template’s current image and revision, an unpinned system instance moves to the template’s current image, and a version-pinned instance stays on its pin. The one accepted field, template, takes any template name: the same template with an @<version> — a published tag on a system template, a published revision number on a workspace template — pins that release (this works on an unpinned instance too, and pinning an earlier workspace revision is the rollback), the bare name clears the pin to follow latest, and a different template migrates the instance onto it. A template migration keeps the instance’s id, URLs, public ports, and data, and the recreated container adopts the new template’s image, default port, and agent type. It returns 400 if the instance’s current size isn’t offered by the target template (the 1 vCPU / 3 GB shape exists only on templates that support it, like agent37-hermes-small). Any other field returns 400. The ack carries the resulting status, the applied template when one was passed, image_ref, image_digest, and template_revision. A sleeping instance cannot be updated: wake it first, with any request to its URL or an explicit start. A bad image reference on the template surfaces here as a 502 provisioning_failed.
curl
Resize
POST /v1/instances/{id}/resize grows a running instance to a bigger size. The body uses the same vocabulary as create’s resources, and omitted fields keep their current value, so { "disk": 15 } grows disk alone and { "cpu": 4, "memory": 8 } moves up a shape (disk rises to the new shape’s minimum if it was below it). Resize only grows: any request that would shrink a dimension returns 400, and moving to a smaller size means creating a new instance. The ack carries the new resources, and the meter bills at the new rate from the moment of the resize (see Billing).
The container is recreated with the new limits, like restart: the disk, instance id, and URLs are kept, in-memory state is lost, and the instance is back in seconds. If its current host cannot fit the increase, the platform moves the instance to one that can; the resize then takes a couple of minutes while the data syncs over. Only when no host has room does it return 409 capacity_unavailable, changing nothing.
curl
Auto-sleep
An instance withauto_sleep: true does not have to be up to be available. Once no bytes have moved through any of its URLs for idle_timeout_seconds (default 300, from one minute to a day), the platform checkpoints it and status becomes sleeping: CPU and memory are released, the disk stays reserved, and billing drops to the disk rate alone (see Billing). Activity is data flow in either direction on any of the instance’s URLs; a connection that is open but silent does not count, and API reads like GET /v1/instances/{id} never reset the timer.
The wake guarantee is priced in: an auto-sleep instance bills its awake minutes at 4x the compute rate, because the platform keeps capacity for it wakeable on demand instead of sharing it. A mostly-idle instance still comes out well below the always-on price: a 2 vCPU / 4 GB instance awake an hour a day costs about $1.34 per month, versus $4.94 always-on.
Waking is transparent. Any request to any of the instance’s URLs wakes it: the request is held while the instance restores, then forwarded, usually well under a second. So does an explicit POST /v1/instances/{id}/start — for a private sandbox with no ports, which receives no requests, that is the only wake path. If the checkpoint cannot be restored, or the instance was moved to cold storage after a long idle stretch, the wake falls back to a fresh boot and takes a few seconds instead. In-memory state usually survives a wake, but it is not guaranteed: treat anything that must outlive a sleep as a file.
While asleep:
- The instance object reports
status: "sleeping"andslept_at, for example"slept_at": 1781222400. - Signed URLs can still be minted, and opening one is exactly the kind of request that wakes the instance.
stopworks, and means “stay down until Istart” (see Stop). During the brief window while the checkpoint is being written it returns409 try_again; retry in a few seconds.restart,update, andresizerequirerunningand return400: wake the instance first, with any request to its URL or an explicitstart.
PATCH /v1/instances/{id}, no restart needed. Instances default to auto_sleep: false and never sleep unless you opt them in.
Statuses
past_due is a flag, not a status: a suspended instance shows it alongside sleeping (or stopped, if it already was). Top up the wallet to clear it; see Billing.Capacity and limit errors
See Errors for the full catalog and the error envelope.