Get started
Authentication and base URL
Every endpoint authenticates with an sk- key from the console. OpenAI-format calls use the Authorization header; native Claude calls also accept x-api-key and native Gemini calls x-goog-api-key. The OpenAI-compatible base URL is https://open.tutujin.com/v1.
Every endpoint uses the same API key. You create keys in the console and they start with sk-. OpenAI-format requests send the key in an Authorization: Bearer header. The native Claude and Gemini endpoints also accept the headers their official SDKs send by default, so with an official SDK you only change the base URL and the key.
Three header styles
| API format | Header | Works on |
|---|---|---|
| OpenAI-compatible (Chat Completions, Responses, Embeddings, images, audio, Rerank) | Authorization: Bearer sk-... | Every endpoint |
| Native Claude Messages | x-api-key: sk-... plus anthropic-version: 2023-06-01 | /v1/messages and the models endpoint |
| Native Gemini generateContent | x-goog-api-key: sk-... | /v1beta/models/... and the models endpoint |
Authorization: Bearer works on every endpoint, including the native Claude and Gemini paths. The other two styles exist so the official SDKs work unchanged. Native Gemini paths also accept a ?key= URL parameter, but URLs tend to end up in logs and proxies, so prefer the header.
curl https://open.tutujin.com/v1/chat/completions \
-H "Authorization: Bearer $TUTUJIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.4-mini",
"messages": [{"role": "user", "content": "Hello"}]
}'curl https://open.tutujin.com/v1/messages \
-H "x-api-key: $TUTUJIN_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-5-5",
"max_tokens": 256,
"messages": [{"role": "user", "content": "Hello"}]
}'curl "https://open.tutujin.com/v1beta/models/gemini-3.8-flash:generateContent" \
-H "x-goog-api-key: $TUTUJIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"role": "user", "parts": [{"text": "Hello"}]}]
}'Setting the base URL
The OpenAI SDK's base URL includes /v1. The Anthropic and Google SDKs append the endpoint path themselves, so give them the site root.
| SDK or method | Option | Value |
|---|---|---|
| OpenAI SDK (Python / Node.js) | base_url / baseURL, or the OPENAI_BASE_URL environment variable | https://open.tutujin.com/v1 |
| Anthropic SDK | base_url / baseURL | https://open.tutujin.com |
| Google Gen AI SDK | base_url inside http_options | https://open.tutujin.com |
| Plain HTTP | Full URL | e.g. https://open.tutujin.com/v1/chat/completions, https://open.tutujin.com/v1/messages |
import os
from openai import OpenAI
client = OpenAI(
base_url="https://open.tutujin.com/v1",
api_key=os.environ["TUTUJIN_API_KEY"],
)import os
import anthropic
client = anthropic.Anthropic(
base_url="https://open.tutujin.com",
api_key=os.environ["TUTUJIN_API_KEY"],
)import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["TUTUJIN_API_KEY"],
http_options=types.HttpOptions(base_url="https://open.tutujin.com"),
)Full SDK setups are in the OpenAI SDK and Anthropic SDK guides.
Key restrictions
When you create or edit a key in the console, you can restrict it:
| Setting | What happens when a request breaks it |
|---|---|
| Group | Decides the line the key uses and the price it pays — see Choosing a group |
| Spending limit | Once the key has spent its limit it returns 401; other keys keep working |
| Expiry | After the expiry date the key returns 401 |
| Model allowlist | Calling a model outside the list returns 403 |
| IP allowlist | Requests from other IPs return 403 |
The console shows keys masked by default. Use one key per project and per environment, and give production keys a model allowlist and an IP allowlist, so a leaked key can only do limited damage. More in API key security best practices.
Keep keys on your servers only, in environment variables or a secrets manager. Never put them in web, app or mini-program front-end code, and never commit them to a repository.
Authentication errors
| Status | Usual cause | What to do |
|---|---|---|
| 401 | The key is wrong, deleted, disabled or expired, or it has used up its spending limit | Check the full key in the header and its status in the console |
| 403 | The account balance ran out, the IP or model is not on the allowlist, or the key's group is unavailable | Fix the setting or add credit as the message says; do not retry automatically |
The full list of status codes and retry advice is in Errors and retries.
Still stuck? Add our WeChat support JsnonoChat and send the request id from the error message, and we will look into it.