Docs
Base URL https://api.hakk.ai/v1 for OpenAI clients. Base URL https://api.hakk.ai for Claude Code. Same API key, same catalog, same ledger. Field-level reference and account routes live on the API reference. Machine-readable contract: openapi.json.
Getting startedAPI referenceOpenAPI
Quickstart
- Request access. Onboarding is invite-only for now, and every account starts with 100 free credits.
- Create an API key from the dashboard.
- Send a request:
curl https://api.hakk.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.6",
"messages": [{"role": "user", "content": "Write a haiku about server racks."}]
}'Authentication
OpenAI-shaped clients send Authorization: Bearer YOUR_API_KEY. Claude Code can send the same key as x-api-key. Keys are created once on the API keys page and are scoped to your organization.
Anthropic clients may send anthropic-version and anthropic-beta. We accept those headers and do not require them.
Contract
Three public inference endpoints share one pipeline: auth, catalog, admission, credits, LiteLLM.
| Endpoint | Used by |
|---|---|
POST /v1/chat/completions | Cursor, Continue, Cline, Aider, OpenAI SDK chat |
POST /v1/responses | Codex CLI, OpenAI SDK responses |
POST /v1/messages | Claude Code |
GET /v1/models | Any client that lists models |
Accepted on Chat Completions:
messages[].contentas a string or as[{type, text}]max_tokensandmax_completion_tokensdeveloperrole (mapped tosystem)tools,tool_choice,stream,temperature,stop,top_p- Responses-shaped
inputandreasoning.efforton the completions path
Ignored extras stay ignored. Unknown fields do not 422.
We do not serve vision, embeddings, legacy /v1/completions, or Anthropic server tools.
| Tool | Protocol | Notes |
|---|---|---|
| Cursor | Chat Completions | Add model IDs by hand. HTTP/1.1 if the agent fails to connect. |
| Claude Code | Messages | Base URL has no /v1. Set ANTHROPIC_MODEL to a catalog ID. |
| Continue | Chat Completions | Set useResponsesApi: false. |
| Cline | Chat Completions | Provider: OpenAI Compatible. |
| Aider | Chat Completions | --model openai/qwen3.6 |
| Codex CLI | Responses | wire_api = "responses" |
| OpenAI SDK | Completions or Responses | base_url=https://api.hakk.ai/v1 |
OpenAI SDK
Python
from openai import OpenAI
client = OpenAI(base_url="https://api.hakk.ai/v1", api_key="YOUR_API_KEY")
response = client.chat.completions.create(
model="qwen3.6",
messages=[{"role": "user", "content": "hello"}],
)
print(response.choices[0].message.content)
# Codex CLI and newer agent code use Responses:
reply = client.responses.create(model="qwen3.6", input="hello")
print(reply.output[0].content[0].text)JavaScript / TypeScript
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.hakk.ai/v1", apiKey: "YOUR_API_KEY" });
const response = await client.chat.completions.create({
model: "qwen3.6",
messages: [{ role: "user", content: "hello" }],
});
console.log(response.choices[0].message.content);Streaming
Set "stream": true. Chat Completions uses OpenAI SSE frames ending in data: [DONE]. Messages uses Anthropic events (message_start, content_block_delta, ping, message_stop). Responses uses response.output_text.delta.
stream = client.chat.completions.create(
model="qwen3.6",
messages=[{"role": "user", "content": "hello"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")Editors & agents
Cursor
- Open Cursor Settings (Cmd+Shift+J on macOS, Ctrl+Shift+J on Windows/Linux) and open Models.
- Turn on OpenAI API Key and paste your hakk.ai key.
- Turn on Override OpenAI Base URL and set it to
https://api.hakk.ai/v1. Keep the/v1suffix. Cursor appends/chat/completionsto that URL. - Click Add Model and type each ID exactly. Cursor does not import our catalog when you refresh the model list. Use
qwen3.6for everyday work.qwen3.6(max thinking)qwen3.6-fast(thinking off)qwen3.6-high(faster thinking)
- Select
qwen3.6in the chat model picker. If a request fails to connect, set Settings → Network → HTTP Compatibility Mode to HTTP/1.1.
Claude Code
Claude Code talks Anthropic Messages. Point it at the host root, not /v1. The client appends /v1/messages.
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.hakk.ai",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY",
"ANTHROPIC_API_KEY": "",
"ANTHROPIC_MODEL": "qwen3.6"
}
}Continue (VS Code / JetBrains)
models:
- name: hakk.ai qwen3.6
provider: openai
model: qwen3.6
apiBase: https://api.hakk.ai/v1
apiKey: YOUR_API_KEY
useResponsesApi: falseCline
- Open the Cline panel → Settings.
- Set API Provider to "OpenAI Compatible".
- Base URL
https://api.hakk.ai/v1, your API key, model IDqwen3.6.
Aider
export OPENAI_API_BASE=https://api.hakk.ai/v1
export OPENAI_API_KEY=YOUR_API_KEY
aider --model openai/qwen3.6Codex CLI
# ~/.codex/config.toml
[model_providers.hakk]
name = "hakk.ai"
base_url = "https://api.hakk.ai/v1"
env_key = "HAKK_API_KEY"
wire_api = "responses"
[models]
default = "qwen3.6"Models
GET https://api.hakk.ai/v1/models lists the models your key can use. Type these IDs exactly in the editor. qwen-3.6 is accepted and mapped to qwen3.6.
| Model | ID | Context |
|---|---|---|
| Qwen3 Coder 30B A3B | chat-default | 64K |
| Qwen 3.6 | qwen3.6 | 256K |
| Qwen 3.6 Fast | qwen3.6-fast | 256K |
| Qwen 3.6 High | qwen3.6-high | 256K |
Compatibility IDs still accepted: glm-5.2-fast, glm-5.2, glm-5.2-high, glm-5.3-high, glm-5.3-fast, glm-5.3. Same weights as the current model in that family.
The public catalog with per-1M-token prices is on the Models page, read from the same source billing charges against.
Credits & errors
Billing is prepaid credits (1 credit = $0.01), deducted per request from the model's published input/output token rates. When your organization's balance is exhausted, requests return 402. Editor routes also return {"error":{"message":"...","type":"...","code":"..."}} and keep detail as the same string. Top up on the billing page.
Under saturation you may briefly wait in the admission queue. If the wait exceeds the timeout you get 503 with a retry hint.