Everything you need to send requests, read responses, and track usage with the OpenDunes API.
The OpenDunes API is OpenAI-compatible: point any OpenAI SDK at https://opendunes.com/api/v1 with your key and your existing code works. Every response is billed in Algerian Dinars (DA) and deducted from your balance in real time.
Send a POST to /v1/chat/completions with a JSON body. The minimum valid request needs a model slug and a messages array.
| Header | Required | Value |
|---|---|---|
Authorization | Yes | Bearer $OPENDUNES_API_KEY |
Content-Type | Yes | application/json |
The Authorization header carries your API key as a Bearer token. Keys begin with sk- and are only shown in full at creation time — only a hash is stored on our end. See Authentication.
To steer the model's response, include a trailing assistant message in your messages array. The model will continue from that text rather than starting fresh.
Note. Not all models honor prefill. The behavior is provider-dependent and passed through as-is.
Successful responses are standard OpenAI-compatible JSON with a choices array and a usage object.
choices[0].finish_reason explains why generation stopped.
| Value | Meaning |
|---|---|
stop | Model reached a natural end or a stop sequence |
length | Hit max_tokens limit |
tool_calls | Model wants to call one or more tools — see Tool calling |
content_filter | Output was filtered |
The usage object in every response shows prompt_tokens, completion_tokens, and total_tokens for the request. Multiply by the model's DA per-million-token rate to get the exact cost, or check /dashboard/analytics for itemized history. Non-chat surfaces return their own usage shape — embeddings report prompt_tokens, transcription reports audio seconds, and so on (see each surface's API page).
The X-Balance-Available response header gives your remaining balance in micro-DA (one-millionth of a Dinar) so you can monitor headroom without a separate API call.
See Rate Limits for the full set of response headers.
For aggregate reporting beyond a single response, the dashboard analytics endpoints are available to session-authenticated requests:
| Endpoint | Returns |
|---|---|
GET /api/analytics/summary | Totals — spend, requests, tokens over a period |
GET /api/analytics/per-model | Spend and request counts grouped by model |
GET /api/analytics/per-key | Spend grouped by API key |
GET /api/analytics/per-surface | Spend grouped by billing unit (tokens, images, audio seconds, characters, search units) |
GET /api/analytics/request-logs | Itemized request log (paginated) |
GET /api/analytics/request-logs/{id} | One request in full, including the error code and detail |
GET /api/analytics/facets | The models, providers, keys, workspaces and statuses you actually have rows for |
GET /api/analytics/export | CSV export of request logs |
per-surface is the one to watch once you use more than chat — it breaks your spend down by surface so you can see how much goes to images vs. transcription vs. embeddings.
request-logs, summary and export take the same filters, so a filtered summary always matches the rows it describes. Repeatable filters accept a comma-separated list.
| Parameter | Accepts |
|---|---|
q | Free text across model name, model slug, key name and request ID |
status | success, error, interrupted, processing, failed, dlq_replay |
model | Model slug, e.g. google/gemini-3-pro |
provider | Provider slug, e.g. google |
key_id | API key UUID |
workspace | Workspace UUID, or personal for keys that belong to no workspace |
from / to | ISO 8601 timestamps |
sort / dir | created_at, total_cost, latency_ms, tokens · asc or desc |
per_page | 1–200 (default 50) |
summary additionally returns a previous block covering the equivalent window immediately before the one you asked for, so you can render a period-over-period delta without a second call.