Back to API docs
Claude Code · Free Tier · Developer Guide

Get a Free-Tier API Key in Claude Code

Preferred path: agent-register in one terminal command. Fallback path: Google OAuth for machines without Claude Code identity or environments where agent-register is unavailable.
Preferred: agent-register Fallback: Google OAuth Output: rk_free_* key

One command. No browser. Under five seconds.

Claude Code can read its existing identity from ~/.claude.json, call POST /cli/auth/agent-register, and save the resulting free-tier key to ~/.ditto_free_tier.env.

  • Best for real Claude Code installs that already have ~/.claude.json.
  • Returns one of three responses: a free-tier rk_free_* key, a managed paid rk_live_* key for Stripe-billed paid orgs (the agent-register paid-refresh path), or status: "login_required" for non-Stripe paid orgs (invoiced / direct-pay).
  • Falls back cleanly to browser-based Google OAuth when Claude Code identity is unavailable.
Primary setup command
Hosted script at https://cat.fish.dog/scripts/agent-register.sh
curl -sL https://cat.fish.dog/scripts/agent-register.sh | bash
Copied
Saved file
~/.ditto_free_tier.env
Env var
FISHDOG_FREE_TIER_API_KEY
Key scope
free:ask
Fallback script
free-tier-auth.sh
Quickstart
This is the shortest reliable path for Claude Code users.
1

Run the hosted script

Paste the primary command above. The script checks for an existing key before registering again.

2

Let Claude Code identify itself

If ~/.claude.json exists, the script sends the required identity fields to /cli/auth/agent-register.

3

Ask a research question

Source ~/.ditto_free_tier.env, then call POST /v1/free/questions and poll GET /v1/jobs/{job_id}.

When agent-register is not available

Use the fallback hosted script: curl -sL https://cat.fish.dog/scripts/free-tier-auth.sh | bash

Re-registration behavior

If previous_key_revoked is true, the prior key string is gone, but replacement free-tier keys owned by the same Fish.Dog user can still access earlier free-tier jobs and saved work.

Which path should I use?
Keep agent-register first. Treat Google OAuth as compatibility fallback.
Path Use it when What happens
Agent register Claude Code is installed and ~/.claude.json exists. Reads Claude Code identity, calls POST /cli/auth/agent-register, and writes FISHDOG_FREE_TIER_API_KEY to ~/.ditto_free_tier.env.
OAuth fallback No Claude Code identity file, non-Claude-Code client, or agent-register is disabled in the target environment. Uses POST /cli/auth/start + POST /cli/auth/complete through a browser-based Google loopback flow.

Preferred hosted script

Run the hosted wrapper and let the script tell you whether a manual browser fallback is needed.

curl -sL https://cat.fish.dog/scripts/agent-register.sh | bash

Fallback hosted script

Use the older OAuth helper directly if you already know the zero-touch path will not apply.

curl -sL https://cat.fish.dog/scripts/free-tier-auth.sh | bash
Manual API request example for agent-register
curl -s -X POST "https://cat.fish.dog/cli/auth/agent-register" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "anthropic_account_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "claude_install_id": "4111c046280c9fe601466edf051cfa0ea8208fb93840463149a218989b1a294d"
  }'

Optional enrichment fields: anthropic_org_uuid, anthropic_account_created_at, anthropic_org_type, and anthropic_billing_type.

What this unlocks
The free tier is enough to validate pricing, positioning, and core problem statements quickly.

Test pricing before launch

Use the shared panel to validate willingness-to-pay and price cliffs before product launch or an investment decision.

ESPN pricing case study

Separate trust problems from price problems

Ask open-ended follow-ups, then validate whether churn or resistance is driven by credibility, experience, or cost.

No Frills diligence case study

Iterate in the same session

Start with a broad pain-discovery question, identify the pattern, then ask a narrower validation question within minutes.

CareQuarter validation example

Pain discovery Positioning tests Pricing validation Competitive intel Feature prioritization
Free-tier contract
What the key does, where it is stored, and how to retrieve final answers.
Panel size
~12
Shared research personas
Key prefix
rk_free_*
Scoped for free-tier ask flows
Saved path
~/.ditto_free_tier.env
Contains FISHDOG_FREE_TIER_API_KEY
Rate snapshot
GET /v1/billing/usage
Available to the current free-tier key

Ask a question

curl -s -X POST "https://cat.fish.dog/v1/free/questions" \
  -H "Authorization: Bearer $FISHDOG_FREE_TIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question":"What frustrates you most about grocery delivery?"}'

The response returns a queue confirmation plus job_id, not the final persona answers.

Poll for answers

curl -s -X GET "https://cat.fish.dog/v1/jobs/<job_id>" \
  -H "Authorization: Bearer $FISHDOG_FREE_TIER_API_KEY"

Final answers live in result.results[].reply when status becomes finished. Partial completions include result.partial and result.pending_job_ids.

Allowed endpoints
  • POST /v1/free/questions
  • GET /v1/jobs/{job_id} for jobs owned by the same free-tier user account
  • GET /v1/billing/usage for live rate and quota snapshots
Not included
  • Research group CRUD
  • Study-management flows
  • Billing admin or other paid-plan endpoints
Reference response shapes
{
  "ok": true,
  "status": "complete",
  "api_key": "rk_free_...",
  "org_uuid": "...",
  "previous_key_revoked": false
}
{
  "status": "finished",
  "result": {
    "partial": false,
    "count": 12,
    "results": [
      {
        "id": 1,
        "uuid": "...",
        "name": "...",
        "reply": "...",
        "assistant_message_id": 123
      }
    ]
  },
  "meta": {
    "free_tier": true
  }
}
What happens when you hit the free-tier limit?
Quota exhaustion now routes through the browser auth bridge, then Stripe Checkout, then a paid-key handoff.
1

Receive a signed upgrade link

A quota-exhausted free-tier org-admin now receives a signed /upgrade?org=...&token=... link instead of a direct Checkout URL.

2

Authenticate in the browser

The upgrade page shows both Google OAuth and magic-link sign-in so the user can create the first browser session safely.

3

Complete Checkout and rotate keys

Stripe Checkout upgrades the org to paid billing, then the checkout webhook mints a user-facing paid rk_live_* key.

Old free keys can return a structured refresh error
{
  "error": {
    "code": "key_rotated_post_upgrade",
    "details": {
      "refresh_command": "curl -sL https://cat.fish.dog/scripts/agent-register.sh | bash"
    }
  }
}
Manual fallback still matters

Claude Code skills can handle this contract more seamlessly, but curl users and custom scripts should treat agent-register.sh as the manual paid-key refresh path.

OAuth fallback
Keep this as the backup path, not the default path.
1

Start the session

Call POST /cli/auth/start or run the fallback hosted script.

2

Open Google login

Use the returned authorization_url in the browser and complete consent.

3

Complete the loopback callback

The CLI captures code and state from the loopback redirect, then calls POST /cli/auth/complete.

curl -sL https://cat.fish.dog/scripts/free-tier-auth.sh | bash
Exact OAuth fallback endpoint examples
curl -s -X POST "https://cat.fish.dog/cli/auth/start" \
  -H "Content-Type: application/json" \
  -d '{"provider":"google","redirect_uri":"http://127.0.0.1:53682/oauth/callback"}'
curl -s -X POST "https://cat.fish.dog/cli/auth/complete" \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<session_id>","code":"<code>","state":"<state>"}'

The loopback redirect must stay on 127.0.0.1 or localhost. For production, the app base URL is https://cat.fish.dog.

FAQ
Short answers for humans, crawlers, and AI agents.

How do I get the key if I already use Claude Code?

Run curl -sL https://cat.fish.dog/scripts/agent-register.sh | bash. That is the preferred path. It reads ~/.claude.json, calls POST /cli/auth/agent-register, and saves the key locally.

What if I am not using Claude Code?

Use the fallback script or the manual /cli/auth/start + /cli/auth/complete Google OAuth flow. The HTML page keeps that flow documented, but it is the secondary path now.

Where do the final answers live?

Submit the prompt with POST /v1/free/questions, keep the returned job_id, and read final persona replies from result.results[].reply when GET /v1/jobs/{job_id} returns status: "finished".

Can I inspect limits or quota without asking a question?

Yes. GET /v1/billing/usage works with the same free-tier key and returns current rate and quota information.

What does login_required mean?

The Anthropic account belongs to a non-Stripe paid organization (invoiced, direct-pay). Do not keep trying to mint a free-tier key. Send the user to https://cat.fish.dog/auth/login so they can manage paid-plan API keys in the signed-in UI.

Stripe-billed paid orgs behave differently: POST /cli/auth/agent-register returns status: "complete" with a managed paid rk_live_* key (broader scopes) directly, no login_required hop. This is the post-upgrade refresh path — your agent gets a working paid key in one round-trip.

What should Claude Code do after setup succeeds?

Confirm that FISHDOG_FREE_TIER_API_KEY is saved, ask the first research question, poll the returned job until it finishes, and then iterate with a sharper follow-up prompt.