{
  "openapi": "3.1.0",
  "info": {
    "title": "AtmoRouter Inference API",
    "version": "1.0.0",
    "description": "Reference for the three public inference/catalog endpoints implemented by AtmoRouter. Dashboard session APIs are documented separately at /docs/management-api. Examples are illustrative. This document does not claim support for Responses, embeddings, image/video generation, or MCP."
  },
  "servers": [
    {
      "url": "https://atmorouter.dev"
    }
  ],
  "paths": {
    "/v1/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "summary": "Create a chat completion",
        "description": "OpenAI Chat Completions passthrough with account billing. Additional fields are forwarded; support depends on the selected model. An OpenAI-compatible API does not imply support for the Responses API.",
        "tags": [
          "Inference"
        ],
        "security": [
          {
            "AtmoKey": []
          },
          {
            "AnthropicKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              },
              "example": {
                "model": "cbcn/glm-5.3",
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello!"
                  }
                ],
                "max_tokens": 128
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed JSON response or SSE stream. Examples are illustrative; upstream-specific fields can vary.",
            "headers": {
              "X-Atmorouter-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Correlation ID when generated by the gateway."
              },
              "X-Atmorouter-Cost": {
                "schema": {
                  "type": "string"
                },
                "description": "Settled charge on non-streaming responses. Not available as a final-charge header after SSE starts."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatResponse"
                },
                "example": {
                  "id": "chatcmpl-example",
                  "object": "chat.completion",
                  "model": "cbcn/glm-5.3",
                  "choices": [
                    {
                      "index": 0,
                      "message": {
                        "role": "assistant",
                        "content": "Hello!"
                      },
                      "finish_reason": "stop"
                    }
                  ],
                  "usage": {
                    "prompt_tokens": 9,
                    "completion_tokens": 2,
                    "total_tokens": 11,
                    "cached_tokens": 0,
                    "cost": 2e-05
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "data: [DONE]\n\n"
              }
            }
          },
          "400": {
            "description": "Invalid request: inspect the body and correct it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or ineligible API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "402": {
            "description": "Local balance, affordability, or promotional eligibility gate. Inspect the message; only payment eligibility issues are resolved by a top-up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not allow this model.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "404": {
            "description": "The model is not enabled or priced for inference.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed; use POST."
          },
          "429": {
            "description": "Account rate limit, concurrency limit, quota, or upstream rate limit. Back off; use Retry-After when supplied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "500": {
            "description": "Gateway error. Record the request ID when available and contact support if it persists."
          },
          "502": {
            "description": "Upstream request failed. Retry conservatively before output only. Incomplete or invalid model billing metadata uses billing_metadata_unavailable and is not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "503": {
            "description": "Temporary service or upstream availability failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InferenceError"
                }
              }
            }
          },
          "424": {
            "description": "Billing settlement pending. Generation may have completed; do not automatically resend. Check Usage first. X-Should-Retry: false. Error code billing_settlement_pending; retryable: false."
          }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Create an Anthropic-format message",
        "description": "Use https://atmorouter.dev as the Anthropic SDK base URL; raw HTTP uses the full /v1/messages path. The model must support the requested features.",
        "tags": [
          "Inference"
        ],
        "security": [
          {
            "AnthropicKey": []
          },
          {
            "AtmoKey": []
          }
        ],
        "parameters": [
          {
            "name": "anthropic-version",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "2023-06-01"
            },
            "description": "Set the API version expected by your Anthropic client."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessagesRequest"
              },
              "example": {
                "model": "cbcn/glm-5.3",
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello!"
                  }
                ],
                "max_tokens": 128
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed JSON response or SSE stream. Examples are illustrative; upstream-specific fields can vary.",
            "headers": {
              "X-Atmorouter-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Correlation ID when generated by the gateway."
              },
              "X-Atmorouter-Cost": {
                "schema": {
                  "type": "string"
                },
                "description": "Settled charge on non-streaming responses. Not available as a final-charge header after SSE starts."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessagesResponse"
                },
                "example": {
                  "id": "msg-example",
                  "type": "message",
                  "role": "assistant",
                  "model": "cbcn/glm-5.3",
                  "content": [
                    {
                      "type": "text",
                      "text": "Hello!"
                    }
                  ],
                  "stop_reason": "end_turn",
                  "usage": {
                    "input_tokens": 9,
                    "output_tokens": 2
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "event: message_stop\ndata: {\"type\":\"message_stop\"}\n\n"
              }
            }
          },
          "400": {
            "description": "Invalid request: inspect the body and correct it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or ineligible API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "402": {
            "description": "Local balance, affordability, or promotional eligibility gate. Inspect the message; only payment eligibility issues are resolved by a top-up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not allow this model.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "404": {
            "description": "The model is not enabled or priced for inference.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed; use POST."
          },
          "429": {
            "description": "Account rate limit, concurrency limit, quota, or upstream rate limit. Back off; use Retry-After when supplied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "500": {
            "description": "Gateway error. Record the request ID when available and contact support if it persists."
          },
          "502": {
            "description": "Upstream request failed. Retry conservatively before output only. Incomplete or invalid model billing metadata uses billing_metadata_unavailable and is not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "503": {
            "description": "Temporary service or upstream availability failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicError"
                }
              }
            }
          },
          "424": {
            "description": "Billing settlement pending. Generation may have completed; do not automatically resend. Check Usage first. X-Should-Retry: false. Error code billing_settlement_pending; retryable: false."
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List the retail model catalog",
        "description": "Public retail catalog and pricing in USD per million tokens. A valid owner API key also includes that account’s private combo/<slug> aliases. Unauthenticated responses contain ordinary models only. Catalog presence does not guarantee every model modality or feature can be called.",
        "tags": [
          "Catalog"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Current catalog. Values below are illustrative, not live prices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "cbcn/glm-5.3",
                      "object": "model",
                      "owned_by": "atmorouter",
                      "family": "CodeBuddy CN",
                      "pricing": {
                        "input": 0.1,
                        "output": 0.2,
                        "cached_input": 0.01
                      },
                      "context_length": 128000,
                      "max_output_tokens": 8192,
                      "modality": "text",
                      "supports_cache": true
                    }
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Catalog unavailable."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AtmoKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "ar- API key"
      },
      "AnthropicKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "ChatRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "description": "Enabled model ID from GET /v1/models, or a private combo/<slug> alias owned by the API key account. Normal member permissions, budgets, pricing, and balance checks apply."
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "description": "Conversation messages. Content blocks and tools depend on the model.",
            "items": {
              "type": "object",
              "properties": {
                "role": {
                  "type": "string",
                  "description": "Message role."
                },
                "content": {
                  "description": "Text or model-supported content blocks.",
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  ]
                }
              },
              "required": [],
              "additionalProperties": true
            }
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1,
            "description": "Requested output limit. Affordability and context caps apply; upstream enforcement varies."
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Return OpenAI-format SSE, ending with data: [DONE]."
          },
          "stream_options": {
            "type": "object",
            "properties": {
              "include_usage": {
                "type": "boolean",
                "description": "Request usage frames. The gateway enables this when stream_options is omitted."
              }
            },
            "required": [],
            "additionalProperties": true
          },
          "temperature": {
            "type": "number",
            "description": "Sampling setting forwarded to the model; support varies."
          },
          "top_p": {
            "type": "number",
            "description": "Nucleus sampling setting; support varies."
          },
          "stop": {
            "description": "Stop sequence(s), when supported.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "OpenAI function definitions; model must support tools."
          },
          "tool_choice": {
            "description": "Tool selection policy, if supported.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              }
            ]
          },
          "response_format": {
            "type": "object",
            "description": "Structured output settings forwarded to the upstream; capability is model-specific.",
            "additionalProperties": true
          }
        },
        "required": [
          "model",
          "messages"
        ],
        "additionalProperties": true
      },
      "MessagesRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "description": "Enabled model ID from GET /v1/models, or a private combo/<slug> alias owned by the API key account. Normal member permissions, budgets, pricing, and balance checks apply."
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1,
            "description": "Required positive integer. Context and affordability caps apply."
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "description": "Conversation messages. Content blocks and tools depend on the model.",
            "items": {
              "type": "object",
              "properties": {
                "role": {
                  "type": "string",
                  "description": "Message role."
                },
                "content": {
                  "description": "Text or model-supported content blocks.",
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  ]
                }
              },
              "required": [],
              "additionalProperties": true
            }
          },
          "system": {
            "description": "System prompt text or Anthropic content blocks.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            ]
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Native Anthropic SSE ending in message_stop."
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Anthropic tool definitions, when supported."
          },
          "tool_choice": {
            "type": "object",
            "description": "Anthropic tool selection, when supported."
          },
          "temperature": {
            "type": "number",
            "description": "Forwarded sampling setting; model-specific."
          },
          "stop_sequences": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Forwarded stop sequences; model-specific."
          }
        },
        "required": [
          "model",
          "messages",
          "max_tokens"
        ],
        "additionalProperties": true
      },
      "ChatResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "usage": {
            "$ref": "#/components/schemas/OpenAIUsage"
          }
        },
        "required": [],
        "additionalProperties": true
      },
      "MessagesResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "content": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "stop_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "type": "object",
            "properties": {
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              }
            },
            "required": [],
            "additionalProperties": true
          }
        },
        "required": [],
        "additionalProperties": true
      },
      "OpenAIUsage": {
        "type": "object",
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          },
          "cached_tokens": {
            "type": "integer"
          },
          "cost": {
            "type": "number",
            "description": "AtmoRouter cost when reported by the gateway. Use settled usage history for reconciliation."
          }
        },
        "required": [],
        "additionalProperties": true
      },
      "InferenceError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "code": {
                "type": "string"
              }
            },
            "required": [],
            "additionalProperties": true
          }
        },
        "required": [],
        "additionalProperties": true
      },
      "AnthropicError": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "error"
          },
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [],
            "additionalProperties": true
          }
        },
        "required": [],
        "additionalProperties": true
      },
      "ModelList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "object": {
                  "type": "string"
                },
                "owned_by": {
                  "type": "string"
                },
                "family": {
                  "type": "string"
                },
                "pricing": {
                  "type": "object",
                  "properties": {
                    "input": {
                      "type": "number"
                    },
                    "output": {
                      "type": "number"
                    },
                    "cached_input": {
                      "type": "number"
                    }
                  },
                  "required": [],
                  "additionalProperties": true
                },
                "context_length": {
                  "type": "integer"
                },
                "max_output_tokens": {
                  "type": "integer"
                },
                "modality": {
                  "type": "string"
                },
                "supports_cache": {
                  "type": "boolean"
                }
              },
              "required": [],
              "additionalProperties": true
            }
          }
        },
        "required": [],
        "additionalProperties": true
      }
    }
  }
}
