Overview
The Omni API gives you language models, images, video, voice, music, sound effects and transcription through one API key and one prepaid balance.
- Base URL:
https://omni-api.rcinc.app/v1 - Auth:
Authorization: Bearer <your key>. Every key already starts withomni_live_; copy the whole key from the dashboard exactly as shown and do not add the prefix again. The key is also accepted asx-api-keyorxi-api-key, so most SDKs work by changing only their base URL. - Format: JSON in and out. File uploads use multipart form data.
- Errors: OpenAI style,
{ "error": { "message", "type", "code" } }.
Create keys and add credit in the dashboard.
Credit and billing
Every call is paid from your credit balance in US dollars.
- Text calls are charged when the response finishes. The response includes
omni.charged_usd, and responses carry anx-omni-charged-usdheader. - Image, video and audio calls run as tasks. While a task runs, an estimate is held from your credit; when it finishes, the hold is released and the final charge is taken. The task shows both under
credit. - Failed tasks cost nothing.
- A
402error with codeinsufficient_balancemeans your credit is too low for the call. Top up in the dashboard. GET /v1/balancereturns your credit.GET /v1/usagelists every deduction and your 30-day totals.
{ "object": "balance", "currency": "USD", "balance_usd": 18.4231 }
Language models
OpenAI-compatible. Streaming ("stream": true) is supported.
curl https://omni-api.rcinc.app/v1/chat/completions \
-H "Authorization: Bearer $OMNI_KEY" -H "content-type: application/json" \
-d '{"model":"gpt-6.1-sol","messages":[{"role":"user","content":"Hello"}]}'
from openai import OpenAI
client = OpenAI(api_key=OMNI_KEY, base_url="https://omni-api.rcinc.app/v1")
reply = client.chat.completions.create(model="claude-sonnet-5", messages=[{"role": "user", "content": "Hello"}])
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OMNI_KEY, baseURL: "https://omni-api.rcinc.app/v1" });
In Windows PowerShell, curl is a different command. Use Invoke-RestMethod:
$key = "<your full omni_live_ key>"
Invoke-RestMethod -Uri "https://omni-api.rcinc.app/v1/chat/completions" -Method Post -Headers @{ Authorization = "Bearer $key" } -ContentType "application/json" -Body '{"model":"gpt-6.1-sol","messages":[{"role":"user","content":"Hello"}]}'
| Endpoint | Notes |
|---|---|
POST /v1/chat/completions | OpenAI Chat Completions |
POST /v1/responses | OpenAI Responses |
POST /v1/completions | Legacy completions |
POST /v1/messages | Anthropic Messages. Point the Anthropic SDK at https://omni-api.rcinc.app |
POST /v1/messages/count_tokens | Free |
Model ids include gpt-6.1-sol, gpt-6-luna, claude-opus-5.5, claude-sonnet-5, gemini-3.8-flash, deepseek-v4.1-flash and more. GET /v1/models lists them all with prices.
Tasks
Images, video and audio return a task with HTTP 202:
{ "id": "task_9f2c…", "object": "task", "status": "pending", "operation": "image", "model": "ai33/gpt-image-2",
"output": null, "error": null, "credit": { "held_usd": 0.0064, "charged_usd": null } }
Poll GET /v1/tasks/{id} every 3 to 5 seconds until status is done or failed:
{ "id": "task_9f2c…", "status": "done", "output": { "images": [{ "url": "https://…", "width": 1024, "height": 1024 }] },
"credit": { "held_usd": 0, "charged_usd": 0.0058 } }
Or pass webhook_url (public https) in the request. When the task finishes we POST { "type": "task.done", "data": <task> } with headers x-omni-timestamp and x-omni-signature: sha256=<hex>, where the hex is HMAC-SHA256 of "<timestamp>.<body>" with your webhook secret from the dashboard.
output holds images, videos or audio (each a list of { url }), plus srt_url, json_url or clips where they apply. Download results promptly; result links can expire.
GET /v1/tasks?limit=20&operation=image lists your recent tasks.
Images
curl https://omni-api.rcinc.app/v1/images/generations \
-H "Authorization: Bearer $OMNI_KEY" -H "content-type: application/json" \
-d '{"model":"ai33/gpt-image-2","prompt":"A lighthouse at dusk, watercolor","aspect_ratio":"16:9","resolution":"2K","n":1}'
| Field | Notes |
|---|---|
model | ai33/gpt-image-2 (default), ai33/bytedance-seedream-5-pro, kie/google/nano-banana, kie/gpt-image-2-text-to-image and any id from GET /v1/models |
prompt | Up to 4,000 characters |
aspect_ratio or size | 16:9, 9:16, 1:1, 4:3, 3:4, or a size like 1024x1536 |
resolution | 1K, 2K or 4K where the model supports it |
n | 1 to 4 |
reference_urls | Up to 10 public image links. Refer to them as @img1, @img2 in the prompt |
input | Extra model-specific fields for kie/… models |
webhook_url | Optional |
Video
curl https://omni-api.rcinc.app/v1/videos/generations \
-H "Authorization: Bearer $OMNI_KEY" -H "content-type: application/json" \
-d '{"model":"kie/kling-3.0/video","prompt":"Slow push-in on a rainy street","image_urls":["https://example.com/frame.png"],"input":{"duration":"5"}}'
Models include kie/kling-3.0/video, kie/bytedance/seedance-2, kie/bytedance/seedance-1.5-pro, kie/grok-imagine/image-to-video and kie/hailuo/02-text-to-video-pro. Model-specific fields go in input. For long or premium clips, set max_cost_usd to raise the hold so the task is not refused.
Lip-sync, upscaling and other models
POST /v1/generations runs any generation model by id:
{ "model": "kie/kling/ai-avatar-standard", "kind": "lipsync", "input": { "image_url": "https://…", "audio_url": "https://…" } }
kind is one of image, video, audio, lipsync, upscale, music or speech.
Voice
All audio endpoints accept JSON, or multipart form data with a file. Direct uploads are limited to about 4 MB; send larger files as file_url (a public https link).
Text to speech: POST /v1/audio/speech
curl https://omni-api.rcinc.app/v1/audio/speech \
-H "Authorization: Bearer $OMNI_KEY" -H "content-type: application/json" \
-d '{"input":"Welcome back to the show.","voice_id":"elevenlabs_TX3LPaxmHKxFdv7VOQHJ","speed":1}'
| Field | Notes |
|---|---|
input | The text |
voice_id | From GET /v1/voices. Ids carry a prefix: elevenlabs_, minimax_, edge_, kokoro_, vbee_, fishaudio_ or clone_ |
speed | 0.5 to 1.5 |
with_transcript | Also return SRT timings |
pronunciation_dictionary_id | From /v1/dictionaries |
Dialogue: POST /v1/audio/dialogue with input written as A> line, B> line, and speakers: [{ "voice_id": "…" }, { "voice_id": "…" }]. Optional delay (0 to 5 seconds) between lines.
Voices: GET /v1/voices?provider=elevenlabs&search=narrator&language=English&gender=female&page=1&page_size=50. Providers: elevenlabs, minimax, edge, kokoro, vbee, fishaudio, and clone for your own voices.
Clone a voice: POST /v1/voices/clone with name and audio_file (multipart, up to 10 MB) or audio_file_url. Use the returned clone_… id anywhere a voice is accepted. DELETE /v1/voices/clone/{voice_id} removes it. Cloned voices are private to your account.
Voice changer: POST /v1/audio/voice-changer with file or file_url, voice_id, optional voice_settings and remove_background_noise.
Voice isolation: POST /v1/audio/voice-isolation with file or file_url (at least 5 seconds).
Dubbing: POST /v1/audio/dubbing with file or file_url (mp3 or m4a), target_lang, optional source_lang, num_speakers and a replacement voice_id.
Pronunciation dictionaries: GET /v1/dictionaries, POST /v1/dictionaries with { "name", "rules": [{ "from": "AI", "to": "A I", "matchType": "word" }] }, GET, PUT and DELETE /v1/dictionaries/{id}, and POST /v1/dictionaries/preview.
Music and sound effects
Music: POST /v1/audio/music
{ "prompt": "Lo-fi beat for a late-night coding stream", "instrumental": true }
Or write the song yourself: { "lyrics": "[Verse 1]\n…", "tags": "indie pop, female vocals", "title": "Border Lights", "vocal_gender": "f" }. Each request returns two versions in output.clips.
Sound effects: POST /v1/audio/sound-effects
{ "prompt": "Thunder rolling over heavy rain", "duration_seconds": 5, "loop": false, "prompt_influence": 0.3 }
duration_seconds is 0.5 to 30, or leave it out for an automatic length.
Transcription
POST /v1/audio/transcriptions with file (multipart) or file_url, up to 200 MB. Set tag_audio_events to mark laughter, music and other sounds. The finished task has output.json_url (word-level timings) and output.srt_url.
Raw passthrough
For anything without a dedicated endpoint, ANY /v1/proxy/{source}/{path} forwards your request and returns the original response, billed per call. For example, POST /v1/proxy/kie/api/v1/veo/generate starts a Veo 3.1 video, then GET /v1/proxy/kie/api/v1/veo/record-info?taskId=… reads it. Jobs started this way also appear in GET /v1/tasks (see the x-omni-task-id response header). Account-level paths are blocked.
Models and prices
GET /v1/models needs no key. It lists every model, its endpoint and its price.
Good practice
- Keep keys on your server. Never ship them in a browser or mobile app.
- Create one key per app so you can revoke one without affecting the others.
- Use
webhook_urlinstead of tight polling loops for long video jobs. - Each key can make up to 600 requests a minute. Above that you get status 429 with code
rate_limitedand aretry-afterheader; wait and retry. Status 429 with another code means a model's queue is full; retry with backoff. - Status 503 with code
provider_unavailablemeans the model's provider is briefly unavailable; retry shortly or use another model.