{"openapi":"3.1.0","info":{"title":"eroq API","version":"1.0.0","description":"Expressive AI, one API — roleplay chat, image, video and voice, metered in credits."},"servers":[{"url":"https://eroq.ai/v1"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from https://eroq.ai/dashboard/keys"}}},"paths":{"/chat/completions":{"post":{"operationId":"chat","summary":"Chat completions","description":"Run a conversation turn against RP+ or RP mini. Credits: RP+ 3 · RP mini 1 per completion · +2 per attached image.","x-credits":"RP+ 3 · RP mini 1 per completion · +2 per attached image","externalDocs":{"url":"https://eroq.ai/docs/chat.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"id":"cmpl_9f2e17ab","object":"chat.completion","model":"eroq-rp-plus","choices":[{"index":0,"message":{"role":"assistant","content":"*slides out from under the manifold, wiping grease on her overalls* That noise is the reactor's way of saying you skipped the coolant flush. Again."},"finish_reason":"stop"}],"usage":{"credits_spent":3,"credits_remaining":997}}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"description":"eroq-rp-plus or eroq-rp-mini.","type":"string"},"messages":{"description":"Conversation turns { role, content } — roles system, user, assistant. content is a string, or an array of text / image_url parts on user turns.","type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["system","user","assistant"]},"content":{"type":"string"}},"required":["role","content"]}},"context":{"description":"Persona, scene or lore block, folded into the engine-side prompt after your system turns (or after the default preamble). Ideal for character sheets and world state you manage separately from the transcript.","type":"string"},"mode":{"description":"scene (default, immersive prose) or messaging (texting register, short and fast).","type":"string"},"stream":{"description":"Stream the reply as SSE chunks. Default false.","type":"boolean"},"temperature":{"description":"Sampling temperature, 0–1.5. Default 0.8 — tuned where roleplay lives.","type":"number"},"max_tokens":{"description":"Completion budget. Default 500, max 1200 (160 in messaging mode).","type":"integer"}},"required":["model","messages"]},"example":{"model":"eroq-rp-plus","context":"Mira: sardonic starship mechanic, dry humor, hates small talk. Scene: engine bay, mid-shift.","messages":[{"role":"user","content":"The reactor is making that noise again."}]}}}}}},"/images/generations":{"post":{"operationId":"images","summary":"Image generation","description":"Generate a 1024×1024 image from a text prompt. Credits: 10 per image · +2 with store: true.","x-credits":"10 per image · +2 with store: true","externalDocs":{"url":"https://eroq.ai/docs/images.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"created":1756118400,"model":"eroq-image-one","data":[{"b64_json":"UklGRl4jAABXRUJQ…"}],"usage":{"credits_spent":10,"credits_remaining":987}}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to draw, up to 2400 characters.","type":"string"},"model":{"description":"Only eroq-image-one today. Default eroq-image-one.","type":"string"},"negative_prompt":{"description":"What to steer away from.","type":"string"},"cfg_scale":{"description":"Prompt adherence, 1–20. Engine default when omitted.","type":"number"},"store":{"description":"Persist to the eroq Store and answer with a CDN URL. +2 credits per started 10MB. Default false.","type":"boolean"},"response_format":{"description":"b64_json (default) or url when available.","type":"string"}},"required":["prompt"]},"example":{"model":"eroq-image-one","prompt":"portrait of a starship mechanic, grease-stained overalls, warm hangar light, 35mm","negative_prompt":"blurry, extra fingers"}}}}}},"/videos/generations":{"post":{"operationId":"video","summary":"Video generation","description":"Generate a short 720p clip from a text prompt. Credits: 100 for 5s · 180 for 10s · + storage with store: true.","x-credits":"100 for 5s · 180 for 10s · + storage with store: true","externalDocs":{"url":"https://eroq.ai/docs/video.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"created":1756118400,"model":"eroq-motion-one","data":[{"b64_json":"AAAAIGZ0eXBpc281…","content_type":"video/mp4"}],"usage":{"credits_spent":100,"credits_remaining":887}}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"The scene to render.","type":"string"},"model":{"description":"Only eroq-motion-one today.","type":"string"},"duration":{"description":"5s (default) or 10s.","type":"string"},"store":{"description":"Persist to the eroq Store and answer with a CDN URL. +2 credits per started 10MB. Default false.","type":"boolean"}},"required":["prompt"]},"example":{"model":"eroq-motion-one","prompt":"slow dolly through a neon-lit hangar, rain on the windows","duration":"5s"}}}}}},"/audio/speech":{"post":{"operationId":"speech","summary":"Text-to-speech","description":"Synthesize speech from text. Returns MP3 audio. Credits: 3 per 100 characters.","x-credits":"3 per 100 characters","externalDocs":{"url":"https://eroq.ai/docs/speech.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"description":"The text to speak.","type":"string"},"voice":{"description":"aria or orion.","type":"string"},"model":{"description":"Only eroq-voice-one today.","type":"string"}},"required":["input","voice"]},"example":{"model":"eroq-voice-one","input":"That noise is the reactor missing its coolant flush. Again.","voice":"aria"}}}}}},"/audio/transcriptions":{"post":{"operationId":"transcriptions","summary":"Transcription","description":"Transcribe an audio file to text. Credits: 5 per request.","x-credits":"5 per request","externalDocs":{"url":"https://eroq.ai/docs/transcriptions.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"model":"eroq-scribe-one","text":"That noise is the reactor missing its coolant flush.","usage":{"credits_spent":5,"credits_remaining":882}}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}},"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"description":"The audio to transcribe (wav or mp3).","type":"string","format":"binary"},"model":{"description":"Only eroq-scribe-one today.","type":"string"},"language":{"description":"ISO language hint, e.g. en, fr.","type":"string"}},"required":["file"]}}}}}},"/storage/objects":{"post":{"operationId":"storage","summary":"Storage · upload","description":"Upload a file to the eroq Store and get a CDN URL back. Credits: 2 per started 10MB, one-time.","x-credits":"2 per started 10MB, one-time","externalDocs":{"url":"https://eroq.ai/docs/storage.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"id":"0b52…","object":"storage.object","url":"https://store.eroq.ai/acc_…/8c1f2-poster.webp","bytes":482133,"content_type":"image/webp","usage":{"credits_spent":2,"credits_remaining":880}}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}},"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"description":"The file to store (any type, up to 100MB).","type":"string","format":"binary"},"name":{"description":"Filename hint kept in the URL (sanitized).","type":"string"}},"required":["file"]}}}}},"get":{"operationId":"storage-list","summary":"Storage · list","description":"List the account's stored objects, newest first. Credits: free.","x-credits":"free","externalDocs":{"url":"https://eroq.ai/docs/storage-list.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"object":"list","data":[{"id":"0b52…","object":"storage.object","url":"https://store.eroq.ai/acc_…/8c1f2-poster.webp","bytes":482133,"content_type":"image/webp","created_at":"2026-08-25T14:02:11Z"}]}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}}}},"/storage/objects/{id}":{"delete":{"operationId":"storage-delete","summary":"Storage · delete","description":"Delete a stored object from the CDN. Credits: free.","x-credits":"free","externalDocs":{"url":"https://eroq.ai/docs/storage-delete.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"id":"0b52…","object":"storage.object","deleted":true}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}}}},"/models":{"get":{"operationId":"models","summary":"List models","description":"The model catalogue with credit pricing. Credits: free.","x-credits":"free","externalDocs":{"url":"https://eroq.ai/docs/models.md","description":"This endpoint documented as markdown"},"security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"object":"list","data":[{"id":"eroq-rp-plus","kind":"chat","pricing":"3 credits / completion"},{"id":"eroq-image-one","kind":"image","pricing":"10 credits / image"}]}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}}}},"/account":{"get":{"operationId":"account","summary":"Account","description":"Balance and usage totals for the calling key. Credits: free.","x-credits":"free","externalDocs":{"url":"https://eroq.ai/docs/account.md","description":"This endpoint documented as markdown"},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"},"example":{"object":"account","credits":905,"usage_30d":{"requests":412,"credits":1543}}}}},"401":{"description":"Missing or invalid API key"},"402":{"description":"Insufficient credits"},"429":{"description":"Rate limit exceeded"}}}}}}