Skip to content
TutujinAPI

Integration guides

Using the OpenAI SDK

In the official OpenAI Python and Node.js SDKs, set base_url to https://www.tutujin.com/v1 and use your Tutujin key to call chat, streaming, embeddings and more — with GPT, Claude, Gemini, DeepSeek and other models.

The official OpenAI SDKs need two changes: set base_url to https://www.tutujin.com/v1 and use your Tutujin key as api_key. One client covers chat, Responses, embeddings, images and audio. To switch models you only change model, and that includes non-GPT models such as Claude, Gemini and DeepSeek wherever the catalog lists Chat Completions support.

Install

pip install openai

Create a client

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://www.tutujin.com/v1",
    api_key=os.environ["TUTUJIN_API_KEY"],
)

Or leave the code alone and set environment variables — the SDKs read OPENAI_BASE_URL and OPENAI_API_KEY by default:

cURL
export OPENAI_BASE_URL="https://www.tutujin.com/v1"
export OPENAI_API_KEY="sk-your-key"

Chat

resp = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "Explain RAG in three sentences."},
    ],
)
print(resp.choices[0].message.content)
print(resp.usage)  # input and output tokens for this call

Parameters are covered in Chat Completions.

Streaming

stream = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "Write a 60-word product description"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Embeddings

emb = client.embeddings.create(
    model="text-embedding-3-small",
    input=["What is the return policy?", "How soon do orders ship?"],
)
print(len(emb.data), len(emb.data[0].embedding))

Passing an array as input handles many texts in one request — faster than one request per text and less likely to hit rate limits.

Calling other vendors' models

Keep the client, change model. Any model the catalog lists for Chat Completions works this way:

Python
for model in ["claude-sonnet-5-5", "deepseek-v4.1-flash"]:
    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": "Hello"}],
    )
    print(model, resp.choices[0].message.content)

Vendors support optional parameters to different degrees. For native Claude features, use the Anthropic SDK with the native Messages endpoint.

Timeouts and retries

The SDKs retry 429s, 5xx responses and network errors automatically, twice by default. In production, tune retries and timeouts for your workload:

client = OpenAI(
    base_url="https://www.tutujin.com/v1",
    api_key=os.environ["TUTUJIN_API_KEY"],
    max_retries=4,
    timeout=60.0,  # seconds
)

An empty balance returns 403, which the SDK does not retry; alert on it in your own code. Details in Errors and retries.

Async calls (Python)

For lots of concurrent requests use AsyncOpenAI; it takes the same options:

Python
import asyncio
import os

from openai import AsyncOpenAI

client = AsyncOpenAI(base_url="https://www.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"])


async def main():
    resp = await client.chat.completions.create(
        model="gpt-5.4-mini",
        messages=[{"role": "user", "content": "Hello"}],
    )
    print(resp.choices[0].message.content)


asyncio.run(main())

For choosing a concurrency cap, see Rate limits.

Troubleshooting

SymptomCause and fix
404base_url is missing /v1; it should be https://www.tutujin.com/v1
401Wrong or invalid key; check the environment variable holds the full key
503 with model_not_foundThe key's group lacks this model; switch groups or check the name — see Choosing a group
Slow responses or timeoutsStream long outputs and raise timeout

Still stuck? Add our WeChat support JsnonoChat and send the request id from the error message, and we will look into it.