Docs · Guides
Agent self-signup
An agent with no API key can create its own workspace and inbox with one call. A human claims it later to lift the limits.
An AI agent doesn’t need a person to get started. It can create its own Agentboxd workspace, with one inbox and an API key, by solving a short proof-of-work challenge. The workspace is unclaimed: it can receive mail freely and send a little, and a human can claim it later to become its owner and lift the limits.
#Sign up from code
The SDKs fetch the challenge, solve it (a few seconds of CPU) and create the workspace. The key is returned once, so store it right away.
import { Agentboxd } from 'agentboxd';
// No API key: solves a short proof-of-work challenge, then creates the workspace.
const { client, api_key, inbox } = await Agentboxd.signup({
agentName: 'research-agent',
ownerEmail: 'you@example.com', // optional: gets a link to claim the workspace
});
// Store api_key now (e.g. as AGENTBOXD_API_KEY): it is shown only once.
const mail = await client.messages.wait(inbox.id, { timeout: 60 });from agentboxd import Agentboxd
s = Agentboxd.signup(agent_name="research-agent", owner_email="you@example.com")
print(s.api_key) # shown only once: store it
mr = s.client # already uses the new key
mail = mr.messages.wait(s.inbox["id"], timeout=60)Without an SDK, it is two calls:
# 1. A challenge (no key needed)
curl https://api.agentboxd.com/v1/signup/challenge
# → { "challenge": "v1.eyJu...", "algorithm": "sha256", "difficulty": 21, "expires_at": "...", ... }
# 2. Find a decimal "solution" so SHA-256(challenge + ":" + solution) starts with 21 zero bits,
# counting up from 0 (the SDKs do this). Then:
curl -X POST https://api.agentboxd.com/v1/signup \
-H "Content-Type: application/json" \
-d '{ "challenge": "v1.eyJu...", "solution": "1830211", "agent_name": "research-agent", "owner_email": "you@example.com" }'{
"api_key": "mr_8Hq2...",
"workspace": { "id": "0b6c…", "name": "research-agent's workspace", "status": "unclaimed", "created_at": "…", "claimed_at": null },
"inbox": { "id": "6f1c…", "address": "brisk-otter-4821@agents.agentboxd.com", … },
"claim": { "status": "email_sent", "email": "y***@example.com" },
"restrictions": {
"recipients_per_day": 20,
"replies_to_inbound_threads": "unlimited",
"inboxes": 1,
"webhooks": false,
"custom_domains": false,
"event_stream": true,
"expires_after_inactive_days": 30
},
"docs_url": "https://agentboxd.com/docs/agent-signup",
"next_steps": ["Store api_key now: it is shown only once. It is scoped to this inbox.", "…"]
}The key is scoped to the new inbox, with the Send & read permissions plus webhooks:manage (for when the workspace is claimed). It can’t create more inboxes, manage domains or mint identity tokens.
#Sign up from an MCP client
Start @agentboxd/mcp without AGENTBOXD_API_KEY. The agent sees a signup tool; after calling it, the same session uses the new key. Nothing is written to disk by default: the tool returns the key and tells the agent to hand it to you. Start the server with --save-key=<file> to keep it across restarts.
{
"mcpServers": {
"agentboxd": {
"command": "npx",
"args": ["-y", "@agentboxd/mcp"]
}
}
}#What an unclaimed workspace can do
| Unclaimed | After a claim (Free plan) | |
|---|---|---|
| Receiving | Unlimited, as on every plan (inbound mail is never refused) | Same |
| Sending | Replies in threads that someone started by emailing the agent, to people already in the thread: not limited. Anything else: at most 20 different recipients per UTC day | Free plan limits |
| Inboxes | 1 (the one created at signup) | 10 |
| Webhooks | No (403 unclaimed_workspace); the event stream works | Yes |
| Custom domains | No | 1 |
| Sign in with Agentboxd | No identity tokens | Yes, with a key that has identity:sign |
| Kept for | 30 days after the last activity (API use or mail), then deleted | Your plan’s retention |
The burst limit, the daily caps and the monthly email quota of the Free plan apply as well. A send over the recipient limit gets 429 unclaimed_recipient_limit with details: { limit, used, retry_after_seconds } and a Retry-After header until 00:00 UTC. GET /v1/account (or client.account.get(), or the get_account MCP tool) shows the claim status, the effective limits, today’s recipient count and when an idle workspace would be deleted.
#Claiming a workspace
Pass owner_email at signup, or call POST /v1/signup/claim { email } later (at most 3 a day). We email that person a single-use link from login@agentboxd.com, valid 72 hours. They open it, review what they are claiming and confirm; that signs them in (like a sign-in link) and makes them the workspace’s owner. The workspace becomes a normal Free workspace and a signup.claimed event is recorded. The address must be the person’s own, outside Agentboxd.
The claim email contains only our own text, the inbox address and the link: nothing the agent wrote. If the person doesn’t know the agent, they can ignore it; nothing happens.
#Abuse controls
- Proof of work. Each challenge needs about two million SHA-256 hashes (a few seconds of one CPU core) and checking it takes one. Challenges are signed, expire after 10 minutes and work once.
- Rate limits. At most 5 signups per IP address per hour and 20 per network (IPv4 /24, IPv6 /56) per day:
429 signup_rate_limitedwithRetry-After. - Sending limits until claimed, above, on top of the usual bounce and complaint checks: a workspace whose mail bounces or draws complaints is suspended automatically.
- Expiry. Unclaimed workspaces with no activity for 30 days are deleted with their mail and files. Their addresses are never handed out again.
- A kill switch. The operator can turn signup off at any time:
503 signup_disabled.
#Acceptable use
Self-signup follows the same rules as every workspace: no spam or unsolicited bulk mail, no phishing or impersonation, no mail to people who didn’t ask for it. Workspaces that break them are suspended and deleted. Report abuse to abuse@agentboxd.com.
#Errors
| Status & code | When |
|---|---|
400 invalid_solution · 400 challenge_expired · 400 challenge_used | The solution doesn’t match, the challenge is older than 10 minutes, or it was already used. Get a new challenge. |
422 invalid_owner_email | owner_email is an Agentboxd address. It must be a person’s own address. |
429 signup_rate_limited | Too many signups from this IP or network. details.scope is ip or network. |
503 signup_disabled | Self-signup is turned off on this server. |
429 unclaimed_recipient_limit | The daily recipient allowance of an unclaimed workspace is used up. |
403 unclaimed_workspace | Webhooks, custom domains, temporary inboxes and identity tokens need a claimed workspace. |
409 already_claimed · 409 not_claimable | A claim was requested for a workspace that already has an owner. |