> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fiddler.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Get evaluator cost roll-ups

> Returns a paginated list of per-evaluator LLM cost and token-usage
totals for the requested time window.

**Data source.** All figures are sourced from Fiddler's evaluator cost
pipeline, which aggregates LLM call records hourly. Results are
pre-aggregated totals for the requested window; individual call-level
records are not returned by this endpoint.

**What appears in `items[]`.** Only evaluator rules that have made at
least one billable LLM call within the requested window appear.
Non-LLM-backed evaluators (embedding, PII detection, FTL trust models,
etc.) never write cost rows and are silently absent — omission is
semantically distinct from a zero. Deleted rules are included with
both `evaluator_rule_id` and `evaluator_rule_name` null (cost is a
spend ledger; deletion does not retract it).

**`cost_usd_estimated`.** Present on every item; `null` when unpriced
(provider did not return pricing information). A `null` value is not
the same as zero.

**UTC-hour snapping.** Cost data is collected at hourly boundaries, so
`start_time` is snapped down to the containing UTC hour and `end_time`
is snapped up. The effective, snapped window is echoed back in
`data.meta.time_range`.

**RBAC.** Org Admins see every application in the organization.
All other callers see only applications in projects they can read
(`APPLICATION: READ`, held by Project Admin, Writer, and Viewer roles).
A caller with no project access receives an empty `200` for any
well-formed `project_id` or `application_id`, including unknown and
cross-organization ones — the access filter runs before the ID check.
An unknown or cross-organization ID for a caller who **can** read
projects returns `400` — not `403` — to avoid acting as an existence
oracle. A same-organization ID the caller cannot read returns an empty
`200`; a malformed ID is still `400`.

**Availability.** The endpoint returns `503` when the evaluator cost
feature is not enabled on your Fiddler instance. Contact your Fiddler
Customer Success Manager if you receive this status.




## OpenAPI

````yaml GET /v3/cost/evaluators
openapi: 3.0.3
info:
  title: Fiddler API - 2.0
  description: APIs to interact with Fiddler
  termsOfService: https://fiddler.ai/about/terms
  contact:
    email: support@fiddler.ai
  license:
    name: Proprietary
    url: '2.0'
  version: '2.0'
servers: []
security:
  - BearerAuth: []
tags:
  - name: access-key
    description: CRUD operations for API keys
  - name: span-v3
  - name: aggregation-invalidation-request-v3
    description: Endpoints related to retrieving aggregation invalidation requests
  - name: alert-rules-v3
    description: CRUD for Alert Rules, Summary, and Stats APIs
  - name: application-v3
  - name: auth
    description: Authentication strategies and login flows
  - name: baseline-v3
    description: CRUD for baseline
  - name: catalog-v3
    description: >-
      Entity catalog provides paginated, searchable discovery of entity names
      (attribute keys, agent names, span types, span names, score names,
      evaluator config names) and their distinct values. Powered by ClickHouse
      materialized views — no worker or PostgreSQL dependency.
  - name: chart-annotation-v3
    description: Endpoints related to retrieving chart annotations
  - name: chart-v3
    description: CRUD for chart
  - name: queries-v3
    description: v3 queries API
  - name: configuration-v3
    description: CRUD for configurations
  - name: cost-evaluators-v3
    description: >
      Paginated roll-up of per-evaluator LLM cost and token usage, aggregated
      hourly. Available only on deployments with evaluator cost reporting
      enabled.
  - name: custom-metrics-v3
  - name: dimensionality-reduction-v3
  - name: environment-v3
    description: Endpoints related to environment management
  - name: evals
  - name: datasets
  - name: evaluation-v3
  - name: evaluator-v3
  - name: rule-evaluators-v3
  - name: experiment-v3
  - name: explainability-v3
  - name: llm_rca-v3
  - name: file-upload
    description: Endpoints related to file uploading.
  - name: fql-expressions-v3
    description: >
      Endpoints for listing FQL (Fiddler Query Language) functions available for
      GenAI custom metrics. Used by the frontend for autocomplete and signature
      hints in the FQL editor.
  - name: genai-alert-rules-v3
    description: CRUD API for GenAI Alert Rules
  - name: genai-custom-metrics-v3
    description: API for GenAI Custom Metrics
  - name: genai-metrics-v3
    description: >-
      Endpoints for pre-aggregated GenAI metrics. All metric data is
      pre-aggregated hourly by a Celery-based metric collector; no real-time
      aggregation is performed at request time.
  - name: guardrails-api
    description: Endpoints related to retrieving Guardrails specific data
  - name: ingestion-v3
  - name: intercom-api
    description: Endpoints related to intercom APIs
  - name: jobs-v3
  - name: llm-gateway-v3
  - name: auth-login
  - name: auth-logout
  - name: mcp-client-setup-v3
    description: Endpoints for retrieving MCP client setup instructions.
  - name: metrics-v3
    description: Metrics endpoints
  - name: model-v3
  - name: dashboard-v3
  - name: model-deployment-v3
  - name: monitoring-summary-v3
  - name: histograms-v3
  - name: organization-roles-v3
    description: Update user org role
  - name: organization-settings-v3
    description: Update organization settings such as timezone, email configuration, etc.
  - name: pagerduty-api
    description: CRUD for Pagerduty services.
  - name: project-v3
  - name: project-roles-v3
    description: Project role assignment management
  - name: scores-v3
    description: Unified CRUD for scores and annotations
  - name: searchable-text-key-v3
    description: >-
      Manage the global searchable text keys table that controls which OTel
      attribute keys are routed to the full-text-searchable `ValueContent`
      column in the unified attributes table. Changes propagate to the backing
      ClickHouse dictionary within 1-2 minutes and affect all tenants.
  - name: segments-v3
  - name: semantic-mapping-v3
    description: >-
      Manage the global semantic name mappings table that maps raw OTel
      attribute keys to canonical semantic concepts. Changes propagate to the
      backing ClickHouse dictionary within 1-2 minutes and affect all tenants.
  - name: server-info-v3
    description: Endpoints related to retrieving server information
  - name: service-account
    description: >
      Service accounts and their API keys. A human Org Admin manages the service
      accounts of their own organization: create, read, update, and
      enable/disable (there is no delete — an account is disabled instead), and
      issue, rename, re-date, enable/disable, and revoke each account's API
      keys. An API key is an `fks_` secret that inherits the account's grants
      and cannot manage service accounts; an active, unexpired key must be
      disabled before it can be revoked, and it authenticates only while both it
      and its account are active. Scopes here are capability scopes (what the
      account may do), not OAuth scopes.
  - name: sessions-v3
    description: v3 session APIs
  - name: team-roles-v3
  - name: team-v3
  - name: traces-v3
    description: v3 trace api for monitoring
  - name: fetch-sessions-v3
    description: v3 fetch sessions api for monitoring
  - name: user-access-key
    description: >
      CRUD operations for user API keys. All endpoints are user-scoped — each
      user can only operate on their own API keys. No one including Org admins
      have access to other users' API keys.
  - name: users-v3
  - name: version-compatibility-v3
  - name: webhooks
externalDocs:
  url: https://docs.fiddler.ai
  description: Find out more about Fiddler
paths:
  /v3/cost/evaluators:
    get:
      tags:
        - cost-evaluators-v3
      summary: Get evaluator cost roll-ups
      description: |
        Returns a paginated list of per-evaluator LLM cost and token-usage
        totals for the requested time window.

        **Data source.** All figures are sourced from Fiddler's evaluator cost
        pipeline, which aggregates LLM call records hourly. Results are
        pre-aggregated totals for the requested window; individual call-level
        records are not returned by this endpoint.

        **What appears in `items[]`.** Only evaluator rules that have made at
        least one billable LLM call within the requested window appear.
        Non-LLM-backed evaluators (embedding, PII detection, FTL trust models,
        etc.) never write cost rows and are silently absent — omission is
        semantically distinct from a zero. Deleted rules are included with
        both `evaluator_rule_id` and `evaluator_rule_name` null (cost is a
        spend ledger; deletion does not retract it).

        **`cost_usd_estimated`.** Present on every item; `null` when unpriced
        (provider did not return pricing information). A `null` value is not
        the same as zero.

        **UTC-hour snapping.** Cost data is collected at hourly boundaries, so
        `start_time` is snapped down to the containing UTC hour and `end_time`
        is snapped up. The effective, snapped window is echoed back in
        `data.meta.time_range`.

        **RBAC.** Org Admins see every application in the organization.
        All other callers see only applications in projects they can read
        (`APPLICATION: READ`, held by Project Admin, Writer, and Viewer roles).
        A caller with no project access receives an empty `200` for any
        well-formed `project_id` or `application_id`, including unknown and
        cross-organization ones — the access filter runs before the ID check.
        An unknown or cross-organization ID for a caller who **can** read
        projects returns `400` — not `403` — to avoid acting as an existence
        oracle. A same-organization ID the caller cannot read returns an empty
        `200`; a malformed ID is still `400`.

        **Availability.** The endpoint returns `503` when the evaluator cost
        feature is not enabled on your Fiddler instance. Contact your Fiddler
        Customer Success Manager if you receive this status.
      operationId: getCostEvaluatorsV3
      parameters:
        - $ref: '#/components/parameters/cost_evaluators_start_time'
        - $ref: '#/components/parameters/cost_evaluators_end_time'
        - $ref: '#/components/parameters/cost_evaluators_group_by'
        - $ref: '#/components/parameters/cost_evaluators_project_id'
        - $ref: '#/components/parameters/cost_evaluators_application_id'
        - $ref: '#/components/parameters/cost_evaluators_limit'
        - $ref: '#/components/parameters/offset'
      responses:
        '200':
          description: >
            Paginated evaluator cost items for the requested window. Returns an
            empty `items` array (not an error) when there is no data or the
            caller has no authorized applications.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PaginatedApiResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/EvaluatorCostsResponse'
                    required:
                      - data
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '429':
          $ref: '#/components/responses/429'
        '500':
          $ref: '#/components/responses/500'
        '503':
          $ref: '#/components/responses/503'
        '504':
          $ref: '#/components/responses/504'
      x-codeSamples:
        - lang: shell
          label: curl — default (last 30 days)
          source: |
            curl -sS "$FIDDLER_URL/v3/cost/evaluators" \
              -H "Authorization: Bearer $FIDDLER_TOKEN" \
              | jq '.data'
        - lang: shell
          label: curl — explicit window, per-rule breakdown
          source: |
            # Use -G with --data-urlencode: ISO 8601 timestamps contain colons
            # that must be percent-encoded in query strings.
            curl -sS -G "$FIDDLER_URL/v3/cost/evaluators" \
              -H "Authorization: Bearer $FIDDLER_TOKEN" \
              --data-urlencode "start_time=2026-08-01T00:00:00Z" \
              --data-urlencode "end_time=2026-09-01T00:00:00Z" \
              --data-urlencode "group_by=both" \
              --data-urlencode "limit=100" \
              | jq -r '.data.items[]
                  | "\(.application_name // "-")\t\(.evaluator_rule_name // "(deleted)")\t\(if .cost_usd_estimated == null then "unpriced" else "$\(.cost_usd_estimated)" end)\t\(if .tokens.total == null then "? tok" else "\(.tokens.total) tok" end)"'
        - lang: shell
          label: curl — one application's spend
          source: |
            # Pick the costliest application of the last 30 days, then drill in.
            APPLICATION_ID=$(curl -sS -G "$FIDDLER_URL/v3/cost/evaluators" \
              -H "Authorization: Bearer $FIDDLER_TOKEN" \
              --data-urlencode "group_by=application_id" \
              --data-urlencode "limit=1" \
              | jq -r '.data.items[0].application_id')

            curl -sS -G "$FIDDLER_URL/v3/cost/evaluators" \
              -H "Authorization: Bearer $FIDDLER_TOKEN" \
              --data-urlencode "application_id=$APPLICATION_ID" \
              | jq -r '.error.message // (.data.items[]
                  | "\(.evaluator_rule_name // "(deleted)")\t\(if .cost_usd_estimated == null then "unpriced" else "$\(.cost_usd_estimated)" end)")'
        - lang: python
          label: Python (requests) — explicit window, project totals
          source: >
            import os

            import requests


            url = os.environ.get("FIDDLER_URL")

            token = os.environ.get("FIDDLER_TOKEN")

            if not url or not token:
                raise SystemExit("Set both FIDDLER_URL and FIDDLER_TOKEN environment variables.")

            # Fetch per-project cost totals for August 2026.

            resp = requests.get(
                f"{url}/v3/cost/evaluators",
                headers={"Authorization": f"Bearer {token}"},
                params={
                    "start_time": "2026-08-01T00:00:00Z",
                    "end_time": "2026-09-01T00:00:00Z",
                    "group_by": "project_id",
                    "limit": 500,
                },
                timeout=30,
            )

            resp.raise_for_status()

            body = resp.json()


            meta = body["data"]["meta"]

            print(f"Window queried : {meta['time_range']['start']} →
            {meta['time_range']['end']}")

            print(f"Earliest data  : {meta['earliest_available_data']}")

            print()


            for item in body["data"]["items"]:
                cost = item["cost_usd_estimated"]
                cost_str = f"${cost:.4f}" if cost is not None else "unpriced"
                print(f"{item['project_name']:30s}  {cost_str}")
components:
  parameters:
    cost_evaluators_start_time:
      name: start_time
      in: query
      description: >
        Inclusive lower bound, ISO 8601 with timezone offset or `Z` (a naive
        timestamp returns `400`). Defaults to `end_time − 30 days` when omitted.
        Snapped down to the containing UTC hour before querying. A range longer
        than 366 days returns `400`. Either bound may be supplied alone.
      required: false
      schema:
        type: string
        format: date-time
    cost_evaluators_end_time:
      name: end_time
      in: query
      description: >
        Exclusive upper bound, ISO 8601 with timezone offset or `Z` (a naive
        timestamp returns `400`). Defaults to now (UTC) when omitted. Snapped up
        to the next UTC hour boundary before querying. The current partial hour
        is always empty — cost rows are written at the close of each hour.
        `start_time >= end_time` returns `400`.
      required: false
      schema:
        type: string
        format: date-time
    cost_evaluators_group_by:
      name: group_by
      in: query
      description: |
        Controls the grouping granularity of `items[]`. One of:

        - `both` *(default)* — one item per (application, evaluator rule).
        - `application_id` — one item per application, costs summed across
          all evaluator rules in that application.
        - `project_id` — one item per project, costs summed across all
          applications and evaluator rules in that project.
      required: false
      schema:
        type: string
        default: both
        enum:
          - project_id
          - application_id
          - both
    cost_evaluators_project_id:
      name: project_id
      in: query
      description: >
        Filter results to a single project. A project in your organization that
        you cannot read returns an empty `200`. An unknown or other-organization
        ID returns `400`, except for a caller who can read no projects, who gets
        an empty `200` for any well-formed ID.
      required: false
      schema:
        type: string
        format: uuid
    cost_evaluators_application_id:
      name: application_id
      in: query
      description: >
        Filter results to a single application. An application in your
        organization that you cannot read returns an empty `200`. An unknown or
        other-organization ID returns `400`, except for a caller who can read no
        projects, who gets an empty `200` for any well-formed ID.
      required: false
      schema:
        type: string
        format: uuid
    cost_evaluators_limit:
      name: limit
      in: query
      description: >
        Page size. Defaults to 100. Maximum 500 — requests above 500 return
        `400`.
      required: false
      schema:
        type: integer
        default: 100
        maximum: 500
        minimum: 1
    offset:
      name: offset
      in: query
      description: Offset for the pagination
      required: false
      schema:
        type: integer
  schemas:
    PaginatedApiResponse:
      type: object
      description: |
        Response object for paginated API responses.
      properties:
        api_version:
          type: string
          default: '3.0'
          enum:
            - '2.0'
            - '3.0'
          description: |
            API version of the response.
        kind:
          type: string
          default: PAGINATED
          enum:
            - PAGINATED
          description: |
            Type of response, indicating a paginated response.
        data:
          type: object
          properties:
            page_size:
              type: integer
              default: 10
              example: 10
              description: |
                Number of items per page in the response.
            item_count:
              type: integer
              default: 10
              example: 10
              description: |
                Number of items in the current page.
            total:
              type: integer
              example: 100
              default: 100
              description: |
                Total number of items across all pages.
            page_count:
              type: integer
              default: 10
              example: 10
              description: |
                Total number of pages.
            page_index:
              type: integer
              default: 1
              example: 1
              description: |
                Current page index.
            offset:
              type: integer
              default: 0
              example: 0
              description: |
                Offset of the first item in the current page.
    EvaluatorCostsResponse:
      type: object
      description: >
        Paginated evaluator cost roll-up. Extends the standard
        `PaginatedApiResponse` data envelope with an `items` array and a `meta`
        block.
      required:
        - items
        - meta
      properties:
        items:
          type: array
          description: >
            Evaluator cost items for the requested window, ordered by descending
            `cost_usd_estimated` (nulls last), then by `application_name`, then
            by `evaluator_rule_name`, then by `project_id`, `application_id`,
            and an internal tiebreaker that is stable across pages but not
            exposed in the response. The trailing three fields are the grouping
            key, so the order is total in every `group_by` mode and page
            boundaries are stable under offset pagination. `application_id` is
            null only when `group_by` is `project_id`; `evaluator_rule_id` is
            null when `group_by` collapses rules or when the rule has been
            deleted. A null `evaluator_rule_name` sorts as an empty string, so
            at equal cost and application a deleted rule sorts before named
            rules. Empty when no cost data exists for the window or the caller
            has no authorized applications.
          items:
            $ref: '#/components/schemas/EvaluatorCostItem'
        meta:
          $ref: '#/components/schemas/EvaluatorCostsMeta'
    EvaluatorCostItem:
      type: object
      description: >
        Cost and token-usage roll-up for one (application, evaluator rule) pair
        — or a project- or application-level aggregate when `group_by` is
        `project_id` or `application_id`.
      required:
        - project_id
        - project_name
        - application_id
        - application_name
        - application_creator
        - evaluator_rule_id
        - evaluator_rule_name
        - tokens
        - cost_usd_estimated
      properties:
        project_id:
          type: string
          format: uuid
          description: UUID of the project this application belongs to.
        project_name:
          type: string
          description: Name of the project.
          example: my-genai-project
        application_id:
          type: string
          format: uuid
          nullable: true
          description: >
            UUID of the GenAI application. `null` when `group_by` is
            `project_id` (cost is aggregated across all applications in the
            project; there is no single application to reference).
        application_name:
          type: string
          nullable: true
          description: >
            Name of the GenAI application. `null` when `group_by` is
            `project_id`.
          example: my-assistant
        application_creator:
          allOf:
            - $ref: '#/components/schemas/UserCompact'
          nullable: true
          description: >
            Creator of the application. `null` when `group_by` is `project_id`
            (multiple applications are aggregated; there is no single creator).
        evaluator_rule_id:
          type: string
          format: uuid
          nullable: true
          description: >
            UUID of the evaluator rule. `null` when `group_by` is `project_id`
            or `application_id` (cost is aggregated across all rules), or when
            the rule has been deleted (cost rows survive deletion as a spend
            ledger, but the rule id can no longer be resolved — deleted rules
            produce the same null as rules collapsed by group_by).
        evaluator_rule_name:
          type: string
          nullable: true
          description: >
            Name of the evaluator rule. `null` when the rule has been deleted
            (cost rows survive deletion as a spend ledger) or when `group_by`
            collapses multiple rules.
          example: faithfulness-judge
        tokens:
          $ref: '#/components/schemas/EvaluatorCostTokens'
        cost_usd_estimated:
          type: number
          format: double
          nullable: true
          description: >
            Estimated cost in USD for this evaluator rule in the requested
            window. Always present — `null` when the provider did not return
            pricing information (not the same as zero).
          example: 0.0034
    EvaluatorCostsMeta:
      type: object
      description: >
        Response-level metadata about the queried window and data availability.
        Always present, even when `items` is empty.
      required:
        - time_range
        - earliest_available_data
        - disclaimer
      properties:
        time_range:
          $ref: '#/components/schemas/EvaluatorCostsTimeRange'
        earliest_available_data:
          type: string
          format: date-time
          nullable: true
          description: >
            UTC timestamp of the earliest cost record available across the
            applications in scope for this request — the caller's authorized
            applications, further narrowed by `project_id` and `application_id`
            when either is supplied. It is an organization-wide value only for
            an Org Admin issuing an unfiltered request; two callers in the same
            organization can legitimately see different values. `null` when no
            cost data exists for that scope. Clients can compare the requested
            window against this value to distinguish "partial data" from "no
            data in range".
          example: '2026-07-01T00:00:00Z'
        disclaimer:
          type: string
          description: |
            Human-readable disclaimer about cost estimation accuracy.
          example: >
            Cost estimates are based on LiteLLM open-source pricing tables, may
            lag provider changes, and should not be treated as exact billing.
    ErrorResponse:
      type: object
      description: |
        Response object for errors returned by the API.
      properties:
        api_version:
          type: string
          default: '3.0'
          enum:
            - '2.0'
            - '3.0'
          description: |
            API version of the response.
        kind:
          type: string
          default: ERROR
          enum:
            - ERROR
          description: |
            Type of response, usually indicating an error.
        error:
          type: object
          properties:
            code:
              type: integer
              format: int32
              description: >
                Represents the code for this error, typically an HTTP response
                code.
              default: 400
              enum:
                - 400
                - 401
                - 403
                - 404
                - 409
                - 410
                - 422
                - 429
                - 500
                - 501
                - 503
            message:
              type: string
              description: >
                A human-readable message providing more details about the error.
                If there are multiple errors, it will be the message for the
                first error.
              example: Resource Not Found
            errors:
              type: array
              description: >
                Container for additional information regarding the error,
                especially for multiple errors.
              items:
                type: object
                properties:
                  reason:
                    type: string
                    description: >
                      Unique identifier for this error, different from the error
                      code.
                    example: ResourceNotFoundException
                  message:
                    type: string
                    description: >
                      A human-readable message providing more details about the
                      error. If there is only one error, this field will match
                      error.message.
                    example: Resource Not Found
                  help:
                    type: string
                    description: >
                      Link to support or documentation providing more
                      information on the error.
    UserCompact:
      type: object
      title: UserCompactV3
      description: >
        Compact version of a user which can be included in the response of
        relevant APIs.
      required:
        - id
        - email
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: |
            Unique identifier for the user.
        full_name:
          type: string
          readOnly: true
          description: |
            Full name of the user.
        email:
          type: string
          format: email
          description: |
            Email address of the user.
    EvaluatorCostTokens:
      type: object
      description: >
        Token counts for one evaluator rule in the requested window. Each field
        is nullable because the enrichment pipeline skips any count the provider
        did not report — `null` is not the same as zero (a zero means the
        provider reported zero tokens; `null` means the count was not provided
        and cannot be inferred).
      required:
        - input
        - output
        - total
      properties:
        input:
          type: integer
          nullable: true
          description: >
            Total input tokens consumed by this evaluator rule in the window.
            `null` when the provider did not report this count.
          example: 12400
        output:
          type: integer
          nullable: true
          description: >
            Total output tokens produced by this evaluator rule in the window.
            `null` when the provider did not report this count.
          example: 3100
        total:
          type: integer
          nullable: true
          description: >
            Total tokens (input + output) for this evaluator rule in the window.
            `null` when the provider did not report this count.
          example: 15500
    EvaluatorCostsTimeRange:
      type: object
      description: >
        The effective, UTC-hour-snapped time window actually queried.
        `start_time` is snapped down to the containing UTC hour; `end_time` is
        snapped up to the next hour boundary. Echoed back so callers can
        distinguish a partial window from an empty one by comparing against
        `earliest_available_data`.
      required:
        - start
        - end
      properties:
        start:
          type: string
          format: date-time
          description: |
            Effective (snapped) inclusive lower bound, ISO 8601 UTC.
          example: '2026-08-01T00:00:00Z'
        end:
          type: string
          format: date-time
          description: |
            Effective (snapped) exclusive upper bound, ISO 8601 UTC.
          example: '2026-09-01T00:00:00Z'
  responses:
    '400':
      description: Bad Request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    '401':
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    '429':
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait before retrying
        X-RateLimit-Limit:
          schema:
            type: string
          description: Rate limit policy
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Remaining requests in current window
        X-RateLimit-Reset:
          schema:
            type: integer
          description: Unix timestamp when the rate limit resets
    '500':
      description: Internal Server Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    '503':
      description: Upstream connect error or disconnect/reset before headers
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    '504':
      description: Gateway Timeout — upstream read exceeded the server-side deadline
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer

````