API reference
Responses API
Headers, parameters, request and response examples and stream events for POST /v1/responses. Same format as the OpenAI Responses API; some models only support this format. Requests are relayed as-is.
POST /v1/responses is OpenAI's newer API format: input replaces messages, system instructions go in instructions, and reasoning effort, structured output and tools are written differently from Chat Completions. Some models in the catalog only support this format. Requests are relayed to the model service in their original format, so whether a parameter takes effect follows that model's official documentation.
https://open.tutujin.com/v1/responsesHeaders
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer sk-..., an API key from the console |
Content-Type | Yes | application/json |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model name, e.g. gpt-6.1-sol |
input | string or array | Yes | The input. A plain string, or an array of messages for multi-turn chats and image input — structure below |
instructions | string | No | System instructions, like the system message in Chat Completions |
max_output_tokens | integer | No | Most tokens to generate, including reasoning tokens |
temperature | number | No | Sampling temperature; higher is more varied. Reasoning models usually do not support it |
top_p | number | No | Nucleus sampling; tune this or temperature, not both |
stream | boolean | No | true returns server-sent events; default false |
reasoning | object | No | Reasoning settings, e.g. {"effort": "low"} with low, medium or high; reasoning models only |
text | object | No | Output format, e.g. {"format": {"type": "json_object"}} for JSON; some models support json_schema for strict structured output |
tools | array | No | Tools the model may call, such as function definitions. Built-in tools depend on the model |
tool_choice | string or object | No | auto, none, required, or a specific tool |
store | boolean | No | Whether the response is stored server-side. Features that rely on stored responses are not verified on this site; set it to false |
previous_response_id | string | No | Continues from a stored response. It relies on server-side storage and is not verified here, so send the history in input instead |
metadata | object | No | Your own key-value pairs for reconciliation and debugging |
The input field
The simplest form is a string. For multi-turn chats or images, pass an array of messages:
[
{ "role": "user", "content": "What is the total on this invoice?" },
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Reply with the amount and currency only." },
{ "type": "input_image", "image_url": "https://example.com/invoice.png" }
]
}
]role is user, assistant, system or developer. You can also inline an image in image_url as data:image/png;base64,....
Request example
curl https://open.tutujin.com/v1/responses \
-H "Authorization: Bearer $TUTUJIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6.1-sol",
"instructions": "You are a finance assistant. Be brief and use two decimal places.",
"input": "Travel cost 1280, meal allowance 80 a day for 3 days. What is the total claim?"
}'import os
from openai import OpenAI
client = OpenAI(base_url="https://open.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"])
resp = client.responses.create(
model="gpt-6.1-sol",
instructions="You are a finance assistant. Be brief and use two decimal places.",
input="Travel cost 1280, meal allowance 80 a day for 3 days. What is the total claim?",
)
print(resp.output_text)
print(resp.usage)import OpenAI from 'openai'
const client = new OpenAI({ baseURL: 'https://open.tutujin.com/v1', apiKey: process.env.TUTUJIN_API_KEY })
const resp = await client.responses.create({
model: 'gpt-6.1-sol',
instructions: 'You are a finance assistant. Be brief and use two decimal places.',
input: 'Travel cost 1280, meal allowance 80 a day for 3 days. What is the total claim?',
})
console.log(resp.output_text)
console.log(resp.usage)Response example
{
"id": "resp_...",
"object": "response",
"created_at": 1794000000,
"status": "completed",
"model": "gpt-6.1-sol",
"output": [
{
"type": "message",
"id": "msg_...",
"status": "completed",
"role": "assistant",
"content": [
{ "type": "output_text", "text": "The total claim is 1520.00.", "annotations": [] }
]
}
],
"usage": {
"input_tokens": 48,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens": 15,
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 63
}
}| Field | Description |
|---|---|
status | completed finished normally; incomplete usually means max_output_tokens cut it off |
output | Output items: message (the answer), reasoning (a reasoning summary), function_call (a function for you to run) |
output[].content[].text | The answer text. The official SDKs expose output_text with all text joined |
usage.input_tokens | Input tokens, billed at the input price |
usage.input_tokens_details.cached_tokens | Input tokens served from the context cache, billed at the cache-read price |
usage.output_tokens | Output tokens, billed at the output price; reasoning_tokens is the thinking part |
Streaming
With "stream": true the server pushes server-sent events. Each event has an event: name; new text arrives in the delta field of response.output_text.delta, and response.completed carries the full response and usage:
event: response.created
data: {"type":"response.created","response":{"id":"resp_...","status":"in_progress"}}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":"The total"}
event: response.output_text.done
data: {"type":"response.output_text.done","output_index":0,"content_index":0,"text":"The total claim is 1520.00."}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_...","status":"completed","usage":{"input_tokens":48,"output_tokens":15,"total_tokens":63}}}With an SDK, pick text out by event type:
stream = client.responses.create(
model="gpt-6.1-sol",
input="Write a 60-word product description",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif event.type == "response.completed":
print("\n", event.response.usage)const stream = await client.responses.create({
model: 'gpt-6.1-sol',
input: 'Write a 60-word product description',
stream: true,
})
for await (const event of stream) {
if (event.type === 'response.output_text.delta') process.stdout.write(event.delta)
if (event.type === 'response.completed') console.log('\n', event.response.usage)
}Notes
- This endpoint is relayed as-is and has not been verified separately on this site. Check parameters and response shape with a little traffic when you adopt a new model.
- For multi-turn chats, send the full history in
inputrather than relying onprevious_response_idandstore. - Reasoning tokens count as output, so reasoning models can cost noticeably more; cap them with
max_output_tokensandreasoning.effort. - Whether built-in tools such as web search work, and whether they are billed separately, depends on the model; the Usage page in the console is the record.
- If a model also supports Chat Completions and you do not need Responses-only features, Chat Completions is simpler, and switching vendors only means changing
model.
Models that support this endpoint
| Model | Vendor | Cheapest group | Input ¥/1M | Output ¥/1M | Per request ¥ |
|---|---|---|---|---|---|
| GPT-6.1 Sol | OpenAI | Standard | ¥4 | ¥20 | — |
| GPT-6 Luna | OpenAI | Standard | ¥0.2 | ¥1 | — |
| GPT-6 Sol | OpenAI | Standard | ¥20 | ¥100 | — |
| gpt-6-astra | OpenAI | Standard | ¥20 | ¥100 | — |
| muse-wonder-1.0 | Other | Standard | ¥56 | ¥280 | — |
Prices in CNY, cheapest group for each model; updated Nov 12, 2026, 8:17 PM.
Still stuck? Add our WeChat support JsnonoChat and send the request id from the error message, and we will look into it.