API documentation
Everything you need to call the Neuronyx models — chat, voice and transcription tuned for Iraqi Arabic — on one page.
On this page
Overview#
The Neuronyx API is a REST API in the widely used Chat Completions format. If you already have chat or speech code, you usually only change the base URL, the key and the model id.
https://api.neuronyxai.com/v1
| Model id | Name | Endpoint |
|---|---|---|
nx-chat-iq-1 | Neuronyx Chat — Iraqi | POST /v1/chat/completions |
nx-voice-iq-1 | Neuronyx Voice — Iraqi | POST /v1/audio/speech |
nx-listen-iq-1 | Neuronyx Listen — Iraqi | POST /v1/audio/transcriptions |
- Format: JSON in and out, UTF-8. Speech returns audio bytes; transcription takes
multipart/form-data. - Request id: every response carries an
x-request-idheader (req_…), and error bodies repeat it. Quote it when you write to us. - Cost headers: every successful paid response that is not streamed carries
x-nx-cost-usd(this request) andx-nx-balance-usd(credit left). A streamed chat sends its headers before the cost is known, so it reports the cost in its last chunk instead: setstream_options.include_usagetotrue(see chat).
Early access
Keys are issued by our team. Request access and we’ll reply within one working day. Details on this page can still change before general release; we list every change in the changelog.
Authentication#
Send your key as a bearer token on every request.
Authorization: Bearer nx_live_9fK2…
- Keys start with
nx_live_followed by 32 random characters. - We store only a hash of your key and show the full key once, when it is created. A lost key can’t be recovered: we revoke it and issue a new one with the same balance.
- A key sent in the query string (
?api_key=) is refused with401 key_in_query, so keys don’t end up in logs.
Keep your key on the server
Never ship it in a web page or a mobile app. Anyone with the key can spend its credit.
Quickstart#
Put your key in an environment variable, then send your first chat request.
export NEURONYX_API_KEY="nx_live_…"
curl https://api.neuronyxai.com/v1/chat/completions \
-H "Authorization: Bearer $NEURONYX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nx-chat-iq-1",
"messages": [
{"role": "system",
"content": "Baghdad electronics shop. In stock: two-door fridge, 1,150,000 IQD."},
{"role": "user",
"content": "عدكم ثلاجة بابين؟"}
]
}'
import os, requests
r = requests.post(
"https://api.neuronyxai.com/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['NEURONYX_API_KEY']}"},
json={
"model": "nx-chat-iq-1",
"messages": [
{"role": "system",
"content": "You are the assistant of a Baghdad electronics shop. "
"In stock: two-door fridge, 1,150,000 IQD."},
{"role": "user",
"content": "عدكم ثلاجة بابين؟"},
],
},
timeout=60,
)
r.raise_for_status()
print(r.json()["choices"][0]["message"]["content"])
const res = await fetch("https://api.neuronyxai.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NEURONYX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "nx-chat-iq-1",
messages: [
{ role: "system",
content: "You are the assistant of a Baghdad electronics shop. " +
"In stock: two-door fridge, 1,150,000 IQD." },
{ role: "user",
content: "عدكم ثلاجة بابين؟" },
],
}),
});
const data = await res.json();
console.log(data.choices[0].message.content);
The reply comes back in natural Baghdadi Arabic, for example:
هلا بيك! إي عدنا، تريد أدزلك صور؟
Using a Chat Completions SDK?
Most SDKs for this format accept a custom base URL. Set it to https://api.neuronyxai.com/v1, use your Neuronyx key, and pass the Neuronyx field dialect as an extra body parameter.
Chat completions#
POST/v1/chat/completions
Generates a reply to a conversation with nx-chat-iq-1. Our Iraqi instructions are placed before your own system message: your system message controls the persona, the task and the facts; ours controls the language. If they disagree about language in baghdadi mode, ours wins.
Request body
modelstringrequired
nx-chat-iq-1.messagesarrayrequired
The conversation so far. Roles
system,user,assistant,tool. Text content only in v1; image input is coming soon.dialect"baghdadi" | "mirror"default "baghdadi"
Neuronyx field.
baghdadi: Arabic replies are natural spoken Baghdadi, whatever Arabic the user writes (formal, Egyptian, Gulf, or Iraqi in Latin letters like “shlonak”); English gets English.mirror: the reply follows the user’s register — formal Arabic gets formal Arabic — for letters, documents and news.dialect_guardbooleandefault false
Neuronyx field. Coming soon The field is accepted today and always answered with
dialect_guard.result: "skipped", never charged. At launch it will re-read every Arabic reply and swap any non-Baghdadi word in place, only if every number, price and name survives (about 2 seconds more). Works withdialect: "baghdadi"only (400withmirror) and not together withtools. It will be billed per started 1,500 characters of checked reply.streambooleandefault false
Server-sent events in the standard chunk format, ending with
data: [DONE]. Headers go out before the cost is known, so a streamed reply has nox-nx-cost-usdheader: send"stream_options": {"include_usage": true}and the last chunk before[DONE]carriesusagewithcost_usd.max_tokensintegerdefault 2000
Up to 8,000. Also accepted as
max_completion_tokens. Counts reasoning tokens too.reasoning_effort"minimal" | "low" | "medium" | "high"default "low"
Higher is better at hard tasks, but slower and uses more output tokens.
tools, tool_choicearray, string | object
Function calling in the standard format.
response_formatobject
{"type": "json_object"}or ajson_schema.temperature, top_p, stop, seednumber, number, string | array, integer
Passed through where supported.
userstring
Your own end-user id, for your usage breakdown. We store only a hash of it.
Example
curl https://api.neuronyxai.com/v1/chat/completions \
-H "Authorization: Bearer $NEURONYX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nx-chat-iq-1",
"dialect": "baghdadi",
"messages": [
{"role": "system",
"content": "Assistant of a Baghdad electronics shop. Two-door fridges in stock."},
{"role": "user",
"content": "عدكم ثلاجة بابين؟"}
]
}'
import os, requests
r = requests.post(
"https://api.neuronyxai.com/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['NEURONYX_API_KEY']}"},
json={
"model": "nx-chat-iq-1",
"dialect": "baghdadi",
"messages": [
{"role": "system",
"content": "You are the assistant of a Baghdad electronics shop. "
"Two-door fridges are in stock."},
{"role": "user",
"content": "عدكم ثلاجة بابين؟"},
],
},
timeout=60,
)
body = r.json()
print(body["choices"][0]["message"]["content"])
print(body["usage"]["cost_usd"])
const res = await fetch("https://api.neuronyxai.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NEURONYX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "nx-chat-iq-1",
dialect: "baghdadi",
messages: [
{ role: "system",
content: "You are the assistant of a Baghdad electronics shop. " +
"Two-door fridges are in stock." },
{ role: "user",
content: "عدكم ثلاجة بابين؟" },
],
}),
});
const body = await res.json();
console.log(body.choices[0].message.content, body.usage.cost_usd);
Response
The standard chat.completion object, plus usage.cost_usd.
{
"id": "chatcmpl_req_01JC8Z…",
"object": "chat.completion",
"created": 1793500000,
"model": "nx-chat-iq-1",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "هلا بيك! إي عدنا، تريد أدزلك صور؟"},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 412,
"completion_tokens": 96,
"completion_tokens_details": {"reasoning_tokens": 61},
"total_tokens": 508,
"cost_usd": 0.000539
}
}
usage.prompt_tokenscounts only your own input. Our Iraqi instructions are not billed to you.usage.cost_usd= 412 × $0.75 / 1M + 96 × $2.40 / 1M (reasoning tokens count as output).- If you send
dialect_guardComing soon, the response also carries adialect_guardobject withresult: "skipped"andcharged: falseuntil the guard launches. - Arabic replies always use the Iraqi spelling ج.
Speech#
POST/v1/audio/speech
Turns text into a Baghdadi voice clip with nx-voice-iq-1. Returns audio bytes.
Request body
modelstringrequired
nx-voice-iq-1.inputstringrequired
1 to 4,000 characters, read exactly as written. Write numbers as words when they must be said a certain way (سبعمية وخمسين ألف).
voicestringdefault "karim"
v1 has one voice:
karim, a warm young Baghdadi man. More voices are coming soon.response_format"mp3" | "ogg" | "wav" | "pcm"default "mp3"
oggis Opus in Ogg, 48 kHz mono, and plays as a WhatsApp voice note as it is.wavis 16-bit 24 kHz mono.pcmis raw 16-bit little-endian, 24 kHz mono.speednumberdefault 1.0
0.8 to 1.25. Changes tempo without changing pitch.
instructionsstring
Optional tone, up to 300 characters — “cheerful”, “calm, like a pharmacist explaining a dose”. The Baghdadi accent always stays on.
language"ar" | "en" | "auto"default "auto"
autofollows the script ofinput. English text is spoken in natural English by the same voice.dialect_guardbooleandefault false
Neuronyx field. Coming soon Accepted today; every clip comes back with
x-nx-dialect-guard: skippedat the normal price. At launch, Arabic clips will be listened to and recorded again when a word, a number or the accent is wrong.
Every clip is trimmed of dead air and levelled. Long input is split at sentence ends, synthesised in parallel and joined with a short natural pause.
curl https://api.neuronyxai.com/v1/audio/speech \
-H "Authorization: Bearer $NEURONYX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "nx-voice-iq-1", "voice": "karim", "response_format": "ogg",
"input": "هلا عيوني، إي متوفرة، تريد أدزلك صورها؟"}' \
--output reply.ogg
import os, requests
r = requests.post(
"https://api.neuronyxai.com/v1/audio/speech",
headers={"Authorization": f"Bearer {os.environ['NEURONYX_API_KEY']}"},
json={
"model": "nx-voice-iq-1",
"voice": "karim",
"response_format": "ogg",
"input": "هلا عيوني، إي متوفرة، تريد أدزلك صورها؟",
},
timeout=60,
)
r.raise_for_status()
with open("reply.ogg", "wb") as f:
f.write(r.content)
print(r.headers["x-nx-audio-seconds"], r.headers["x-nx-cost-usd"])
import { writeFile } from "node:fs/promises";
const res = await fetch("https://api.neuronyxai.com/v1/audio/speech", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NEURONYX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "nx-voice-iq-1",
voice: "karim",
response_format: "ogg",
input: "هلا عيوني، إي متوفرة، تريد أدزلك صورها؟",
}),
});
await writeFile("reply.ogg", Buffer.from(await res.arrayBuffer()));
Response
Audio bytes with Content-Type audio/mpeg, audio/ogg, audio/wav or audio/L16;rate=24000, and these headers:
| Header | Meaning |
|---|---|
x-nx-characters-billed | Characters charged, at least 100. |
x-nx-audio-seconds | Length of the clip. |
x-nx-dialect-guard | Always skipped for now: the voice guard is Coming soon. |
x-nx-cost-usd, x-nx-balance-usd | This request’s cost and the credit left. |
Streaming audio as it is generated is Coming soon.
Transcriptions#
POST/v1/audio/transcriptions
Turns an Iraqi voice note into text with nx-listen-iq-1. Send multipart/form-data.
Form fields
filefilerequired
ogg/opus (WhatsApp voice notes as they come), mp3, wav, m4a, aac, webm or flac. Up to 25 MB and 10 minutes. Long audio is split and transcribed in parallel.
modelstringrequired
nx-listen-iq-1.language"ar" | "en" | "auto"default "ar"
A hint. With
ar, English words and English speech still come out right.response_format"json" | "text"default "json"
verbose_jsonwith segment timestamps is coming soon.promptstringComing soon
Names and brands to expect, such as a shop’s product list.
curl https://api.neuronyxai.com/v1/audio/transcriptions \
-H "Authorization: Bearer $NEURONYX_API_KEY" \
-F model=nx-listen-iq-1 \
-F language=ar \
-F file=@voice-note.ogg
import os, requests
with open("voice-note.ogg", "rb") as audio:
r = requests.post(
"https://api.neuronyxai.com/v1/audio/transcriptions",
headers={"Authorization": f"Bearer {os.environ['NEURONYX_API_KEY']}"},
data={"model": "nx-listen-iq-1", "language": "ar"},
files={"file": ("voice-note.ogg", audio, "audio/ogg")},
timeout=120,
)
r.raise_for_status()
print(r.json()["text"])
import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("model", "nx-listen-iq-1");
form.append("language", "ar");
form.append("file", new Blob([await readFile("voice-note.ogg")], { type: "audio/ogg" }), "voice-note.ogg");
const res = await fetch("https://api.neuronyxai.com/v1/audio/transcriptions", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.NEURONYX_API_KEY}` },
body: form,
});
console.log((await res.json()).text);
Response
{
"text": "هلا بيكم، عدكم ثلاجة بابين متقابلين؟ اريد وحدة كبيرة",
"language": "ar",
"duration": 8.8,
"usage": {"seconds": 8.8, "billed_seconds": 9, "cost_usd": 0.00525}
}
Audio is billed per started second (minimum 3): 8.8 s is billed as 9 s × $0.035 / 60 = $0.00525.
Numbers and prices come out as they were heard — in words or in digits. The transcript keeps the speaker’s own words. An option that turns Iraqi number words into digits is Coming soon.
Models#
GET/v1/models
Lists all Neuronyx models with their current prices, whichever models your key is allowed to call. Free; needs a key. The dialect_guard price fields are for the guard, which is Coming soon; the chat guard will be charged per started 1,500 characters of reply.
{"object": "list", "data": [
{"id": "nx-chat-iq-1", "object": "model", "owned_by": "neuronyx",
"name": "Neuronyx Chat — Iraqi", "type": "chat",
"context_length": 128000,
"pricing": {"input_per_1m_tokens": 0.75, "output_per_1m_tokens": 2.40,
"dialect_guard_per_reply": 0.005}},
{"id": "nx-voice-iq-1", "type": "text-to-speech", "voices": ["karim"],
"pricing": {"per_1m_characters": 120, "per_1m_characters_with_dialect_guard": 190}},
{"id": "nx-listen-iq-1", "type": "speech-to-text",
"pricing": {"per_audio_minute": 0.035}}
]}
Usage and balance#
GET/v1/usage
Your balance and spending, per day or per model. Free.
start, enddate (YYYY-MM-DD)default: this month
Dates in Baghdad time (UTC+3).
group_by"day" | "model"default "day"
How rows in
dataare grouped.
curl "https://api.neuronyxai.com/v1/usage?start=2026-11-01&end=2026-11-30&group_by=model" \
-H "Authorization: Bearer $NEURONYX_API_KEY"
{"object": "usage", "key": "nx_live_9fK2…",
"balance_usd": 7.42, "daily_cap_usd": null,
"period": {"start": "2026-11-01", "end": "2026-11-30"},
"totals": {"requests": 626, "cost_usd": 2.99},
"data": [
{"model": "nx-chat-iq-1", "requests": 410,
"input_tokens": 512300, "output_tokens": 98200,
"guarded_replies": 0, "cost_usd": 0.62},
{"model": "nx-voice-iq-1", "requests": 96,
"characters": 14400, "audio_seconds": 1290.5, "cost_usd": 1.73},
{"model": "nx-listen-iq-1", "requests": 120,
"audio_seconds": 1104.0, "cost_usd": 0.64}
]}
Errors#
Errors use the standard shape, so most SDKs raise their usual exceptions.
{
"error": {
"message": "Your credit balance is $0.03; this request needs up to $0.05. Top up to continue.",
"type": "billing_error",
"code": "insufficient_credit",
"param": null
},
"request_id": "req_01JC8Z3X4V5W6Y7Z8A9B0C1D2E"
}
| HTTP | Type | Codes | When |
|---|---|---|---|
| 400 | invalid_request_error | invalid_parameter, missing_parameter, input_too_long, context_length_exceeded, unsupported_voice, unsupported_format | Something in the body is wrong, or the conversation is longer than the model can read. |
| 401 | authentication_error | invalid_api_key, missing_api_key, key_in_query | No key, or a wrong key. |
| 402 | billing_error | insufficient_credit, daily_cap_reached | Not enough credit for this request. |
| 403 | permission_error | key_revoked, model_not_allowed | A revoked key, or a model not enabled for this key. |
| 404 | not_found_error | model_not_found, route_not_found | Unknown model or path. |
| 413 | invalid_request_error | file_too_large | Audio over 25 MB. |
| 415 | invalid_request_error | unsupported_media_type | Audio we cannot decode. |
| 429 | rate_limit_error | rate_limit_exceeded | Too many requests; see rate limits. |
| 500 | api_error | internal_error | Our bug. Not charged. |
| 502 | api_error | upstream_error | The model backend failed. Not charged. |
| 503 | api_error | overloaded | The voice queue is full. Not charged. |
| 504 | api_error | timeout | No answer in time. Not charged. |
Retry 429, 502, 503 and 504 with a short backoff. Don’t retry 4xx errors without changing the request.
Rate limits#
Limits are per key. These are the defaults; if you need more, ask us.
| Endpoint | Requests / min | At once | Also |
|---|---|---|---|
chat/completions | 60 | 10 | 200,000 tokens / min |
audio/speech | 20 | 2 | 20,000 characters / min |
audio/transcriptions | 30 | 4 | 30 audio minutes / min |
models, usage | 120 | — | Free |
Every response carries x-ratelimit-limit-requests, x-ratelimit-remaining-requests and x-ratelimit-reset-requests (seconds). Past a limit you get 429 rate_limit_exceeded with a Retry-After header. At busy times a speech request may wait in a queue for up to 20 seconds; after that it returns 503 overloaded, which is not charged.
Credit and billing#
- Prepaid, in US dollars. Each key has its own balance. Our team adds credit to your key after payment; we share the payment options when we issue the key.
- Reserve, then settle. Before a request runs, its worst-case cost is reserved — for chat, your input plus
max_tokensof output. If your balance can’t cover it you get402 insufficient_creditand nothing runs. Afterwards only the real cost is charged and the rest is released. - Not charged: requests rejected before a model runs, any
5xx, timeouts, and a non-streamed request you cancel before the first byte. A streamed chat you cancel is charged for the tokens already generated. - Daily cap. We can set a daily spending cap on a key; past it you get
402 daily_cap_reached. - Prices are on the models page and in
GET /v1/models. Both read from the same price list.
Data policy#
- No training by us. We do not use your requests or outputs to train or tune any model.
- Metadata-only logs. We log the time, request id, key id (not the key), model, endpoint, token/character/second counts, cost, latency, status and error code — and a hash of
userif you send it. No message text, no audio, no transcripts. - On our servers, content is held only while the request runs, in memory or in a temporary file deleted when the response is sent.
- Requests are processed by Neuronyx servers and by the cloud AI infrastructure our models run on, under that provider’s own data terms.
- To have your usage records deleted, email info@neuronyxai.com. See also our privacy policy.
Versioning#
The path carries the API version (/v1). A model id never changes behaviour silently: new behaviour ships under a new id (for example nx-chat-iq-2), and an old id keeps working for at least 90 days after its replacement ships.
Changelog#
| Date | Change |
|---|---|
| 1 Nov 2026 | v1 early access: nx-chat-iq-1, nx-voice-iq-1 (voice karim), nx-listen-iq-1, GET /v1/models, GET /v1/usage. |
Coming soon
- The dialect guard for chat and voice (
dialect_guard). The field is accepted now and returnsskipped, free of charge. - Streaming audio from
/v1/audio/speech. - More voices, including a female voice.
- Segment timestamps (
verbose_json), word hints (prompt) and digits for Iraqi number words in transcription. - Image input for chat.
- Free test keys for trying the API without credit.
Questions or something missing? Write to info@neuronyxai.com and include the x-request-id.