Docs / Get started
How it works
Stack states, the TTL, expiry and snapshot retention, claim codes, tokens and the shape of service URLs.
A stack is one deploy unit: a name, up to 4 services, and the credentials to manage it. This page explains the states a stack moves through, what happens at expiry, and who holds which credential.
Stack states#
Every stack has a status, returned by GET /v0/stacks/{id} and by
agentserve status:
| status | meaning | what visitors see |
|---|---|---|
building | The first build (or a restore) is running. | A "Building…" page that refreshes itself (503). |
live | All services are up and serving. | The app. |
failed | The first build failed, or a service crashed more than 5 times in 10 minutes. error says why. | A "This deploy failed" page with the error (502). |
expired | The TTL ran out. Processes are stopped; the snapshot is kept. | A "This preview expired" page (410). |
deleted | Destroyed, or purged after retention. | A "Gone" page (410). |
Two more fields matter during redeploys. deploying holds the generation number currently being built
(or null), and deploy_error is set when a redeploy failed and the previous generation was
put back. A redeploy never takes a live stack out of live while it builds; see
Redeploys and rollbacks.
TTL and expiry#
Anonymous stacks get a 1h TTL by default. You can set a different one with ttl in
agentserve.yaml or --ttl on the CLI, as a duration such as 15m or
30m; the minimum is 15 minutes, and the server caps how long an unclaimed stack can live (see
Limits). The response's expires_at is a Unix timestamp.
- 5 minutes before expiry, the stack emits
stack.expiring, a cue for the agent to remind its human to claim it. agentserve extend --ttl 30m(orPATCH /v0/stacks/{id}with{"ttl": "30m"}) moves the expiry to now plus that duration. It doesn't add to the remaining time.- At expiry, every process is stopped, the status becomes
expired, andstack.expiredis emitted withretained_until.
Snapshots and retention#
An expired stack isn't deleted straight away. Its built services (the current generation's source, virtualenvs,
node_modules and static output) and every service's $DATA_DIR stay on disk for 7 days. The
API reports this as expired_at and retained_until.
Claiming an expired stack restores it from that snapshot: the services are started again from their built
artifacts, without a rebuild, at the same URLs and with the same data. A stack.restored event follows.
If nobody claims it within the retention window, the stack and its data are deleted.
An expired stack can't be redeployed or extended. It can only be claimed.
Claim codes#
An anonymous deploy returns a claim code and a claim URL:
{
"claim_code": "CLM-7KQ4-XM2P-9RTW",
"claim_url": "https://agentserve.sh/claim/CLM-7KQ4-XM2P-9RTW",
"note": "Unclaimed stacks expire. Give claim_url to your human so they can keep this stack."
}
Codes use an alphabet without 0, O, 1, I and L,
so they survive being read aloud. They are accepted in any case, with or without dashes and the CLM
prefix. A code works once: claiming clears it. Someone with only the code can also enter it at
/claim. Details in Claiming a stack.
Who holds what#
The agent and the human hold different credentials, and they grant different things.
| credential | looks like | held by | grants |
|---|---|---|---|
| Manage token | ast_anon_… | The agent that created the stack | Status, logs, events, redeploy, extend and destroy for that one stack. |
| Claim code | CLM-XXXX-XXXX-XXXX | The human (the agent passes it on) | Taking ownership of the stack, once. |
| API key | as_live_… | The account owner | Every stack in the account, deploying into the account, and claiming over the API. |
| Email and password | The account owner | The dashboard at /dashboard. | |
| Webhook secret | whsec_… | Whoever receives webhooks | Verifying X-AgentServe-Signature. |
All of these are returned once and stored only as hashes. The manage token, the API key and the webhook secret
are sent as Authorization: Bearer <token> where they apply (the webhook secret never is: it only
signs deliveries).
After a claim, the agent's manage token keeps working, so the agent can go on redeploying. The owner can revoke it from the project's settings page in the dashboard; from then on only the API key manages the stack.
An agent that has its human's API key can deploy straight into the account: no claim code is issued, and the stack has no TTL. Only give an agent your API key if you want it to act on your whole account.
URLs#
Each service gets its own host name:
<service>-<slug>.<domain>
https://api-todo-app-8c1f.agentserve.sh
https://web-todo-app-8c1f.agentserve.sh
The slug is the stack name, lowercased and shortened to 24 characters, plus a random 4-character suffix, fixed when the stack is created. Redeploys, expiry, restores and claims never change it.
Responses from an unclaimed stack carry an X-AgentServe-Unclaimed header, and every response carries
X-AgentServe-Stack with the stack id.