Send messages to any model and receive a completion or a streamed response.
Chat completions are the core of the OpenDunes API. Pass an ordered array of messages, choose a model, and get a reply — optionally streamed token by token.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://opendunes.com/v1",
apiKey: process.env.OPENDUNES_API_KEY,
});
const resp = await client.chat.completions.create({
model: "google/gemini-2.5-pro",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "What is the capital of Algeria?" },
],
max_tokens: 256,
temperature: 0.7,
});
console.log(resp.choices[0].message.content);
// Estimated cost in micro-DA visible in X-Balance-Available response headerModel slugs follow the provider/model format. Find available models at /models or via the Models API.
Set stream: true to receive tokens as they arrive over server-sent events. The openai SDK handles SSE framing automatically — you iterate over delta chunks.
const stream = await client.chat.completions.create({
model: "anthropic/claude-opus-4.8",
messages: [{ role: "user", content: "Explain tifinagh script in two sentences." }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content ?? "";
process.stdout.write(delta);
}
// The final chunk carries usage: prompt_tokens + completion_tokensThe stream ends with a [DONE] sentinel. If an error occurs mid-stream, a final error event arrives before [DONE] — inspect chunk.error or catch the thrown OpenAIError.
| Field | Type | Required | Notes |
|---|---|---|---|
model | string | Yes | provider/model slug |
messages | array | Yes | system · user · assistant · tool roles |
stream | boolean | No | Default false |
max_tokens | integer | No | Cap on output tokens |
temperature | number | No | 0–2, default 1 |
top_p | number | No | 0–1, default 1 |
For models with vision capability, pass image content as a parts array:
{
role: "user",
content: [
{ type: "text", text: "What is in this image?" },
{ type: "image_url", image_url: { url: "https://example.com/photo.jpg" } },
],
}Every response includes:
X-Balance-Available — remaining balance in micro-DA after this request. Not on a streamed answer.X-Request-Id — a UUID-v7 trace ID; include it when contacting support.There is no cap on the number of requests, so there is no request counter.
import OpenAI, { APIError } from "openai";
try {
const resp = await client.chat.completions.create({ ... });
} catch (err) {
if (err instanceof APIError) {
// err.error is the body's `error` object: { code, message, metadata }
const error = err.error as { code: number; message: string; metadata?: { limit_source?: string; error_type?: string } };
if (err.status === 402 && error?.metadata?.limit_source === "wallet") {
// Redirect the user to deposit DA at /dashboard/billing
}
if (err.status === 429) {
// Respect Retry-After before retrying
}
}
}See the full error reference in API Errors.