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.
http://127.0.0.1:3847/v1
# 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.
/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.
| Scope | Limit | Applies 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
| Method | Path | Description |
|---|---|---|
| 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
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
List every image model with parameter schemas, brand, and logos (light / dark / color).
curl http://127.0.0.1:3847/v1/models
Single model. Unknown id → 404 with allowed list.
curl http://127.0.0.1:3847/v1/models/gpt-image-2
# Images
Create a generation batch. model must exist in the catalog.
| Field | Type | Description |
|---|---|---|
| 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
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.
Do not send a model field — it is fixed by the API.
Recommended defaults
- Send a free-text
prompt(style / mood). Prefer omittingtags. - If you pass
tags, include at least one tag (empty array is rejected). -
Strength: at most one of
prompt_strengthandstyle_scalemay be >1.0. Defaults:style_scale: 4.5,prompt_strength: 1.0. - Instrumental:
instrumental: trueand nolyrics. - With vocals:
instrumental: falseand requiredlyrics.
Statuses
| Status | Meaning |
|---|---|
queued | Waiting / generating (not playable yet) |
streaming | Live preview ready via stream_url |
completed | Final file ready via audio_url |
failed | Generation failed (no charge) |
# 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.
| Query | Type | Description |
|---|---|---|
| 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
Start a generation. Returns a job id and usually two
variants (A/B). Poll the job or a variant id.
| Field | Type | Description |
|---|---|---|
| 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
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
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
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
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
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"
}
}
| Status | Meaning |
|---|---|
400 | Validation (bad model, ratio, length…) |
404 | Not found |
500 / 502 / 503 | Server 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_lengthis enforced by this API. - CORS is open for local tools.