Chat completions and streaming
POSThttps://api.aderra.ai/v1/chat/completions
OpenAI Chat Completions. Any OpenAI SDK works with the base URL https://api.aderra.ai/v1. Send the key as Authorization: Bearer.
Request body
modelstringrequired- A chat model id, for example
deepseek-v4.1-flash-uncensored. See Models. messagesarrayrequired- The whole conversation. Nothing is kept between requests.
max_tokensintegeroptional- Output ceiling, capped at the model limit (32,768). Absent: the limit. It also sizes the hold on your wallet.
max_completion_tokensworks too. streambooleanoptional- Send the reply as server-sent events.
temperature, top_p, top_knumberoptional- Sampling.
tools, tool_choicearray, string | objectoptional- Function calling, as in OpenAI.
parallel_tool_callsis accepted. response_formatobjectoptional- JSON mode or a JSON schema, as in OpenAI.
reasoning_effortstringoptional- Thinking budget. See Thinking on the Models page.
stop, seedstring | array, integeroptional- As in OpenAI.
presence_penalty, frequency_penalty, logit_bias, logprobs, top_logprobsvariousoptional- As in OpenAI.
nintegeroptional- Must be 1 or absent. Anything else is refused with
unsupported_n.
curl https://api.aderra.ai/v1/chat/completions \ -H "Authorization: Bearer $ADERRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4.1-flash-uncensored", "max_tokens": 1024, "messages": [ {"role": "system", "content": "Answer in one sentence."}, {"role": "user", "content": "Why is the sea salty?"} ] }'import osfrom openai import OpenAI
client = OpenAI(base_url="https://api.aderra.ai/v1", api_key=os.environ["ADERRA_API_KEY"])
reply = client.chat.completions.create( model="deepseek-v4.1-flash-uncensored", max_tokens=1024, messages=[ {"role": "system", "content": "Answer in one sentence."}, {"role": "user", "content": "Why is the sea salty?"}, ],)print(reply.choices[0].message.content)print(reply.usage)import OpenAI from 'openai';
const client = new OpenAI({ baseURL: 'https://api.aderra.ai/v1', apiKey: process.env.ADERRA_API_KEY,});
const reply = await client.chat.completions.create({ model: 'deepseek-v4.1-flash-uncensored', max_tokens: 1024, messages: [ { role: 'system', content: 'Answer in one sentence.' }, { role: 'user', content: 'Why is the sea salty?' }, ],});console.log(reply.choices[0].message.content);console.log(reply.usage);Response: application/jsonA chat.completion object, or text/event-stream when stream is true.
Fields not listed above are dropped rather than refused, so a client that sends extra OpenAI fields keeps working. user and metadata are replaced by Aderra’s own; store, prediction and service_tier are not supported.
Streaming
Section titled “Streaming”With "stream": true the reply arrives as server-sent events: one data: line per chat.completion.chunk, ending with data: [DONE]. The last chunk before [DONE] has an empty choices array and the token usage: Aderra always asks for it, so you get it even without stream_options.
curl -N https://api.aderra.ai/v1/chat/completions \ -H "Authorization: Bearer $ADERRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "glm-5.3-flash", "max_tokens": 1024, "stream": true, "messages": [{"role": "user", "content": "Count to five."}]}'stream = client.chat.completions.create( model="glm-5.3-flash", max_tokens=1024, stream=True, messages=[{"role": "user", "content": "Count to five."}],)for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True) if chunk.usage: print("\n", chunk.usage)const stream = await client.chat.completions.create({ model: 'glm-5.3-flash', max_tokens: 1024, stream: true, messages: [{ role: 'user', content: 'Count to five.' }],});for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? ''); if (chunk.usage) console.log('\n', chunk.usage);}If your client disconnects mid-stream, you pay for what was generated up to that point.
Function calling works as in OpenAI: declare tools, read tool_calls from the reply, run them, and send the results back as tool messages in the next request.
tools = [{ "type": "function", "function": { "name": "get_weather", "description": "Current weather for a city", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, },}]
reply = client.chat.completions.create( model="glm-5.3-flash", max_tokens=1024, tools=tools, messages=[{"role": "user", "content": "Weather in Lyon?"}],)print(reply.choices[0].message.tool_calls)Images in messages
Section titled “Images in messages”Send images as image_url content parts, as a URL or a data: URI. Only models whose input_modalities (from GET /v1/models) include image can read them. Large images are shrunk before they reach the model.
{ "role": "user", "content": [ {"type": "text", "text": "What is in this picture?"}, {"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBOR..."}} ]}Images you send here also become the input for image edits and video.
System prompts
Section titled “System prompts”With an API key, your system prompt is yours. Your system and developer messages reach the model untouched: nothing is removed or reworded, and there is no Aderra persona. Aderra adds exactly one line, “Never produce any sexual content involving minors.”, as a system message placed first. It costs about ten input tokens.
A terminal key (Claude Code, Codex, Aderra Agent) works differently: its requests carry Aderra’s agent instructions as well. See Coding tools.
Response headers
Section titled “Response headers”| Header | Meaning |
|---|---|
x-aderra-model-used |
The model that answered. You pay its price. See routing. |
x-aderra-route |
Why that model answered. |
x-aderra-reservation |
The id of this call’s credit hold. Quote it when you contact support about a charge. |
Behaviour to know
Section titled “Behaviour to know”- One answer per request.
nmust be 1. - Nothing is stored. Send the whole conversation each time.
- The hold. Before the call, Aderra holds your input plus the full
max_tokensat the model’s output price. A nearly empty wallet can refuse a request with a largemax_tokens: send a smaller one, or add funds. See Pricing. - An empty answer is free. A reply with no text, tool call or refusal in it (for example, all thinking) is charged nothing.
- Request size. A body is refused above roughly 4 MB after images are shrunk, with
413 request_too_large. See Rate limits.