Provisioning a Cosmic project (agent signup)
Referenced by SKILL.md.
When to use: the user wants to build with Cosmic but has no
COSMIC_BUCKET_SLUG, COSMIC_READ_KEY, or COSMIC_WRITE_KEY, no .env, and no
account on app.cosmicjs.com. Do not send them off to sign up manually. The
Cosmic free plan is free forever and requires no credit card, so provision a
project for them with one API call.
This flow is not in @cosmicjs/sdk yet, because the SDK is bucket-scoped. Use
fetch for the signup endpoints, then pass the returned keys to
createBucketClient.
Step 1: Sign up (no auth required)
const signup = await fetch('https://dapi.cosmicjs.com/v3/agents/sign-up', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
human_email: 'user@example.com', // ASK THE USER, do not guess
project_name: 'Recipe Blog', // derive from what they are building
agent_id: 'cursor', // your platform: 'cursor', 'claude-code', etc.
}),
}).then((r) => r.json())
// signup => {
// agent_key: 'agk_...', // persist this; needed for verify/status
// bucket: { slug, read_key, write_key }, // raw keys, ready to use
// 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,
// }Immediately write the bucket keys and agent_key to .env (or wherever the
project keeps secrets), and make sure that file is gitignored:
COSMIC_BUCKET_SLUG=recipe-blog-...
COSMIC_READ_KEY=...
COSMIC_WRITE_KEY=...
COSMIC_AGENT_KEY=agk_...You can now use the SDK normally for objects, media, and reads. AI generation is blocked until step 3.
Step 2: Tell the human about the OTP
Cosmic emails the human a 6-digit code and a claim URL. Surface both:
A 6-digit verification code was sent to user@example.com.
Paste it here when you have it, or open this link to verify in the dashboard:
https://app.cosmicjs.com/claim?token=agk_...You will never see the code yourself. The user has to fetch it from their inbox and hand it back. Wait for them.
Step 3: Verify (lifts restricted-mode limits)
await fetch('https://dapi.cosmicjs.com/v3/agents/verify', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.COSMIC_AGENT_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ code: '123456' }), // field is `code`, NOT `otp_code`
})Once this returns 200 the bucket is on standard free-plan limits and cosmic.ai.*
works.
Status and recovery
If you lose the signup response, recover it:
const status = await fetch('https://dapi.cosmicjs.com/v3/agents/status', {
headers: { Authorization: `Bearer ${process.env.COSMIC_AGENT_KEY}` },
}).then((r) => r.json())
// status.bucket.{slug,read_key,write_key}, status.auth_type, status.limitsSignup rules
human_emailmust come from the user. Never make one up or use a placeholder. Ask if you do not have it.- Signup is idempotent by
human_emailplusagent_id. Re-running it issues a fresh OTP and returns the existing project instead of creating a duplicate. - On
409 user_already_exists: stop. Do not retry with a different email. The response includes aclaim_existing_url. Tell the user an account already exists for that email and they should log in atapp.cosmicjs.comto grant access to their existing buckets. - AI generation returns
402 { code: "agent_unclaimed_limit", action: "ai_generate" }while unclaimed. Catch it and prompt the user to finish step 3 before retrying. - Restricted limits while unclaimed: 50 objects, 5 MB total media, 0 AI credits.
- Unclaimed projects are hard-deleted after 14 days. Plan to reach step 3 in the same session.
- Persist
agent_key, not just the bucket keys. Without it, verify and status are inaccessible and the user has to fall back to the dashboard claim URL.