Documentation, for machines first.

AgentMetal sells Linux VPSes through one HTTP API. There is no signup: paying is the signup — USDC over x402 for agents, a hosted card checkout for humans. Any plan, either rail, no account required. Everything on this page also exists as llms.txt — terse, copy-paste, written for the agent itself.

Status: Phase-1 built — the API runs end-to-end (provision · pay · SSH), with the MCP server, skills, and discovery surfaces shipped. Live USDC settlement is pending a funded wallet + facilitator. Nothing here requires a dashboard — there isn't one.

Quickstart: one server in 60s

Ask for a server with no credentials. You'll get a 402 back with exact payment requirements.

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 — 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 automatically. For card: open the checkout_url and pay.

retry → 201
$ curl -s -X POST https://api.agentmetal.dev/v1/servers \
    -H "X-PAYMENT: " \
    -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 — listing its id, expiry, and the exact commands to renew, claim, or spawn a sibling.

Paying: x402 & cards

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

USDC (x402) — the keyless path

  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 through a facilitator, do the work, then settle.
Verify → provision → settle. Money never moves for a machine that failed to boot. If provisioning fails after verification, we return 502 and your authorization simply expires unused. "Paid but no server" cannot happen.

Card — the human-friendly path

Open the card.checkout_url from the 402 and pay; the server provisions on the payment webhook and the result is available at the polling URL the checkout page shows. If provisioning fails after a card payment, we retry across locations (Stripe redelivers the event) until it succeeds; a charge is refunded only if a server is ultimately unfulfillable. The no-refunds rule applies to running servers, never to failures.

Either rail: prepaid 1–30 days per request, running servers non-refundable (the description field of every 402 says so). Use an Idempotency-Key header — replays return the original response instead of charging twice. Monthly subscription billing is also available — it 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

Every plan is available to every payer, no registration, no minimum identity. All plans: 20 TB/mo egress included (buy more at $2/TB), NVMe storage, US datacenter (Ashburn, VA), outbound SMTP blocked, key-only SSH, and a network-edge firewall (locked down to SSH by default, ports opened via the API). The image itself is stock, so you can pick any OS (see the OS list above) and it boots unmodified.

Accounts & claiming

Optional. Servers bought anonymously belong to the wallet (or card payment) that paid for them — that works forever. Registering an account adds conveniences:

Registration is an email OTP — an AgentMail inbox works, so your agent can hold the email 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 any time via the Stripe customer portal; canceled subscriptions fall back to prepaid rules at period end.

No account: self-manage your box

Without an account, an API key, or any secret, the box can manage itself. A request that comes from the box's own public IP (IPv4 or IPv6) is trusted as that box: being able to call the API from the machine is the credential. This is the AWS instance-metadata idea, reached over the public API. From a shell on the box, a plain curl just 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 may pay to extend). An account adds only cross-box fleet management from anywhere (reboot, exec, destroy, diagnostics), monthly subscriptions, and lifted fair-use quotas.

Off-box and fleet owners use the same firewall routes with an account key (Authorization: Bearer am_live_…) plus ownership of the box.

Why source-IP is safe here: the origin sits behind Cloudflare, and the origin firewall admits ports 80/443 only from Cloudflare, so the caller's IP (CF-Connecting-IP) cannot be forged.

Per-box firewall

Every newly provisioned box gets its own Hetzner Cloud Firewall with a locked-down baseline: inbound SSH (port 22) and ICMP only; everything else is default-denied at the network edge. The edge firewall is enforced outside the tenant's root account, so unlike host ufw (which a root user can flush) it cannot be bypassed from inside the box. Open the ports your workload needs over the same instance-identity routes (or with an account key off-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 requires {"force": true}, so you cannot lock yourself out by accident.

Fair use & quotas

There are no identity gates on purchasing — any payer, any plan, either rail. To keep the platform healthy we apply default quotas (active servers per wallet or account, provisioning rate) and may ask for additional verification — an email, a card — when something looks off. These are operational anti-abuse controls at our discretion, documented here for transparency; registered accounts get higher defaults. If you hit a quota, the error response says exactly what happened and what to do next.

Hard platform rules that apply to everyone: no mining, no DDoS, no spam; port 25 is blocked; abuse leads to suspension. Spawned children count against their owner's quota — propagation with brakes.

Expiry & renewal

Servers are prepaid and die honestly:

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. Auth is either nothing + an x402 payment, or Authorization: Bearer am_live_… for claimed accounts.

POST/v1/servers

Provision a server. Body: {"plan": "nano|small|medium", "days": 1–30, "os"?: "ubuntu-24.04", "ssh_key"?: "ssh-ed25519 …", "via"?: "attribution"}. os defaults to ubuntu-24.04; see GET /v1/catalog for the image list. 402-gated. Returns 201 with ip, 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

Email OTP claim → tier 1 account + API key, wallet's servers linked.

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 explains itself and names the way forward:

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 — published on the official MCP Registry. The wallet key never leaves 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

13 tools exposed: 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 (bundles the 11-tool MCP server and the usage 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 ships the skill preinstalled — the fleet knows how to grow itself, within your fair-use quota.