OpenAI-compatible
Chat Completions
Call models on NoviaHub in the OpenAI Chat Completions format — URL, headers, request parameters, response, streaming and sample code.
Compatible with OpenAI’s Create chat completion. This is the most general way to call a model: almost every model can be called through it (any model whose endpoint labels include Chat; see Protocol conversion).
POST https://noviahub.com/v1/chat/completionsHeaders
Section titled “Headers”| Header | Required | Description |
|---|---|---|
Authorization |
Yes | Bearer <your API key> |
Content-Type |
Yes | application/json |
Request parameters
Section titled “Request parameters”The table lists the main parameters NoviaHub recognises and forwards. Whether a parameter takes effect depends on the model you call. A model may ignore parameters it doesn’t support, or its upstream may reject them.
| Parameter | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Model ID, such as deepseek-v4-flash. Available IDs are on Models & Pricing. |
messages |
array | Yes | The conversation; structure below. |
stream |
boolean | No | true returns a stream (SSE); see Streaming. |
stream_options |
object | No | Streaming options. include_usage: whether usage is sent at the end; NoviaHub defaults it to true. |
max_tokens |
integer | No | Maximum tokens to generate. |
max_completion_tokens |
integer | No | Maximum tokens to generate, including reasoning; OpenAI’s newer name. |
temperature |
number | No | Sampling temperature; higher is more random. |
top_p |
number | No | Nucleus sampling. |
top_k |
integer | No | Top-K sampling (some models). |
stop |
string / array | No | Stop when any of these strings appears. |
n |
integer | No | Number of candidate replies. |
frequency_penalty |
number | No | Frequency penalty. |
presence_penalty |
number | No | Presence penalty. |
seed |
number | No | Random seed. |
response_format |
object | No | Output format, such as {"type": "json_object"} or {"type": "json_schema", "json_schema": {...}}. |
tools |
array | No | Tools (functions) the model may call, each like {"type": "function", "function": {"name", "description", "parameters", "strict"}}. |
tool_choice |
string / object | No | Whether and which tool to call. |
parallel_tool_calls |
boolean | No | Allow several tool calls at once. |
reasoning_effort |
string | No | Reasoning effort (reasoning models), such as low, medium, high. |
logprobs |
boolean | No | Return the probability of each token. |
top_logprobs |
integer | No | How many candidate tokens per position to return probabilities for. |
web_search_options |
object | No | Web search options (supporting models): search_context_size, user_location. |
prompt_cache_key |
string | No | Prompt cache key (supporting models). |
user, metadata |
— | No | User identifier and extra data, forwarded as is. |
NoviaHub also recognises and forwards modalities, audio, prediction, logit_bias, store, prompt_cache_retention, verbosity, reasoning, extra_body, and some vendor-specific extensions (such as enable_thinking, thinking_budget, chat_template_kwargs, thinking).
Structure of messages
Section titled “Structure of messages”Each message is an object:
| Field | Description |
|---|---|
role |
system, developer, user, assistant or tool. |
content |
A string, or an array mixing text, images and more (below). |
name |
Optional speaker name. |
tool_calls |
Tool calls made by the model, in assistant messages. |
tool_call_id |
In tool messages, which tool call this answers. |
When content is an array, each item’s type can be text (with text), image_url (with image_url: {"url": "...", "detail": "..."}), input_audio, file or video_url. Whether a model can read images or audio is shown under Input types on its Models & Pricing page.
Sample code
Section titled “Sample code”curl https://noviahub.com/v1/chat/completions \ -H "Authorization: Bearer $NOVIAHUB_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4-flash", "messages": [ {"role": "system", "content": "You are a concise assistant."}, {"role": "user", "content": "Explain what an API is in one sentence."} ] }'import os
from openai import OpenAI
client = OpenAI( base_url="https://noviahub.com/v1", api_key=os.environ["NOVIAHUB_API_KEY"],)
completion = client.chat.completions.create( model="deepseek-v4-flash", messages=[ {"role": "system", "content": "You are a concise assistant."}, {"role": "user", "content": "Explain what an API is in one sentence."}, ],)
print(completion.choices[0].message.content)import OpenAI from 'openai'
const client = new OpenAI({ baseURL: 'https://noviahub.com/v1', apiKey: process.env.NOVIAHUB_API_KEY,})
const completion = await client.chat.completions.create({ model: 'deepseek-v4-flash', messages: [ { role: 'system', content: 'You are a concise assistant.' }, { role: 'user', content: 'Explain what an API is in one sentence.' }, ],})
console.log(completion.choices[0].message.content)Response
Section titled “Response”| Field | Description |
|---|---|
id |
ID of this reply. |
object |
Always chat.completion. |
created |
Creation time (Unix seconds). |
model |
Model ID. |
choices[].message.content |
The model’s answer. |
choices[].message.tool_calls |
Tool calls requested by the model, if any. |
choices[].message.reasoning_content |
Some models return their reasoning here. |
choices[].finish_reason |
Why generation stopped, such as stop (finished), length (hit the limit), tool_calls (wants to call a tool). |
usage.prompt_tokens |
Input tokens. |
usage.completion_tokens |
Output tokens. |
usage.total_tokens |
Total. |
{ "id": "chatcmpl-mock123", "object": "chat.completion", "created": 1790609866, "model": "deepseek-v4-flash", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Hello from the mock upstream." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 12, "completion_tokens": 7, "total_tokens": 19 }}When a model is reached through protocol conversion (for example a Claude or Gemini model called here), usage contains extra internal fields you can ignore; see Protocol conversion.
Streaming
Section titled “Streaming”Add "stream": true and the response arrives as SSE (Server-Sent Events). Each piece starts with data: and holds a chat.completion.chunk object; new text is in choices[0].delta.content. The last line is data: [DONE].
By default NoviaHub sends one more piece before [DONE] that only carries usage (an empty choices array plus usage), even if you didn’t send stream_options. To leave it out, send "stream_options": {"include_usage": false}.
data: {"id":"chatcmpl-mock123","object":"chat.completion.chunk","created":1790609866,"model":"deepseek-v4-flash","choices":[{"index":0,"delta":{"content":"Hello","role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-mock123","object":"chat.completion.chunk","created":1790609866,"model":"deepseek-v4-flash","choices":[{"index":0,"delta":{"content":" from the mock upstream."},"finish_reason":null}]}
data: {"id":"chatcmpl-mock123","object":"chat.completion.chunk","created":1790609866,"model":"deepseek-v4-flash","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-mock123","object":"chat.completion.chunk","created":1790609866,"model":"deepseek-v4-flash","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":7,"total_tokens":19}}
data: [DONE]curl https://noviahub.com/v1/chat/completions \ -H "Authorization: Bearer $NOVIAHUB_API_KEY" \ -H "Content-Type: application/json" \ -N \ -d '{ "model": "deepseek-v4-flash", "stream": true, "messages": [{"role": "user", "content": "Write a four-line poem."}] }'import os
from openai import OpenAI
client = OpenAI( base_url="https://noviahub.com/v1", api_key=os.environ["NOVIAHUB_API_KEY"],)
stream = client.chat.completions.create( model="deepseek-v4-flash", messages=[{"role": "user", "content": "Write a four-line poem."}], stream=True,)
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("\nUsage:", chunk.usage)import OpenAI from 'openai'
const client = new OpenAI({ baseURL: 'https://noviahub.com/v1', apiKey: process.env.NOVIAHUB_API_KEY,})
const stream = await client.chat.completions.create({ model: 'deepseek-v4-flash', messages: [{ role: 'user', content: 'Write a four-line poem.' }], stream: true,})
for await (const chunk of stream) { const text = chunk.choices[0]?.delta?.content if (text) process.stdout.write(text) if (chunk.usage) console.log('\nUsage:', chunk.usage)}The usage-only piece has an empty choices array, so check it before reading choices[0], as the samples do.
Common errors
Section titled “Common errors”| HTTP status | Cause |
|---|---|
| 400 | Missing model (Model name not specified...), missing messages (field messages is required), or the body isn’t valid JSON. |
| 401 | The key is invalid, disabled, expired or out of quota (Invalid token). |
| 403 | The key isn’t allowed to use this model, the IP isn’t on the allow list, or the account balance is too low. |
| 503 | Wrong model ID, or no channel is currently available for the model (No available channel for model ...). |
See Errors and troubleshooting for details.