Agent signup
POST /api/auth?action=agent-signup - autonomous agents create an account with an email OTP and receive an sk_ account token. No captcha, no browser.
Read as MarkdownAgent signup lets an autonomous agent create a ProxyLLM account by itself: it submits an email, verifies a one-time code from that inbox, and receives an sk_ account token. There is no captcha and no browser step. The new account starts without a membership; every management endpoint answers 402 with a checkout link until a human activates one, and the account is removed automatically 48 hours after signup if nobody does.
Machine-readable instructions for this whole flow live at proxyllm.ai/auth.md; point your agent there.
Step 1: request a code
POST https://proxyllm.ai/api/auth?action=agent-signup
curl -X POST "https://proxyllm.ai/api/auth?action=agent-signup" \
-H "Content-Type: application/json" \
-d '{"email": "ops@youragency.com", "source": "authmd"}'
source is optional: a short slug naming the artifact that sent the agent (mcp, authmd, clawhub, bazaar, content). It is stored on the account for attribution and changes nothing else.
Response:
{
"ok": true,
"new_account": true,
"account_expires_at": "2026-07-17T15:04:05.000Z"
}
A 6-digit code lands in the inbox. The email says plainly that an AI agent initiated the signup. If the email already belongs to a ProxyLLM account, the code simply signs in to it (new_account: false) and no removal deadline is added.
Disposable email domains are refused: control of a durable inbox is the identity anchor for this lane. Codes are limited to 3 per email per hour on top of a per-IP limit.
Step 2: verify and receive the token
POST https://proxyllm.ai/api/auth?action=agent-verify
curl -X POST "https://proxyllm.ai/api/auth?action=agent-verify" \
-H "Content-Type: application/json" \
-d '{"email": "ops@youragency.com", "code": "123456"}'
Response:
{
"user": { "id": "5e2f8c1a-...", "email": "ops@youragency.com" },
"account_token": "sk_...",
"token_prefix": "sk_1234567890a",
"token_scope": "read_write",
"plan": "free",
"payment": {
"checkout_url": "https://whop.com/checkout/plan_...",
"price_usd": 129,
"account_expires_at": "2026-07-17T15:04:05.000Z",
"poll": "GET /v1/organizations/me until plan is \"pro\"",
"message": "This account has no active membership yet. ..."
}
}
account_token is returned exactly once; store it. It is a normal read and write account token, revocable any time under Settings. On the first verify, the account owner also gets one email naming the removal deadline and the checkout link, so the human hears about the account even if the agent forgets to mention it.
Step 3: get a human to activate the membership
Until a membership is active, every management endpoint returns 402 with the same payment block and a plain message built for relaying to your operator. The one exception is GET /v1/organizations/me, which keeps answering so the agent can poll:
{
"id": "5e2f8c1a-...",
"email": "ops@youragency.com",
"plan": "free",
"token_scope": "read_write",
"token_label": "Agent signup",
"payment": { "checkout_url": "...", "account_expires_at": "..." },
"message": "This account has no active membership yet. ..."
}
Hand your operator the checkout_url, then poll me until plan is "pro". From there the full management surface opens: create routing keys, connect Codex, register bridges.
The 48-hour removal
To prevent spam, an agent-created account that never activates a membership is removed automatically 48 hours after signup. The deadline is fixed at signup and returned as account_expires_at in every response above. After removal the token stops working with 410 account_expired, and the same email may sign up again from scratch. Activation clears the deadline permanently.
Errors
| Status | Code | When |
|---|---|---|
| 400 | (none) | Missing or invalid email, disposable email domain, or a wrong/expired code. |
| 402 | payment_required | Any management call before a membership is active. |
| 410 | account_expired | The 48-hour window passed with no activation. Sign up again. |
| 429 | (none) | Rate limit: more than 3 codes per email per hour, or too many requests per IP. |
| 502 | (none) | The verification email could not be sent. Try again. |