Claude Code Setup
Use Sleepy AI with Claude Code
Point Claude Code at Sleepy AI's Anthropic-compatible Messages API. Same account, same virtual key, same usage pool as the dashboard, the Sleepy CLI, and /v1/chat/completions.
What you need
- A Sleepy AI account — sleepyai.org/signup
- A virtual key from Dashboard → API Keys
- Claude Code installed (
npm i -g @anthropic-ai/claude-code, or Anthropic's official installer)
Free-tier accounts may also need to join the Telegram group the dashboard asks for. Without that, every request returns 403.
The one setting that will 404 if you get it wrong
Claude Code always appends /v1/messages to ANTHROPIC_BASE_URL.
Our gateway lives at /api/v1/messages, so the base URL must stop at /api:
https://www.sleepyai.org/api
You set ANTHROPIC_BASE_URL to | Claude Code actually calls | Result |
|---|---|---|
https://www.sleepyai.org/api | POST /api/v1/messages | works |
https://www.sleepyai.org/api/v1 | POST /api/v1/v1/messages | 404 |
https://www.sleepyai.org | POST /v1/messages | 404 |
OpenAI clients are the opposite: they take https://www.sleepyai.org/api/v1 and append /chat/completions. Do not reuse that value here.
Configure
Export these in the shell you launch claude from (or put them in ~/.zshrc / ~/.bashrc):
export ANTHROPIC_BASE_URL="https://www.sleepyai.org/api"
export ANTHROPIC_AUTH_TOKEN="sk-..." # your Sleepy virtual key
export ANTHROPIC_MODEL="<model-id>" # from GET /api/v1/models
Then:
claude
Claude Code sends the key as x-api-key. Sleepy accepts that header (and Authorization: Bearer if you ever call the endpoint yourself).
Pin a model
ANTHROPIC_MODEL must be a chat model id from your catalogue — anything with modelType chat-completion or anthropic-responses. Image / video / TTS / STT ids will 404 on this path.
curl https://www.sleepyai.org/api/v1/models \
-H "Authorization: Bearer sk-..."
Use the id (or modelId) field as-is. A sleepy/ prefix is optional and stripped either way. Ids are case-insensitive.
If you skip ANTHROPIC_MODEL, Claude Code will try Anthropic's own default (claude-sonnet-…). That only works if that exact id exists in your catalogue.
You can also pick per-session:
claude --model <model-id>
Settings file (optional)
Same three values in ~/.claude/settings.json (user) or .claude/settings.json (project):
{
"env": {
"ANTHROPIC_BASE_URL": "https://www.sleepyai.org/api",
"ANTHROPIC_AUTH_TOKEN": "sk-...",
"ANTHROPIC_MODEL": "<model-id>"
}
}
Do not commit a project settings file that contains a live key.
Smoke-test the path before launching Claude Code
If this fails, Claude Code will fail the same way:
curl https://www.sleepyai.org/api/v1/messages \
-H "x-api-key: sk-..." \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "<model-id>",
"max_tokens": 64,
"messages": [{"role": "user", "content": "ping"}]
}'
A good reply looks like Anthropic's Message object ("type": "message", "role": "assistant", content as typed blocks). You should not see OpenAI's choices array.
Streaming ("stream": true) is named SSE events — message_start, content_block_delta, message_stop — not OpenAI data: chunks. Claude Code always streams.
anthropic-version is accepted and ignored. We do not require a specific version header.
What works
- Text turns, including a top-level
systemprompt - Tool use (
tool_use/tool_result) — this is what Claude Code's file/shell tools ride on - Images as
imageblocks (base64 or URL) max_tokens,temperature,top_p,stop_sequences,tool_choicePOST /v1/messages/count_tokens(free; no upstream call)
Both chat-completion and anthropic-responses models are reachable on this path. Billing, plan restrictions, the free-model daily cap, and the output-token clamp are the same as /v1/chat/completions.
What does not work
Claude Code (and the Anthropic SDK) also call a few sibling routes we do not serve. Anything else is 404:
| Path | Status |
|---|---|
POST /v1/messages | supported |
POST /v1/messages/count_tokens | supported (unbilled) |
GET /v1/models | supported |
POST /v1/complete | not served |
| prompt-caching beta extras beyond what the translator already maps | not a separate API |
If Claude Code ever hits a 404 on a non-messages path, that call is outside this compatibility layer — it is not a bad key.
Errors you will actually see
Sleepy answers Claude Code in Anthropic's error envelope ({"type":"error","error":{"type":"…","message":"…"}}), so the CLI can print the message instead of dying on an unparseable body.
| HTTP | error.type | Usual cause |
|---|---|---|
| 401 | authentication_error | Missing or invalid virtual key |
| 403 | permission_error | Model not on your plan, or Telegram group gate |
| 402 | api_error (message mentions credits / daily limit) | Allowance spent and no extra credits |
| 429 | rate_limit_error | RPM / spending window / free-model daily cap. A 429 also starts a 5-minute account cooldown. |
| 404 | not_found_error | Wrong base URL, or a non-chat model id |
Usage lands in Dashboard → Usage under source api, same as any other key-authenticated call.
Using the Anthropic SDK directly
Same host, same key. The official clients also append /v1/messages to the base URL.
Python
import anthropic
client = anthropic.Anthropic(
base_url="https://www.sleepyai.org/api",
api_key="sk-...",
)
msg = client.messages.create(
model="<model-id>",
max_tokens=1024,
messages=[{"role": "user", "content": "hello"}],
)
print(msg.content)
TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://www.sleepyai.org/api",
apiKey: "sk-...",
});
const msg = await client.messages.create({
model: "<model-id>",
max_tokens: 1024,
messages: [{ role: "user", content: "hello" }],
});
console.log(msg.content);
Related
- Public API reference (OpenAI dialect): sleepyai.org/docs
- Model catalogue: sleepyai.org/models
- Keys: sleepyai.org/dashboard/keys