OpenAI-compatible · HTTP API

Documentation

Drop your existing OpenAI-style client onto this base URL. Same routes, familiar JSON — models, image generations, and polling. No prompts or keys on the public status feed.

Base URL http://127.0.0.1:3847/v1
Image generations Model catalog Public status Batch polling

# Overview

Clients talk to this server as if it were an OpenAI-style API under /v1. Request and response bodies use familiar field names (model, prompt, data, …). Only models present in the local catalog are accepted — invented IDs are rejected.

Media

Images via OpenAI-shaped POST /v1/images/generations and poll with GET /v1/images/:id.

Models

Full parameter schemas + logos from GET /v1/models. Unknown models return 400/404.

Observability

Public live metrics at /status — no key required. No prompts or secrets exposed.

GET
Root path. JSON index lives at /v1. Humans use /, /docs, /models, /status.

# Base URL

Default listen address is http://127.0.0.1:3847 (override with HOST / PORT). API routes are under /v1.

http://127.0.0.1:3847/v1

# Authentication

Every generation endpoint requires an API key. Send it on each request:

Authorization: Bearer YOUR_API_KEY
# or
x-api-key: YOUR_API_KEY

Keys are verified on every call. An unknown or revoked key returns 401 invalid_api_key. Admin keys have no quotas; regular keys follow the limits below.

Public (no key): /health, /v1/models, /v1/status, /v1/config, docs UI. Everything that generates or costs credits is protected.

# Rate limits

Limits are per API key and apply to POST requests only. Polling a job, listing models or downloading audio is free.

ScopeLimitApplies to
Music 3 / minute POST /v1/music/generations
Image 3 / minute POST /v1/images/generations
Voice 15 / minute POST /v1/voice-clone/*, POST /v1/audio/*
Helpers 30 / minute Prompt enhance, tokenize, agent chat. Not billed to the daily generation quota.
Lyrics enhance 10 / minute · 150 / day POST /v1/music/lyrics/enhance only. Separate from the shared generation daily quota.
Daily 500 / day Music + image + voice generations combined. Resets for everyone at 03:00 Europe/Istanbul (not a rolling 24h window).
Failures 20 / minute Responses with status ≥ 400. Failed calls cost no quota, but repeated failures are capped separately.

Metered responses carry the remaining budget:

x-ratelimit-limit-minute: 3
x-ratelimit-remaining-minute: 2
x-ratelimit-limit-day: 500
x-ratelimit-remaining-day: 487

Exceeding a limit returns 429 with a retry_after value in seconds:

{
  "error": {
    "message": "Rate limit reached for music: 3 requests per minute. Retry in 42s.",
    "type": "rate_limit_error",
    "code": "rate_limited",
    "scope": "music",
    "limit": 3,
    "retry_after": 42
  }
}

Check your own consumption any time:

curl "http://127.0.0.1:3847/v1/usage" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Quickstart

1. List models and pick a catalog id:

curl http://127.0.0.1:3847/v1/models

2. Generate an image:

curl -X POST http://127.0.0.1:3847/v1/images/generations \
  -H "Content-Type: application/json" \
  -d "{
    \"prompt\": \"a red fox in snow, cinematic\",
    \"model\": \"gpt-image-2\",
    \"aspect_ratio\": \"16:9\",
    \"quality\": \"medium\"
  }"

3. Poll the batch with the returned id:

curl "http://127.0.0.1:3847/v1/images/BATCH_ID"

# Endpoints

MethodPathDescription
GET /health Liveness
GET /v1 JSON API index
GET /v1/status Public metrics (safe feed)
GET /v1/models List catalog models + schemas
GET /v1/models/:id Single model detail
POST /v1/images/generations Create image generation
GET /v1/images/:id Poll generation batch
GET /v1/logos Provider logo catalog
GET /v1/music/tags Style tag catalog for music model v1
POST /v1/music/generations Start music generation (model v1)
GET /v1/music/generations/:id Poll music job / variant
GET /v1/music/stream/:id Live audio stream while generating
GET /v1/music/files/:id Final audio file

# Status

GET /v1/status

Public live feed — requests by model, route family, and recent traffic. No prompts or keys are exposed. Model breakdown only includes IDs from GET /v1/models.

UI: /status

curl http://127.0.0.1:3847/v1/status

# Models

GET /v1/models

List every image model with parameter schemas, brand, and logos (light / dark / color).

curl http://127.0.0.1:3847/v1/models
GET /v1/models/:id

Single model. Unknown id → 404 with allowed list.

curl http://127.0.0.1:3847/v1/models/gpt-image-2

# Images

POST /v1/images/generations

Create a generation batch. model must exist in the catalog.

FieldTypeDescription
prompt required string Text prompt (length limits per model)
model string Catalog id (default gpt-image-2)
aspect_ratio enum Per-model allowed ratios
resolution enum If supported (e.g. 1K, 2K)
quality enum low | medium | high
generations_count 1–4 Also accepts n
wait bool Poll until complete (default false)
{
  "prompt": "a red fox in snow, cinematic",
  "model": "gpt-image-2",
  "aspect_ratio": "16:9",
  "resolution": "1K",
  "quality": "medium",
  "generations_count": 1,
  "wait": false
}

Success returns batch id, data[] with status/urls, and convenience url.

# Poll batch

GET /v1/images/:batchId

Use the batch id returned from generate.

curl "http://127.0.0.1:3847/v1/images/BATCH_ID"

# Music

Create songs with the v1 music model (lyrics or instrumental). Authenticate with the same API key as images. Poll until completed, or stream audio while status is streaming.

v1
Model id is always v1. Do not send a model field — it is fixed by the API.

Recommended defaults

  • Send a free-text prompt (style / mood). Prefer omitting tags.
  • If you pass tags, include at least one tag (empty array is rejected).
  • Strength: at most one of prompt_strength and style_scale may be > 1.0. Defaults: style_scale: 4.5, prompt_strength: 1.0.
  • Instrumental: instrumental: true and no lyrics.
  • With vocals: instrumental: false and required lyrics.

Statuses

StatusMeaning
queuedWaiting / generating (not playable yet)
streamingLive preview ready via stream_url
completedFinal file ready via audio_url
failedGeneration failed (no charge)

# Music tags

GET /v1/music/tags

Full style-tag vocabulary for music model v1 (~4k entries). Prefer a free-text prompt for generation; use tags only when you need hard style constraints (min 1 if sent). No API key required.

QueryTypeDescription
q string Optional case-insensitive substring filter (alias: search).
limit int Optional page size (max 2000). Omit for full list after offset.
offset int Skip N tags (default 0).
curl "http://127.0.0.1:3847/v1/music/tags?q=synth&limit=20"

Response shape:

{
  "object": "list",
  "model": "v1",
  "data": ["synthpop", "…"],
  "count": 20,
  "total": 42,
  "offset": 0,
  "limit": 20,
  "q": "synth"
}

# Create track

POST /v1/music/generations

Start a generation. Returns a job id and usually two variants (A/B). Poll the job or a variant id.

FieldTypeDescription
prompt string Style / mood text (recommended). Max 500 chars. Alias: style.
lyrics string Required when not instrumental. Max ~12k chars.
instrumental boolean Default: true if no lyrics, else false.
tags string[] Optional. If set, min 1 tag. Prefer omitting for auto style.
negative_tags string[] Optional styles/instruments to avoid.
prompt_strength float 1.0–4.0. Default 1.0. Only one of this / style_scale may be > 1.
style_scale float 1.0–12.0. Default 4.5. Style adherence.
length_range [min, max] Optional seconds hint; multiples of 30 (min 0–270, max 30–300).
enable_streaming boolean Hint for live stream readiness (default off).
stream_format ogg | mp3 Live stream container (default ogg).
curl -X POST http://127.0.0.1:3847/v1/music/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "dreamy synth-pop, warm pads",
    "lyrics": "Verse one...\nChorus...",
    "instrumental": false
  }'

Instrumental-only:

curl -X POST http://127.0.0.1:3847/v1/music/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "dark trap, 140 BPM, heavy 808s", "instrumental": true }'

Example response:

{
  "id": "mg_…",
  "object": "music.generation",
  "status": "queued",
  "model": "v1",
  "instrumental": false,
  "created": 1710000000,
  "variants": [
    { "id": "mg_…_a", "object": "music.variant", "status": "queued" },
    { "id": "mg_…_b", "object": "music.variant", "status": "queued" }
  ]
}

# Poll music

GET /v1/music/generations/:id

Poll the parent job id or a variant id. When status is streaming, use stream_url. When completed, use audio_url.

curl "http://127.0.0.1:3847/v1/music/generations/mg_…" \
  -H "Authorization: Bearer YOUR_API_KEY"

Typical completed variant fields:

{
  "id": "mg_…_a",
  "object": "music.variant",
  "status": "completed",
  "title": "…",
  "duration": 182.4,
  "stream_url": null,
  "audio_url": "/v1/music/files/mg_…_a"
}

# Stream / file

GET /v1/music/stream/:id

Progressive live audio while generating. Prefer opening only when the user presses play (avoids background stream spam). Auth not required on this path (opaque id).

curl -N "http://127.0.0.1:3847/v1/music/stream/mg_…_a" -o preview.ogg
GET /v1/music/files/:id

Final audio after completed. Supports HTTP Range for seeking.

curl "http://127.0.0.1:3847/v1/music/files/mg_…_a" -o track.ogg

# Logos

GET /v1/logos

Provider logo catalog. Theme: light | dark | color.

curl http://127.0.0.1:3847/v1/logos/openai?theme=dark
curl "http://127.0.0.1:3847/v1/logos/gpt-image-2?theme=light&redirect=0"

# Health

GET /health

Service liveness. Returns {"ok":true}.

# Errors

Validation errors (client input):

{
  "error": {
    "message": "Validation failed",
    "type": "invalid_request_error",
    "code": "validation_error",
    "details": [ { "field": "model", "message": "…" } ]
  }
}

All other server-side failures use a generic shape (no internal details):

{
  "error": {
    "message": "Server Error. Please try again later.",
    "type": "server_error",
    "code": "server_error"
  }
}
StatusMeaning
400Validation (bad model, ratio, length…)
404Not found
500 / 502 / 503Server Error. Please try again later.

# Limits & notes

  • Model IDs must match the catalog — freestyle names are rejected.
  • Parameter enums (aspect ratio, quality, resolution) are per-model.
  • Catalog max_length is enforced by this API.
  • CORS is open for local tools.

# Privacy

Never exposed to clients: prompts in status feed, tokens, emails, cookies, account IDs, or raw internal error bodies.