{
  "openapi": "3.1.0",
  "info": {
    "title": "Token Factory Inference API",
    "version": "1",
    "summary": "Public `api.<domain>/v1/*` inference surface (client contract v1)",
    "description": "Hand-authored OpenAPI 3.1 description of the **public** inference surface Token Factory\nexposes on `api.<domain>/v1/*` (Envoy AI Gateway data plane; ext_authz = tf-warden,\next_proc = tf-relay, dialect translation = tf-babel).\n\n**Source of truth** is the frozen client contract\n`docs/api/INFERENCE-CLIENT-CONTRACT-v1.md` (S5-INF-010) and its executable fixtures under\n`test/contract/v1/`. Where this file and the contract disagree, the contract wins — file a\nbug against this spec.\n\n### Reading this spec\n* Request bodies are **OpenAI-compatible**. Only the parameters Token Factory itself\n  validates or rejects are modelled explicitly (`stop` ≤ 4, image `response_format:\"url\"`\n  rejected, image `size` allowlist, vision gate, `tool_call_id` matching, `image_url.url`\n  format). Everything else is passed to the provider as-is — consult the OpenAI reference\n  for the full parameter set; schemas here carry `additionalProperties: true`.\n* Response bodies are **exactly** the contract's per-modality \"standard body\" (§2), i.e. the\n  OpenAI/Anthropic-native shape with the strip-list (§3) applied and the always-present\n  `provider_metadata` object (§4) added.\n* Every response — success or error, JSON or audio or SSE — carries the `X-TF-*` side-channel\n  headers (§6.1). Every error on every path is the `ErrorEnvelope` (§5) with `request_id`\n  in the body.\n* The `model` field in every request **must be a curated alias** (ADR-0002). Provider-native\n  ids are rejected with 404 `model_not_found`. The `model` echoed in every response **is the\n  alias** the client sent (never the upstream id) — the upstream id is in\n  `provider_metadata.actual_model`.\n* This is the current and only public contract (contract §9) — there is no rollout flag\n  and no legacy passthrough mode; every request in every environment gets this behaviour.\n\nItems marked **ASSUMED** could not be verified against running code in this docs-only\nchange and are taken from the contract text / ADRs rather than observed behaviour.\n",
    "contact": {
      "name": "Token Factory platform team"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "externalDocs": {
    "description": "Inference client contract v1 (normative)",
    "url": "../INFERENCE-CLIENT-CONTRACT-v1.md"
  },
  "servers": [
    {
      "url": "https://api.tokenfactory.iamsaif.ai/v1",
      "description": "This environment"
    }
  ],
  "security": [
    {
      "bearerApiKey": []
    },
    {
      "xApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Models",
      "description": "Model catalogue discovery."
    },
    {
      "name": "Chat",
      "description": "OpenAI Chat Completions dialect."
    },
    {
      "name": "Completions",
      "description": "OpenAI legacy text completions dialect."
    },
    {
      "name": "Embeddings"
    },
    {
      "name": "Images"
    },
    {
      "name": "Audio"
    },
    {
      "name": "Rerank"
    },
    {
      "name": "Video",
      "description": "Async video generation — the durable job resource (contract §8, ADR-0006)."
    },
    {
      "name": "Anthropic Messages",
      "description": "Anthropic Messages dialect served by tf-babel (translated to the routed backend)."
    }
  ],
  "paths": {
    "/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "listModels",
        "summary": "List the models this API key can request",
        "description": "OpenAI-compatible model list. Token Factory routes this path to tf-warden so API-key\nauthentication runs before any catalogue data is returned. The response lists every\n**enabled, routable curated alias** — rerank and video included — filtered by the\nauthenticated key's plan, key and project model allowlists.\n\nEach entry is the **public model card** (catalog ADR-0002, contract §7.1): a valid OpenAI\nmodel object (`id`, `object`, `created`, `owned_by`) and a valid OpenRouter\n`/api/v1/models` entry, plus the Token Factory extras `context_window` (= `context_length`),\n`max_output` (= `top_provider.max_completion_tokens`) and `pricing.unit`. `name`,\n`created`, `architecture` and `top_provider` are always present; every other field is\n**omitted** when the catalogue holds no real value for it (never estimated).\n\n* `name` — the operator display name, else the `id`.\n* `architecture` — authored modality lists when set, else derived from the model's mode;\n  `modality` is `\"<in>+<in>-><out>\"` in the fixed order text, image, audio, video, file.\n* `supported_parameters` — the operator-authored list for the model when one is set;\n  otherwise (chat models only) derived from the catalogue capability flags: every chat\n  model lists `max_tokens`, plus `stop`, `temperature`, `top_p` unless it is a\n  reasoning model; `tools`/`function_calling` adds `tools`, `tool_choice`; `reasoning`\n  adds `reasoning`; `json_mode` adds `response_format`; `structured_outputs` adds\n  `response_format`, `structured_outputs`. A flag that is absent or false adds nothing.\n  Parameters a model does not list are still accepted and passed through (best effort).\n* `default_parameters` — sampling defaults only (numeric `temperature`, `top_p`, `top_k`,\n  `frequency_penalty`, `presence_penalty`, `repetition_penalty`, `min_p`).\n* `pricing` — the client rate Token Factory bills for the API key's region (that\n  region's price, else the default price), as decimal strings in USD per **one** unit\n  (see `ModelPricing`). **`pricing` absent means \"price unknown\", not \"free\"**: the\n  model has no price row, or the gateway has not loaded prices yet (briefly after a\n  restart) — retry later.\n\nChanged in 0.16.1: `pricing.currency`, `pricing.region`, the `*_per_1m` fields and\n`price_per_unit` (never in a released build) were removed in favour of per-unit strings.\n\nDeprecation markers (ADR-0002 inference) are **not** surfaced here. Provider, routing,\ncost-basis and internal ids are never exposed (`top_provider` carries only the model's\nlimits and `is_moderated`).\n\nThe list fails closed: when the gateway cannot read the catalogue or the caller's\nproject/organization state it answers 503 with `Retry-After` and never an unfiltered list.\n",
        "responses": {
          "200": {
            "description": "Model list.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "description": "`type: server_error`, `code: service_degraded` (caller state unreadable) or `server_error` (catalogue not loaded). Retry after the `Retry-After` delay.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/chat/completions": {
      "post": {
        "tags": [
          "Chat"
        ],
        "operationId": "createChatCompletion",
        "summary": "Create a chat completion (OpenAI dialect)",
        "description": "OpenAI Chat Completions. Streaming (`stream:true`) returns `text/event-stream` with\n`chat.completion.chunk` records and a final `usage` chunk (Token Factory **always forces**\n`stream_options.include_usage`), then `data: [DONE]`.\n\nToken Factory–owned validation (tf-warden, before the provider is called):\n* `stop` — at most 4 sequences → 400 `invalid_stop_sequences`.\n* `messages[].tool_call_id` must match a `tool_calls[].id` in the preceding assistant\n  message → 400 `invalid_tool_call_id`.\n* `messages[].content[].image_url.url` must be a non-empty `http`/`https` URL, or a\n  `data:` URL in RFC 2397 form with a `;base64`-declared, comma-separated payload that\n  decodes as standard base64 (format only, never fetched) → 400 `invalid_image_url`.\n* Image content on a model whose catalogue entry has `capabilities.vision=false`\n  → 400 `vision_not_supported` (fails **open** when the capability is unknown).\n* `max_tokens` / `max_completion_tokens` above the request's output-token ceiling\n  (a global ceiling, plus the model's catalogue ceiling and the plan cap when the\n  operator enforces them) → 400 `max_tokens_exceeded`, checked before the credit\n  check.\n* `messages` — at most 2048 entries by default → 400 `array_above_max_length`; every\n  entry must be an object → 400 `invalid_type` (`param: messages[i]`).\n* `metadata` — an object of at most 16 string values, keys ≤ 64 and values ≤ 512\n  characters, no control characters → otherwise 400 `invalid_metadata`.\n* Control characters in `model`, `user` or a tool's `function.name`\n  → 400 `invalid_characters`.\n\nPost-first-byte stream failures are surfaced **in-band** (contract §6.3): one\n`data: {\"error\":{...}}` record and the stream ends **without** `data: [DONE]`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion (JSON) or SSE stream when `stream:true`.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletion"
                },
                "examples": {
                  "clean": {
                    "summary": "Fixture `test/contract/v1/chat.openai-clean/expected.json`",
                    "value": {
                      "id": "chatcmpl-1",
                      "object": "chat.completion",
                      "created": 1724680001,
                      "model": "gpt-4o",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "Hi",
                            "refusal": null
                          },
                          "finish_reason": "stop",
                          "logprobs": null
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 5,
                        "completion_tokens": 1,
                        "total_tokens": 6
                      },
                      "system_fingerprint": "fp_1",
                      "service_tier": "default",
                      "provider_metadata": {
                        "provider": "openai",
                        "actual_model": "gpt-4o-2024-08-06"
                      }
                    }
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionSSE"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/completions": {
      "post": {
        "tags": [
          "Completions"
        ],
        "operationId": "createCompletion",
        "summary": "Create a legacy text completion (OpenAI dialect)",
        "description": "OpenAI legacy Completions. Same auth/policy/validation path as chat (`stop` ≤ 4 applies).\nResponse is the OpenAI `text_completion` body with the v1 strip-list applied and\n`provider_metadata` added. ASSUMED: the contract §2 table does not list `/v1/completions`\nseparately; it is treated under the chat rules (same `usage` allowlist).\nA streaming request (`stream:true`) must set `stream_options.include_usage:true`,\nor it is rejected with 400 `invalid_request` (`param: \"stream_options.include_usage\"`):\nusage is metered from the final stream chunk, which the upstream only sends when\nasked, and the gateway cannot add the flag on this endpoint.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompletionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Text completion (JSON) or SSE stream when `stream:true`.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Completion"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "SSE `data:` records of `text_completion` chunks, terminated by `data: [DONE]`."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/embeddings": {
      "post": {
        "tags": [
          "Embeddings"
        ],
        "operationId": "createEmbedding",
        "summary": "Create embeddings (OpenAI dialect)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Embedding list.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingList"
                },
                "examples": {
                  "basic": {
                    "summary": "Fixture `test/contract/v1/embeddings.basic/expected.json`",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "object": "embedding",
                          "index": 0,
                          "embedding": [
                            0.1,
                            0.2
                          ]
                        }
                      ],
                      "model": "bge-m3",
                      "usage": {
                        "prompt_tokens": 4,
                        "total_tokens": 4,
                        "prompt_tokens_details": {
                          "cached_tokens": 0,
                          "cache_write_tokens": 0
                        }
                      },
                      "provider_metadata": {
                        "provider": "vllm-staging",
                        "actual_model": "BAAI/bge-m3"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/images/generations": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "createImage",
        "summary": "Generate images (OpenAI dialect)",
        "description": "Token Factory–owned validation (tf-warden):\n* `prompt` required → 400 `missing_prompt`; empty → 400 `empty_prompt`.\n* `response_format:\"url\"` is **rejected** → 400 `unsupported_response_format`. Only\n  `b64_json` is served (recorded decision, not a gap).\n* `size` must be on the deployment allowlist (`TF_WARDEN_IMAGE_ALLOWED_SIZES`, default\n  `512x512,1024x1024,768x1344,1344x768`) → 400 `invalid_image_size`. Absent `size` uses\n  the model default.\n* Body over `TF_WARDEN_IMAGE_MAX_BODY_BYTES` (8388608 = 8 MiB in Helm — the\n  image-generation cap is deliberately kept tighter than the 32 MiB global\n  ext_authz cap, sized for a base64 reference image) → 413 `request_too_large`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageGenerationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated image(s).",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImagesResponse"
                },
                "examples": {
                  "junkUsageDropped": {
                    "summary": "Fixture `test/contract/v1/image.junk-usage/expected.json`",
                    "value": {
                      "created": 1724680002,
                      "data": [
                        {
                          "b64_json": "AAAA",
                          "revised_prompt": "a cat"
                        }
                      ],
                      "provider_metadata": {
                        "provider": "vllm-staging",
                        "actual_model": "black-forest-labs/FLUX.1-schnell"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/audio/speech": {
      "post": {
        "tags": [
          "Audio"
        ],
        "operationId": "createSpeech",
        "summary": "Text to speech (OpenAI dialect)",
        "description": "Returns an **audio body** (`audio/*`); there is never a JSON envelope on success. The\n`provider_metadata` side-channel rides **only** in the `X-TF-*` response headers.\n\n**Streaming is best-effort / a documented deviation** (ADR-0010, status *Proposed*).\nTwo contracts currently work on the data plane but neither is OpenAI\n`speech.audio.delta`-compliant:\n1. `stream:true` — chunked `audio/wav` (progressive, not SSE-shaped);\n2. `stream:true` + `stream_format:\"sse\"` — `text/event-stream` of bare base64-PCM\n   `data:` lines, **no usage event**.\nWhich one becomes the shipped contract is decided by PoC-5 (S5-INF-005 → S5-INF-063).\nDo not build on either as a stable interface yet. Full `speech.audio.delta` parity is\n**not promised**.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpeechRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audio bytes (or the best-effort stream described above).",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-TF-Cost": {
                "$ref": "#/components/headers/X-TF-Cost"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "audio/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Best-effort base64-PCM `data:` lines (ADR-0010, not stable)."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/audio/transcriptions": {
      "post": {
        "tags": [
          "Audio"
        ],
        "operationId": "createTranscription",
        "summary": "Speech to text (OpenAI dialect)",
        "description": "`multipart/form-data` upload (bounded by the 32 MiB ext_authz body cap → 413\n`request_too_large` beyond it). `response_format:\"json\"` (default) and `\"verbose_json\"`\nreturn the JSON body below with `provider_metadata`; `text`, `srt`, `vtt` are returned\n**verbatim** with the side-channel in headers only.\n",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TranscriptionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transcription.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-TF-Cost": {
                "$ref": "#/components/headers/X-TF-Cost"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transcription"
                },
                "examples": {
                  "json": {
                    "summary": "Fixture `test/contract/v1/stt.json/expected.json`",
                    "value": {
                      "text": "hello world",
                      "usage": {
                        "type": "duration",
                        "seconds": 3
                      },
                      "provider_metadata": {
                        "provider": "vllm-staging",
                        "actual_model": "openai/whisper-large-v3"
                      }
                    }
                  }
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "`response_format` text / srt / vtt — verbatim."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/audio/translations": {
      "post": {
        "tags": [
          "Audio"
        ],
        "operationId": "createTranslation",
        "summary": "Speech to English text (OpenAI dialect)",
        "description": "Same contract as `/audio/transcriptions` (STT / translation share the §2 row).",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TranscriptionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Translation.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-TF-Cost": {
                "$ref": "#/components/headers/X-TF-Cost"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transcription"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/rerank": {
      "post": {
        "tags": [
          "Rerank"
        ],
        "operationId": "createRerank",
        "summary": "Rerank documents against a query",
        "description": "Cohere/Jina-style rerank body. Routed by **path** (plain HTTPRoute); rerank aliases are\nlisted by `GET /v1/models` with `pricing.unit: document`. `usage` keeps only `total_tokens`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RerankRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ranked results.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RerankResponse"
                },
                "examples": {
                  "basic": {
                    "summary": "Fixture `test/contract/v1/rerank.basic/expected.json`",
                    "value": {
                      "id": "rr-1",
                      "model": "bge-reranker",
                      "results": [
                        {
                          "index": 1,
                          "relevance_score": 0.91
                        },
                        {
                          "index": 0,
                          "relevance_score": 0.12
                        }
                      ],
                      "usage": {
                        "total_tokens": 40
                      },
                      "provider_metadata": {
                        "provider": "vllm-staging",
                        "actual_model": "BAAI/bge-reranker-v2-m3"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/videos": {
      "post": {
        "tags": [
          "Video"
        ],
        "operationId": "createVideoJob",
        "summary": "Submit an async video-generation job",
        "description": "Creates a durable video job (ADR-0006) and returns the **job resource** (contract §8).\nGeneration is asynchronous — poll `GET /v1/videos/{id}`.\n\n* `Idempotency-Key` header: same key + same organisation ⇒ the **same** job is returned\n  (200, not 201). Without a key Token Factory fingerprints\n  `(org, key, model, prompt, size, seconds)` for a 10-minute window.\n* Billing is charged **only on confirmed completion**; `billing.state` starts `pending`.\n* ASSUMED: the current data plane also recognises the legacy create path\n  `/v1/videos/generations` (tf-relay `isVideoCreatePath`); the contract path is `/v1/videos`\n  (tf-control `SpecialRoutePath`). Integrate against `/v1/videos`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VideoCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay — an existing job matched the `Idempotency-Key` / fingerprint.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoJob"
                }
              }
            }
          },
          "201": {
            "description": "New job created.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoJob"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "409": {
            "description": "Conflict — ASSUMED: the same `Idempotency-Key` reused with a **different** request body\n(code `conflict`). The contract only specifies the same-body replay (200).\n",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "$ref": "#/components/responses/ModelDeprecated"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/videos/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VideoJobId"
        }
      ],
      "get": {
        "tags": [
          "Video"
        ],
        "operationId": "getVideoJob",
        "summary": "Poll a video job",
        "description": "Returns the job resource with **200 for every state, including `failed`** and `expired`\n(contract I9). A failed generation is never an HTTP error on poll: read\n`status:\"failed\"` + the `error` object inside the body. After `expires_at` the job is\n`expired`, `result` is removed, and the poll still returns 200.\n",
        "responses": {
          "200": {
            "description": "Current job state.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoJob"
                },
                "examples": {
                  "failed": {
                    "summary": "Fixture `test/contract/v1/video.job-failed/expected.json`",
                    "value": {
                      "id": "vid_01J8TESTVID01",
                      "object": "video.job",
                      "model": "ltx-2",
                      "status": "failed",
                      "created_at": 1724680000,
                      "started_at": 1724680001,
                      "completed_at": 1724680030,
                      "expires_at": 1725284800,
                      "progress": 0,
                      "error": {
                        "type": "server_error",
                        "message": "generation failed upstream",
                        "code": "provider_error",
                        "request_id": "req_01J8TESTVID01"
                      },
                      "billing": {
                        "state": "void"
                      },
                      "provider_metadata": {
                        "provider": "ltx-staging",
                        "actual_model": "ltx-2.3-distilled"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "No job with this id is visible to this organisation (`type: not_found_error`, `code: job_not_found`). Also returned for `vid_` ids looked up without an organisation scope.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/videos/{id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VideoJobId"
        }
      ],
      "post": {
        "tags": [
          "Video"
        ],
        "operationId": "cancelVideoJob",
        "summary": "Cancel a video job",
        "description": "Moves a job that has not yet completed to `cancelled`. A cancelled job is **not charged**\n(`billing.state:\"void\"`). ASSUMED: cancelling a job already in a terminal state returns\nthe resource unchanged with 200 (idempotent); the contract does not specify a 409 here.\n",
        "responses": {
          "200": {
            "description": "Job resource after cancellation.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoJob"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "No job with this id is visible to this organisation.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/messages": {
      "post": {
        "tags": [
          "Anthropic Messages"
        ],
        "operationId": "createMessage",
        "summary": "Create a message (Anthropic Messages dialect)",
        "description": "Anthropic Messages API as used by Claude SDKs, served by **tf-babel** (dialect adapter\n`/v1/messages`; `/v1/messages/count_tokens` is also handled but is not part of the v1\ncontract). The response is the **native Anthropic body** plus `provider_metadata`.\n`model` echoes the client alias. Streaming keeps the native `message_start` /\n`content_block_*` / `message_delta` / `message_stop` event sequence with the side-channel\nin headers.\n\n**Errors on this path use the Anthropic envelope** (`AnthropicErrorEnvelope`), not the\nOpenAI one — `request_id` is a top-level sibling of `error`.\n\nAuth: `x-api-key` (Anthropic SDK default) or `Authorization: Bearer` are both accepted.\nThe `anthropic-version` header is accepted and passed through (ASSUMED: not validated by\nToken Factory).\n",
        "parameters": [
          {
            "name": "anthropic-version",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "2023-06-01"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnthropicMessageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message (JSON) or Anthropic SSE event stream when `stream:true`.",
            "headers": {
              "X-TF-Request-Id": {
                "$ref": "#/components/headers/X-TF-Request-Id"
              },
              "X-TF-Provider": {
                "$ref": "#/components/headers/X-TF-Provider"
              },
              "X-TF-Actual-Model": {
                "$ref": "#/components/headers/X-TF-Actual-Model"
              },
              "X-TF-Model": {
                "$ref": "#/components/headers/X-TF-Model"
              },
              "X-TF-Deprecation": {
                "$ref": "#/components/headers/X-TF-Deprecation"
              },
              "X-RateLimit-Limit-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
              },
              "X-RateLimit-Remaining-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
              },
              "X-RateLimit-Reset-Requests": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
              },
              "X-RateLimit-Limit-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
              },
              "X-RateLimit-Remaining-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
              },
              "X-RateLimit-Reset-Tokens": {
                "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnthropicMessage"
                },
                "examples": {
                  "cache": {
                    "summary": "Fixture `test/contract/v1/anthropic.cache/expected.json`",
                    "value": {
                      "id": "msg_1",
                      "type": "message",
                      "role": "assistant",
                      "model": "claude-sonnet",
                      "content": [
                        {
                          "type": "text",
                          "text": "Hi"
                        }
                      ],
                      "stop_reason": "end_turn",
                      "stop_sequence": null,
                      "usage": {
                        "input_tokens": 10,
                        "output_tokens": 2,
                        "cache_read_input_tokens": 6,
                        "cache_creation_input_tokens": 4
                      },
                      "provider_metadata": {
                        "provider": "anthropic",
                        "actual_model": "claude-sonnet-4-5-20250929",
                        "native_finish_reason": "end_turn",
                        "cache": {
                          "read_tokens": 6,
                          "write_tokens": 4
                        }
                      }
                    }
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Native Anthropic event stream (`message_start` … `message_stop`); the final `message_delta` usage carries the billed `cost` (contract §2.1)."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/AnthropicBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "402": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "403": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "404": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "410": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "413": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "429": {
            "$ref": "#/components/responses/AnthropicRateLimited"
          },
          "502": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "503": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "504": {
            "$ref": "#/components/responses/AnthropicError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token Factory API key in `Authorization: Bearer <key>` (OpenAI SDK default). Keys are\nscoped Organisation → Project → API key; the key's model allowlist, IP allowlist, plan,\nrate limits and spend caps are enforced by tf-warden before any provider is called.\n"
      },
      "xApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Alternative header (Anthropic SDK default). tf-warden reads `authorization` first and\nfalls back to `x-api-key`. Any client-supplied `X-TF-Request-Id` / `X-Request-Id` is\n**ignored and overwritten** — request ids are minted server-side.\n"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Client idempotency key for async submits (contract §8). Same key + same org ⇒ same job.",
        "schema": {
          "type": "string",
          "maxLength": 255
        }
      },
      "VideoJobId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Opaque Token Factory job id returned on submit (e.g. `vid_01J…`). Valid until `expires_at`.",
        "schema": {
          "type": "string"
        }
      }
    },
    "headers": {
      "X-TF-Request-Id": {
        "description": "Server-minted request id. Equals `error.request_id` on any error. Quote it in support requests.",
        "schema": {
          "type": "string",
          "example": "req_01J8TESTCHAT02"
        }
      },
      "X-TF-Provider": {
        "description": "`provider_metadata.provider` — the Token Factory provider name that served the request.",
        "schema": {
          "type": "string"
        }
      },
      "X-TF-Actual-Model": {
        "description": "`provider_metadata.actual_model` — the upstream model id that served the request.",
        "schema": {
          "type": "string"
        }
      },
      "X-TF-Model": {
        "description": "The client alias (what you sent in `model`).",
        "schema": {
          "type": "string"
        }
      },
      "X-TF-Deprecation": {
        "description": "Only for a deprecated alias inside its window: `sunset=<RFC3339>; replacement=<alias>`.",
        "schema": {
          "type": "string"
        }
      },
      "X-TF-Cost": {
        "description": "The billed amount for this request in USD — the same exact decimal as `usage.cost`\n(`UsageCost`, contract §2.1). Set **only on non-JSON responses**: TTS audio and STT with\n`response_format` `text`/`srt`/`vtt`. JSON responses carry `usage.cost` in the body and never\nthis header. Absent when the model is unpriced or the billed quantity cannot be known\nbefore the body (e.g. an upload whose duration cannot be read).\n",
        "schema": {
          "type": "string",
          "pattern": "^[0-9]+(\\.[0-9]{1,9})?$",
          "example": "0.000075"
        }
      },
      "X-RateLimit-Limit-Requests": {
        "description": "Requests-per-minute limit of the binding request limiter (tf-warden two-bucket weighted\nsliding window): of the key RPM and the project RPM, the one that refused the request,\notherwise the one with the least remaining. Present on 200 and 429 when either is configured.\n",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Requests": {
        "description": "Requests remaining in the binding limiter's current rolling minute. Always `0` on a request-limit 429.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset-Requests": {
        "description": "Seconds until the binding request window resets (integer seconds, rounded up, at least 1; same value as `Retry-After` on a request-limit 429).",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Tokens": {
        "description": "Token limit of the binding token quota: of the key and project daily/monthly token quotas,\nthe one that refused the request, otherwise the one with the least remaining. Present when\nany is configured.\n",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Tokens": {
        "description": "Tokens remaining in the binding quota window. A near-real-time snapshot, not a per-request\nexact count: usage is added to the counter asynchronously after metering, so the value\nexcludes this request and requests still in flight, and catches up shortly after they\ncomplete. Billing uses the full metered usage. Always `0` on a token-quota 429.\n",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset-Tokens": {
        "description": "Seconds until the binding token quota window resets (UTC midnight for a daily quota, the next UTC month for a monthly one; rounded up, at least 1).",
        "schema": {
          "type": "integer"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait (integer, at least 1). Sent on every 429. On a Token Factory limiter 429\n(`rate_limit_exceeded`, `project_rate_limit_exceeded`, `quota_exceeded`,\n`project_quota_exceeded`) it equals the refusing window's `X-RateLimit-Reset-*`; on a\nprovider 429 (`provider_rate_limited`) the provider's own `Retry-After` is forwarded, or `1`\nwhen the provider sent none. **Not** sent on 402 — a funds denial is not\ncongestion; retrying does not help until the wallet is topped up.\n",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Request rejected by Token Factory validation (`type: invalid_request_error`) **or** a\nprovider 400 passed through with the **verbatim provider message** (`code: provider_error`).\nTF-owned codes: `invalid_request_body`, `invalid_stop_sequences`, `missing_prompt`,\n`empty_prompt`, `unsupported_response_format`, `invalid_image_size`, `invalid_tool_call_id`,\n`invalid_image_url`, `vision_not_supported`, `unsupported_parameter`, `invalid_request`,\n`max_tokens_exceeded`, `array_above_max_length`, `invalid_type`, `invalid_metadata`,\n`invalid_characters`.\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "stopSequences": {
                "value": {
                  "error": {
                    "type": "invalid_request_error",
                    "message": "Invalid 'stop': at most 4 stop sequences are supported",
                    "code": "invalid_stop_sequences",
                    "param": "stop",
                    "request_id": "req_01J8EXAMPLE"
                  }
                }
              },
              "providerVerbatim": {
                "summary": "Fixture `test/contract/v1/error.provider-400`",
                "value": {
                  "error": {
                    "type": "invalid_request_error",
                    "message": "<verbatim provider message>",
                    "code": "provider_error",
                    "param": null,
                    "request_id": "req_01J8EXAMPLE"
                  }
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Bad, missing, inactive or expired API key (`type: authentication_error`; codes\n`missing_api_key`, `invalid_api_key`, `inactive_api_key`, `expired_api_key`). A provider\nrejecting **Token Factory's** upstream credential is **never** surfaced as 401 — it is\nmasked to 502 `provider_unavailable`.\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": {
                "type": "authentication_error",
                "message": "Invalid API key",
                "code": "invalid_api_key",
                "param": null,
                "request_id": "req_01J8EXAMPLE"
              }
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "**Insufficient credit** (`type: insufficient_quota`, `code: insufficient_funds`) or a\nper-key USD spend cap reached (`code: key_spend_cap_reached`), or a project monthly cost\nceiling reached (`code: project_quota_exceeded`). Deliberately **402, not 429**: SDK\nretry/backoff does not help, and the platform's 429 retry amplification must not sweep it\nup. No `Retry-After`. tf-warden reserves (holds) an estimated cost before the\nprovider call and releases/settles it after; the denial is against balance minus open\nreservations.\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": {
                "type": "insufficient_quota",
                "message": "Insufficient credit balance — top up to continue",
                "code": "insufficient_funds",
                "param": null,
                "request_id": "req_01J8EXAMPLE"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Policy denial (`type: permission_error`): `model_not_allowed` (key allowlist),\n`model_not_on_plan`, `project_disabled`, `organization_suspended`, `ip_not_allowed`,\n`daily_spend_cap_reached`.\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ModelNotFound": {
        "description": "`type: not_found_error`, `code: model_not_found` — the alias is unknown, not visible to\nthis key, **or a provider-native model id was requested** (only curated aliases are valid\ninput; ADR-0002). Message for the native-id case: \"… is not a curated model alias\"\n(contract §5.2; ASSUMED wording — tf-warden today emits the generic \"does not exist or you\ndo not have access to it\" text for both cases).\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": {
                "type": "not_found_error",
                "message": "The model `gpt-4o-2024-08-06` is not a curated model alias",
                "code": "model_not_found",
                "param": "model",
                "request_id": "req_01J8EXAMPLE"
              }
            }
          }
        }
      },
      "ModelDeprecated": {
        "description": "`code: model_deprecated` — the alias passed its deprecation `sunset` (ADR-0002). The message\nnames the replacement alias when one exists. Inside the window the request is served\nnormally with `provider_metadata.deprecation` + `X-TF-Deprecation`.\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "RequestTooLarge": {
        "description": "Body over the ext_authz cap (32 MiB, `extAuthMaxBodyBytes`) or the image-generation cap\n(`TF_WARDEN_IMAGE_MAX_BODY_BYTES`). Rendered by Envoy's `BackendTrafficPolicy`\n`responseOverride` or tf-warden; **must** carry `request_id`. `code: request_too_large`.\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": {
                "type": "invalid_request_error",
                "message": "Request body too large.",
                "code": "request_too_large",
                "param": null,
                "request_id": "req_01J8EXAMPLE"
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "`type: rate_limit_error`. Either a Token Factory limit — `rate_limit_exceeded` (per-key\nRPM), `project_rate_limit_exceeded`, `quota_exceeded` / `project_quota_exceeded`\n(token quotas) — or a **provider** 429 preserved as `provider_rate_limited` with the\nprovider's verbatim message. Always honour `Retry-After`.\n\nTwo Token Factory **capacity** 429s share `code: rate_limit_exceeded` and carry\n`Retry-After: 1` with no `X-RateLimit-*` window (they are not per-key limits):\n\n* `Too many concurrent large requests. Please retry.` — a request body of 1 MiB or\n  more (e.g. inline base64 vision) arrived while the gateway's large-body concurrency\n  bound (`TF_WARDEN_MAX_CONCURRENT_LARGE_CHECKS`) was saturated. Smaller requests are\n  never subject to it. Prefer an `https` `image_url` (or a downscaled image) over a\n  multi-MB inline image.\n* `The gateway could not complete authorization in time. Please retry.` — the\n  authorization decision ran out of time before the credit checks finished; the\n  request is refused (never admitted unchecked).\n\nBoth are safe to retry; OpenAI SDKs do so automatically.\n",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-RateLimit-Limit-Requests": {
            "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
          },
          "X-RateLimit-Remaining-Requests": {
            "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
          },
          "X-RateLimit-Reset-Requests": {
            "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
          },
          "X-RateLimit-Limit-Tokens": {
            "$ref": "#/components/headers/X-RateLimit-Limit-Tokens"
          },
          "X-RateLimit-Remaining-Tokens": {
            "$ref": "#/components/headers/X-RateLimit-Remaining-Tokens"
          },
          "X-RateLimit-Reset-Tokens": {
            "$ref": "#/components/headers/X-RateLimit-Reset-Tokens"
          },
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "tf": {
                "value": {
                  "error": {
                    "type": "rate_limit_error",
                    "message": "Rate limit exceeded",
                    "code": "rate_limit_exceeded",
                    "param": null,
                    "request_id": "req_01J8EXAMPLE"
                  }
                }
              },
              "large-body-concurrency": {
                "summary": "Large-body concurrency shed (Retry-After 1)",
                "value": {
                  "error": {
                    "type": "rate_limit_error",
                    "message": "Too many concurrent large requests. Please retry.",
                    "code": "rate_limit_exceeded",
                    "param": null,
                    "request_id": "req_01J8EXAMPLE"
                  }
                }
              },
              "provider": {
                "summary": "Fixture `test/contract/v1/error.provider-429/expected.json`",
                "value": {
                  "error": {
                    "type": "rate_limit_error",
                    "message": "Rate limit reached for gpt-4o in organization org-x on tokens per min (TPM): Limit 30000, Used 29000, Requested 2000.",
                    "code": "provider_rate_limited",
                    "param": null,
                    "request_id": "req_01J8TESTERR02"
                  }
                }
              }
            }
          }
        }
      },
      "BadGateway": {
        "description": "`type: server_error`. Provider 401/403 **masked** (`provider_unavailable`, message\n\"upstream provider rejected the platform credential\", provider text not forwarded);\nprovider 404 / 5xx (`provider_error`, generic message with the provider text in\n`provider_detail`); connection failure / no healthy backend (`provider_unavailable`).\n",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": {
                "type": "server_error",
                "message": "upstream provider rejected the platform credential",
                "code": "provider_unavailable",
                "param": null,
                "request_id": "req_01J8EXAMPLE"
              }
            }
          }
        }
      },
      "Unavailable": {
        "description": "`type: server_error`, `code: provider_unavailable` / `provider_error` — upstream 503 or no healthy backend.",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "GatewayTimeout": {
        "description": "`type: server_error`, `code: provider_unavailable` — upstream timed out (route timeout, default 300s).",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "AnthropicBadRequest": {
        "description": "Anthropic-dialect error envelope; same status rules as the OpenAI paths (contract §5.2).",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AnthropicErrorEnvelope"
            }
          }
        }
      },
      "AnthropicError": {
        "description": "Anthropic-dialect error envelope; same status rules as the OpenAI paths (contract §5.2).",
        "headers": {
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AnthropicErrorEnvelope"
            }
          }
        }
      },
      "AnthropicRateLimited": {
        "description": "Anthropic-dialect 429 with `Retry-After` and the `X-RateLimit-*` headers.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-RateLimit-Limit-Requests": {
            "$ref": "#/components/headers/X-RateLimit-Limit-Requests"
          },
          "X-RateLimit-Remaining-Requests": {
            "$ref": "#/components/headers/X-RateLimit-Remaining-Requests"
          },
          "X-RateLimit-Reset-Requests": {
            "$ref": "#/components/headers/X-RateLimit-Reset-Requests"
          },
          "X-TF-Request-Id": {
            "$ref": "#/components/headers/X-TF-Request-Id"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AnthropicErrorEnvelope"
            }
          }
        }
      }
    },
    "schemas": {
      "ModelAlias": {
        "type": "string",
        "description": "A **curated model alias** from the Token Factory catalogue (e.g. `gpt-4o`, `bge-m3`,\n`qwen/qwen2.5-0.5b`). Provider-native ids are rejected (404 `model_not_found`). The same\nstring is echoed as `model` in every response, even when the serving provider changed.\n",
        "example": "gpt-4o"
      },
      "ProviderMetadata": {
        "type": "object",
        "description": "Governed side-channel (contract §4). **Always present** on every successful JSON body with\nat least `provider` and `actual_model`. Populated **only** from this allowlist — nothing\nelse a provider sent is forwarded. Adding a key is a contract minor version + fixture.\nOn streams and audio bodies the same information rides in the `X-TF-*` headers.\n",
        "required": [
          "provider",
          "actual_model"
        ],
        "additionalProperties": false,
        "properties": {
          "provider": {
            "type": "string",
            "description": "Token Factory provider name (from the catalogue), e.g. `nvidia-nim`, `openai`, `anthropic`."
          },
          "actual_model": {
            "type": "string",
            "description": "The upstream model id that served the request."
          },
          "native_finish_reason": {
            "type": "string",
            "description": "Provider's own finish reason when it differs from OpenAI's enum (openai-compatible family) or Anthropic `stop_reason` mirrored."
          },
          "reasoning_content": {
            "type": "string",
            "deprecated": true,
            "description": "Deprecated (contract v1) — a copy of `choices[0].message.reasoning_content` on a non-streaming chat response, kept for backward compatibility. Read `choices[].message.reasoning_content` instead; this copy will be removed in a future major revision."
          },
          "cache": {
            "type": "object",
            "description": "Provider-native prompt-cache usage (ADR-0005). Never estimated.",
            "additionalProperties": false,
            "properties": {
              "read_tokens": {
                "type": "integer",
                "minimum": 0
              },
              "write_tokens": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "deprecation": {
            "type": "object",
            "description": "Present only while a deprecated alias is inside its window (ADR-0002).",
            "required": [
              "alias",
              "sunset",
              "message"
            ],
            "additionalProperties": false,
            "properties": {
              "alias": {
                "type": "string"
              },
              "sunset": {
                "type": "string",
                "format": "date-time"
              },
              "replacement": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "region": {
            "type": "string",
            "description": "Catalogue region label of the serving binding (metadata only; ADR-0008 pending)."
          },
          "cost": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UsageCost"
              }
            ],
            "description": "Mirror of `usage.cost` on a JSON body (same value, same presence — contract §2.1). On a\nstream, carried only by the optional §6.2 terminal record.\n"
          }
        }
      },
      "UsageCost": {
        "type": "number",
        "minimum": 0,
        "description": "The amount Token Factory bills for this request, in USD — in normal operation equal to the\nledger charge recorded for the response's `X-TF-Request-Id` (same rating function over\ntf-control's current price and the same metered quantities; tf-ledger is authoritative —\nsee contract §2.1 for the reprice / unrated / env-fallback edge cases). Never the\nupstream provider's own price. Rendered as an exact decimal of whole nano-USD (at\nmost 9 fractional digits, no exponent, no float noise), e.g. `0.0000129`. Absent — never a\nfabricated 0 — when the model is unpriced, pricing is unwired, or the request is not\nrated. Present on chat/completions/embeddings/responses/messages/images/JSON-STT/rerank\nbodies, the final usage chunk of chat/completions streams, the Responses terminal event,\nand the final `message_delta` of a `/v1/messages` stream, and on a charged video job.\nNon-JSON responses (TTS, STT text formats) carry the same value in the `X-TF-Cost` header.\n",
        "examples": [
          0.0000129
        ]
      },
      "ErrorEnvelope": {
        "type": "object",
        "description": "Uniform error body on every OpenAI-dialect path (contract §5.1). `request_id` is always\npresent and equals the `X-TF-Request-Id` header. For provider-originated errors the\nverbatim provider message is preserved in `message`, except where Token Factory masks it\n(provider 401/403 → generic 502; provider 5xx → generic message, provider text in\n`provider_detail`).\n",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "message",
              "code",
              "request_id"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/ErrorType"
              },
              "message": {
                "type": "string"
              },
              "code": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/ErrorCode"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "param": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Offending parameter name, or `null`."
              },
              "request_id": {
                "type": "string",
                "example": "req_01J8TESTERR02"
              },
              "provider_detail": {
                "type": "string",
                "description": "Verbatim provider message when Token Factory replaced the top-level `message` (provider 5xx)."
              }
            }
          }
        }
      },
      "ErrorType": {
        "type": "string",
        "description": "Canonical OpenAI error type.",
        "enum": [
          "invalid_request_error",
          "authentication_error",
          "permission_error",
          "not_found_error",
          "rate_limit_error",
          "insufficient_quota",
          "server_error",
          "api_error"
        ]
      },
      "ErrorCode": {
        "type": "string",
        "description": "Stable machine code. Source: `libs/apidialect/codes.go` (dialect-independent catalogue)\nplus the codes introduced by the v1 contract (`provider_rate_limited`, `model_deprecated`,\n`request_too_large`, `stream_interrupted`, `api_key_terminated`). Branch on `code`, not on\n`message` (message text is not a stable surface).\n",
        "enum": [
          "missing_api_key",
          "invalid_api_key",
          "inactive_api_key",
          "expired_api_key",
          "model_not_allowed",
          "model_not_on_plan",
          "project_disabled",
          "organization_suspended",
          "ip_not_allowed",
          "daily_spend_cap_reached",
          "model_not_found",
          "model_deprecated",
          "job_not_found",
          "insufficient_quota",
          "insufficient_credit",
          "insufficient_funds",
          "key_spend_cap_reached",
          "quota_exceeded",
          "project_quota_exceeded",
          "rate_limit_exceeded",
          "project_rate_limit_exceeded",
          "provider_rate_limited",
          "invalid_request",
          "invalid_request_body",
          "invalid_stop_sequences",
          "missing_prompt",
          "empty_prompt",
          "unsupported_response_format",
          "invalid_image_size",
          "invalid_tool_call_id",
          "vision_not_supported",
          "invalid_image_url",
          "unsupported_parameter",
          "request_too_large",
          "max_tokens_exceeded",
          "array_above_max_length",
          "invalid_type",
          "invalid_metadata",
          "invalid_characters",
          "server_error",
          "gateway_internal_error",
          "provider_unavailable",
          "provider_error",
          "stream_interrupted",
          "api_key_terminated",
          "conflict",
          "not_configured",
          "invalid_configuration",
          "deployment_failed",
          "gitops_sync_failed"
        ]
      },
      "AnthropicErrorEnvelope": {
        "type": "object",
        "description": "Error body on `/v1/messages` (contract §5.1, Anthropic dialect).",
        "required": [
          "type",
          "error",
          "request_id"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "error"
          },
          "error": {
            "type": "object",
            "required": [
              "type",
              "message"
            ],
            "properties": {
              "type": {
                "type": "string",
                "description": "Anthropic error type (`invalid_request_error`, `authentication_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `api_error`, `overloaded_error`)."
              },
              "message": {
                "type": "string"
              }
            }
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "StreamErrorEvent": {
        "type": "object",
        "description": "In-band error record on an SSE stream **after** the 200 status was sent (contract §6.3).\nEmitted as one `data:` record, after which the stream ends **without** `data: [DONE]`.\nCodes: `stream_interrupted` (upstream reset) or `api_key_terminated` (key killed mid-stream).\n",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "message",
              "code",
              "request_id"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "server_error"
              },
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "enum": [
                  "stream_interrupted",
                  "api_key_terminated"
                ]
              },
              "request_id": {
                "type": "string"
              }
            }
          }
        }
      },
      "ModelList": {
        "type": "object",
        "required": [
          "object",
          "data"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelCard"
            }
          }
        },
        "example": {
          "object": "list",
          "data": [
            {
              "id": "anthropic/claude-sonnet-4.5",
              "canonical_slug": "anthropic/claude-sonnet-4.5-20250929",
              "name": "Claude Sonnet 4.5",
              "object": "model",
              "created": 1759190400,
              "owned_by": "Token Factory",
              "description": "Anthropic's balanced model for coding and agents.",
              "context_length": 200000,
              "context_window": 200000,
              "max_output": 64000,
              "architecture": {
                "modality": "text+image->text",
                "input_modalities": [
                  "text",
                  "image"
                ],
                "output_modalities": [
                  "text"
                ],
                "tokenizer": "Claude"
              },
              "pricing": {
                "unit": "token",
                "prompt": "0.000003",
                "completion": "0.000015",
                "input_cache_read": "0.0000003",
                "input_cache_write": "0.00000375"
              },
              "top_provider": {
                "context_length": 200000,
                "max_completion_tokens": 64000,
                "is_moderated": false
              },
              "supported_parameters": [
                "max_tokens",
                "stop",
                "temperature",
                "tool_choice",
                "tools",
                "top_p"
              ],
              "default_parameters": {
                "temperature": 1
              },
              "knowledge_cutoff": "2025-01-31"
            },
            {
              "id": "openai/text-embedding-3-small",
              "name": "openai/text-embedding-3-small",
              "object": "model",
              "created": 1756684800,
              "owned_by": "Token Factory",
              "context_length": 8191,
              "context_window": 8191,
              "architecture": {
                "modality": "text->embeddings",
                "input_modalities": [
                  "text"
                ],
                "output_modalities": [
                  "embeddings"
                ]
              },
              "pricing": {
                "unit": "token",
                "prompt": "0.00000002"
              },
              "top_provider": {
                "context_length": 8191,
                "is_moderated": false
              }
            },
            {
              "id": "black-forest-labs/flux-1.1-pro",
              "name": "black-forest-labs/flux-1.1-pro",
              "object": "model",
              "created": 1756684800,
              "owned_by": "Token Factory",
              "architecture": {
                "modality": "text->image",
                "input_modalities": [
                  "text"
                ],
                "output_modalities": [
                  "image"
                ]
              },
              "pricing": {
                "unit": "image",
                "image_output": "0.04"
              },
              "top_provider": {
                "is_moderated": false
              }
            },
            {
              "id": "google/veo-3",
              "name": "Veo 3",
              "object": "model",
              "created": 1758067200,
              "owned_by": "Token Factory",
              "architecture": {
                "modality": "text+image->video",
                "input_modalities": [
                  "text",
                  "image"
                ],
                "output_modalities": [
                  "video"
                ]
              },
              "pricing": {
                "unit": "second",
                "video_output": "0.4"
              },
              "top_provider": {
                "is_moderated": false
              }
            }
          ]
        }
      },
      "ModelCard": {
        "type": "object",
        "description": "The public model card (catalog ADR-0002): an OpenAI model object and an OpenRouter\n`/api/v1/models` entry in one. Optional fields are omitted when the catalogue has no\nvalue; they are never estimated.\n",
        "required": [
          "id",
          "name",
          "object",
          "created",
          "owned_by",
          "architecture",
          "top_provider"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "canonical_slug": {
            "type": "string",
            "description": "OpenRouter canonical slug (catalogue metadata)."
          },
          "hugging_face_id": {
            "type": "string",
            "description": "Hugging Face model id (catalogue metadata)."
          },
          "name": {
            "type": "string",
            "description": "Display name: the operator-set display name, else the `id`."
          },
          "object": {
            "type": "string",
            "const": "model"
          },
          "created": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix seconds the model was added to the catalogue."
          },
          "owned_by": {
            "type": "string",
            "const": "Token Factory"
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          },
          "context_length": {
            "type": "integer",
            "minimum": 1,
            "description": "Context window in tokens (OpenRouter name). Omitted when the catalogue has no value."
          },
          "context_window": {
            "type": "integer",
            "minimum": 1,
            "description": "Same value as `context_length` (product name)."
          },
          "max_output": {
            "type": "integer",
            "minimum": 1,
            "description": "Output-token ceiling (= `top_provider.max_completion_tokens`). Omitted when the catalogue has no value."
          },
          "architecture": {
            "type": "object",
            "required": [
              "modality",
              "input_modalities",
              "output_modalities"
            ],
            "properties": {
              "modality": {
                "type": "string",
                "examples": [
                  "text+image->text"
                ],
                "description": "`<in>+<in>-><out>`; authored, else derived from the lists."
              },
              "input_modalities": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string"
                }
              },
              "output_modalities": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string"
                }
              },
              "tokenizer": {
                "type": "string"
              },
              "instruct_type": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "pricing": {
            "$ref": "#/components/schemas/ModelPricing"
          },
          "top_provider": {
            "type": "object",
            "description": "The model's limits as served. Never names a provider.",
            "required": [
              "is_moderated"
            ],
            "properties": {
              "context_length": {
                "type": "integer",
                "minimum": 1
              },
              "max_completion_tokens": {
                "type": "integer",
                "minimum": 1
              },
              "is_moderated": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          },
          "supported_parameters": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The operator-authored list when set, else (chat models only) derived from catalogue capability flags (see the operation description). Sorted, unique."
          },
          "default_parameters": {
            "type": "object",
            "description": "Sampling defaults; only the listed keys, numeric values.",
            "properties": {
              "temperature": {
                "type": "number"
              },
              "top_p": {
                "type": "number"
              },
              "top_k": {
                "type": "number"
              },
              "frequency_penalty": {
                "type": "number"
              },
              "presence_penalty": {
                "type": "number"
              },
              "repetition_penalty": {
                "type": "number"
              },
              "min_p": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "supported_voices": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "TTS voices."
          },
          "knowledge_cutoff": {
            "type": "string"
          },
          "expiration_date": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ModelPricing": {
        "type": "object",
        "description": "Client list price of one model for the caller's billing region — the rate Token Factory\nbills — as decimal strings in USD per **one** unit (no exponent, trailing zeros trimmed,\n`\"0\"` for a real free component). `unit` decides the fields: `token` (chat, embedding) →\n`prompt`, `completion`, `input_cache_read`, `input_cache_write` per token; `character`\n(TTS) → `prompt` per input character; `image` → `image_output` per image; `second` →\n`prompt` per audio second (STT) or `video_output` per video second (video); `document`\n(rerank) → `prompt` per document. A field appears only when the model has that rate (an\nembedding model has no `completion`; absent cache prices mean cache reads/writes bill at\n`prompt`). The whole object is omitted when the price is unknown (no price row, a row that\ncannot be billed, or prices not loaded yet after a gateway restart — retry); never a\nguessed 0. Prices are the stored rate rounded once to nano-USD per 1M units (token,\ncharacter) or per unit; each request is billed from the exact rate with one rounding, so\n`prompt × tokens` can differ from the bill by under 1 nano-USD per 1M tokens.\n",
        "required": [
          "unit"
        ],
        "properties": {
          "unit": {
            "type": "string",
            "enum": [
              "token",
              "character",
              "image",
              "second",
              "document"
            ]
          },
          "prompt": {
            "type": "string",
            "pattern": "^[0-9]+(\\.[0-9]+)?$",
            "description": "USD per input token (token), input character (character), audio second (second, STT) or document (document)."
          },
          "completion": {
            "type": "string",
            "pattern": "^[0-9]+(\\.[0-9]+)?$",
            "description": "USD per output token."
          },
          "input_cache_read": {
            "type": "string",
            "pattern": "^[0-9]+(\\.[0-9]+)?$",
            "description": "USD per prompt-cache read token."
          },
          "input_cache_write": {
            "type": "string",
            "pattern": "^[0-9]+(\\.[0-9]+)?$",
            "description": "USD per prompt-cache write token."
          },
          "image_output": {
            "type": "string",
            "pattern": "^[0-9]+(\\.[0-9]+)?$",
            "description": "USD per generated image."
          },
          "video_output": {
            "type": "string",
            "pattern": "^[0-9]+(\\.[0-9]+)?$",
            "description": "USD per second of generated video (Token Factory field)."
          }
        },
        "additionalProperties": false
      },
      "ChatCompletionRequest": {
        "type": "object",
        "description": "OpenAI Chat Completions request. Only TF-validated fields are modelled; others pass through.",
        "required": [
          "model",
          "messages"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "role"
              ],
              "additionalProperties": true,
              "properties": {
                "role": {
                  "type": "string",
                  "enum": [
                    "system",
                    "developer",
                    "user",
                    "assistant",
                    "tool"
                  ]
                },
                "content": {
                  "description": "String, or an array of content parts. Parts of type `image_url` are subject to the vision gate and URL-format check.",
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          },
                          "image_url": {
                            "type": "object",
                            "properties": {
                              "url": {
                                "type": "string",
                                "description": "Non-empty `http`/`https` URL, or a `data:` URL in RFC 2397 form (`;base64`-declared, comma-separated, standard-base64-decodable payload). Format-checked only (never fetched by Token Factory) → 400 `invalid_image_url`."
                              },
                              "detail": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "tool_call_id": {
                  "type": "string",
                  "description": "Must match a `tool_calls[].id` in the preceding assistant message → 400 `invalid_tool_call_id` otherwise."
                }
              }
            }
          },
          "stream": {
            "type": "boolean",
            "default": false
          },
          "stream_options": {
            "type": "object",
            "description": "`include_usage` is forced to `true` by Token Factory so the final usage chunk is always present.",
            "properties": {
              "include_usage": {
                "type": "boolean"
              }
            }
          },
          "stop": {
            "description": "At most **4** stop sequences → 400 `invalid_stop_sequences`.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "maxItems": 4,
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "max_tokens": {
            "type": "integer",
            "description": "Also used by tf-warden to size the prepaid credit reservation (falls back to `TF_WARDEN_RESERVE_DEFAULT_TOKENS` when omitted)."
          },
          "max_completion_tokens": {
            "type": "integer"
          },
          "temperature": {
            "type": "number"
          },
          "top_p": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 1,
            "description": "Nucleus sampling. Must be in the range `(0, 1]` — `0` asks for an empty nucleus and is rejected pre-dispatch with 400 `invalid_request` (`param: top_p`), as is any value above `1`. Omit it for the model default; an explicit `null` and a non-numeric value are forwarded to the provider unchanged."
          },
          "n": {
            "type": "integer"
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "tool_choice": {},
          "functions": {
            "deprecated": true,
            "description": "Legacy pre-`tools` field. **Not supported** — any non-null value is rejected pre-dispatch with 400 `unsupported_parameter` (`param: functions`). Send `tools` (each entry `{type: function, function: {...}}`) instead.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "function_call": {
            "deprecated": true,
            "description": "Legacy pre-`tool_choice` field. **Not supported** — any non-null value is rejected pre-dispatch with 400 `unsupported_parameter` (`param: function_call`). Send `tool_choice` instead.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          },
          "response_format": {
            "type": "object",
            "additionalProperties": true
          },
          "user": {
            "type": "string"
          }
        }
      },
      "ChatCompletion": {
        "type": "object",
        "description": "Contract §2 chat row — OpenAI `chat.completion` with the strip-list (§3) applied.",
        "required": [
          "id",
          "object",
          "created",
          "model",
          "choices",
          "provider_metadata"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "chat.completion"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "index",
                "message",
                "finish_reason"
              ],
              "properties": {
                "index": {
                  "type": "integer"
                },
                "message": {
                  "type": "object",
                  "required": [
                    "role"
                  ],
                  "properties": {
                    "role": {
                      "type": "string"
                    },
                    "content": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "reasoning_content": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Reasoning text of a reasoning model (DeepSeek, GLM, Qwen, gpt-oss, Gemma, …), next\nto `content` — the DeepSeek / vLLM / OpenRouter convention. Present only when the\nprovider returned reasoning. An upstream `message.reasoning` string is renamed to\nthis key (contract §3).\n"
                    },
                    "tool_calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "refusal": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "annotations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "audio": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": true
                    }
                  }
                },
                "finish_reason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "logprobs": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/TokenUsage"
          },
          "system_fingerprint": {
            "type": [
              "string",
              "null"
            ]
          },
          "service_tier": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "ChatCompletionSSE": {
        "type": "string",
        "description": "`text/event-stream`. Each `data:` record is an OpenAI `chat.completion.chunk` whose `model`\nis the alias; chunks are otherwise passed through byte-identical (fixture\n`chat.stream.alias`). Each record's shape is `ChatCompletionChunk`. A final chunk carries\n`usage` (forced) including the billed `usage.cost` (fixture `chat.stream.cost`), then\n`data: [DONE]`.\nOptional (off by default, `TF_RELAY_STREAM_TERMINAL_METADATA=true`): one\n`{\"object\":\"tf.provider_metadata\",...}` record before `[DONE]`. On failure after the first\nbyte: a `StreamErrorEvent` record and EOF **without** `[DONE]` (fixture `chat.stream.interrupted`).\n"
      },
      "ChatCompletionChunk": {
        "type": "object",
        "description": "One `data:` record of a chat stream (`ChatCompletionSSE`). Passed through as the provider\nsent it apart from `model` (= alias) and the forced final `usage` normalization (contract\n§6.2); fields beyond those listed are the provider's own.\n",
        "required": [
          "id",
          "object",
          "created",
          "model",
          "choices"
        ],
        "additionalProperties": true,
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "chat.completion.chunk"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "delta": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "role": {
                      "type": "string"
                    },
                    "content": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "reasoning_content": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Incremental reasoning text of a reasoning model, next to `content`. Stream\nchunks are not rewritten: an upstream that names it `delta.reasoning` is\npassed through as sent.\n"
                    },
                    "tool_calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "refusal": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "finish_reason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "logprobs": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/TokenUsage"
          }
        }
      },
      "TokenUsage": {
        "type": "object",
        "description": "OpenAI-native usage. Only these keys survive the strip-list; provider timing keys are\ndropped. `prompt_tokens_details`/`completion_tokens_details` are ALWAYS present —\n`cached_tokens`/`cache_write_tokens`/`reasoning_tokens` default to `0` when the upstream\nbackend didn't report them, never a larger estimated value (ADR-0005: the default is a\nshape guarantee, not an estimate). This gives every caller one consistent schema\nregardless of which backend serves a given alias (mirrors OpenRouter's normalized\nusage schema) — any other fields the backend actually sent (e.g. `audio_tokens`)\nare preserved untouched alongside the guaranteed keys. `cost` is TF-injected, not upstream:\nthe billed amount for the request (`UsageCost`, contract §2.1) — on non-streaming bodies\nand on the final `usage` chunk of a stream alike.\n",
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          },
          "prompt_tokens_details": {
            "type": "object",
            "properties": {
              "cached_tokens": {
                "type": "integer"
              },
              "cache_write_tokens": {
                "type": "integer"
              },
              "audio_tokens": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          },
          "completion_tokens_details": {
            "type": "object",
            "properties": {
              "reasoning_tokens": {
                "type": "integer"
              },
              "audio_tokens": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          },
          "cost": {
            "$ref": "#/components/schemas/UsageCost"
          }
        },
        "additionalProperties": false
      },
      "CompletionRequest": {
        "type": "object",
        "required": [
          "model",
          "prompt"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "prompt": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "stop": {
            "description": "At most 4 stop sequences → 400 `invalid_stop_sequences`.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "maxItems": 4,
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "max_tokens": {
            "type": "integer"
          },
          "stream": {
            "type": "boolean"
          },
          "temperature": {
            "type": "number"
          },
          "top_p": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 1,
            "description": "Nucleus sampling. Must be in the range `(0, 1]` — `0` asks for an empty nucleus and is rejected pre-dispatch with 400 `invalid_request` (`param: top_p`), as is any value above `1`. Omit it for the model default; an explicit `null` and a non-numeric value are forwarded to the provider unchanged."
          }
        }
      },
      "Completion": {
        "type": "object",
        "required": [
          "id",
          "object",
          "created",
          "model",
          "choices",
          "provider_metadata"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "text_completion"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "text": {
                  "type": "string"
                },
                "finish_reason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "logprobs": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/TokenUsage"
          },
          "system_fingerprint": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "EmbeddingRequest": {
        "type": "object",
        "required": [
          "model",
          "input"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "input": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      }
                    }
                  ]
                }
              }
            ]
          },
          "encoding_format": {
            "type": "string",
            "enum": [
              "float",
              "base64"
            ]
          },
          "dimensions": {
            "type": "integer"
          },
          "user": {
            "type": "string"
          }
        }
      },
      "EmbeddingList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "model",
          "usage",
          "provider_metadata"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "object",
                "index",
                "embedding"
              ],
              "properties": {
                "object": {
                  "type": "string",
                  "const": "embedding"
                },
                "index": {
                  "type": "integer"
                },
                "embedding": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    },
                    {
                      "type": "string",
                      "description": "base64 when `encoding_format:\"base64\"`."
                    }
                  ]
                }
              }
            }
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "usage": {
            "type": "object",
            "description": "`prompt_tokens` + `total_tokens` + `prompt_tokens_details` (always present, `cached_tokens`/`cache_write_tokens` default to `0` — see TokenUsage); `cost` is the billed amount (UsageCost, contract §2.1).",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              },
              "prompt_tokens_details": {
                "type": "object",
                "properties": {
                  "cached_tokens": {
                    "type": "integer"
                  },
                  "cache_write_tokens": {
                    "type": "integer"
                  }
                },
                "additionalProperties": true
              },
              "cost": {
                "$ref": "#/components/schemas/UsageCost"
              }
            },
            "additionalProperties": false
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "ImageGenerationRequest": {
        "type": "object",
        "required": [
          "model",
          "prompt"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "description": "Required (400 `missing_prompt`) and non-empty (400 `empty_prompt`)."
          },
          "response_format": {
            "type": "string",
            "enum": [
              "b64_json"
            ],
            "default": "b64_json",
            "description": "`url` is **rejected** with 400 `unsupported_response_format`."
          },
          "size": {
            "type": "string",
            "description": "Must be on the deployment allowlist (`TF_WARDEN_IMAGE_ALLOWED_SIZES`; default\n`512x512`, `1024x1024`, `768x1344`, `1344x768`) → 400 `invalid_image_size`. Omit for the model default.\n",
            "examples": [
              "1024x1024",
              "512x512",
              "768x1344",
              "1344x768"
            ]
          },
          "n": {
            "type": "integer",
            "minimum": 1
          },
          "quality": {
            "type": "string"
          },
          "style": {
            "type": "string"
          },
          "image": {
            "type": "string",
            "description": "Optional base64 reference image (image-to-image). Counts toward the 8 MiB image-generation body cap (`TF_WARDEN_IMAGE_MAX_BODY_BYTES`)."
          },
          "user": {
            "type": "string"
          }
        }
      },
      "ImagesResponse": {
        "type": "object",
        "description": "Contract §2 image row. `usage` keeps only OpenAI `ImageGenUsage` keys (timing junk is\ndropped) plus TF's billed `cost`; when the provider reported no usage, `usage` holds only\n`cost` (contract §2.1).\n",
        "required": [
          "created",
          "data",
          "provider_metadata"
        ],
        "properties": {
          "created": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "b64_json"
              ],
              "properties": {
                "b64_json": {
                  "type": "string",
                  "contentEncoding": "base64"
                },
                "revised_prompt": {
                  "type": "string"
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              },
              "input_tokens_details": {
                "type": "object",
                "additionalProperties": true
              },
              "cost": {
                "$ref": "#/components/schemas/UsageCost"
              }
            }
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "SpeechRequest": {
        "type": "object",
        "required": [
          "model",
          "input"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "input": {
            "type": "string"
          },
          "voice": {
            "type": "string"
          },
          "response_format": {
            "type": "string",
            "description": "wav, mp3, opus, aac, flac, pcm — provider dependent."
          },
          "speed": {
            "type": "number"
          },
          "stream": {
            "type": "boolean",
            "description": "Best-effort (ADR-0010 Proposed). See operation description."
          },
          "stream_format": {
            "type": "string",
            "enum": [
              "audio",
              "sse"
            ],
            "description": "With `stream:true`, `sse` yields base64-PCM `data:` lines (non-standard, no usage event). Best-effort."
          }
        }
      },
      "TranscriptionRequest": {
        "type": "object",
        "required": [
          "model",
          "file"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Audio upload; the whole request is bounded by the 32 MiB ext_authz cap."
          },
          "language": {
            "type": "string"
          },
          "prompt": {
            "type": "string"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "json",
              "verbose_json",
              "text",
              "srt",
              "vtt"
            ],
            "default": "json",
            "description": "`text` / `srt` / `vtt` bodies are returned verbatim (no `provider_metadata` in the body; headers only)."
          },
          "temperature": {
            "type": "number"
          },
          "timestamp_granularities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "word",
                "segment"
              ]
            }
          }
        }
      },
      "Transcription": {
        "type": "object",
        "description": "Contract §2 STT row. `language`, `duration`, `segments`, `words` appear with `response_format:\"verbose_json\"`.",
        "required": [
          "text",
          "provider_metadata"
        ],
        "properties": {
          "text": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "duration": {
            "type": "number"
          },
          "segments": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "words": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "usage": {
            "type": "object",
            "description": "Provider-reported usage, kept as sent (e.g. `{type:\"duration\", seconds}` or token\nusage), plus TF's billed `cost`; only `cost` when the provider reported none\n(contract §2.1). Counts are never invented.\n",
            "additionalProperties": true,
            "properties": {
              "cost": {
                "$ref": "#/components/schemas/UsageCost"
              }
            }
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "RerankRequest": {
        "type": "object",
        "required": [
          "model",
          "query",
          "documents"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "query": {
            "type": "string"
          },
          "documents": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object",
                  "properties": {
                    "text": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true
                }
              ]
            }
          },
          "top_n": {
            "type": "integer",
            "minimum": 1
          },
          "return_documents": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "RerankResponse": {
        "type": "object",
        "required": [
          "results",
          "model",
          "provider_metadata"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "index",
                "relevance_score"
              ],
              "properties": {
                "index": {
                  "type": "integer"
                },
                "relevance_score": {
                  "type": "number"
                },
                "document": {
                  "description": "Present when `return_documents:true`.",
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "description": "Only `total_tokens` survives the strip-list, plus TF's billed `cost` (contract §2.1).",
            "additionalProperties": false,
            "properties": {
              "total_tokens": {
                "type": "integer"
              },
              "cost": {
                "$ref": "#/components/schemas/UsageCost"
              }
            }
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "VideoCreateRequest": {
        "type": "object",
        "required": [
          "model",
          "prompt"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "prompt": {
            "type": "string",
            "minLength": 1
          },
          "size": {
            "type": "string",
            "description": "e.g. `1280x720` — provider dependent. Part of the idempotency fingerprint."
          },
          "seconds": {
            "type": "integer",
            "minimum": 1,
            "description": "Requested duration. Part of the idempotency fingerprint and the billed unit."
          },
          "input_reference": {
            "type": "string",
            "description": "Optional base64 reference image (ASSUMED provider-dependent)."
          }
        }
      },
      "VideoJob": {
        "type": "object",
        "description": "The durable async job resource (contract §8, ADR-0006). Returned by every `/v1/videos*`\noperation with HTTP 200 regardless of `status` — a failed generation is `status:\"failed\"` +\n`error` **inside** this body, never an HTTP error on poll.\n",
        "required": [
          "id",
          "object",
          "model",
          "status",
          "created_at",
          "expires_at",
          "billing",
          "provider_metadata"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable opaque job id, valid until `expires_at`.",
            "example": "vid_01J8TESTVID01"
          },
          "object": {
            "type": "string",
            "const": "video.job"
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "processing",
              "completed",
              "failed",
              "cancelled",
              "expired"
            ],
            "description": "Lifecycle: `queued → processing → completed | failed | cancelled`; `expired` after retention (result removed)."
          },
          "created_at": {
            "type": "integer",
            "description": "Unix seconds."
          },
          "started_at": {
            "type": [
              "integer",
              "null"
            ]
          },
          "completed_at": {
            "type": [
              "integer",
              "null"
            ]
          },
          "expires_at": {
            "type": "integer",
            "description": "completion + retention window (default 7 days)."
          },
          "progress": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "0..100 when the provider reports it."
          },
          "result": {
            "type": "object",
            "description": "Only when `status:\"completed\"` and not yet expired.",
            "properties": {
              "url": {
                "type": "string",
                "format": "uri"
              },
              "content_type": {
                "type": "string",
                "example": "video/mp4"
              },
              "seconds": {
                "type": "number"
              }
            },
            "additionalProperties": true
          },
          "error": {
            "type": "object",
            "description": "Only when `status:\"failed\"`. Same shape as `ErrorEnvelope.error`.",
            "required": [
              "type",
              "message",
              "code",
              "request_id"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/ErrorType"
              },
              "message": {
                "type": "string"
              },
              "code": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/ErrorCode"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "request_id": {
                "type": "string"
              }
            }
          },
          "billing": {
            "type": "object",
            "required": [
              "state"
            ],
            "properties": {
              "state": {
                "type": "string",
                "enum": [
                  "pending",
                  "charged",
                  "void"
                ],
                "description": "`charged` only on confirmed completion; `void` for failed/cancelled (never charged)."
              }
            }
          },
          "usage": {
            "type": "object",
            "description": "Present only once the job is `completed` and `billing.state:\"charged\"` (contract §2.1, §8) — from the first poll after the charge is recorded.",
            "required": [
              "cost"
            ],
            "properties": {
              "cost": {
                "$ref": "#/components/schemas/UsageCost"
              }
            },
            "additionalProperties": false
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      },
      "AnthropicMessageRequest": {
        "type": "object",
        "description": "Anthropic Messages request. Passed to tf-babel for translation; only `model` is TF-validated (alias rule).",
        "required": [
          "model",
          "messages",
          "max_tokens"
        ],
        "additionalProperties": true,
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "role",
                "content"
              ],
              "additionalProperties": true,
              "properties": {
                "role": {
                  "type": "string",
                  "enum": [
                    "user",
                    "assistant"
                  ]
                },
                "content": {}
              }
            }
          },
          "max_tokens": {
            "type": "integer"
          },
          "system": {},
          "stream": {
            "type": "boolean"
          },
          "temperature": {
            "type": "number"
          },
          "stop_sequences": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "AnthropicMessage": {
        "type": "object",
        "description": "Native Anthropic message body (kept intact) + `provider_metadata` (contract §2 last row; fixture `anthropic.cache`).",
        "required": [
          "id",
          "type",
          "role",
          "content",
          "model",
          "stop_reason",
          "usage",
          "provider_metadata"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "const": "message"
          },
          "role": {
            "type": "string",
            "const": "assistant"
          },
          "model": {
            "$ref": "#/components/schemas/ModelAlias"
          },
          "content": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type"
              ],
              "additionalProperties": true,
              "properties": {
                "type": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                }
              }
            }
          },
          "stop_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "stop_sequence": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "type": "object",
            "required": [
              "input_tokens",
              "output_tokens"
            ],
            "properties": {
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              },
              "cache_read_input_tokens": {
                "type": "integer"
              },
              "cache_creation_input_tokens": {
                "type": "integer"
              },
              "cost": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/UsageCost"
                  }
                ],
                "description": "Token Factory extension to the Anthropic usage object — the billed amount (contract §2.1). Also on the final `message_delta` event's `usage` when streaming."
              }
            },
            "additionalProperties": true
          },
          "provider_metadata": {
            "$ref": "#/components/schemas/ProviderMetadata"
          }
        }
      }
    }
  }
}
