{
  "openapi": "3.1.0",
  "info": {
    "title": "Consus Gateway API",
    "version": "1.0.0",
    "description": "Consus Gateway routes AI inference to government-authorized cloud infrastructure (FedRAMP, DoD IL2/IL4/IL5, ITAR) behind OpenAI- and Anthropic-compatible surfaces. Point an existing OpenAI or Anthropic client at this API and change only the base URL and API key. See https://gateway.consus.io for full documentation, including model coverage, reasoning, tool use, and error handling.",
    "contact": {
      "name": "Consus",
      "email": "sales@consusindustries.co",
      "url": "https://gateway.consus.io"
    }
  },
  "servers": [
    {
      "url": "https://api.consus.io",
      "description": "Production"
    }
  ],
  "security": [{ "ApiKeyAuth": [] }],
  "tags": [
    { "name": "Inference", "description": "Endpoints that generate model output." },
    { "name": "Models", "description": "Discover which models are available." },
    { "name": "Management", "description": "Manage your organization's keys, spend, and request logs. Requires a management key." },
    { "name": "System", "description": "Service health." }
  ],
  "paths": {
    "/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Service health check",
        "description": "Returns service health status. The only endpoint that does not require an API key. Responds 503 only when the gateway itself cannot serve requests; an individual upstream provider having trouble is reported in `providers` as `degraded` while the gateway stays healthy.",
        "tags": ["System"],
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "healthy" },
                    "service": { "type": "string", "example": "gov-open-router" },
                    "version": { "type": "string", "example": "1.0.0" },
                    "providers": {
                      "type": "object",
                      "description": "Per-provider status: `ok`, or `degraded` when that provider's calls are stuck or its capacity is saturated. Informational; a degraded provider never makes the gateway unhealthy.",
                      "additionalProperties": { "type": "string", "enum": ["ok", "degraded"] },
                      "example": { "azure_openai": "ok", "aws_bedrock": "ok", "aws_bedrock_mantle": "ok", "gcp_vertex": "ok", "aws_sagemaker": "ok" }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The gateway cannot currently serve requests (`status`: `unhealthy`). The load balancer replaces the instance; retry."
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List available models",
        "description": "Returns every requestable composite model ID (base model plus compliance level, e.g. `claude-sonnet-4-5:itar`, `gpt-5.6-sol:il5+itar`). Only models with an active provider integration are returned.",
        "tags": ["Models"],
        "responses": {
          "200": {
            "description": "List of available models.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ModelList" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": { "$ref": "#/components/responses/PermissionError" },
          "429": { "$ref": "#/components/responses/RateLimitError" }
        }
      }
    },
    "/v1/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "summary": "Create a chat completion",
        "description": "OpenAI Chat Completions-compatible endpoint. The primary, multi-provider endpoint for generating AI responses: text, multi-turn conversation, tool use, vision (image input), and extended reasoning via `reasoning_effort`. Requests route to the government cloud provider that serves the requested model.",
        "tags": ["Inference"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ChatCompletionRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion (or, with `stream: true`, a `text/event-stream` of chat completion chunks terminated by `data: [DONE]`).",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChatCompletionResponse" }
              },
              "text/event-stream": {
                "schema": { "type": "string", "description": "Server-sent events, one JSON chat-completion-chunk object per `data:` line." }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequestError" },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": { "$ref": "#/components/responses/PermissionError" },
          "429": { "$ref": "#/components/responses/RateLimitError" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "502": { "$ref": "#/components/responses/ServerError" },
          "504": { "$ref": "#/components/responses/TimeoutError" }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Create a message (native Anthropic Messages API)",
        "description": "Native Anthropic Messages API for Claude models only — no translation layer, so Anthropic SDKs and Anthropic-format clients (Claude Code, Claude Desktop) point here directly. The compliance level in `model` selects the government cloud provider. For Google or OpenAI models, use `/v1/chat/completions` instead. The gateway validates `model`, `messages`, and `max_tokens`; every other Anthropic Messages API field passes through unchanged.",
        "tags": ["Inference"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MessagesRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Anthropic Messages API response (or, with `stream: true`, an Anthropic-format `text/event-stream`).",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MessagesResponse" }
              },
              "text/event-stream": {
                "schema": { "type": "string", "description": "Anthropic-format server-sent events (message_start, content_block_delta, message_stop, etc.)." }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequestError" },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": { "$ref": "#/components/responses/PermissionError" },
          "429": { "$ref": "#/components/responses/RateLimitError" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "502": { "$ref": "#/components/responses/ServerError" },
          "504": { "$ref": "#/components/responses/TimeoutError" }
        }
      }
    },
    "/v1/messages/count_tokens": {
      "post": {
        "operationId": "countMessageTokens",
        "summary": "Count tokens for a Messages API request",
        "description": "Returns the input token count a `/v1/messages` request would consume, without generating a completion. Accepts the same body as `/v1/messages`; `max_tokens` is accepted and ignored (it is an output-side cap and cannot change the input count).",
        "tags": ["Inference"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MessagesRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token count for the given request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "input_tokens": { "type": "integer", "example": 42 }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequestError" },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": { "$ref": "#/components/responses/PermissionError" }
        }
      }
    },
    "/v1/responses": {
      "post": {
        "operationId": "createResponse",
        "summary": "Create a response (OpenAI Responses API)",
        "description": "OpenAI Responses API for GPT models on Azure Government OpenAI and AWS GovCloud Bedrock. This is the endpoint Codex CLI targets when configured with `wire_api = \"responses\"`. A thin proxy to the provider's native Responses API, restricted to GPT models. The gateway is stateless: `store: true` and `previous_response_id` are rejected with `400`.",
        "tags": ["Inference"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ResponsesRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Provider response payload (or, with `stream: true`, a `text/event-stream`).",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ResponsesResponse" }
              },
              "text/event-stream": {
                "schema": { "type": "string", "description": "OpenAI Responses API server-sent events." }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequestError" },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": { "$ref": "#/components/responses/PermissionError" },
          "429": { "$ref": "#/components/responses/RateLimitError" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "502": { "$ref": "#/components/responses/ServerError" },
          "504": { "$ref": "#/components/responses/TimeoutError" }
        }
      }
    },
    "/v1/embeddings": {
      "post": {
        "operationId": "createEmbeddings",
        "summary": "Create embeddings",
        "description": "OpenAI Embeddings-compatible endpoint. Generates vector embeddings for one or more input strings for semantic search, retrieval, and RAG. Up to 512 strings per request, 2 MB total; oversized input returns `400` rather than being truncated.",
        "tags": ["Inference"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/EmbeddingsRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Embedding vectors, one per input string, in input order.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmbeddingsResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequestError" },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": { "$ref": "#/components/responses/PermissionError" },
          "429": { "$ref": "#/components/responses/RateLimitError" }
        }
      }
    },
    "/v1/logs": {
      "get": {
        "operationId": "listRequestLogs",
        "summary": "List organization request logs",
        "description": "Returns metadata-only, org-wide usage logs (token counts, cost, latency, status — never prompt or response content), newest first. Requires a dedicated management key; standard API keys receive `403`.",
        "tags": ["Management"],
        "security": [{ "ManagementApiKeyAuth": [] }],
        "parameters": [
          { "name": "start", "in": "query", "description": "Window start (UTC, ISO 8601). Defaults to 30 days before `end`.", "schema": { "type": "string", "format": "date-time" } },
          { "name": "end", "in": "query", "description": "Window end (UTC, ISO 8601). Defaults to now. Max window is 90 days.", "schema": { "type": "string", "format": "date-time" } },
          { "name": "status", "in": "query", "description": "Filter by outcome.", "schema": { "type": "string", "enum": ["all", "success", "errors"], "default": "all" } },
          { "name": "api_key_id", "in": "query", "description": "Scope results to one API key ID.", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "description": "Rows per page.", "schema": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 } },
          { "name": "cursor", "in": "query", "description": "Opaque pagination token from a previous response's `next_cursor`. Treat as opaque.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "A page of request log rows.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RequestLogList" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/AuthenticationError" },
          "403": {
            "description": "Not a management key, used outside the Management API, or expired.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } }
            }
          }
        }
      }
    },
    "/v1/keys": {
      "get": {
        "operationId": "listKeys",
        "summary": "List organization keys",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Your organization's keys with owner, label, status, cap, and this month's spend. Management keys aren't listed.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "revoked",
                "all"
              ],
              "default": "active"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "description": "Only keys owned by this email address (case-insensitive).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "billing_class",
            "in": "query",
            "description": "Only internal or only external keys.",
            "schema": {
              "type": "string",
              "enum": [
                "internal",
                "external"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The organization's keys, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagementKeyList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequestError"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createKey",
        "summary": "Create an inference key",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Creates an inference key. `owner` is required and can't change later. The cap is limited to your organization's cap. Your organization needs a monthly spend cap. An external key needs external keys enabled for your organization (`external_markup` set on `GET /v1/org`), else `400 external_not_enabled`. An external key can take `policy_id`, one of your organization's grant policies from `GET /v1/org`, and then uses only that policy's models (an unknown or restrict policy returns `400 invalid_external_policy`); without it, the key can use every model your organization allows. Other fields return `400`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MintKeyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new key. `value` is returned once and never again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MintKeyResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequestError"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`org_cap_required`, `max_keys_reached`, or `org_key_limit_reached`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Creating the key failed upstream. No usable key was left behind. Retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/{key_id}": {
      "get": {
        "operationId": "getKey",
        "summary": "Get a key",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "The list fields plus model access, per-person cap, trial cap, and lifetime spend.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "An inference key id belonging to your organization.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{6,32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Key detail.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagementKeyDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not one of your organization's keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "revokeKey",
        "summary": "Revoke a key",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Disables the key immediately. It stays listed under `status=revoked`.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "An inference key id belonging to your organization.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{6,32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "revoked"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not one of your organization's keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Revocation failed upstream.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/{key_id}/limit": {
      "patch": {
        "operationId": "setKeyLimit",
        "summary": "Change a key's monthly spend limit",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Positive amount required, capped at your organization's limit. Needs an organization spend cap.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "An inference key id belonging to your organization.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{6,32}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "requested_monthly_limit_usd"
                ],
                "properties": {
                  "requested_monthly_limit_usd": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored (clamped) limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key_id": {
                      "type": "string"
                    },
                    "monthly_limit_usd": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequestError"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not one of your organization's keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`org_cap_required`: your organization needs a monthly spend cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/{key_id}/metadata": {
      "patch": {
        "operationId": "relabelKey",
        "summary": "Rename a key",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Changes the label only. A key's owner and billing class are fixed: sending `owner` or `billing_class` returns `400`.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "An inference key id belonging to your organization.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{6,32}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "label"
                ],
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 64,
                    "pattern": "^[A-Za-z0-9 ._@%+-]+$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key_id": {
                      "type": "string"
                    },
                    "updated": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequestError"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not one of your organization's keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org": {
      "get": {
        "operationId": "getOrganization",
        "summary": "Organization summary",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Your caps, model access, this month's spend, key counts, and when your management key expires.",
        "responses": {
          "200": {
            "description": "Organization summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgSummary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/spend": {
      "get": {
        "operationId": "getSpendReport",
        "summary": "Monthly spend report",
        "tags": [
          "Management"
        ],
        "security": [
          {
            "ManagementApiKeyAuth": []
          }
        ],
        "description": "Monthly spend per key. Up to 3 months for the organization or 12 for one key. Months with no activity are left out; `totals` covers every month.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "description": "First month, inclusive. Defaults to `end`.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
            }
          },
          {
            "name": "end",
            "in": "query",
            "description": "Last month, inclusive. Defaults to the current month.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
            }
          },
          {
            "name": "api_key_id",
            "in": "query",
            "description": "Scope to one of your organization's inference keys.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Spend buckets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpendReport"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequestError"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationError"
          },
          "403": {
            "description": "Not a management key, or the management key has expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not one of your organization's keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Standard inference API key. Grants access to all inference endpoints (`/v1/chat/completions`, `/v1/messages`, `/v1/messages/count_tokens`, `/v1/responses`, `/v1/embeddings`) and `GET /v1/models`. Can't call the Management API (returns `403`). Not required on `GET /health`. Each key carries a requests-per-second limit, a burst allowance, and a monthly quota, enforced at the API Gateway layer before the request reaches the application. Issued by Consus on request — see https://gateway.consus.io/authentication."
      },
      "ManagementApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Management key. One per organization, issued by Consus on request. Calls only the Management API (`/v1/keys`, `/v1/org`, `/v1/spend`, `/v1/logs`) and only for your organization. Can't run inference or touch management keys. Expires after 180 days. See https://gateway.consus.io/management-api."
      }
    },
    "responses": {
      "InvalidRequestError": {
        "description": "Bad request: invalid model, missing fields, validation failure, or payload exceeds limits.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "AuthenticationError": {
        "description": "Authentication failed.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "PermissionError": {
        "description": "Invalid or missing API key, or access denied to the requested model.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "RateLimitError": {
        "description": "API key rate limit / monthly quota exceeded, or an upstream model rate limit after one automatic retry.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "ServerError": {
        "description": "Internal server error, or the upstream provider was unavailable / returned a server error.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "TimeoutError": {
        "description": "Request exceeded its maximum duration (5 minutes non-streaming, ~15 minutes streaming). Not automatically retried.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": { "type": "string" },
              "type": {
                "type": "string",
                "enum": ["invalid_request_error", "authentication_error", "permission_error", "rate_limit_error", "server_error", "timeout"]
              },
              "code": { "type": "string", "description": "Present on some errors, e.g. `upstream_rate_limit`, `context_window_exceeded`." }
            },
            "required": ["message", "type"]
          }
        }
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "Composite model ID to use in requests, listed with the `consus/` prefix (requests accept it with or without), e.g. `consus/claude-sonnet-4-5:itar`.", "example": "consus/claude-sonnet-4-5:itar" },
          "object": { "type": "string", "example": "model" },
          "created": { "type": "integer", "description": "Unix timestamp." },
          "owned_by": { "type": "string", "description": "Upstream provider, e.g. `anthropic`, `openai`, `google`, `xai`, `amazon`." },
          "display_name": { "type": "string", "description": "Human-readable model name, without the compliance level (read that from `id`).", "example": "Claude Sonnet 4.5" },
          "context_window": { "type": "integer", "description": "Maximum input tokens.", "example": 200000 },
          "max_output_tokens": { "type": ["integer", "null"], "description": "Largest `max_tokens` the model accepts. `null` for embedding models.", "example": 64000 },
          "input_modalities": { "type": "array", "items": { "type": "string", "enum": ["text", "image", "pdf", "video"] }, "description": "Accepted input types.", "example": ["text", "image", "pdf"] },
          "reasoning_efforts": { "type": "array", "items": { "type": "string", "enum": ["low", "medium", "high", "xhigh"] }, "description": "`reasoning_effort` values the model honors, weakest first. `[]` = no reasoning (a sent `reasoning_effort` is accepted and ignored). A value above the last entry is lowered to it rather than rejected.", "example": ["low", "medium", "high"] },
          "pricing": { "$ref": "#/components/schemas/ModelPricing" }
        },
        "required": ["id", "object", "created", "owned_by"]
      },
      "ModelPricing": {
        "type": "object",
        "description": "USD per 1M tokens for this ID. Priced per ID because the compliance level can select a different cloud. Standard rates; GPT-5.6 long-context rates are documented separately. A rate the model doesn't offer is 0.",
        "properties": {
          "input": { "type": "number", "example": 3.6 },
          "output": { "type": "number", "example": 18.0 },
          "cache_read": { "type": "number", "description": "Cache reads; 0 when the model has no cache-read rate.", "example": 0.36 },
          "cache_write": { "type": "number", "description": "Cache writes (5-minute); 0 when the model has no cache-write rate.", "example": 4.5 }
        },
        "required": ["input", "output", "cache_read", "cache_write"]
      },
      "ModelList": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "example": "list" },
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/Model" } }
        }
      },
      "ChatMessage": {
        "type": "object",
        "properties": {
          "role": { "type": "string", "enum": ["system", "user", "assistant", "tool"] },
          "content": {
            "description": "Plain string (max 2 MB), or an array of content parts (`text`, `image_url`) for vision input.",
            "oneOf": [
              { "type": "string" },
              { "type": "array", "items": { "type": "object" } }
            ]
          },
          "tool_calls": { "type": "array", "items": { "type": "object" }, "description": "On assistant messages, max 128." },
          "tool_call_id": { "type": "string", "description": "On tool messages: the id of the tool call this message responds to." }
        },
        "required": ["role", "content"]
      },
      "Tool": {
        "type": "object",
        "properties": {
          "type": { "type": "string", "enum": ["function"] },
          "function": {
            "type": "object",
            "properties": {
              "name": { "type": "string", "pattern": "^[a-zA-Z0-9_-]{1,64}$" },
              "description": { "type": "string", "maxLength": 65536 },
              "parameters": { "type": "object", "description": "JSON Schema for the tool's arguments." }
            },
            "required": ["name"]
          }
        },
        "required": ["type", "function"]
      },
      "ChatCompletionRequest": {
        "type": "object",
        "properties": {
          "model": { "type": "string", "description": "Composite model ID. See GET /v1/models." },
          "messages": { "type": "array", "items": { "$ref": "#/components/schemas/ChatMessage" }, "maxItems": 2048 },
          "temperature": { "type": "number", "minimum": 0, "maximum": 2 },
          "max_tokens": { "type": "integer" },
          "top_p": { "type": "number", "minimum": 0, "maximum": 1 },
          "stream": { "type": "boolean" },
          "stream_options": { "type": "object", "properties": { "include_usage": { "type": "boolean" } } },
          "stop": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
          "tools": { "type": "array", "items": { "$ref": "#/components/schemas/Tool" }, "maxItems": 128 },
          "tool_choice": { "oneOf": [{ "type": "string", "enum": ["auto", "none", "required"] }, { "type": "object" }] },
          "reasoning_effort": { "type": "string", "enum": ["none", "low", "medium", "high", "xhigh"] }
        },
        "required": ["model", "messages"]
      },
      "ChatCompletionResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "object": { "type": "string", "example": "chat.completion" },
          "created": { "type": "integer" },
          "model": { "type": "string" },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": { "type": "integer" },
                "message": { "$ref": "#/components/schemas/ChatMessage" },
                "finish_reason": { "type": "string", "enum": ["stop", "length", "tool_calls", "content_filter"] }
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": { "type": "integer" },
              "completion_tokens": { "type": "integer" },
              "total_tokens": { "type": "integer" },
              "completion_tokens_details": {
                "type": "object",
                "properties": { "reasoning_tokens": { "type": "integer" } }
              }
            }
          },
          "x_consus_governance": {
            "type": "object",
            "description": "Present only when a tool call's arguments contain an outbound destination (URL, s3://, mailto:, raw IP, etc). Advisory only — the tool call is not modified or blocked.",
            "properties": {
              "flags": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "tool_call_id": { "type": "string" },
                    "tool_name": { "type": "string" },
                    "destinations": { "type": "array", "items": { "type": "string" } },
                    "reason": { "type": "string", "example": "external_destination" }
                  }
                }
              }
            }
          }
        }
      },
      "MessagesRequest": {
        "type": "object",
        "description": "Native Anthropic Messages API body. The gateway validates model, messages, and max_tokens; every other field (system, temperature, top_p, tools, tool_choice, stop_sequences, metadata, stream, thinking, ...) passes through unchanged to Anthropic's Messages API. See https://docs.anthropic.com/en/api/messages for the full upstream schema.",
        "properties": {
          "model": { "type": "string", "description": "A Claude model with a compliance level, e.g. `claude-sonnet-4-5:itar`. Bare model names return 400." },
          "messages": { "type": "array", "items": { "type": "object" }, "minItems": 1 },
          "max_tokens": { "type": "integer" },
          "system": { "oneOf": [{ "type": "string" }, { "type": "array" }] },
          "stream": { "type": "boolean" },
          "tools": { "type": "array", "items": { "type": "object" } },
          "tool_choice": { "type": "object" },
          "thinking": { "type": "object" }
        },
        "required": ["model", "messages", "max_tokens"],
        "additionalProperties": true
      },
      "MessagesResponse": {
        "type": "object",
        "description": "Native Anthropic Messages API response, with an optional x_consus_governance field (same shape as on /v1/chat/completions) appended when tool-output governance flags are present.",
        "properties": {
          "id": { "type": "string" },
          "type": { "type": "string", "example": "message" },
          "role": { "type": "string", "example": "assistant" },
          "content": { "type": "array", "items": { "type": "object" } },
          "model": { "type": "string" },
          "stop_reason": { "type": "string" },
          "stop_sequence": { "type": ["string", "null"] },
          "usage": {
            "type": "object",
            "properties": {
              "input_tokens": { "type": "integer" },
              "output_tokens": { "type": "integer" }
            }
          },
          "x_consus_governance": { "type": "object" }
        },
        "additionalProperties": true
      },
      "ResponsesRequest": {
        "type": "object",
        "properties": {
          "model": { "type": "string", "description": "Composite GPT model ID, e.g. `gpt-5.6-sol:itar`." },
          "input": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "object" } }] },
          "instructions": { "type": "string" },
          "tools": { "type": "array", "items": { "type": "object" } },
          "tool_choice": { "oneOf": [{ "type": "string" }, { "type": "object" }] },
          "reasoning": {
            "type": "object",
            "properties": {
              "effort": { "type": "string", "enum": ["low", "medium", "high", "xhigh"] },
              "summary": { "type": "string", "enum": ["auto", "concise", "detailed", "none"] }
            }
          },
          "max_output_tokens": { "type": "integer" },
          "temperature": { "type": "number" },
          "top_p": { "type": "number" },
          "parallel_tool_calls": { "type": "boolean" },
          "metadata": { "type": "object" },
          "stream": { "type": "boolean" },
          "store": { "type": "boolean", "enum": [false], "description": "Must be false or omitted — the gateway is stateless and rejects true with 400." },
          "previous_response_id": { "type": "string", "description": "Not accepted — rejected with 400. Send the full input array each turn." }
        },
        "required": ["model", "input"],
        "additionalProperties": true
      },
      "ResponsesResponse": {
        "type": "object",
        "description": "The provider's Responses API payload, unchanged, with an optional x_consus_governance field appended.",
        "properties": {
          "id": { "type": "string" },
          "object": { "type": "string", "example": "response" },
          "created_at": { "type": "integer" },
          "status": { "type": "string" },
          "model": { "type": "string" },
          "output": { "type": "array", "items": { "type": "object" } },
          "usage": {
            "type": "object",
            "properties": {
              "input_tokens": { "type": "integer" },
              "output_tokens": { "type": "integer" },
              "total_tokens": { "type": "integer" }
            }
          },
          "x_consus_governance": { "type": "object" }
        },
        "additionalProperties": true
      },
      "EmbeddingsRequest": {
        "type": "object",
        "properties": {
          "model": { "type": "string", "description": "An embedding model ID, e.g. `titan-embed-text-v2:il5`." },
          "input": {
            "description": "Text to embed. Up to 512 strings per request, 2 MB total. Token arrays are not accepted.",
            "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" }, "maxItems": 512 }]
          },
          "encoding_format": { "type": "string", "enum": ["float", "base64"], "default": "float" }
        },
        "required": ["model", "input"]
      },
      "EmbeddingsResponse": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "example": "list" },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "object": { "type": "string", "example": "embedding" },
                "index": { "type": "integer" },
                "embedding": {
                  "description": "Array of floats, or a base64 string of little-endian float32 values when encoding_format is base64.",
                  "oneOf": [{ "type": "array", "items": { "type": "number" } }, { "type": "string" }]
                }
              }
            }
          },
          "model": { "type": "string" },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": { "type": "integer" },
              "total_tokens": { "type": "integer" }
            }
          }
        }
      },
      "RequestLogRow": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "timestamp": { "type": "string", "format": "date-time" },
          "api_key_id": { "type": "string" },
          "model": { "type": "string" },
          "compliance": { "type": ["string", "null"], "example": "il5+itar" },
          "reasoning_effort": { "type": ["string", "null"] },
          "input_tokens": { "type": "integer" },
          "output_tokens": { "type": "integer" },
          "cost": { "type": "number", "description": "USD." },
          "latency_ms": { "type": "integer" },
          "status": { "type": "string", "description": "HTTP status returned to the caller, as a string." }
        }
      },
      "RequestLogList": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "example": "list" },
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/RequestLogRow" } },
          "has_more": { "type": "boolean" },
          "next_cursor": { "type": "string", "description": "Opaque. Pass back as `cursor` to fetch the next page. Only meaningful when has_more is true." }
        }
      },
      "ManagementKey": {
        "type": "object",
        "properties": {
          "key_id": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "owner": {
            "type": "string",
            "nullable": true
          },
          "billing_class": {
            "type": "string",
            "enum": [
              "internal",
              "external"
            ],
            "description": "The key's type: internal or external."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "revoked",
              "unmanaged"
            ]
          },
          "created": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "monthly_limit_usd": {
            "type": "number",
            "nullable": true,
            "description": "Per-key monthly cap. `null` means the organization cap applies."
          },
          "expires": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Trial keys only."
          },
          "month_to_date_cost_usd": {
            "type": "number"
          }
        }
      },
      "ManagementKeyList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ]
          },
          "period": {
            "type": "string",
            "description": "The month `month_to_date_cost_usd` covers."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManagementKey"
            }
          }
        }
      },
      "ManagementKeyDetail": {
        "type": "object",
        "properties": {
          "key_id": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "owner": {
            "type": "string",
            "nullable": true
          },
          "billing_class": {
            "type": "string",
            "enum": [
              "internal",
              "external"
            ],
            "description": "The key's type: internal or external."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "revoked",
              "unmanaged"
            ]
          },
          "created": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "monthly_limit_usd": {
            "type": "number",
            "nullable": true,
            "description": "Per-key monthly cap. `null` means the organization cap applies."
          },
          "expires": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Trial keys only."
          },
          "month_to_date_cost_usd": {
            "type": "number"
          },
          "allowed_models": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true,
            "description": "Allowed models. `null` means no restriction."
          },
          "person_monthly_limit_usd": {
            "type": "number",
            "nullable": true
          },
          "max_spend_usd": {
            "type": "number",
            "nullable": true,
            "description": "Lifetime cap, trial keys only."
          },
          "lifetime_cost_usd": {
            "type": "number"
          }
        }
      },
      "MintKeyRequest": {
        "type": "object",
        "required": [
          "owner"
        ],
        "additionalProperties": false,
        "properties": {
          "owner": {
            "type": "string",
            "format": "email",
            "maxLength": 64,
            "description": "Who owns the key. Can't change later."
          },
          "label": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9 ._@%+-]+$"
          },
          "billing_class": {
            "type": "string",
            "enum": [
              "internal",
              "external"
            ],
            "default": "internal",
            "description": "The key's type: internal or external. Set at creation and can't be changed. Leave out for an internal key."
          },
          "policy_id": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[a-z0-9][a-z0-9-]*$",
            "description": "External keys only: a grant policy's `policy_id` from `GET /v1/org`. The key uses only that policy's models. Leave out and the key can use every model your organization allows. Sending it on an internal key returns `400`."
          },
          "description": {
            "type": "string"
          },
          "requested_monthly_limit_usd": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Capped at your organization's limit. Leave out for the default."
          }
        }
      },
      "MintKeyResponse": {
        "type": "object",
        "properties": {
          "key_id": {
            "type": "string"
          },
          "value": {
            "type": "string",
            "description": "The key's secret. Shown once."
          },
          "monthly_limit_usd": {
            "type": "number"
          },
          "billing_class": {
            "type": "string",
            "enum": [
              "internal",
              "external"
            ]
          }
        }
      },
      "OrgSummary": {
        "type": "object",
        "properties": {
          "org_id": {
            "type": "string"
          },
          "period": {
            "type": "string"
          },
          "org_monthly_limit_usd": {
            "type": "number",
            "nullable": true
          },
          "default_monthly_limit_usd": {
            "type": "number",
            "nullable": true
          },
          "enabled_models": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "month_to_date_cost_usd": {
            "type": "number"
          },
          "active_keys": {
            "type": "integer"
          },
          "revoked_keys": {
            "type": "integer"
          },
          "prepaid_credit_usd": {
            "type": "number",
            "nullable": true
          },
          "contract_start": {
            "type": "string",
            "nullable": true
          },
          "external_markup": {
            "type": "number",
            "nullable": true,
            "description": "The markup your contract sets for external keys. Set by Consus; read-only. `null` means external keys aren't enabled for your organization."
          },
          "management_key_expires": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "When your management key expires."
          },
          "policies": {
            "type": "array",
            "description": "Your organization's model policies, managed by your portal administrators. Use a grant policy's `policy_id` when you create an external key.",
            "items": {
              "type": "object",
              "properties": {
                "policy_id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "grant",
                    "restrict"
                  ],
                  "description": "`grant` gives the models listed; `restrict` removes them."
                },
                "allowed_models": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "nullable": true,
                  "description": "`null` on a grant policy means every model your organization allows."
                }
              }
            }
          }
        }
      },
      "SpendReport": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ]
          },
          "start": {
            "type": "string"
          },
          "end": {
            "type": "string"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "api_key_id": {
                  "type": "string"
                },
                "period": {
                  "type": "string"
                },
                "requests": {
                  "type": "integer"
                },
                "input_tokens": {
                  "type": "integer"
                },
                "output_tokens": {
                  "type": "integer"
                },
                "cached_input_tokens": {
                  "type": "integer"
                },
                "cost_usd": {
                  "type": "number"
                }
              }
            }
          },
          "totals": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "period": {
                  "type": "string"
                },
                "requests": {
                  "type": "integer"
                },
                "input_tokens": {
                  "type": "integer"
                },
                "output_tokens": {
                  "type": "integer"
                },
                "cached_input_tokens": {
                  "type": "integer"
                },
                "cost_usd": {
                  "type": "number"
                }
              }
            }
          }
        }
      }
    }
  }
}
