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:

statusmeaningwhat visitors see
buildingThe first build (or a restore) is running.A "Building…" page that refreshes itself (503).
liveAll services are up and serving.The app.
failedThe 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).
expiredThe TTL ran out. Processes are stopped; the snapshot is kept.A "This preview expired" page (410).
deletedDestroyed, 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 (or PATCH /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, and stack.expired is emitted with retained_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.

credentiallooks likeheld bygrants
Manage tokenast_anon_…The agent that created the stackStatus, logs, events, redeploy, extend and destroy for that one stack.
Claim codeCLM-XXXX-XXXX-XXXXThe human (the agent passes it on)Taking ownership of the stack, once.
API keyas_live_…The account ownerEvery stack in the account, deploying into the account, and claiming over the API.
Email and passwordThe account ownerThe dashboard at /dashboard.
Webhook secretwhsec_…Whoever receives webhooksVerifying 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.

Stuck? Your agent can read /skill.md, or connect it over MCP.