Documentation, for machines first.

AgentMetal sells Linux VPSes through one HTTP API. There's no signup: paying is the signup. Agents pay in USDC over x402, people use a hosted card checkout. Any plan works with either rail, and you don't need an account. This page also exists as llms.txt, a short copy-paste version written for the agent itself.

Start here: the quickstart walks you through asking for a server, paying and connecting over SSH. To wire up an agent, see the MCP and skills sections below.

Quickstart: one server in 60s

Ask for a server without credentials. You'll get a 402 back that says exactly what to pay.

request
$ curl -s -X POST https://api.agentmetal.dev/v1/servers \
    -H "Content-Type: application/json" \
    -d '{"plan": "nano", "days": 7}'
response · 402
HTTP/1.1 402 Payment Required
{
  "x402Version": 2,
  "error": "payment required",
  "resource": {
    "url": "https://api.agentmetal.dev/v1/servers",
    "description": "nano server (2vCPU/2GB), 7 days, prepaid, no refunds.",
    "mimeType": "application/json"
  },
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:8453",               // Base mainnet (CAIP-2)
    "amount": "8400000",                   // $8.40 in atomic USDC, 6dp (nano × 7d)
    "asset": "0x8335…",                     // USDC on Base
    "payTo": "0x7c…e1",
    "maxTimeoutSeconds": 120,
    "extra": { "name": "USD Coin", "version": "2" }
  }],
  "card": { "checkout_url": "https://checkout.stripe.com/c/pay/cs_…" }  // or pay by card
}

Pick a rail. For USDC, sign an EIP-3009 transferWithAuthorization for that amount and retry with the X-PAYMENT header. Wallet helpers like @x402/fetch do both steps for you. For a card, open the checkout_url and pay.

retry → 201
$ curl -s -X POST https://api.agentmetal.dev/v1/servers \
    -H "X-PAYMENT: <base64 v2 payment payload>" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{"plan": "nano", "days": 7}'

HTTP/1.1 201 Created
{
  "id": "srv_kx04qd",
  "status": "running",
  "plan": "nano",
  "ipv4": "188.245.32.17",
  "ssh": "[email protected]",  // access with the ssh_key you sent
  "expires_at": "2026-07-06T00:00:00Z",
  "renew": "POST /v1/servers/srv_kx04qd/extend"
}

That's the whole product. SSH in. The machine boots with /root/SERVER.md (its birth certificate), which lists its id, its expiry and the exact commands to renew, claim an account or spawn a sibling.

Paying: x402 & cards

Every paid endpoint answers an unpaid request with 402 Payment Required and lists all your payment options: the x402 accepts array (USDC on Base) and a card.checkout_url (hosted Stripe Checkout). Any plan works with either rail, and you don't need an account.

USDC (x402): no keys or accounts

  1. Call any paid endpoint without payment → 402 with an accepts array.
  2. Your wallet signs an EIP-3009 USDC authorization for the exact amount.
  3. Retry the identical request with the signed payload in X-PAYMENT.
  4. We verify the payment through a facilitator, do the work, and then settle.
Verify, provision, then settle. If the machine fails to boot, no money moves. When provisioning fails after verification, we return 502 and your authorization expires unused. You can't end up paid with no server.

Card: for people

Open the card.checkout_url from the 402 and pay. The server starts when the payment webhook arrives, and the checkout page shows a URL you can poll for the result. If provisioning fails after a card payment, we retry across locations (Stripe redelivers the event) until it works. We refund the charge only if we can't deliver a server at all. The no-refunds rule covers running servers, never failures.

On either rail you prepay 1–30 days per request, and running servers aren't refundable (the description field of every 402 says so). Send an Idempotency-Key header: a replay returns the original response instead of charging you twice. Monthly subscription billing needs a registered account.

Plans & pricing

planspecsprepaid (usdc or card)monthly (account)
nano2 vCPU · 2 GB · 40 GB NVMe$1.20 / day$30 / mo
small3 vCPU · 4 GB · 80 GB NVMe$2.20 / day$55 / mo
medium4 vCPU · 8 GB · 160 GB NVMe$4.20 / day$99 / mo

Anyone who pays can buy any plan. You don't register or prove who you are. All plans: 20 TB/mo egress included (buy more at $2/TB), NVMe storage, a US datacenter (Ashburn, VA), outbound SMTP blocked, key-only SSH, and a network-edge firewall (only SSH open by default; you open ports through the API). The OS image is stock, so any OS in GET /v1/catalog boots unmodified.

Accounts & claiming

Optional. A server bought anonymously belongs to the wallet (or card payment) that paid for it, and that never changes. An account adds:

You register with an email OTP. An AgentMail inbox works, so your agent can own the email address itself.

claim flow
$ curl -X POST …/v1/claim -d '{"email": "[email protected]"}'
# 6-digit code arrives by email
$ curl -X POST …/v1/claim/verify \
    -d '{"email": "[email protected]", "code": "493817", "wallet": "0xAB…", "wallet_signature": "0x…"}'
# Linking a wallet requires wallet_signature: sign "AgentMetal: link wallet <wallet> to <email>"
HTTP/1.1 200 OK  { "account": "acc_…", "api_key": "am_live_…", "servers_claimed": 2 }

For monthly billing, POST /v1/billing/checkout returns a Stripe Checkout URL for a subscription. Manage or cancel it any time in the Stripe customer portal. A canceled subscription falls back to prepaid rules at the end of the period.

No account: self-manage your box

The box can manage itself with no account, API key or secret. We trust a request that comes from the box's own public IP (IPv4 or IPv6) as that box: calling the API from the machine is the credential. It's the AWS instance-metadata idea, served over the public API. From a shell on the box, a plain curl works:

on the box · who am I
$ curl -s https://api.agentmetal.dev/v1/self
{
  "server_id": "srv_kx04qd",
  "plan": "nano",
  "status": "running",
  "expires_at": "2026-07-06T00:00:00Z",
  "ipv4": "188.245.32.17",
  "firewall": { … current inbound rules … }
}

What you can do with no account: discover plans (GET /v1/catalog), provision and pay (x402 USDC or card), poll an order (GET /v1/orders/<session_id>), self-test x402 (GET /v1/ping), self-manage the box you are on (GET /v1/self, open and close your own firewall), and extend a lease (anyone can pay to extend). An account adds three things: managing your whole fleet from anywhere (reboot, exec, destroy, diagnostics), monthly subscriptions, and higher fair-use quotas.

From off the box, owners use the same firewall routes with an account key (Authorization: Bearer am_live_…), as long as they own the box.

Why trusting the source IP is safe here: the origin sits behind Cloudflare, and its firewall only lets Cloudflare reach ports 80/443, so nobody can forge the caller's IP (CF-Connecting-IP).

Per-box firewall

Every new box gets its own Hetzner Cloud Firewall. Out of the box it lets in SSH (port 22) and ICMP, and the network edge drops everything else. The firewall runs outside the box, so root can't turn it off from inside (root can flush host ufw, though). Open the ports your workload needs over the same instance-identity routes, or with an account key from off the box:

on the box · open then close 443
$ curl -s https://api.agentmetal.dev/v1/servers/srv_kx04qd/firewall
{ "managed": true, "rules": [ { "protocol": "tcp", "port": "22", … }, … ] }

$ curl -s -X POST https://api.agentmetal.dev/v1/servers/srv_kx04qd/firewall/rules \
    -d '{"protocol":"tcp","port":"443"}'

$ curl -s -X DELETE https://api.agentmetal.dev/v1/servers/srv_kx04qd/firewall/rules \
    -d '{"protocol":"tcp","port":"443"}'

Rule validation: protocol is one of tcp, udp, icmp, esp, gre; port is 1–65535 or a range like "8000-9000" (required for tcp and udp); up to 10 source CIDRs (default 0.0.0.0/0 + ::/0); at most 20 rules. Removing the last SSH (port 22) rule needs {"force": true}, so you can't lock yourself out by accident.

Fair use & quotas

We don't check who you are before you buy. Anyone who pays can buy any plan on either rail. To stop abuse we set default quotas (active servers per wallet or account, and a provisioning rate), and we may ask for an email or a card when something looks off. We apply these at our discretion and list them here so you know. Registered accounts get higher defaults. If you hit a quota, the error says what happened and what to do next.

Rules for everyone: no mining, no DDoS, no spam. Port 25 is blocked, and abuse gets you suspended. Spawned children count against their owner's quota, so a fleet can grow only so far.

Expiry & renewal

Servers are prepaid, and they end when the time runs out:

renew
$ curl -X POST …/v1/servers/srv_kx04qd/extend -d '{"days": 7}'
← 402 (same dance) → retry with X-PAYMENT → 200  { "expires_at": "2026-06-24…" }

API reference

Base URL https://api.agentmetal.dev. For auth, send nothing and pay over x402, or send Authorization: Bearer am_live_… if you've claimed an account.

POST/v1/servers

Provision a server. Body: {"plan": "nano|small|medium", "days": 1–30, "os"?: "ubuntu-24.04", "location"?: "cdmx-1", "ssh_key"?: "ssh-ed25519 …", "via"?: "attribution"}. os defaults to ubuntu-24.04; see GET /v1/catalog for images and zones. Leave out location for Hetzner US. cdmx-1 is our own bare metal in Mexico City: Ubuntu 22.04/24.04 only, and SSH is on the box's own port of a shared IP (ssh_port in the response). 402-gated. Returns 201 with ip, ssh_port, ssh key (once), expiry.

GET/v1/servers/:id

Status, plan, ip, expires_at. Free.

GET/v1/self

The box identifies itself by source IP, no key needed. Returns { server_id, plan, status, ipv4, expires_at, firewall }. Call it from a shell on the box.

GET/v1/servers/:id/firewall

List inbound rules: { managed, rules }. Instance identity (from the box) or owner account.

POST/v1/servers/:id/firewall/rules

Open a port. Body: {"protocol": "tcp", "port": "443"}. Instance identity or owner account.

DELETE/v1/servers/:id/firewall/rules

Close a port. Same body. Removing the last SSH (22) rule needs {"force": true}.

POST/v1/servers/:id/extend

Add 1–30 paid days. 402-gated. Anyone can pay to extend a server; only its owner can destroy it.

DELETE/v1/servers/:id

Destroy immediately. Owner only (paying wallet or claimed account). No refund of remaining days.

POST/v1/claim · /v1/claim/verify

Claim by email OTP. You get a tier 1 account and an API key, and the wallet's servers are linked to it.

POST/v1/billing/checkout

Stripe Checkout session for tier 2. Requires a claimed account.

Errors teach

Agents don't browse docs sites, so every non-2xx body says what went wrong and what to do next:

403 example
{
  "error": "quota_exceeded",
  "message": "This wallet has 2 active servers (the default fair-use quota).",
  "hint": "Register an account to raise default quotas:
           POST /v1/claim {\"email\": \"…\"}",
  "docs": "https://agentmetal.dev/llms.txt"
}

MCP server

For agents that speak Model Context Protocol. It's on the official MCP Registry. The wallet key stays on your machine: the MCP server signs locally and calls the public API.

claude code
$ claude mcp add agentmetal -e WALLET_PRIVATE_KEY=0x… -- npx @agentmetal/mcp

It exposes 13 tools: get_catalog, provision_server, get_server, list_servers, extend_server, reboot_server, server_logs, exec_command, get_firewall, manage_firewall, destroy_server, claim_account, verify_claim.

Skills

All three skills live in the public, auditable agentmetal/agents repo.

Claude Code / Agent SDK: one command installs the plugin. It bundles the 13-tool MCP server and the skill that teaches the full flow.

claude code · plugin
$ /plugin marketplace add agentmetal/agents
$ /plugin install agentmetal@agentmetal

Prefer just the tools? Add the MCP server on its own.

Every server we sell comes with the skill installed, so the fleet can grow itself up to your fair-use quota.

AgentMetal Cloud: the console

You can run servers without an agent. AgentMetal Cloud is our own OpenStack cloud with a web console for people. It's a free invite-only beta for now, and it's separate from the API above: servers you launch there don't show up in /v1/servers yet.

  1. Sign in at cloud.agentmetal.dev with the details from your invite. You land in your own project, which already has a private network, a router to the internet, and a firewall that lets in SSH and ping.
  2. Add a key pair under Compute → Key Pairs (paste your public key), or set a login password while launching.
  3. Launch an instance: pick an Ubuntu 22.04 or 24.04 image, a flavor (m1.tiny to m1.large), and the private network. Leave the security group on default.
  4. Connect. Within a minute the instance gets a floating IP (172.16.2.N, shown in the instance list). SSH in on port 22000 + N: floating IP 172.16.2.81 means ssh -p 22081 [email protected]. The same command is saved in the instance's metadata as ssh. The Console action opens a screen in your browser tab, no SSH needed.

Beta limits: up to 10 instances, 16 vCPUs and 32 GB of RAM per project; boot from image only (no volumes yet); from the internet, only SSH reaches your instances, through the port above. Load balancers and Heat stacks are available under Network and Orchestration.

New to HTTP payments? Read how the x402 protocol pays for API requests before you pay for a server.