Docs · Reference

Model API

Call the platform catalog's text, image, speech, video and 3D models from https://api.origingame.ai/v1 with one account API token; the API works with the official OpenAI, Anthropic and Gemini SDKs.

Base URL and authentication

Every model call goes to one host:

UseURL
OpenAI-compatible APIhttps://api.origingame.ai/v1
Anthropic SDK base URLhttps://api.origingame.ai
Gemini APIhttps://api.origingame.ai/v1beta

The origingame.ai site does not forward model requests, and browsers never relay model calls through the Portal. Call api.origingame.ai directly from your server or script.

Authenticate with the account API token (it starts with og-). Create, copy or rotate it at /me/access. An account has one; rotating it invalidates the old value at once. Signed-in devices and connected apps hold their own credentials and do not use this token.

Get an API token
HeaderApplies toNotes
Authorization: Bearer og-...every endpointthe default
x-api-key: og-.../v1/messages, /v1/messages/count_tokensthe Anthropic SDK's native header
x-goog-api-key: og-.../v1beta/models/*the Gemini SDK's native header; ?key= is also accepted, but query strings end up in access logs, so prefer the header
X-Origin-Org: <organization id>optionalbill the organization's wallet and use its private channels; requires your permission to use that organization
Note: previously issued sk- keys keep working until 2026-12-31; copying and rotating now only return og-.

The token acts as your account and spends your balance. Keep it in server-side environment variables; never put it in a web page or a game, or commit it to a repository.

Compatible protocols and SDKs

Point the official SDK's base URL at Origin and use your og- token as the API key.

OpenAI

Chat Completions (/v1/chat/completions) and Responses (POST /v1/responses) are supported. Responses has no WebSocket transport; use HTTP.

import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.origingame.ai/v1',
  apiKey: process.env.OG_API_KEY,
})
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.origingame.ai/v1", api_key=os.environ["OG_API_KEY"])

Anthropic

Messages (/v1/messages) and the unbilled POST /v1/messages/count_tokens (returns {input_tokens, estimated}) are supported. The Anthropic SDK appends /v1 itself, so its base URL has no /v1.

import os
import anthropic

client = anthropic.Anthropic(base_url="https://api.origingame.ai", api_key=os.environ["OG_API_KEY"])
message = client.messages.create(
    model="MODEL_ID",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)

Replace MODEL_ID with an id from Listing models whose supported_endpoint_types contains anthropic.

Gemini

POST /v1beta/models/{model}:generateContent and :streamGenerateContent are supported; other Gemini actions return 404.

curl "https://api.origingame.ai/v1beta/models/MODEL_ID:generateContent" \
  -H "x-goog-api-key: $OG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents":[{"parts":[{"text":"Hello"}]}]}'
import os
from google import genai
from google.genai import types

client = genai.Client(
    api_key=os.environ["OG_API_KEY"],
    http_options=types.HttpOptions(base_url="https://api.origingame.ai"),
)
response = client.models.generate_content(model="MODEL_ID", contents="Hello")
print(response.text)

For MODEL_ID, pick a model whose supported_endpoint_types contains gemini.

Listing models

GET /v1/models returns the models your token can use. The catalog changes as operations configure it, and account and token model restrictions shape the result, so rely on the answer you get rather than hard-coding ids.

curl https://api.origingame.ai/v1/models \
  -H "Authorization: Bearer $OG_API_KEY"

The default answer is OpenAI-shaped ({"object":"list","data":[…]}). Each entry's supported_endpoint_types names the endpoints the model serves, for example openai, openai-response, anthropic, gemini, image-generation, audio-tts, openai-video. A request carrying both x-api-key and anthropic-version gets the Anthropic shape; one carrying x-goog-api-key gets the Gemini shape ({"models":[…]}).

Prices, capabilities and per-model integration guides with samples are in the model catalog; a single model is at /tools/models/<model id>.

For native GPT-Realtime-2.1 voice, endpoint metadata uses audio-realtime (GET /v1/realtime?model={model}), distinct from audio-stt-realtime (GET /v1/realtime?intent=transcription&model={model}) for standalone transcription.

Chat and streaming

The samples use gpt-5.6-sol. If your model list does not include it, use any id from the list whose supported_endpoint_types contains openai.

curl https://api.origingame.ai/v1/chat/completions \
  -H "Authorization: Bearer $OG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-5.6-sol","messages":[{"role":"user","content":"Introduce yourself in one sentence"}]}'

For streaming, add "stream": true; the response is SSE:

curl -N https://api.origingame.ai/v1/chat/completions \
  -H "Authorization: Bearer $OG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-5.6-sol","stream":true,"messages":[{"role":"user","content":"Write a short poem about pixels"}]}'
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.origingame.ai/v1',
  apiKey: process.env.OG_API_KEY,
})

const stream = await client.chat.completions.create({
  model: 'gpt-5.6-sol',
  messages: [{ role: 'user', content: 'Write a short poem about pixels' }],
  stream: true,
})
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '')
}
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.origingame.ai/v1", api_key=os.environ["OG_API_KEY"])

stream = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[{"role": "user", "content": "Write a short poem about pixels"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Endpoint reference

Every path is under https://api.origingame.ai; authentication is described in Base URL and authentication. Requests and responses match each vendor's native API; per-model request samples are on the model pages of the model catalog.

Text

MethodPathNotes
POST/v1/chat/completionsOpenAI Chat Completions, with stream
POST/v1/responsesOpenAI Responses (HTTP only)
POST/v1/messagesAnthropic Messages
POST/v1/messages/count_tokenscounts input tokens; no generation, no charge
POST/v1/embeddingsembeddings
POST/v1beta/models/{model}:generateContentGemini; :streamGenerateContent streams
GET/v1/modelsmodel list

Images

MethodPathNotes
POST/v1/images/generationstext to image
POST/v1/images/editsimage editing

Speech and audio

MethodPathNotes
POST/v1/audio/speechtext to speech (OpenAI shape); Gemini TTS models use the task flow below and may answer 202 with task metadata
POST/v1/audio/speech/tasksGemini TTS async task; Idempotency-Key required (1–128 visible ASCII characters)
GET/v1/audio/speech/tasks/{id}speech task status
GET/v1/audio/speech/tasks/{id}/contentdownload the generated audio (task owner only)
GET/v1/audio/voices?model=...available preset voices
POST/v1/audio/transcriptionsrecorded audio to text, multipart file upload (for example model=gpt-transcribe, up to 25 MiB)
GET/v1/realtime?model=gpt-realtime-2.1native GA realtime voice WebSocket (wss://); full-session funded cap and terminal provider usage (see below)
POST/v1/realtime/client_secretsreusable Gateway ogrt_ client capability, not a provider key
POST/v1/realtime/callsWebRTC: multipart sdp/session or application/sdp with capability defaults; local owned call Location
GET/v1/realtime?call_id=...call sideband WebSocket
POST/v1/realtime/calls/{id}/{action}SIP accept, reject, refer, hangup, using the original provider call id after signed webhook admission
POST/v1/realtime/webhooks/{binding}signed provider SIP inbox; not a client-authenticated call creation route
GET/v1/realtime?intent=transcription&model=gpt-live-transcribelive transcription WebSocket (wss://), mono PCM16 at 24 kHz, at most 60 seconds per turn
POST/elevenlabs/v1/text-to-speech/{voice_id}ElevenLabs native API, plus /stream and /with-timestamps
POST/elevenlabs/v1/text-to-dialogue, /elevenlabs/v1/speech-to-text, /elevenlabs/v1/speech-to-speech/{voice_id}ElevenLabs dialogue, transcription, voice changer
POST/elevenlabs/v1/sound-generation, /elevenlabs/v1/music, /elevenlabs/v1/audio-isolation, /elevenlabs/v1/forced-alignmentElevenLabs sound effects, music, voice isolation, alignment
GET/elevenlabs/v1/voices, /elevenlabs/v1/modelsElevenLabs voices and models
POST/v1/sound-generation, /v1/music, /v1/music/stream, /v1/audio-isolation, /v1/audio-isolation/stream, /v1/forced-alignment, /v1/speech-to-speech/{voice_id}prefix-free aliases of the ElevenLabs endpoints above

The live transcription WebSocket needs an Authorization header on the handshake, which browsers cannot set, so connect from a server.

Native GPT-Realtime-2.1

This describes the current workspace implementation, not a claim of production deployment or full verification. The GA native protocol passes through events including concurrent/out-of-band responses, VAD, tools, images, audio codecs and interruptions. Sessions are capped at 60 minutes. The 32 MiB serialized WebSocket message ceiling is a Gateway limit, not a universal upstream bound. Legacy beta session endpoints are not implemented. The strict intent=transcription GPT-Live path above remains separate from native voice and its input ASR.

Client capabilities last 10–7200 seconds, are reusable, and revalidate the parent credential on use; no provider key is returned. For SIP, operators configure the root runtime secret realtime.sip_bindings array (route, project_id, channel_id, user_id, webhook_secret). Signed inbox bindings establish the tenant, never phone headers. Users receive the original OpenAI event through a separate project webhook registration. Real SIP acceptance needs a provisioned project webhook, trunk and test phone; these are not yet available or verified.

Optional X-Origin-Realtime-Budget specifies a pre-funded full-session cap in USD (conservative default: $6.144 for gpt-realtime-2.1). Prices are frozen for the session. Authoritative terminal response and ASR usage are accounted for separately, with customer settlement capped at the funded amount. The platform bears excess, unpriced or unobserved usage. Termination is requested on loss of observation or budget protection; it is not guaranteed instantaneous. Client disconnect briefly drains cancellation usage; all closes conservatively mark observation incomplete rather than inventing usage.

Video

MethodPathNotes
POST/v1/videoscreate a video task
GET/v1/videos/{id}task status
GET/v1/videos/{id}/contentdownload the finished video

3D

MethodPathNotes
POST/v1/3d/tasksHunyuan3D task; Idempotency-Key optional (up to 256 bytes)
GET/v1/3d/tasks/{id}, /v1/3d/tasks/{id}/contenttask status, GLB download
POST/v1/tripo/tasksTripo task (generation, texture, remesh, rigging, animation, conversion); Idempotency-Key required (up to 256 bytes)
GET/v1/tripo/tasks/{id}, /v1/tripo/tasks/{id}/contenttask status, result download
POST/meshy/openapi/v2/text-to-3dMeshy text to 3D
POST/meshy/openapi/v1/{resource}other Meshy tasks: image-to-3d, multi-image-to-3d, remesh, convert, resize, retexture, rigging, animations, uv-unwrap, text-to-motion
GET/meshy/openapi/{version}/{resource}/{id}Meshy native task status; /stream streams progress
GET/meshy/openapi/v1/animations/libraryMeshy animation library (not billed)
GET/meshy/tasks/{id}, /meshy/tasks/{id}/contentthe platform's stored Meshy task status and main result
GET/meshy/tasks/{id}/artifacts, /meshy/tasks/{id}/artifacts/{name}/contentlist and download every artifact of a task

Decisions and classification

MethodPathNotes
POST/v1/decisionsOpenAI Decisions, model gpt-6-luna-decisions; only input tokens are billed
POST/v1/systemoneTypeSafe classification (jev-* models)

Media files

MethodPathNotes
POST/v1/media/uploads, /v1/media/upload-authorizations, /v1/media/{id}/completeupload input files
GET, DELETE/v1/media/{id}read or delete media metadata
GET/v1/media/{id}/{file}download media content
POST/v1/media/download-authorizationsget a short-lived download link, for example {"task_id":"...","kind":"speech"}

Async tasks

Video, speech tasks and 3D are asynchronous: the create request returns a task object at once (usually 202, 200 on some video channels); you then poll the status endpoint and download the result when it is done.

  1. Create the task and keep the returned id. Where Idempotency-Key is required, generate a unique value for each new task.
  2. Query .../{id} every few seconds until status is completed or failed.
  3. After completed, download the result from result_url or .../{id}/content.
curl https://api.origingame.ai/v1/tripo/tasks \
  -H "Authorization: Bearer $OG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"model":"tripo-v3.1","operation":"text","parameters":{"prompt":"A low-poly treasure chest","texture":true,"pbr":true}}'

curl https://api.origingame.ai/v1/tripo/tasks/TASK_ID \
  -H "Authorization: Bearer $OG_API_KEY"

curl https://api.origingame.ai/v1/tripo/tasks/TASK_ID/content \
  -H "Authorization: Bearer $OG_API_KEY" -o model.bin

Common states: queued, in_progress, completed, failed, submission_unknown.

  • Resending the same request with the same Idempotency-Key returns the original task instead of creating another; the same key with different parameters returns 409.
  • submission_unknown means it is not known whether the provider accepted the job. Do not resubmit under a new key, or you may pay twice; the task's hold is kept for the platform to reconcile.
  • Generated files are kept for the platform's retention period; copy them to your own storage promptly.

Errors

Errors keep the shape of the protocol you called. OpenAI-compatible and Gemini endpoints:

{"error":{"message":"...","type":"new_api_error","param":"","code":"..."}}

/v1/messages answers in the Anthropic shape: {"type":"error","error":{"type":"...","message":"..."}}. An unknown path is 404 with error.code not_found.

StatusExample codeMeaning and what to do
400model_price_errorinvalid request, or the model has no published price yet
401token missing, invalid or rotated
403insufficient_user_quotanot enough balance or plan allowance; see Billing
403pre_consume_token_quota_failedthis token's budget is used up
403risk_blockedthe account is restricted by risk control
403the token is not allowed to use this model
409the same Idempotency-Key was sent with different parameters
429rate_limitedover the rate or concurrency limit; wait the Retry-After seconds, then retry
5xxthe platform or provider is temporarily unavailable; for generation, check the task status before deciding to retry

Environment variables

The platform's scripts and skills use these two variables; reuse the same names in your own code:

VariableValueNotes
OG_API_KEYog-...the account API token
OG_AI_GATEWAYhttps://api.origingame.aithe API host, without /v1; this is the default, change it only for a local or test environment
export OG_API_KEY=og-...
export OG_AI_GATEWAY=https://api.origingame.ai
curl "$OG_AI_GATEWAY/v1/models" -H "Authorization: Bearer $OG_API_KEY"