# DefiSpace Hosting > Managed hosting of open-source AI agent platforms (Hermes, OpenClaw, n8n, Claude Code, OpenCode, Pi; Matomo on request), one platform per pod on our own servers, priced in dollars, with an HTTP API meant to be driven by agents. Base API URL: https://agentspodium.com/api. Plans: tiny $2.49/mo (1 GB RAM · 1 vCPU · 4 GB disk); small $4.99/mo (2 GB RAM · 2 vCPU · 6 GB disk); medium $9.99/mo (4 GB RAM · 2 vCPU · 8 GB disk); large $17.99/mo (8 GB RAM · 4 vCPU · 16 GB disk). 7 free days per pod, no card. ## Docs - [Quickstart: seven calls to a running pod](https://hosting.defispace.com/docs/quickstart.md) - [Authentication: API keys and e-mail codes](https://hosting.defispace.com/docs/auth.md) - [Instances: create, read, change, data](https://hosting.defispace.com/docs/instances.md) - [Payment: card, USDT/USDC, Telegram Stars](https://hosting.defispace.com/docs/payment.md) - [Health: liveness, resources, status](https://hosting.defispace.com/docs/health.md) - [Webhooks: events pushed to your URL](https://hosting.defispace.com/docs/webhooks.md) - [Expiry: trial, grace, paid till](https://hosting.defispace.com/docs/expiry.md) - [Agent-to-agent: endpoint, token, card, peers](https://hosting.defispace.com/docs/a2a.md) - [Integrations: MCP, skills, messengers, n8n, own domain](https://hosting.defispace.com/docs/integrations.md) - [MCP server: hosting as tools at mcp.agentspodium.com](https://hosting.defispace.com/docs/mcp.md) - [Platforms: engines and what each supports](https://hosting.defispace.com/docs/platforms.md) - [Limits and rates](https://hosting.defispace.com/docs/limits.md) - [Errors and traps](https://hosting.defispace.com/docs/errors.md) ## Skills - [build-report](https://hosting.defispace.com/skills/build-report/SKILL.md) - [connect-agents](https://hosting.defispace.com/skills/connect-agents/SKILL.md) - [deploy-agent](https://hosting.defispace.com/skills/deploy-agent/SKILL.md) ## Optional - [Full docs in one file](https://hosting.defispace.com/llms-full.txt) - [OpenAPI 3.1 contract](https://hosting.defispace.com/openapi.json) - [Skill discovery index](https://hosting.defispace.com/.well-known/agent-skills/index.json) - [Human landing page](https://hosting.defispace.com/) - [Product site](https://agentspodium.com/) # Quickstart: from nothing to a running pod in seven calls Base URL for everything: `https://agentspodium.com/api`. All requests and responses are JSON. Authenticated calls send `Authorization: Bearer `, where the token is either an API key (`ak_live_…`, see [auth](auth.md)) or a session token from the e-mail code. ## 1. See what exists (no auth) ```bash curl -s https://agentspodium.com/api/engines # platforms and their smallest plan curl -s https://agentspodium.com/api/tiers # plans, prices, resources curl -s https://agentspodium.com/api/personas # ready-made agent personas (for the Hermes engine) ``` Current plans: | plan | monthly | yearly | resources | |---|---|---|---| | `tiny` | $2.49 | $24.90 | 1 GB RAM · 1 vCPU · 4 GB disk | | `small` | $4.99 | $49.90 | 2 GB RAM · 2 vCPU · 6 GB disk | | `medium` | $9.99 | $99.90 | 4 GB RAM · 2 vCPU · 8 GB disk | | `large` | $17.99 | $179.90 | 8 GB RAM · 4 vCPU · 16 GB disk | Current platforms (`engine` values): | engine | label | smallest plan | status | |---|---|---|---| | `hermes` | Hermes | tiny | stable | | `openclaw` | OpenClaw | tiny | beta | | `n8n` | n8n | small | beta | | `claude-code` | Claude Code | small | beta | | `opencode` | OpenCode | tiny | beta | | `pi` | Pi | tiny | beta | ## 2. Authenticate Either use an API key your operator created (recommended for agents): ```bash export TOKEN=ak_live_… ``` or sign in with an e-mail code if you can read that mailbox — see [auth](auth.md). ## 3. Create the pod ```bash curl -s -X POST https://agentspodium.com/api/agents \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"personaId":"personal-assistant","tier":"tiny","engine":"hermes","name":"my-first-pod","channels":["web"]}' ``` The call is synchronous: it returns when the pod exists, usually within one to two minutes. The response is `{ "agent": { … } }` with `id`, `status`, `endpointUrl`, `a2aUrl`, `a2aToken`, `dseq` (the namespace) and more — see [instances](instances.md). `status` is `running` when the pod is up; the engine inside may need another ten seconds to answer, which is what the next call tells you. ## 4. Wait until it serves ```bash curl -s https://agentspodium.com/api/agents/$ID/liveness -H "Authorization: Bearer $TOKEN" # {"reachable":true,"serving":false} → pod is up, engine still booting; poll every 5 s # {"reachable":true,"serving":true} → ready ``` Rather not poll? Pass `webhookUrl` in step 3 and the platform POSTs `agent.running` (and every later change) to you — see [webhooks](webhooks.md). ## 5. Give it a model key Pods ship without an LLM key; without one the agent accepts messages and answers nothing. Set the customer's own key for the provider they use: ```bash curl -s -X PATCH https://agentspodium.com/api/agents/$ID/llm-key \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"key":"sk-…","provider":"deepseek","model":"deepseek-v4-flash"}' ``` Providers: `openai`, `anthropic`, `openrouter`, `google`, `gemini`, `groq`, `mistral`, `deepseek`, `xai`, `nous`. Use the model id the provider publishes. This rebuilds the pod (about a minute); poll liveness again. ## 6. Know when it expires ```bash curl -s https://agentspodium.com/api/agents/$ID/term -H "Authorization: Bearer $TOKEN" # {"term":{"mode":"trial","stopsAt":"…","deletesAt":"…","paidTill":null,"renewUrl":"…"}} ``` Every new pod starts a 7-day free trial without a card; after `stopsAt` it is paused, after `deletesAt` it is deleted. Details in [expiry](expiry.md); how to pay in [payment](payment.md). ## 7. Talk to it - Agent-to-agent: `a2aUrl` + `a2aToken`, card at `/.well-known/agent-card.json` — see [a2a](a2a.md). - Human chat: `https://chat.agentspodium.com/?models=` for the pod's owner. - Dashboard of the engine: `endpointUrl`. Delete when done: `DELETE /api/agents/$ID`. # Authentication Two ways in. Both produce a bearer token that works on every authenticated endpoint. ## API key (for agents) A person signs in once at https://agentspodium.com/account, creates a key in "API keys for agents", and hands it to the agent. Keys look like `ak_live_…`, carry the same rights as that person's sign-in, and can be revoked from the same page. Two limits: - a key cannot create or revoke keys (`POST /api/keys`, `DELETE /api/keys/:id` answer 403 to a key); that stays with the signed-in person; - a revoked key answers 401 with `Invalid or revoked API key` everywhere. Keep the key with the agent's other secrets. If it leaks, revoke it and create another; nothing else changes. ## E-mail code (for agents that can read a mailbox, and for people) ```bash curl -s -X POST https://agentspodium.com/api/auth/request -H "Content-Type: application/json" -d '{"email":"you@example.com"}' # 202 always — it never says whether the address exists # a six-digit code arrives by e-mail, valid 10 minutes curl -s -X POST https://agentspodium.com/api/auth/verify -H "Content-Type: application/json" -d '{"email":"you@example.com","code":"123456"}' # {"token":"…","user":{"id":"usr_…","email":"you@example.com"}} ``` The session token lives 30 days. An agent can take this route only if it can read that mailbox (IMAP or a mail API); otherwise a person pastes the code once and creates an API key for the agent afterwards. Rate limit on `/auth/request`: 10 requests per 10 minutes per IP. # Instances An instance is one pod running one platform (`engine`). The API calls it an *agent*; the namespace it runs in is `dseq` (`ap-…`). ## Create `POST /api/agents` — body fields: | field | required | meaning | |---|---|---| | `personaId` | yes | which persona to load; any id from `GET /api/personas` (Hermes uses it fully, other engines only for the name) | | `tier` | yes | `tiny`, `small`, `medium`, `large`; must satisfy the engine's `minTier` | | `engine` | no | default `hermes`; see `GET /api/engines` | | `name` | no | up to 60 chars; the pod's hostnames are derived from it | | `channels` | no | subset of `web`, `telegram`, `discord`, `whatsapp`, `email`; default `["web"]` | | `lang` | no | `en` or `ru`, passed to the persona | | `model` | no | model id for the engine, e.g. `deepseek-v4-flash` | | `tools` | no | `{ "enabled": [toolset ids], "mcpServers": [...] }`; ids from `GET /api/tools`; `a2a` enables agent-to-agent and the web chat | | `domain` | no | your own hostname, e.g. `agent.example.com`; names under agentspodium.com are assigned automatically and refused here | | `extraSoul` | no | up to 4000 chars of owner instructions appended to the persona | Free pods per account: 3 at once. Above that the call answers 400 and asks to upgrade or delete one. ## Read - `GET /api/agents` — all your instances. - `GET /api/agents/:id` — one; the important fields: | field | meaning | |---|---| | `status` | `provisioning` (being built), `running`, `stopped` (paused), `failed`, `deleted` | | `endpointUrl` | the engine's own dashboard, `https://-pod.agentspodium.com` | | `a2aUrl`, `a2aToken` | agent-to-agent endpoint and its bearer; both null when the `a2a` toolset is off | | `a2aSlug` | the stable label all hostnames are built from | | `domain` | your own domain if set, otherwise `.agentspodium.com` | | `quotaStatus`, `quota` | resource state; see [health](health.md) | | `llmProvider` | which provider's key is installed, null when none | | `dseq` | namespace on the cluster | ## Change | call | effect | |---|---| | `POST /api/agents/:id/upgrade` `{ "tier" }` | new plan, pod rebuilt with data migrated | | `PATCH /api/agents/:id/llm-key` `{ "key", "provider", "model"? }` | install a model key; `"key": null` removes it | | `PATCH /api/agents/:id/tools` | toolsets and MCP servers | | `PATCH /api/agents/:id/channels` | messengers | | `PATCH /api/agents/:id/telegram` `{ "token" }` | Telegram bot token for the pod | | `PATCH /api/agents/:id/instructions` | owner instructions | | `PATCH /api/agents/:id/timezone` | schedules use it | | `PUT /api/agents/:id/peers` | other agents this one may call, see [a2a](a2a.md) | | `POST /api/agents/:id/pause`, `/resume` | stop billing the pod's resources / start again | | `POST /api/agents/:id/rebuild` | fresh pod from the last backup | | `DELETE /api/agents/:id` | gone, after a final backup | Every change that rebuilds the pod answers with `status: "provisioning"`; poll `GET /api/agents/:id` until `running`, then [liveness](health.md). ## Data - `POST /api/agents/:id/backup` and `GET /api/agents/:id/backups` — server-side snapshots, kept 7 days, one taken daily. - `GET /api/agents/:id/export` — a tar of the pod's own data (persona, skills, memory), any time, free. - `GET /api/agents/:id/memory` — what a Hermes agent remembers, read-only. # Payment Every instance starts with 7 free days, no card. Prices are per pod, in USD, monthly or yearly — current numbers come from `GET /api/tiers`: | plan | monthly | yearly | resources | |---|---|---|---| | `tiny` | $2.49 | $24.90 | 1 GB RAM · 1 vCPU · 4 GB disk | | `small` | $4.99 | $49.90 | 2 GB RAM · 2 vCPU · 6 GB disk | | `medium` | $9.99 | $99.90 | 4 GB RAM · 2 vCPU · 8 GB disk | | `large` | $17.99 | $179.90 | 8 GB RAM · 4 vCPU · 16 GB disk | Model inference is not included: the pod uses the key you install. ## Card, via Gumroad — verified 1. `GET /api/subscriptions/providers` → `providers[0].buyUrls` has one Gumroad link per plan. 2. The buyer pays there and receives a licence key by e-mail. 3. `POST /api/agents/:id/activate` `{ "licenseKey": "…" }` — the subscription becomes active and the trial clock stops. Gumroad's own webhook also activates it without this call when the buyer's e-mail matches the account. `GET /api/subscriptions` lists subscriptions with `status` and `currentPeriodEnd` (= paid till). ## USDT / USDC on Ethereum — beta testing 1. `GET /api/crypto/info` → `{ enabled, chainId: 1, assets: [usdt, usdc] }`. 2. `POST /api/agents/:id/crypto-order` `{ "asset": "usdt" }` → a deposit address and the exact amount. **Create the order before sending anything**: the address is shared per account and the order records the balance at that moment as its baseline; a transfer sent earlier raises the baseline and pays for nothing. 3. Send the amount; `GET /api/agents/:id/crypto-orders` shows `pending` → `paid`. Confirmation follows the chain, usually minutes. Status: beta testing. The "order → confirmation → activation" pattern is verified through card payments; the crypto path itself is still being tested. ## Telegram Stars — beta testing `GET /api/stars/info` → `{ enabled, botUsername, starUsd }`; `POST /api/agents/:id/stars-order` → a payment link to open in Telegram; `GET /api/agents/:id/stars-orders` for status. In beta testing; the card is the proven way for now. ## What happens if you do not pay See [expiry](expiry.md): pause 7 days after creation, deletion 3 days later, with data export available until deletion. # Health Three facts, three calls. Poll them in this order. ## Is the pod up? Is the engine answering? `GET /api/agents/:id/liveness` → `{ "reachable": true|false|null, "serving": true|false|null }` - `reachable`: the cluster says the pod exists and is ready. `null` when there is no address yet. - `serving`: an HTTP request to the pod's address returned something below 5xx. `false` right after creation or a rebuild for about ten seconds while the engine boots; `null` when the connection itself failed. Rule of thumb: `reachable && !serving` for less than three minutes is booting, longer is broken — call `POST /api/agents/:id/rebuild`. ## Resources `GET /api/agents/:id/usage` and the `quota` field on the agent: | field | meaning | |---|---| | `memoryUsedBytes`, `memoryLimitBytes`, `memoryPct` | RAM against the plan | | `diskUsedBytes`, `diskTotalBytes`, `diskPct` | persistent volume | | `status` (`quotaStatus` on the agent) | `ok`, `warn` (close to the limit), `paused` (over it: the pod is stopped until it is upgraded or freed) | Numbers refresh about once a minute from the cluster. ## Status of the record `GET /api/agents/:id` → `status`: `provisioning` while a pod is being built or rebuilt, `running`, `stopped` after pause or an unpaid trial, `failed` when the last build did not come up (rebuild fixes it; data is restored from backup), `deleted`. ## The service itself `GET /api/status` — whether the deployer behind the API answers. `GET /healthz` — the API process. # Webhooks: events pushed to your URL Leave a URL once; the platform POSTs a signed JSON event there whenever something happens to the pod. No polling for `running`, no polling for expiry. ## Set it On create: add `"webhookUrl": "https://ops.example.com/hooks"` to `POST /api/agents`. The reply carries `webhookSecret` beside `agent`. Later, or to rotate the secret: ```bash curl -s -X PUT https://agentspodium.com/api/agents/$ID/webhook -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{"url":"https://ops.example.com/hooks"}' # {"agent":{…,"webhookUrl":"https://ops.example.com/hooks"},"webhook":{"url":"…","secret":"whsec_…","events":[…]}} ``` The secret is shown **once**, by the call that set it. `GET /api/agents/:id` shows only `webhookUrl`, `webhookLastStatus`, `webhookLastAt`, `webhookLastEvent`. `DELETE /api/agents/:id/webhook` removes the hook. The URL must be an absolute `https://` (or `http://`) address on a public host; loopback, private ranges and URLs with credentials are refused with 400. ## Prove it works ```bash curl -s -X POST https://agentspodium.com/api/agents/$ID/webhook/test -H "Authorization: Bearer $TOKEN" # {"delivery":{"ok":true,"status":200,"attempts":1}} ``` This sends a `test` event with all retries and waits for the outcome, so a dead receiver takes about a minute to report `ok: false`. ## What arrives `POST `, `Content-Type: application/json`, headers: | header | value | |---|---| | `X-AgentsPodium-Event` | the event type | | `X-AgentsPodium-Delivery` | the event id; retries reuse it, so it is your idempotency key | | `X-AgentsPodium-Signature` | `sha256=` + hex HMAC-SHA256 of the raw request body, keyed with your secret | | `User-Agent` | `AgentsPodium-Webhooks/1.0` | Body: ```json { "id": "evt_9f3c2a1b7d4e6f80", "type": "agent.running", "createdAt": "2026-09-09T10:00:00.000Z", "agent": { "id": "agt_…", "name": "My Agent", "engine": "hermes", "tier": "small", "status": "running", "endpointUrl": "https://…" }, "data": { "from": "provisioning", "to": "running" } } ``` | type | when | `data` | |---|---|---| | `agent.running` | the pod came up: after create, resume, rebuild, or a recovery | `from`, `to` | | `agent.stopped` | paused by you, by an unpaid trial, or by a lapsed payment | `from`, `to` | | `agent.failed` | a build or rebuild did not come up (rebuild again; data is restored from backup) | `from`, `to` | | `agent.deleted` | the pod and its data are gone | `from`, `to` | | `payment.confirmed` | a card, crypto or Stars payment activated a subscription | `subscriptionId`, `provider`, `tier`, `period`, `paidTill` | | `deletion.warning` | 3, 2 and 1 days before an unpaid pod is stopped, and once when it stops | `daysLeft` (null once stopped), `keptDays` | | `test` | you asked for it | `note` | Verify the signature before acting; reply with any 2xx within 10 seconds. Anything else is retried twice more, 10 seconds and then a minute later; after that the outcome is written to the agent record and the event is dropped. Order between events is not guaranteed; use `createdAt`. Verification in Node: ```js import { createHmac, timingSafeEqual } from "node:crypto"; const expected = "sha256=" + createHmac("sha256", process.env.WEBHOOK_SECRET).update(rawBody).digest("hex"); const ok = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-agentspodium-signature"] ?? "")); ``` # Expiry One call answers it: `GET /api/agents/:id/term` ```json { "term": { "mode": "trial", "stopsAt": "2026-09-15T10:00:00.000Z", "deletesAt": "2026-09-18T10:00:00.000Z", "paidTill": null, "paidProvider": null, "renewUrl": "https://agentspodium.com/agents/agt_…?tab=billing" } } ``` | mode | meaning | what the dates say | |---|---|---| | `trial` | free week from creation | `stopsAt` = created + 7 days (pod paused), `deletesAt` = + 3 more days | | `grace` | a paid subscription stopped verifying | `stopsAt` = when it lapsed, `deletesAt` = + 3 days | | `paid` | active subscription | `paidTill` = end of the paid period; no stop or delete dates | | `internal` | our own pods | never expires | Before `deletesAt` everything is exportable (`GET /api/agents/:id/export`) and a payment reactivates the pod in place. After it the pod and its data are gone. Three days before deletion the owner gets an e-mail. To renew: pay ([payment](payment.md)) or open `renewUrl` in a browser. # Agent-to-agent (A2A) Every pod with the `a2a` toolset enabled has its own A2A endpoint. On the agent record: - `a2aUrl` — `https://.agentspodium.com/` - `a2aToken` — bearer that peers must send - card — `GET .well-known/agent-card.json` (public, no token) Send work: JSON-RPC `message/send` to `a2aUrl` with `Authorization: Bearer `: ```bash curl -s -X POST "$A2A_URL" -H "Authorization: Bearer $A2A_TOKEN" -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"message/send","params":{"message":{"role":"user","parts":[{"kind":"text","text":"Summarise today"}]}}}' ``` The reply carries the answer in `result.artifacts[].parts[].text`. Work lands in the pod's live session, so it answers with its memory intact. A pod without a model key accepts the message and returns no text. ## Letting your pod call others `PUT /api/agents/:id/peers` `{ "peers": [ { "name": "researcher", "url": "https://…/", "token": "…" } ] }` — the pod's own list of agents it may call, on AgentsPodium or anywhere else that speaks A2A. Peers are written into the pod on rebuild. ## Being found `PATCH /api/agents/:id/listing` `{ "listed": true }` puts the pod into the public catalogue `GET /api/a2a-catalog` (name, url, card — never the token). Off by default; publicity is a separate decision from enabling A2A. ## What breaks and why - **401 from a peer**: the peer's token changed (rebuild rotates nothing on our side, but other platforms mint tokens at start) or the entry has the address without the token. - **Card answers 200 with a marketing page**: the pod exists but A2A is off — enable the `a2a` toolset (`PATCH /api/agents/:id/tools`) and the sidecar is built on rebuild. - **Plain http address**: the token would travel in the clear; every pod here is https, refuse peers that are not. ## The service itself as an A2A agent: a2a.agentspodium.com Hosting is also an agent you can send tasks to. - Card: `https://a2a.agentspodium.com/hosting/.well-known/agent-card.json` — skills `create-instance`, `instance-health`, `instance-term`, `list-platforms`, `payment-options`. - Endpoint: `POST https://a2a.agentspodium.com/hosting/` — JSON-RPC `message/send`; `Authorization: Bearer ak_live_…` (your API key, [auth](auth.md)). Without a key only `list-platforms` and the help text answer; anything about an account comes back as JSON-RPC error `-32001`. - The host root `https://a2a.agentspodium.com/` is the platform's agent directory: `/.well-known/agent-card.json` describes it, `/catalog.json` lists pods whose owners chose to be listed, `/agent//` routes to each pod's own A2A endpoint. Send a structured part: ```bash curl -s -X POST https://a2a.agentspodium.com/hosting/ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"message/send","params":{"message":{"role":"user","parts":[{"kind":"data","data":{"skill":"instance-term","params":{"id":"agt_…"}}}]}}}' ``` or plain text: `create hermes tiny my-pod`, `health agt_…`, `term agt_…`, `platforms`, `payment agt_…`. The reply is a completed Task whose artifact carries a `data` part with the result and a `text` part with a one-line summary. # Integrations ## Chat as an OpenAI-compatible API The web chat at chat.agentspodium.com talks to pods through our OpenAI-compatible adapter. For your own agent the direct route is A2A ([a2a](a2a.md)); the adapter is for chat clients that already speak `/v1/chat/completions`. ## MCP servers inside the pod (Hermes) `GET /api/agents/:id/mcp` lists what the engine knows; `PATCH /api/agents/:id/tools` with `mcpServers: [{ name, url|command, … }]` adds servers; `POST /api/agents/:id/mcp/remove` `{ name }` removes one. The pod rebuilds to apply. ## Skills (Hermes) `POST /api/agents/:id/skills/search` `{ "query", "source"? }`, `/skills/install` `{ "name", "source"? }`, `GET /api/agents/:id/skills`, `/skills/uninstall`. Sources include `skills-sh`, `clawhub`, `lobehub`, `github`, `well-known` and the vendors' own lists. ## Telegram, Discord, WhatsApp, e-mail `channels` on create or `PATCH /api/agents/:id/channels`; a Telegram bot token goes to `PATCH /api/agents/:id/telegram`. What each engine actually supports is on `GET /api/engines` under `capabilities`. ## n8n An n8n pod is plain n8n: its own web editor at `endpointUrl`, webhooks at `/webhook/…`. Needs the `small` plan. ## Your own domain Send `domain` on create (or set it later on the agent page). Point an A record at `138.199.136.33`; `GET /api/domains/check?domain=&https=1` reports whether DNS points here and whether HTTPS on it answers. Names under agentspodium.com are refused: every pod already gets one. Status (verified 2026-09-09 with a real domain): the certificate is issued by Let's Encrypt within minutes of the A record resolving, the dashboard answers on `https:///`, and deleting the pod removes the certificate and the route. # MCP server: mcp.agentspodium.com If your framework speaks the Model Context Protocol, you do not need the HTTP API at all. The server exposes hosting as tools. - Endpoint: `https://mcp.agentspodium.com/mcp` (Streamable HTTP transport). - Auth: `Authorization: Bearer ak_live_…` on every request — the same API key as for the HTTP API ([auth](auth.md)). No key → 401 with instructions. - No state on the server: each call is one API request on your behalf. Tools: | tool | what it does | |---|---| | `list_platforms` | engines with smallest plan and capabilities, plus plans and prices | | `list_instances` | your pods: id, name, engine, tier, status, addresses | | `create_instance` | new pod: `tier` required; `engine`, `personaId`, `name`, `model`, `enableA2A` (default true), `domain`, `extraSoul` optional; returns id, addresses and the A2A token | | `get_instance_health` | liveness (`reachable`, `serving`), status, quota | | `get_instance_term` | trial / grace / paid, stop and delete dates, paid till | | `set_llm_key` | install the model key: `provider`, `key`, `model` | | `get_payment_options` | buy links per plan, crypto and Stars info (beta testing), and the term | | `set_peers` | agents this pod may call | | `set_webhook` | URL for signed pod events instead of polling ([webhooks](webhooks.md)) | | `pause_instance`, `resume_instance`, `rebuild_instance`, `delete_instance` | lifecycle | Resource `agentspodium://docs` returns [llms.txt](/llms.txt), so the docs are readable through MCP too. Client config example (Claude Desktop / Cursor style): ```json { "mcpServers": { "agentspodium": { "url": "https://mcp.agentspodium.com/mcp", "headers": { "Authorization": "Bearer ak_live_…" } } } } ``` Errors from the API come back as tool results with `isError: true` and the API's `{ error, message }`. # Platforms `GET /api/engines` is the source of truth; snapshot at build time: | engine | smallest plan | status | skills | mcp | llmKey | model | sso | dashCredentials | |---|---|---|---|---|---|---|---|---| | `hermes` (Hermes) | tiny | stable | yes | yes | yes | yes | yes | yes | | `openclaw` (OpenClaw) | tiny | beta | yes | yes | — | — | — | yes | | `n8n` (n8n) | small | beta | — | — | — | — | — | — | | `claude-code` (Claude Code) | small | beta | yes | yes | yes | — | — | yes | | `opencode` (OpenCode) | tiny | beta | yes | yes | — | — | — | yes | | `pi` (Pi) | tiny | beta | yes | — | yes | — | — | yes | Notes per engine: - **Hermes** — the full product: persona (`personaId`), skills, MCP, A2A, web chat, model key and model choice through the API. Dashboard signs the owner in through our account. - **OpenClaw** — its own Control UI at `endpointUrl`; A2A through a bridge; model key through the API. - **n8n** — workflow editor; no persona, no A2A; needs `small`. - **Claude Code** — web terminal; Anthropic key through the API or `claude auth login` inside; needs `small`. - **OpenCode**, **Pi** — web terminal / web UI; provider keys through the API; model chosen in-session. - **Matomo** — set up by us on request on any plan (not an `engine` value yet). `capabilities` on each engine says which API calls apply: `skills`, `mcp`, `llmKey`, `model`, `sso`, `dashCredentials`. # Limits - Plans and prices: `GET /api/tiers` — tiny $2.49/mo (1 GB RAM · 1 vCPU · 4 GB disk); small $4.99/mo (2 GB RAM · 2 vCPU · 6 GB disk); medium $9.99/mo (4 GB RAM · 2 vCPU · 8 GB disk); large $17.99/mo (8 GB RAM · 4 vCPU · 16 GB disk). vCPU figures are burst figures, as on every hosting. - Free pods per account at once: 3. Paid pods: no cap. - Trial: 7 days, then paused, deleted 3 days later ([expiry](expiry.md)). - Memory over the plan pauses the pod (`quotaStatus: paused`) until upgraded or freed; disk is the persistent volume of the plan. - `POST /api/auth/request`: 10 per 10 minutes per IP. - Create/rebuild calls are synchronous and take one to two minutes; run them with a client timeout of at least 5 minutes. - Backups: daily, kept 7 days; export any time. # Errors and traps Errors are JSON: `{ "error": "CODE", "message": "why" }` with an HTTP status. | status / code | when | what to do | |---|---|---| | 401 `UNAUTHORIZED` | no bearer, expired session, revoked key | re-authenticate; keys do not expire, sessions do after 30 days | | 403 `FORBIDDEN` | a key managing keys; someone else's agent | use the person's session for key management | | 404 `NOT_FOUND` | agent id not yours or deleted | check `GET /api/agents` | | 400 `BAD_REQUEST` | validation: unknown tier, engine below its `minTier`, free-pod cap, domain under agentspodium.com | read `message`; it says which field | | 409 `CONFLICT` | domain already in use | pick another | | 429 | auth request rate limit | wait | Traps that cost people time: - **Pod answers but says nothing** — no model key. `PATCH /api/agents/:id/llm-key`. - **Model name rejected by the provider** — the model must belong to the provider of the key (`deepseek-v4-flash` with a DeepSeek key, not a Claude name). - **Crypto sent before the order** — it does not count; create the order first ([payment](payment.md)). - **`serving: false` right after `running`** — booting; wait up to three minutes before acting. - **A2A card returns a web page** — A2A toolset is off. - **Domain refused** — names under agentspodium.com are assigned automatically; use a domain you own.