components:
    schemas:
        APIKey:
            type: object
        ChatCompletion:
            type: object
        Model:
            description: An upstream model.
            properties:
                aliases:
                    description: Aliases callers can use in the request `model` field that resolve to this model via the default mapping.
                    items:
                        type: string
                    type: array
                configured:
                    description: Whether an upstream credential is currently mounted for this provider. Unconfigured models cannot be routed to.
                    type: boolean
                context_window:
                    description: Maximum total tokens (prompt + completion) the upstream accepts.
                    type: integer
                id:
                    description: Concrete upstream model id, e.g. `gpt-4o-mini`.
                    type: string
                pricing:
                    description: USD per million tokens for `prompt` and `completion`.
                    type: object
                provider:
                    description: Upstream vendor — `openai`, `gemini`, `deepseek`.
                    type: string
            type: object
            x-sample: |
                {
                  "id":             "gpt-4o-mini",
                  "provider":       "openai",
                  "aliases":        ["auto", "cheap"],
                  "context_window": 128000,
                  "pricing": {
                    "prompt":     0.15,
                    "completion": 0.60
                  },
                  "configured":     true
                }
            x-sample-label: The Model object
        Route:
            description: A routing rule.
            properties:
                action:
                    description: 'Resolution. For `pin`: `provider` + `model`.'
                    type: object
                action_kind:
                    description: '`pin` sends to a fixed provider/model pair. `auto` defers to routeur.ai''s picker.'
                    x-type: pin | auto
                created_at:
                    description: ISO-8601 UTC timestamp.
                    x-type: timestamp
                enabled:
                    description: Disabled rules are skipped at runtime.
                    type: boolean
                id:
                    description: Unique identifier, prefixed `route_`.
                    type: string
                match:
                    description: Match condition. Currently supports `requested_model` (exact string match).
                    type: object
                name:
                    description: Human-readable rule identifier surfaced in trace metadata as `rule:<name>`.
                    type: string
                priority:
                    description: Higher numbers evaluate first.
                    type: integer
                updated_at:
                    description: ISO-8601 UTC timestamp.
                    x-type: timestamp
            type: object
            x-sample: |
                {
                  "id":          "route_01J...",
                  "name":        "premium_demo",
                  "priority":    100,
                  "enabled":     true,
                  "action_kind": "pin",
                  "match": {
                    "requested_model": "demo-premium"
                  },
                  "action": {
                    "provider": "openai",
                    "model":    "gpt-4o"
                  },
                  "created_at": "2026-05-29T10:00:00Z",
                  "updated_at": "2026-05-29T10:00:00Z"
                }
            x-sample-label: The Route object
        Trace:
            description: A compact record persisted for every request through the gateway.
            properties:
                api_key_id:
                    description: Resolved caller key id.
                    type: string
                cost_usd:
                    description: Estimate from the configured pricing table.
                    type: number
                disclosed_bytes:
                    description: Bytes of model output that had already reached the caller when a chunked-moderation block aborted the stream (ADR-011 disclosure trade-off).
                    type: integer
                latency_ms:
                    description: End-to-end latency measured by routeur.ai.
                    type: integer
                model:
                    description: Final upstream model selected for the call.
                    type: string
                organization_id:
                    description: Owning organisation for the request.
                    type: string
                payload_url:
                    description: Short-lived signed URL to the full payload archive when payload storage is enabled.
                    type: string
                prompt_tokens / completion_tokens / total_tokens:
                    description: Usage metrics returned by the upstream provider.
                    type: integer
                provider:
                    description: Final upstream provider selected for the call.
                    type: string
                redactions:
                    description: Number of input substitutions DLP made before the upstream call.
                    type: integer
                request_id:
                    description: Stable id used across response metadata, trace records, and payload archives.
                    type: string
                requested_model:
                    description: Model alias or string the caller originally sent.
                    type: string
                route_reason:
                    description: '`default` or `rule:<name>`.'
                    type: string
                status_code:
                    description: Caller-visible HTTP status code.
                    type: integer
                stream_aborted:
                    description: True when a stream was cut after delivery began — a mid-stream upstream failure, a client disconnect, or a chunked output-moderation block.
                    type: boolean
                streamed:
                    description: True when the response was delivered as a server-sent event stream.
                    type: boolean
                ttfb_ms:
                    description: Time to first byte — ms from request start until the first response byte left the gateway. Streamed requests only.
                    type: number
            type: object
            x-sample: |
                {
                  "request_id":        "01K...",
                  "organization_id":   "org_42",
                  "api_key_id":        "key_01J...",
                  "provider":          "openai",
                  "model":             "gpt-4o-mini",
                  "requested_model":   "auto",
                  "route_reason":      "default",
                  "latency_ms":        2939,
                  "prompt_tokens":     13,
                  "completion_tokens": 7,
                  "total_tokens":      20,
                  "cost_usd":          0.00000615,
                  "status_code":       200,
                  "redactions":        1,
                  "streamed":          true,
                  "ttfb_ms":           184,
                  "payload_url":       "https://payloads.routeur.ai/...?sig=..."
                }
            x-sample-label: The Trace object
    securitySchemes:
        bearer_auth:
            description: |
                All requests authenticate with a bearer token.
                See [Authentication](/guides/authentication).
            scheme: bearer
            type: http
info:
    contact:
        name: routeur.ai
        url: https://routeur.ai
    description: Intelligent LLM gateway.
    title: routeur.ai API
    version: "1"
openapi: 3.1.0
paths:
    /v1/api-keys:
        get:
            description: List the API keys available to the authenticated organisation.
            operationId: listApiKeys
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "data": [
                                    {
                                      "id":           "key_01J...",
                                      "name":         "Production",
                                      "prefix":       "rtr_live_qF8…",
                                      "created_at":   "2026-04-12T09:11:30Z",
                                      "last_used_at": "2026-05-29T10:55:00Z"
                                    }
                                  ]
                                }
                            x-label: Response
                    description: OK
            summary: List API keys
            tags:
                - api-keys
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/api-keys \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch("https://api.routeur.ai/v1/api-keys", {
                      headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` }
                    });
                    const { data } = await res.json();
                - lang: python
                  source: |
                    r = requests.get(
                        "https://api.routeur.ai/v1/api-keys",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    keys = r.json()["data"]
            x-stability: Preview
        post:
            description: Create a new API key for authenticating requests to routeur.ai.
            operationId: createApiKey
            requestBody:
                content:
                    application/json:
                        schema:
                            properties:
                                name:
                                    description: Human label that appears in the dashboard and trace records, e.g. `Production`.
                                    type: string
                            required:
                                - name
                            type: object
                required: true
            responses:
                "201":
                    content:
                        application/json:
                            example: |
                                {
                                  "id":         "key_01J...",
                                  "name":       "Production",
                                  "prefix":     "rtr_live_qF8…",
                                  "key":        "rtr_live_qF8…W2k",
                                  "created_at": "2026-05-29T11:05:00Z"
                                }
                            x-label: Response
                    description: Created
            summary: Create an API key
            tags:
                - api-keys
            x-codeSamples:
                - lang: curl
                  source: |
                    curl -X POST https://api.routeur.ai/v1/api-keys \
                      -H "Authorization: Bearer $ROUTEUR_KEY" \
                      -H "Content-Type: application/json" \
                      -d '{ "name": "Production" }'
                - lang: node
                  source: |
                    const res = await fetch("https://api.routeur.ai/v1/api-keys", {
                      method: "POST",
                      headers: {
                        Authorization: `Bearer ${process.env.ROUTEUR_KEY}`,
                        "Content-Type": "application/json"
                      },
                      body: JSON.stringify({ name: "Production" })
                    });
                    const created = await res.json();
                - lang: python
                  source: |
                    r = requests.post(
                        "https://api.routeur.ai/v1/api-keys",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                        json={"name": "Production"},
                    )
                    created = r.json()
            x-stability: Preview
    /v1/api-keys/{id}:
        delete:
            description: Revoke an API key so it can no longer be used for authentication.
            operationId: revokeApiKey
            responses:
                "204":
                    description: No Content
            summary: Revoke an API key
            tags:
                - api-keys
            x-codeSamples:
                - lang: curl
                  source: |
                    curl -X DELETE https://api.routeur.ai/v1/api-keys/key_01J... \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    await fetch(`https://api.routeur.ai/v1/api-keys/${id}`, {
                      method: "DELETE",
                      headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` }
                    });
                - lang: python
                  source: |
                    requests.delete(
                        f"https://api.routeur.ai/v1/api-keys/{key_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
            x-stability: Preview
        parameters:
            - description: API key id (the `id` field, not the prefix or the secret itself).
              in: path
              name: id
              required: true
              schema:
                type: string
    /v1/chat/completions:
        post:
            description: Submit an OpenAI-compatible chat completion request through routeur.ai routing.
            operationId: createChatCompletion
            parameters:
                - description: Append a `routeur` metadata block to the response.
                  in: header
                  name: Routeur-Trace
                  required: false
                  schema:
                    x-type: true | false
                - description: Return the route resolution without calling the upstream provider.
                  in: header
                  name: Routeur-Dry-Run
                  required: false
                  schema:
                    x-type: true | false
            requestBody:
                content:
                    application/json:
                        schema:
                            properties:
                                messages:
                                    description: Conversation history. Each item has a `role` and `content`.
                                    items:
                                        type: object
                                    type: array
                                model:
                                    description: |
                                        The model to use. Pass `auto` (or any other alias defined in
                                        your routing rules) to let routeur.ai pick the upstream model.
                                        Pass an explicit upstream model id (e.g. `gpt-4o-mini`,
                                        `claude-3-5-sonnet`) to bypass routing and send the request
                                        directly to that model.
                                    type: string
                                stream:
                                    default: false
                                    description: |
                                        When true, the response is streamed as server-sent events (`text/event-stream`): a sequence of `chat.completion.chunk` objects terminated by `data: [DONE]`. For organizations with output-moderation rules the stream is delivered only after moderation completes (see the Streaming section of the guide).
                                    type: boolean
                                temperature:
                                    default: 1
                                    description: Sampling temperature passed through to the upstream provider.
                                    type: number
                            required:
                                - model
                                - messages
                            type: object
                required: true
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "id": "chatcmpl_01J...",
                                  "object": "chat.completion",
                                  "model": "gpt-4o-mini",
                                  "choices": [{
                                    "index": 0,
                                    "message": {
                                      "role": "assistant",
                                      "content": "Hello there!"
                                    },
                                    "finish_reason": "stop"
                                  }],
                                  "routeur": {
                                    "provider": "openai",
                                    "model": "gpt-4o-mini",
                                    "route_reason": "default",
                                    "redactions": 1
                                  }
                                }
                            x-label: Response
                        text/event-stream:
                            example: |
                                data: {"id":"chatcmpl_01J...","object":"chat.completion.chunk","model":"gpt-4o-mini","choices":[{"index":0,"delta":{"role":"assistant"}}]}

                                data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hello"}}]}

                                data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":9,"completion_tokens":2,"total_tokens":11}}

                                data: [DONE]
                            x-label: Streamed response (stream=true)
                    description: |
                        OK. A single chat completion object when `stream` is false, or an SSE `text/event-stream` of `chat.completion.chunk` objects when `stream` is true.
            summary: Create a chat completion
            tags:
                - chat-completions
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/chat/completions \
                      -H "Authorization: Bearer $ROUTEUR_KEY" \
                      -H "Content-Type: application/json" \
                      -d '{
                        "model": "auto",
                        "messages": [
                          {"role": "user", "content": "Hello"}
                        ]
                      }'
                - lang: node
                  source: |
                    import OpenAI from "openai";

                    const client = new OpenAI({
                      apiKey: process.env.ROUTEUR_KEY,
                      baseURL: "https://api.routeur.ai/v1"
                    });

                    const r = await client.chat.completions.create({
                      model: "auto",
                      messages: [{ role: "user", content: "Hello" }]
                    });
                - lang: python
                  source: |
                    from openai import OpenAI

                    client = OpenAI(
                        api_key=os.environ["ROUTEUR_KEY"],
                        base_url="https://api.routeur.ai/v1",
                    )

                    r = client.chat.completions.create(
                        model="auto",
                        messages=[{"role": "user", "content": "Hello"}],
                    )
            x-stability: Stable
    /v1/models:
        get:
            description: List the upstream models currently available through routeur.ai.
            operationId: listModels
            parameters:
                - description: Restrict the result to one provider, e.g. `openai`.
                  in: query
                  name: provider
                  required: false
                  schema:
                    type: string
                - description: Restrict to models whose provider credentials are currently mounted.
                  in: query
                  name: configured
                  required: false
                  schema:
                    type: boolean
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "data": [
                                    {
                                      "id":       "gpt-4o-mini",
                                      "provider": "openai",
                                      "context_window": 128000,
                                      "configured": true
                                    },
                                    {
                                      "id":       "gemini-1.5-pro-latest",
                                      "provider": "gemini",
                                      "context_window": 2000000,
                                      "configured": true
                                    }
                                  ]
                                }
                            x-label: Response
                    description: OK
            summary: List models
            tags:
                - models
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/models \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch("https://api.routeur.ai/v1/models", {
                      headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` }
                    });
                    const { data } = await res.json();
                - lang: python
                  source: |
                    r = requests.get(
                        "https://api.routeur.ai/v1/models",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    models = r.json()["data"]
            x-stability: Stable
    /v1/models/{id}:
        get:
            description: Retrieve metadata for a single model by its identifier.
            operationId: retrieveModel
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "id":             "gpt-4o-mini",
                                  "provider":       "openai",
                                  "context_window": 128000,
                                  "pricing": { "prompt": 0.15, "completion": 0.60 },
                                  "configured":     true
                                }
                            x-label: Response
                    description: OK
            summary: Retrieve a model
            tags:
                - models
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/models/gpt-4o-mini \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch(
                      `https://api.routeur.ai/v1/models/${id}`,
                      { headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` } }
                    );
                    const model = await res.json();
                - lang: python
                  source: |
                    r = requests.get(
                        f"https://api.routeur.ai/v1/models/{model_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    model = r.json()
            x-stability: Stable
        parameters:
            - description: Model id, e.g. `gpt-4o-mini`. Aliases (`auto`) resolve to their underlying model.
              in: path
              name: id
              required: true
              schema:
                type: string
    /v1/routes:
        get:
            description: List the routing rules configured for the authenticated organisation.
            operationId: listRoutes
            parameters:
                - description: Restrict the result to only enabled (or only disabled) rules.
                  in: query
                  name: enabled
                  required: false
                  schema:
                    type: boolean
                - description: Maximum number of rules to return.
                  in: query
                  name: limit
                  required: false
                  schema:
                    default: 50
                    maximum: 200
                    type: integer
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "data": [
                                    {
                                      "id":       "route_01J...",
                                      "name":     "premium_demo",
                                      "priority": 100,
                                      "enabled":  true,
                                      "action_kind": "pin",
                                      "match":  { "requested_model": "demo-premium" },
                                      "action": { "provider": "openai", "model": "gpt-4o" }
                                    }
                                  ],
                                  "has_more": false
                                }
                            x-label: Response
                    description: OK
            summary: List routes
            tags:
                - routes
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/routes \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch("https://api.routeur.ai/v1/routes", {
                      headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` }
                    });
                    const { data } = await res.json();
                - lang: python
                  source: |
                    import os, requests

                    r = requests.get(
                        "https://api.routeur.ai/v1/routes",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    data = r.json()["data"]
            x-stability: Preview
        post:
            description: Create a new routing rule for model selection and request handling.
            operationId: createRoute
            requestBody:
                content:
                    application/json:
                        schema:
                            properties:
                                action:
                                    description: For `pin`, supply `provider` and `model`.
                                    type: object
                                action_kind:
                                    description: Resolution strategy.
                                    x-type: pin | auto
                                enabled:
                                    default: true
                                    description: Create disabled if you want to stage a rule without it taking effect.
                                    type: boolean
                                match:
                                    description: Match condition. Currently supports `requested_model`.
                                    type: object
                                name:
                                    description: Unique within the organisation. Surfaced in trace metadata.
                                    type: string
                                priority:
                                    default: 0
                                    description: Higher numbers evaluate first.
                                    type: integer
                            required:
                                - name
                                - action_kind
                                - match
                                - action
                            type: object
                required: true
            responses:
                "201":
                    content:
                        application/json:
                            example: |
                                {
                                  "id":          "route_01J...",
                                  "name":        "premium_demo",
                                  "priority":    100,
                                  "enabled":     true,
                                  "action_kind": "pin",
                                  "match":  { "requested_model": "demo-premium" },
                                  "action": { "provider": "openai", "model": "gpt-4o" },
                                  "created_at": "2026-05-29T10:00:00Z"
                                }
                            x-label: Response
                    description: Created
            summary: Create a route
            tags:
                - routes
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/routes \
                      -H "Authorization: Bearer $ROUTEUR_KEY" \
                      -H "Content-Type: application/json" \
                      -d '{
                        "name": "premium_demo",
                        "priority": 100,
                        "action_kind": "pin",
                        "match":  { "requested_model": "demo-premium" },
                        "action": { "provider": "openai", "model": "gpt-4o" }
                      }'
                - lang: node
                  source: |
                    const res = await fetch("https://api.routeur.ai/v1/routes", {
                      method: "POST",
                      headers: {
                        Authorization: `Bearer ${process.env.ROUTEUR_KEY}`,
                        "Content-Type": "application/json"
                      },
                      body: JSON.stringify({
                        name: "premium_demo",
                        priority: 100,
                        action_kind: "pin",
                        match:  { requested_model: "demo-premium" },
                        action: { provider: "openai", model: "gpt-4o" }
                      })
                    });
                - lang: python
                  source: |
                    r = requests.post(
                        "https://api.routeur.ai/v1/routes",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                        json={
                            "name": "premium_demo",
                            "priority": 100,
                            "action_kind": "pin",
                            "match":  {"requested_model": "demo-premium"},
                            "action": {"provider": "openai", "model": "gpt-4o"},
                        },
                    )
            x-stability: Preview
    /v1/routes/{id}:
        delete:
            description: Delete a routing rule by its identifier.
            operationId: deleteRoute
            responses:
                "204":
                    description: No Content
            summary: Delete a route
            tags:
                - routes
            x-codeSamples:
                - lang: curl
                  source: |
                    curl -X DELETE https://api.routeur.ai/v1/routes/route_01J... \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    await fetch(`https://api.routeur.ai/v1/routes/${id}`, {
                      method: "DELETE",
                      headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` }
                    });
                - lang: python
                  source: |
                    requests.delete(
                        f"https://api.routeur.ai/v1/routes/{route_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
            x-stability: Preview
        get:
            description: Retrieve a single routing rule by its identifier.
            operationId: retrieveRoute
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "id":          "route_01J...",
                                  "name":        "premium_demo",
                                  "priority":    100,
                                  "enabled":     true,
                                  "action_kind": "pin",
                                  "match":  { "requested_model": "demo-premium" },
                                  "action": { "provider": "openai", "model": "gpt-4o" }
                                }
                            x-label: Response
                    description: OK
            summary: Retrieve a route
            tags:
                - routes
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/routes/route_01J... \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch(
                      `https://api.routeur.ai/v1/routes/${id}`,
                      { headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` } }
                    );
                    const route = await res.json();
                - lang: python
                  source: |
                    r = requests.get(
                        f"https://api.routeur.ai/v1/routes/{route_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    route = r.json()
            x-stability: Preview
        parameters:
            - description: Route id, e.g. `route_01J...`.
              in: path
              name: id
              required: true
              schema:
                type: string
        patch:
            description: Update selected fields on an existing routing rule.
            operationId: updateRoute
            requestBody:
                content:
                    application/json:
                        schema:
                            type: object
                required: true
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "id":         "route_01J...",
                                  "enabled":    false,
                                  "updated_at": "2026-05-29T11:00:00Z"
                                }
                            x-label: Response
                    description: OK
            summary: Update a route
            tags:
                - routes
            x-codeSamples:
                - lang: curl
                  source: |
                    curl -X PATCH https://api.routeur.ai/v1/routes/route_01J... \
                      -H "Authorization: Bearer $ROUTEUR_KEY" \
                      -H "Content-Type: application/json" \
                      -d '{ "enabled": false }'
                - lang: node
                  source: |
                    await fetch(`https://api.routeur.ai/v1/routes/${id}`, {
                      method: "PATCH",
                      headers: {
                        Authorization: `Bearer ${process.env.ROUTEUR_KEY}`,
                        "Content-Type": "application/json"
                      },
                      body: JSON.stringify({ enabled: false })
                    });
                - lang: python
                  source: |
                    requests.patch(
                        f"https://api.routeur.ai/v1/routes/{route_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                        json={"enabled": False},
                    )
            x-stability: Preview
        put:
            description: Replace an existing routing rule with a full new definition.
            operationId: replaceRoute
            requestBody:
                content:
                    application/json:
                        schema:
                            type: object
                required: true
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "id":          "route_01J...",
                                  "name":        "premium_demo",
                                  "priority":    200,
                                  "updated_at":  "2026-05-29T11:00:00Z"
                                }
                            x-label: Response
                    description: OK
            summary: Replace a route
            tags:
                - routes
            x-codeSamples:
                - lang: curl
                  source: |
                    curl -X PUT https://api.routeur.ai/v1/routes/route_01J... \
                      -H "Authorization: Bearer $ROUTEUR_KEY" \
                      -H "Content-Type: application/json" \
                      -d '{
                        "name": "premium_demo",
                        "priority": 200,
                        "enabled": true,
                        "action_kind": "pin",
                        "match":  { "requested_model": "demo-premium" },
                        "action": { "provider": "openai", "model": "gpt-4o" }
                      }'
                - lang: node
                  source: |
                    await fetch(`https://api.routeur.ai/v1/routes/${id}`, {
                      method: "PUT",
                      headers: {
                        Authorization: `Bearer ${process.env.ROUTEUR_KEY}`,
                        "Content-Type": "application/json"
                      },
                      body: JSON.stringify(fullRoute)
                    });
                - lang: python
                  source: |
                    requests.put(
                        f"https://api.routeur.ai/v1/routes/{route_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                        json=full_route,
                    )
            x-stability: Preview
    /v1/traces:
        get:
            description: List recent request traces for the authenticated organisation.
            operationId: listTraces
            parameters:
                - description: Maximum number of records to return.
                  in: query
                  name: limit
                  required: false
                  schema:
                    default: 50
                    maximum: 200
                    type: integer
                - description: Cursor — `request_id` from the previous page.
                  in: query
                  name: starting_after
                  required: false
                  schema:
                    type: string
                - description: Restrict to a single HTTP status code, e.g. `200` or `403`.
                  in: query
                  name: status
                  required: false
                  schema:
                    type: integer
                - description: Restrict to a single upstream provider.
                  in: query
                  name: provider
                  required: false
                  schema:
                    type: string
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "data": [
                                    {
                                      "request_id":  "01K...",
                                      "provider":    "openai",
                                      "model":       "gpt-4o-mini",
                                      "latency_ms":  2939,
                                      "status_code": 200,
                                      "cost_usd":    0.00000615
                                    }
                                  ],
                                  "has_more": true
                                }
                            x-label: Response
                    description: OK
            summary: List traces
            tags:
                - traces
            x-codeSamples:
                - lang: curl
                  source: |
                    curl "https://api.routeur.ai/v1/traces?limit=20&status=200" \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch(
                      "https://api.routeur.ai/v1/traces?limit=20",
                      { headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` } }
                    );
                    const { data, has_more } = await res.json();
                - lang: python
                  source: |
                    r = requests.get(
                        "https://api.routeur.ai/v1/traces",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                        params={"limit": 20, "status": 200},
                    )
                    traces = r.json()["data"]
            x-stability: Preview
    /v1/traces/{request_id}:
        get:
            description: Retrieve the full stored trace record for a single request.
            operationId: retrieveTrace
            responses:
                "200":
                    content:
                        application/json:
                            example: |
                                {
                                  "request_id":  "01K...",
                                  "provider":    "openai",
                                  "model":       "gpt-4o-mini",
                                  "latency_ms":  2939,
                                  "status_code": 200,
                                  "cost_usd":    0.00000615,
                                  "redactions":  1,
                                  "payload_url": "https://payloads.routeur.ai/...?sig=..."
                                }
                            x-label: Response
                    description: OK
            summary: Retrieve a trace
            tags:
                - traces
            x-codeSamples:
                - lang: curl
                  source: |
                    curl https://api.routeur.ai/v1/traces/01K... \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch(
                      `https://api.routeur.ai/v1/traces/${requestId}`,
                      { headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` } }
                    );
                    const trace = await res.json();
                - lang: python
                  source: |
                    r = requests.get(
                        f"https://api.routeur.ai/v1/traces/{request_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    trace = r.json()
            x-stability: Preview
        head:
            description: Inspect high-level trace metadata through response headers only.
            operationId: inspectTrace
            responses:
                "200":
                    description: OK
                    headers:
                        X-Routeur-Trace-Payload:
                            description: Signed URL for the payload archive if one exists. Absent when payload storage is disabled.
                            schema:
                                x-type: url
                        X-Routeur-Trace-Provider:
                            description: Final upstream provider used.
                            schema:
                                type: string
                        X-Routeur-Trace-Status:
                            description: Caller-visible HTTP status the original request received.
                            schema:
                                type: integer
                    x-body: |
                        X-Routeur-Trace-Status:   200
                        X-Routeur-Trace-Provider: openai
                        X-Routeur-Trace-Payload:  https://payloads.routeur.ai/...?sig=...
                    x-content-type: no body
                    x-label: Response headers
                    x-lang: text
            summary: Inspect a trace
            tags:
                - traces
            x-codeSamples:
                - lang: curl
                  source: |
                    curl -I https://api.routeur.ai/v1/traces/01K... \
                      -H "Authorization: Bearer $ROUTEUR_KEY"
                - lang: node
                  source: |
                    const res = await fetch(
                      `https://api.routeur.ai/v1/traces/${requestId}`,
                      { method: "HEAD", headers: { Authorization: `Bearer ${process.env.ROUTEUR_KEY}` } }
                    );
                    const payloadUrl = res.headers.get("X-Routeur-Trace-Payload");
                - lang: python
                  source: |
                    r = requests.head(
                        f"https://api.routeur.ai/v1/traces/{request_id}",
                        headers={"Authorization": f"Bearer {os.environ['ROUTEUR_KEY']}"},
                    )
                    payload_url = r.headers.get("X-Routeur-Trace-Payload")
            x-stability: Preview
        parameters:
            - description: Trace request id, e.g. `01K...`. Returned from the `routeur` block of any chat response.
              in: path
              name: request_id
              required: true
              schema:
                type: string
security:
    - bearer_auth: []
servers:
    - description: Production
      url: https://api.routeur.ai
tags:
    - description: OpenAI-compatible chat completion requests routed through routeur.ai.
      name: chat-completions
    - description: Routing rule management for model resolution and traffic shaping.
      name: routes
    - description: Available upstream model inventory and metadata.
      name: models
    - description: Request trace records and trace inspection endpoints.
      name: traces
    - description: API key lifecycle operations for authenticating to routeur.ai.
      name: api-keys
