{"openapi": "3.1.0", "info": {"title": "Dyadic OpenRouter-Compatible Gateway", "version": "1.0.0", "description": "OpenRouter's API through Dyadic: point an OpenRouter client (or an OpenAI SDK with OpenRouter's model ids) at\n`https://dyadic.app/api/openrouter/v1` with a Dyadic API key that has the AI gateway switch.\n\n**Who turns it on.** The gateway reaches any of OpenRouter's models at the platform's cost, so it's a platform decision:\nDyadic (a platform administrator) turns it on for an app's key on request. The key's owner can turn it off at any time in\nthe key's settings; turning it back on is again Dyadic's. A key without it is answered `403 gateway_not_allowed`: that's\nthe policy, not a fault.\n\nRequests and answers are OpenRouter's, forwarded unchanged (model ids like `anthropic/claude-haiku-5.5`, `models` fallback\nlists, `provider` routing, `reasoning`, `plugins`, `usage.cost`), on the application's own OpenRouter key when its API key\ncarries one, else on Dyadic's. Every request counts against the key's rate, spending and concurrency limits, is billed to\nthe account, and is kept in the key's activity log (and Black Box, when the key records). The key's switches apply:\nimages, embeddings, audio and moderation.\n\n`/key` and `/credits` are answered by Dyadic, never OpenRouter: the Dyadic key's own usage and limits, and its account's\nallowance, in US dollars. `/generation` answers only for this key's own requests.\n"}, "servers": [{"url": "https://dyadic.app/api/openrouter/v1"}, {"url": "https://dyadic.app/api/gateway/v1"}], "components": {"schemas": {"Error": {"type": "object", "properties": {"error": {"type": "object", "properties": {"message": {"type": "string"}, "type": {"type": "string"}, "code": {"type": ["string", "null"]}}}}}, "KeyInfo": {"type": "object", "properties": {"data": {"type": "object", "properties": {"label": {"type": "string"}, "usage": {"type": "number", "description": "What the key has cost, ever, in dollars."}, "limit": {"type": ["number", "null"], "description": "Its spending limit in dollars (or its credits limit in dollars)."}, "limit_remaining": {"type": ["number", "null"]}, "limit_reset": {"type": ["string", "null"], "enum": ["daily", "weekly", "monthly", null]}, "is_free_tier": {"const": false}, "is_provisioning_key": {"const": false}, "rate_limit": {"type": "object", "properties": {"requests": {"type": "integer"}, "interval": {"const": "1m"}}}}}}}, "Credits": {"type": "object", "properties": {"data": {"type": "object", "properties": {"total_credits": {"type": ["number", "null"], "description": "This week's allowance in dollars; null when unlimited."}, "total_usage": {"type": "number", "description": "Used and held this week, in dollars."}}}}}}, "securitySchemes": {"bearer": {"type": "http", "scheme": "bearer"}}}, "security": [{"bearer": []}], "paths": {"/chat/completions": {"post": {"tags": ["Models"], "operationId": "createChatCompletion", "summary": "Chat completion", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "OpenRouter's request body."}}}}}}, "/completions": {"post": {"tags": ["Models"], "operationId": "createCompletion", "summary": "Text completion", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "OpenRouter's request body."}}}}}}, "/embeddings": {"post": {"tags": ["Models"], "operationId": "createEmbedding", "summary": "Embeddings (the key's Embeddings switch)", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "OpenRouter's request body."}}}}}}, "/audio/speech": {"post": {"tags": ["Models"], "operationId": "createSpeech", "summary": "Text to speech (the key's Audio switch)", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "OpenRouter's request body."}}}}}}, "/audio/transcriptions": {"post": {"tags": ["Models"], "operationId": "createTranscription", "summary": "Transcription (the key's Audio switch)", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "OpenRouter's request body."}}}}}}, "/images": {"post": {"tags": ["Models"], "operationId": "createImage", "summary": "Image generation (the key's Images switch)", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "description": "OpenRouter's request body."}}}}}}, "/models": {"get": {"tags": ["Lookups"], "operationId": "listModels", "summary": "OpenRouter's models", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/models/{author}/{slug}/endpoints": {"get": {"tags": ["Lookups"], "operationId": "listEndpoints", "summary": "A model's providers and prices", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "parameters": [{"name": "author", "in": "path", "required": true, "schema": {"type": "string"}}, {"name": "slug", "in": "path", "required": true, "schema": {"type": "string"}}]}}, "/images/models/{author}/{slug}/endpoints": {"get": {"tags": ["Lookups"], "operationId": "listImageEndpoints", "summary": "An image model's providers and prices", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "parameters": [{"name": "author", "in": "path", "required": true, "schema": {"type": "string"}}, {"name": "slug", "in": "path", "required": true, "schema": {"type": "string"}}]}}, "/generation": {"get": {"tags": ["Lookups"], "operationId": "getGeneration", "summary": "A generation's cost and tokens (this key's own requests only)", "responses": {"200": {"description": "OpenRouter's answer, unchanged", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "parameters": [{"name": "id", "in": "query", "required": true, "schema": {"type": "string"}, "description": "A generation id this key made."}]}}, "/key": {"get": {"tags": ["Account"], "operationId": "getKey", "summary": "This Dyadic key's usage and limits (answered by Dyadic)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/KeyInfo"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/credits": {"get": {"tags": ["Account"], "operationId": "getCredits", "summary": "The account's allowance and use, in dollars (answered by Dyadic)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Credits"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "gateway_not_allowed: the key doesn't have the AI gateway (Dyadic turns it on for an app)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate, spending or concurrency limit", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}}}