Agents
The Agents API lets an AI agent provision a brand new Cosmic project and bucket on behalf of a human, without the human needing a Cosmic account up-front. The bucket starts in a restricted "unclaimed" state, an OTP is emailed to the human, and the agent can hand the code back to lift the limits.
This is the underlying API used by the Agent Signup flow exposed in the CLI and the MCP /v1/agent scope.
Base URL
https://dapi.cosmicjs.com
Unlike the bucket-scoped endpoints in the rest of this reference, the Agents endpoints live on the dashboard API (dapi.cosmicjs.com).
Sign up
Provision a new project + bucket and trigger a claim email to human_email.
This endpoint does not require authentication. The request must be sent as JSON with Content-Type: application/json. Re-calling with the same human_email + agent_id is idempotent: it refreshes the OTP and returns the existing project rather than creating a new one.
Required body
- Name
human_email- Type
- string
- Description
The human's email address. The 6-digit OTP and a claim URL are sent here. Must be a valid email and not already a human-owned Cosmic account (see errors).
- Name
project_name- Type
- string
- Description
Display name for the new Cosmic project. The bucket slug is derived from this.
- Name
agent_id- Type
- string
- Description
Stable identifier for the calling agent (e.g.
cursor,claude-code, your-internal-agent slug). Used for rate limiting and analytics. Plain string, 1-128 chars.
Optional body
- Name
client- Type
- string
- Description
Free-form label for the surface the agent runs in (e.g.
desktop,cli,mcp). Echoed back in/v3/agents/status.
Response
- Name
agent_key- Type
- string
- Description
Bearer token (prefix
agk_) used to call/v3/agents/verifyand/v3/agents/status. Persist this securely; it is the durable agent-flow credential and survives token rotation.
- Name
access_token- Type
- string
- Description
User-scoped JWT for the shadow user that owns the new project + bucket. Pass it as
Authorization: Bearer <access_token>to call any standard Dashboard API endpoint (object types, webhooks, team, etc.) on the agent's project. Valid for 14 days while unclaimed (matches the auto-delete window). Auto-revoked when the human claims the bucket (the shadow user'sstatusflips to 0). For long-lived agents, hit/v3/agents/statusperiodically to obtain a fresh token.
- Name
auth_type- Type
- string
- Description
Always
unclaimedon a fresh sign-up.
- Name
project- Type
- object
- Description
{ id, name }for the provisioned project.
- Name
bucket- Type
- object
- Description
{ slug, read_key, write_key }. Use these immediately with the standard bucket API and SDK. The keys returned here are raw (not JWT-wrapped) and ready to drop intocreateBucketClient. Bucket keys are durable and survive claim.
- Name
claim_url- Type
- string
- Description
URL the agent can hand the human as an alternative to the OTP. Visiting it on
app.cosmicjs.comlets the human verify and take ownership in one step.
- Name
limits- Type
- object
- Description
Restricted-mode quotas, see Auth states & limits.
- Name
auto_delete_after_days- Type
- number
- Description
Number of days until the project is hard-deleted if it has not been claimed. Currently
14.
Request
curl -X POST https://dapi.cosmicjs.com/v3/agents/sign-up \
-H "Content-Type: application/json" \
-d '{
"human_email": "tony@example.com",
"project_name": "Recipe Blog",
"agent_id": "my-agent-platform"
}'
200 OK
{
"message": "Agent signup created. OTP sent to human_email.",
"auth_type": "unclaimed",
"agent_key": "agk_...",
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"project": { "id": "...", "name": "Recipe Blog" },
"bucket": {
"slug": "recipe-blog-...",
"read_key": "...",
"write_key": "..."
},
"claim_url": "https://app.cosmicjs.com/claim?token=agk_...",
"limits": {
"ai_credits_remaining": 0,
"media_mb_total": 5,
"objects_max": 50
},
"auto_delete_after_days": 14
}
Verify
Submit the 6-digit code from the claim email to lift restricted-mode limits.
Requires Authorization: Bearer agk_... from the sign-up response. The agent never sees the code itself; the human reads it from their email and pastes it back.
Required body
- Name
code- Type
- string
- Description
The 6-digit numeric OTP from the claim email. The code expires; if expired, call
/v3/agents/sign-upagain with the samehuman_email+agent_idto issue a fresh one (idempotent).
Response
- Name
auth_type- Type
- string
- Description
verifiedon success.
- Name
claim_status- Type
- string
- Description
verified.
- Name
access_token- Type
- string
- Description
A freshly issued user JWT, with a longer expiry now that the project is verified (
90d). Replace any previously stored token with this one.
- Name
limits- Type
- null
- Description
nullonce verified; the bucket is on standard free-tier limits.
Request
curl -X POST https://dapi.cosmicjs.com/v3/agents/verify \
-H "Authorization: Bearer agk_..." \
-H "Content-Type: application/json" \
-d '{ "code": "123456" }'
200 OK
{
"message": "Verified. Restricted-mode limits lifted.",
"auth_type": "verified",
"claim_status": "verified",
"limits": null
}
Status
Check the current claim state and remaining limits for the agent's project + bucket. Safe to poll while waiting for the human to verify.
Requires Authorization: Bearer agk_.... Also useful as a recovery path: if the agent lost the sign-up response (e.g. CLI re-login on a new machine), /status returns the bucket slug, read key, and write key.
Response
- Name
auth_type- Type
- string
- Description
unclaimedorverified.
- Name
claim_status- Type
- string
- Description
unclaimed,verified, orhuman_owned(the human signed up atapp.cosmicjs.comwith the same email and absorbed the project).
- Name
plan_id- Type
- string
- Description
agent_unclaimedwhile restricted, otherwise the project's normal plan id.
- Name
access_token- Type
- string
- Description
A freshly issued user JWT for the shadow user. Treat
/statusas the canonical refresh endpoint: call it periodically with theagent_keyto rotate the token before it expires.
- Name
limits- Type
- object | null
- Description
Restricted-mode limits while unclaimed,
nullonce verified or claimed.
- Name
auto_delete_after_days- Type
- number | null
- Description
Days until hard-delete if unclaimed;
nullonce claimed.
- Name
project- Type
- object | null
- Description
{ id, name }.
- Name
bucket- Type
- object | null
- Description
{ slug, read_key, write_key }. Keys are raw (not JWT-wrapped).
- Name
human_email- Type
- string
- Description
The email the agent signed up against.
- Name
agent_id- Type
- string | null
- Description
Echoed back from sign-up.
Request
curl https://dapi.cosmicjs.com/v3/agents/status \
-H "Authorization: Bearer agk_..."
200 OK (unclaimed)
{
"auth_type": "unclaimed",
"claim_status": "unclaimed",
"plan_id": "agent_unclaimed",
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"limits": {
"ai_credits_remaining": 0,
"media_mb_total": 5,
"objects_max": 50
},
"auto_delete_after_days": 14,
"project": { "id": "...", "name": "Recipe Blog" },
"bucket": {
"slug": "recipe-blog-...",
"read_key": "...",
"write_key": "..."
},
"human_email": "tony@example.com",
"agent_id": "my-agent-platform",
"client": "cli"
}
Auth states and limits
An agent-created project moves through three states:
| State | What it means | What's allowed |
|---|---|---|
unclaimed | Bucket created by agent, human has not verified yet | Create/read/update up to 50 objects, up to 5 MB total media. AI generation is disabled. |
verified | Human passed the OTP back to the agent (or visited the claim URL) | Standard free-tier limits, including AI generation |
human_owned | Human took ownership by signing up at app.cosmicjs.com with the same email | Standard free-tier limits, full dashboard access |
Calls that exceed restricted-mode quotas return 402 with code: "agent_unclaimed_limit" and the offending action (ai_generate, object_create, or media_upload). Use this signal to prompt the human to claim:
402 Payment Required
{
"message": "AI generation is disabled on unclaimed agent buckets. Ask the human to claim this bucket to enable AI features.",
"code": "agent_unclaimed_limit",
"action": "ai_generate",
"limits": {
"ai_credits_remaining": 0,
"media_mb_total": 5,
"objects_max": 50
}
}
Unclaimed projects are hard-deleted after 14 days if not claimed. Plan accordingly: prompt the human early, and persist the agent_key so a returning user can resume the claim flow.
Errors
| Status | code | When |
|---|---|---|
400 | (none) | Missing/invalid body or expired/incorrect OTP on /verify. |
401 | (none) | Missing or invalid Authorization: Bearer agk_... on /verify or /status. |
402 | agent_unclaimed_limit | Caller exceeded restricted-mode quotas (returned by the bucket data plane, not by this API). |
409 | user_already_exists | human_email already belongs to a Cosmic user. Response includes a claim_existing_url pointing the human to /login?email=.... Do not retry with a different email; ask the human to log in and provision a bucket from the dashboard. |
429 | (none) | Rate limit. The /sign-up endpoint is capped per IP, and agent_id has a daily ceiling. Back off and retry. |
Related
- Agent Signup overview - end-to-end flow, including CLI and MCP.
- Authentication - where
agent_keyfits among other auth methods. - CLI:
cosmic agent-signup- the same flow without writing fetch calls. - MCP server: agent scope - the same flow exposed as MCP tools.