{"openapi":"3.1.0","info":{"title":"BVE Gateway","description":"OpenAI-compatible API gateway for Fuelix","version":"1.0.0"},"servers":[{"url":"https://api.bve.me"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sk-bve-..."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}}}}},"paths":{"/health":{"get":{"summary":"Health check","security":[],"responses":{"200":{"description":"Service is healthy"}}}},"/v1/models":{"get":{"summary":"List available models","responses":{"200":{"description":"List of available models"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/models/{model}":{"get":{"summary":"Retrieve a model","parameters":[{"name":"model","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Model details"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Model not found"}}}},"/v1/chat/completions":{"post":{"summary":"Create chat completion","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","messages"],"properties":{"model":{"type":"string"},"messages":{"type":"array","items":{"type":"object"}},"max_tokens":{"type":"integer"},"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number"},"stream":{"type":"boolean"},"stream_options":{"type":"object"},"stop":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"presence_penalty":{"type":"number"},"frequency_penalty":{"type":"number"},"logprobs":{"type":"boolean"},"logit_bias":{"type":"object"},"n":{"type":"integer"},"response_format":{"type":"object"},"seed":{"type":"integer"},"tools":{"type":"array"},"tool_choice":{"oneOf":[{"type":"string"},{"type":"object"}]},"user":{"type":"string"}}}}}},"responses":{"200":{"description":"Chat completion response"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/responses":{"post":{"summary":"Create a model response (OpenAI Responses API)","description":"Proxied directly to Fuelix. Requires max_output_tokens >= 16.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","input"],"properties":{"model":{"type":"string"},"input":{"oneOf":[{"type":"string"},{"type":"array"}]},"max_output_tokens":{"type":"integer","minimum":16}}}}}},"responses":{"200":{"description":"Response object"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/completions":{"post":{"summary":"Create completion (emulated — not natively supported by Fuelix)","description":"Emulated via /v1/chat/completions. Streaming (stream=true) is not supported and returns 400.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","prompt"],"properties":{"model":{"type":"string"},"prompt":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"max_tokens":{"type":"integer"},"temperature":{"type":"number"},"stream":{"type":"boolean","description":"Must be false — streaming is not supported"}}}}}},"responses":{"200":{"description":"Completion response"},"400":{"description":"Streaming not supported","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/embeddings":{"post":{"summary":"Create embeddings","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","input"],"properties":{"model":{"type":"string"},"input":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"encoding_format":{"type":"string","enum":["float","base64"]},"dimensions":{"type":"integer"},"user":{"type":"string"}}}}}},"responses":{"200":{"description":"Embeddings response"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/audio/speech":{"post":{"summary":"Create speech (text-to-speech)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","input","voice"],"properties":{"model":{"type":"string","example":"tts-1"},"input":{"type":"string"},"voice":{"type":"string","enum":["alloy","echo","fable","onyx","nova","shimmer"]},"response_format":{"type":"string","enum":["mp3","opus","aac","flac","wav","pcm"]},"speed":{"type":"number","minimum":0.25,"maximum":4}}}}}},"responses":{"200":{"description":"Audio data (binary)","content":{"audio/mpeg":{}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/files":{"get":{"summary":"List files","description":"All authenticated BVE users share the same upstream Fuelix account files.","parameters":[{"name":"purpose","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"File list"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Upload a file","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Uploaded file object"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/files/{file_id}":{"get":{"summary":"Retrieve a file","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File object"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete a file","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deletion result"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/files/{file_id}/content":{"get":{"summary":"Retrieve file content","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File content (binary)"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/assistants":{"get":{"summary":"List assistants","description":"All BVE users share the same upstream Fuelix account assistants.","responses":{"200":{"description":"Assistant list"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create an assistant","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Created assistant"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/assistants/{assistant_id}":{"get":{"summary":"Retrieve an assistant","parameters":[{"name":"assistant_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Assistant object"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Modify an assistant","parameters":[{"name":"assistant_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Modified assistant"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete an assistant","parameters":[{"name":"assistant_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deletion result"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/threads":{"get":{"summary":"List threads","description":"All BVE users share the same upstream Fuelix account threads.","responses":{"200":{"description":"Thread list"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a thread","responses":{"200":{"description":"Created thread"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/threads/{thread_id}":{"get":{"summary":"Retrieve a thread","parameters":[{"name":"thread_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Thread object"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/threads/{thread_id}/messages":{"get":{"summary":"List thread messages","parameters":[{"name":"thread_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Message list"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a thread message","parameters":[{"name":"thread_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Created message"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/threads/{thread_id}/runs":{"get":{"summary":"List thread runs","parameters":[{"name":"thread_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Run list"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a run","parameters":[{"name":"thread_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Created run"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/admin/api-keys":{"post":{"summary":"Create API key","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"rpm_limit":{"type":"integer","default":60},"rpd_limit":{"type":"integer","default":10000},"monthly_limit":{"type":"integer","nullable":true}}}}}},"responses":{"201":{"description":"API key created (raw key only returned here)"},"401":{"description":"Unauthorized"}}},"get":{"summary":"List API keys","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"List of API keys"},"401":{"description":"Unauthorized"}}}},"/admin/api-keys/{id}/revoke":{"post":{"summary":"Revoke API key","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key revoked"},"404":{"description":"Key not found"}}}},"/admin/usage":{"get":{"summary":"Get usage statistics","security":[{"BearerAuth":[]}],"parameters":[{"name":"key_id","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage statistics"},"401":{"description":"Unauthorized"}}}}}}