Orux AIOruxAI

Orux AI Documentation

One API, every leading model

OpenAI SDK compatible, with unified authentication, unified Credits billing, and automatic model-based routing for speed and reliability.

Quickstart

Get your API key and make your first request in a few minutes.

1. Create an API key

Sign up and open the API Keys page in your dashboard, then create a new key. The key is shown in full only once — copy it somewhere safe. You can view or copy it again later from the same page, and revoke it at any time.

Keys are prefixed with sk- and should be treated like a password: never commit them to source control or expose them in client-side code.

2. Make your first request

Orux AI speaks the OpenAI API protocol. Point any OpenAI-compatible client at https://orux.top/api/v1 and pass your key as a bearer token — no other code changes are required.

curl

curl https://orux.top/api/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4",
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'

Python

from openai import OpenAI

client = OpenAI(
    base_url="https://orux.top/api/v1",
    api_key="sk-xxxxxxxx",
)

response = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Hello!"}],
)

print(response.choices[0].message.content)

Node.js

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://orux.top/api/v1",
  apiKey: process.env.ORUX_API_KEY,
});

const response = await client.chat.completions.create({
  model: "gpt-5.4",
  messages: [{ role: "user", content: "Hello!" }],
});

console.log(response.choices[0].message.content);

3. Where to go next

  • Authentication — how bearer tokens are validated and best practices for storing keys.
  • Chat — streaming and non-streaming chat completions.
  • Embeddings — vector embeddings for search and retrieval.
  • Images — synchronous image generation.
  • Async tasks — video and audio/music generation, which run as background jobs.
  • Models — how to list the models currently available to your key.

Authentication

How to pass your API key and how the gateway validates it.

Bearer token

Every request to /api/v1/* (except GET /api/v1/models) must include your API key in the Authorization header as a bearer token:

header

Authorization: Bearer sk-xxxxxxxx

Key lifecycle

Keys are created and managed from your dashboard. Unlike some providers, Orux AI lets you reveal and copy the full key again after creation — you do not need to regenerate it if you lose it, though you can revoke and rotate at any time.

A key can optionally be scoped to a specific model allowlist. If your key is restricted and you call a model outside that list, the request is rejected before it reaches any upstream provider.

Authentication errors

Missing, malformed, or invalid keys all return HTTP 401 with an OpenAI-compatible error body:

response

{
  "error": {
    "message": "Invalid API key",
    "type": "invalid_request_error",
    "code": "invalid_api_key"
  }
}

Security recommendations

  • Never embed your key in frontend/browser code — proxy requests through your own backend.
  • Use a separate key per environment (dev / staging / production) so you can revoke one without affecting others.
  • Set a model allowlist on keys that only need access to a subset of models.
  • Rotate a key immediately if you suspect it has leaked.

Chat

POST /api/v1/chat/completions — OpenAI-compatible chat completions, with streaming support.

Request

Send a model name and a list of messages. This endpoint mirrors the OpenAI Chat Completions API, so any parameter your OpenAI client supports is passed through.

curl (non-streaming)

curl https://orux.top/api/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4",
    "messages": [{ "role": "user", "content": "Hello!" }],
    "stream": false
  }'

response

{
  "id": "chatcmpl-...",
  "choices": [
    { "index": 0, "message": { "role": "assistant", "content": "Hello! How can I help you today?" } }
  ],
  "usage": { "prompt_tokens": 12, "completion_tokens": 9, "total_tokens": 21 }
}

Streaming (SSE)

Set "stream": true to receive incremental output as Server-Sent Events. Each event is a JSON chunk with a choices[0].delta field; the stream ends with a literal data: [DONE] line. If the client disconnects mid-stream, the gateway stops forwarding immediately.

Pass "stream_options": { "include_usage": true } to receive one extra chunk at the end of the stream containing token usage for the whole response.

curl (streaming)

curl https://orux.top/api/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4",
    "messages": [{ "role": "user", "content": "Write a haiku about the sea" }],
    "stream": true,
    "stream_options": { "include_usage": true }
  }'

event stream

data: {"choices":[{"index":0,"delta":{"role":"assistant","content":""}}]}

data: {"choices":[{"index":0,"delta":{"content":"Waves"}}]}

data: {"choices":[{"index":0,"delta":{"content":" crash"}}]}

data: {"choices":[{"index":0,"delta":{}}],"usage":{"prompt_tokens":14,"completion_tokens":7,"total_tokens":21}}

data: [DONE]

Python (streaming)

from openai import OpenAI

client = OpenAI(base_url="https://orux.top/api/v1", api_key="sk-xxxxxxxx")

stream = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Write a haiku about the sea"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    print(delta, end="", flush=True)

Supported request fields

  • model (required) — the model alias, see the Models page for how to list available values.
  • messages (required) — array of { role, content }; content can be a string or a content-part array for multimodal models.
  • stream — set true for SSE streaming.
  • stream_options.include_usage — append a final usage-only chunk when streaming.
  • temperature, max_tokens, and other OpenAI-compatible parameters are passed through to the upstream model where supported.

Billing

Chat requests are billed in Credits based on prompt and completion token usage, only on success. Failed requests are not charged.

Embeddings

POST /api/v1/embeddings — OpenAI-compatible vector embeddings.

Request

Send one string or an array of strings as input, along with an embedding model alias. The response mirrors the OpenAI Embeddings API shape.

curl

curl https://orux.top/api/v1/embeddings \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-large",
    "input": ["Orux AI is a unified model gateway"]
  }'

Python

from openai import OpenAI

client = OpenAI(base_url="https://orux.top/api/v1", api_key="sk-xxxxxxxx")

response = client.embeddings.create(
    model="text-embedding-3-large",
    input=["Orux AI is a unified model gateway"],
)

print(response.data[0].embedding[:5])

response (truncated)

{
  "object": "list",
  "data": [{ "object": "embedding", "index": 0, "embedding": [0.0023, -0.009, "..."] }],
  "model": "text-embedding-3-large",
  "usage": { "prompt_tokens": 8, "total_tokens": 8 }
}

Supported request fields

  • model (required) — an embedding-capable model alias.
  • input (required) — a string or array of strings.
  • encoding_format — optional, passed through to the upstream model.

Images

POST /api/v1/images/generations — synchronous image generation, OpenAI-compatible.

Request

This endpoint returns image URLs synchronously once generation completes. It is intended for fast image models; slower or video-adjacent generation should go through the async Tasks API instead.

curl

curl https://orux.top/api/v1/images/generations \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "A cat sitting on a windowsill at sunset",
    "n": 1,
    "size": "1024x1024"
  }'

Python

from openai import OpenAI

client = OpenAI(base_url="https://orux.top/api/v1", api_key="sk-xxxxxxxx")

response = client.images.generate(
    model="gpt-image-2",
    prompt="A cat sitting on a windowsill at sunset",
    n=1,
    size="1024x1024",
)

print(response.data[0].url)

response

{ "data": [{ "url": "https://cdn.orux.top/....png" }] }

Supported request fields

  • model (required) — an image-capable model alias.
  • prompt (required) — text description of the desired image.
  • n — number of images to generate, 1–10.
  • size — image dimensions, model-dependent.
  • response_format — optional, passed through to the upstream model.

Billing

Billed in Credits per generated image, only on success.

Async tasks

POST /api/v1/tasks and GET /api/v1/tasks/{taskId} — the unified entry point for video, audio/music, and other long-running generations.

Why async tasks

Video and audio/music generation are not exposed as OpenAI-compatible synchronous endpoints (there is no /api/v1/videos/generations or /api/v1/audio/*). These modalities can take anywhere from several seconds to several minutes, so the gateway exposes them through a single async task queue: you submit a job, then poll for its result.

1. Submit a task

POST a model alias and a model-specific input object. input is passed through to the underlying model as-is (for example a video model expects a prompt and duration; a music model expects a prompt and lyrics). An optional callback URL can be provided to receive a webhook when the task finishes, instead of polling.

curl

curl https://orux.top/api/v1/tasks \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1",
    "input": {
      "prompt": "A slow sunrise over calm ocean waves",
      "duration": 8
    }
  }'

response (202 Accepted)

{
  "task_id": "tk_1a2b3c4d5e6f7a8b9c0d1e2f",
  "status": "QUEUED",
  "created_at": 1755000000,
  "model": "veo-3.1"
}

2. Poll for the result

Use the returned task_id to check status. Poll at a reasonable interval (a few seconds) until the task reaches a terminal state.

curl

curl https://orux.top/api/v1/tasks/tk_1a2b3c4d5e6f7a8b9c0d1e2f \
  -H "Authorization: Bearer sk-xxxxxxxx"

response (still running)

{
  "task_id": "tk_1a2b3c4d5e6f7a8b9c0d1e2f",
  "status": "RUNNING",
  "model": "veo-3.1",
  "created_at": 1755000000,
  "updated_at": 1755000012,
  "result": null,
  "error": null
}

response (success)

{
  "task_id": "tk_1a2b3c4d5e6f7a8b9c0d1e2f",
  "status": "SUCCESS",
  "model": "veo-3.1",
  "created_at": 1755000000,
  "updated_at": 1755000090,
  "result": ["https://cdn.orux.top/....mp4"],
  "error": null
}

response (failed)

{
  "task_id": "tk_1a2b3c4d5e6f7a8b9c0d1e2f",
  "status": "FAILED",
  "model": "veo-3.1",
  "created_at": 1755000000,
  "updated_at": 1755000030,
  "result": null,
  "error": { "code": "task_failed", "message": "Task failed" }
}

Task status values

  • QUEUED — accepted, waiting to start.
  • RUNNING — in progress upstream.
  • SUCCESS — finished; result contains one or more output URLs.
  • FAILED — finished with an error; see error.code and error.message.
  • EXPIRED — the task result window elapsed before it was retrieved.

Submit request fields

  • model (required) — an async-capable model alias (video, audio, or async image).
  • input (required) — a model-specific object, passed through to the underlying model.
  • callback — optional URL to receive a webhook on completion instead of polling.

Billing

Billed in Credits when the task reaches SUCCESS. Failed or expired tasks are not charged.

Video generation: No /api/v1/videos/generations endpoint

There is no synchronous video endpoint. Submit video generation jobs through POST /api/v1/tasks with a video-capable model alias, then poll GET /api/v1/tasks/{taskId} — see the Async tasks page for the full request/response cycle and status machine.

curl

curl https://orux.top/api/v1/tasks \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1",
    "input": { "prompt": "A slow sunrise over calm ocean waves", "duration": 8 }
  }'

Audio & music generation: No /api/v1/audio/* endpoint

There is no synchronous audio or music endpoint. Submit music generation jobs through POST /api/v1/tasks with a music-capable model alias, then poll GET /api/v1/tasks/{taskId} — see the Async tasks page for the full request/response cycle and status machine.

curl

curl https://orux.top/api/v1/tasks \
  -H "Authorization: Bearer sk-xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-v5",
    "input": { "prompt": "An upbeat lo-fi track", "instrumental": false }
  }'

Models

GET /api/v1/models — list the models currently available to your key.

Listing models

Model availability changes over time as providers are added or updated, so do not hardcode a model list in your application — call this endpoint (or check the Models catalog page) instead. The endpoint does not require authentication and mirrors the OpenAI /v1/models response shape.

curl

curl https://orux.top/api/v1/models

response (truncated)

{
  "object": "list",
  "data": [
    { "id": "gpt-5.4", "object": "model", "created": 1755000000, "owned_by": "orux" },
    { "id": "gpt-image-2", "object": "model", "created": 1755000000, "owned_by": "orux" }
  ]
}

Full catalog with pricing

For a browsable catalog with descriptions and Credit pricing per model, see the Models page in the main site navigation.

Example response

aliasModalityVendorStreaming
gpt-5.4
CHAT
OpenAIYes
gemini-3.6-flash
CHAT
GoogleYes
gpt-image-2
IMAGE
OpenAINo
seedream-5-lite
IMAGE
ByteDanceNo
kling-v3
VIDEO
KuaishouNo
suno-v5
AUDIO
SunoNo

Rate limits & concurrency

Requests are subject to per-key and per-account concurrency and rate limits.

How limits are applied

Limits are enforced at multiple levels: per API key, and per account across all of your keys combined. Exact numeric limits depend on your plan and are shown in your dashboard rather than fixed in this documentation, since they can be adjusted per account.

  • Per-key concurrency — the maximum number of in-flight requests for a single API key.
  • Per-account concurrency — the maximum combined in-flight requests across all keys under your account.
  • Rate limit (requests per time window) — enforced per key.

What happens when you hit a limit

Depending on the endpoint, an over-limit request is either rejected immediately with HTTP 429, held briefly in a wait queue, or (for async task submission) queued for later processing. A 429 response includes an OpenAI-compatible error body with code rate_limit or concurrency_limit_exceeded — back off and retry.

Checking your current limits

See the Usage / Plan section of your dashboard for the concurrency and rate limits attached to your account and each key.

Errors

All errors use the OpenAI-compatible { error: { message, type, code } } response shape.

Error response shape

response

{
  "error": {
    "message": "human-readable description",
    "type": "invalid_request_error",
    "code": "param_error"
  }
}

Troubleshooting tips

  • 401 invalid_api_key — check the Authorization header format and that the key has not been revoked.
  • 400 param_error / invalid_messages — validate your request body against the field lists on each endpoint page.
  • 400 model_not_routed / model_not_allowed — the model alias does not exist, is not enabled, or is outside your key’s allowlist; check GET /api/v1/models.
  • 429 rate_limit / concurrency_limit_exceeded — you have hit your concurrency or rate limit; retry with backoff.
  • 429 quota_exceeded — your account or key has insufficient Credits or has hit a spending limit.
  • 5xx / upstream errors — transient upstream failure; safe to retry with backoff for idempotent requests.
  • task_failed / task_expired / task_not_found — see the Async tasks page for the task status machine.

Billing

How usage is converted into Credits.

All usage is metered and billed in Credits, deducted from your account balance only after a request succeeds. Failed requests are never charged.

  • Chat and embeddings — billed per token, with input (prompt) and output (completion) tokens priced separately; streaming responses are billed the same way as non-streaming once the stream completes.
  • Images — billed per successfully generated image.
  • Async tasks (video, audio/music) — billed once when the task reaches the SUCCESS status; tasks that fail or expire are not charged.
  • Exact Credit prices per model are shown on the Models page and in your dashboard before you commit to a request.
  • You can track balance and per-request cost breakdowns from the Usage section of your dashboard.