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

# Chat Compare

> Send one conversation to several models at once and get their answers together.

Pass 2–10 model ids in `models` with the usual `messages`. They run in parallel and
each result carries its own content, token usage and latency, so you can compare
quality against cost on real traffic instead of guessing.

Set `comparison_model` to have a further model judge the answers, optionally steered
by `comparison_instructions`. Use `model_overrides` when one model needs different
parameters from the rest; `temperature` and `max_tokens` otherwise apply to all.
With `stream` true, results arrive as they finish rather than after the slowest.

**Every model in the list is a billed call**, so a comparison across five models
costs five completions plus the judge, and one model failing does not fail the
request — that result reports its own error.



## OpenAPI

````yaml /api/openapi.json post /v1/chat/compare
openapi: 3.1.0
info:
  title: MeshAPI
  description: One key, all AI models.
  version: 0.1.0
servers:
  - url: https://api.meshapi.ai
security:
  - BearerAuth: []
paths:
  /v1/chat/compare:
    post:
      tags:
        - Chat
      summary: Chat Compare
      description: >-
        Send one conversation to several models at once and get their answers
        together.


        Pass 2–10 model ids in `models` with the usual `messages`. They run in
        parallel and

        each result carries its own content, token usage and latency, so you can
        compare

        quality against cost on real traffic instead of guessing.


        Set `comparison_model` to have a further model judge the answers,
        optionally steered

        by `comparison_instructions`. Use `model_overrides` when one model needs
        different

        parameters from the rest; `temperature` and `max_tokens` otherwise apply
        to all.

        With `stream` true, results arrive as they finish rather than after the
        slowest.


        **Every model in the list is a billed call**, so a comparison across
        five models

        costs five completions plus the judge, and one model failing does not
        fail the

        request — that result reports its own error.
      operationId: chat_compare
      parameters:
        - in: header
          name: X-Mesh-Version
          required: false
          schema:
            type: string
            enum:
              - 2026-08
            default: 2026-08
          example: 2026-08
          description: >-
            Dated version of the API contract to pin this request to. Omit it
            and the request is served under `2026-08` — the oldest supported
            version, so an existing integration is never moved by a release. A
            malformed or unsupported value is rejected with `400
            invalid_api_version` rather than falling back silently. The version
            actually served is echoed as `X-Mesh-Version` on every response,
            including errors.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompareRequest'
            examples:
              default:
                summary: Example request
                value:
                  models:
                    - openai/gpt-4o-mini
                    - anthropic/claude-haiku-4.5
                  messages:
                    - role: user
                      content: Explain TCP vs UDP in two sentences.
                  comparison_model: openai/gpt-4o-mini
      responses:
        '200':
          description: >-
            Per-model results plus an optional synthesized comparison (JSON), or
            an SSE stream when stream=true
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompareResponse'
              example:
                comparison_id: cmp_01ARZ3NDEKTSV4RRFFQ6
                object: compare.completion
                created: 1748331628
                models:
                  - openai/gpt-4o-mini
                  - anthropic/claude-haiku-4.5
                  - google/gemini-3-flash-preview
                results:
                  - model: openai/gpt-4o-mini
                    response_body:
                      id: chatcmpl-DrTNOwFsT3v79HmQwOwMgEM2IbWJl
                      object: chat.completion
                      created: 1748331628
                      model: gpt-4o-mini-2024-07-18
                      choices:
                        - index: 0
                          message:
                            role: assistant
                            content: >-
                              TCP is a connection-oriented protocol that
                              guarantees ordered, reliable delivery; UDP is
                              connectionless and sends datagrams without
                              delivery or ordering guarantees.
                          finish_reason: stop
                      usage:
                        prompt_tokens: 24
                        completion_tokens: 47
                        total_tokens: 71
                    content: >-
                      TCP is a connection-oriented protocol that guarantees
                      ordered, reliable delivery; UDP is connectionless and
                      sends datagrams without delivery or ordering guarantees.
                    latency_ms: 812
                    usage:
                      prompt_tokens: 24
                      completion_tokens: 47
                      total_tokens: 71
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV::openai/gpt-4o-mini
                  - model: anthropic/claude-haiku-4.5
                    response_body:
                      id: chatcmpl-019ed1d24b0371a390ab
                      object: chat.completion
                      model: anthropic/claude-haiku-4.5
                      choices:
                        - index: 0
                          message:
                            role: assistant
                            content: >-
                              TCP establishes a connection and guarantees
                              ordered, intact delivery. UDP fires packets
                              without a connection, trading reliability for
                              lower latency.
                          finish_reason: stop
                      usage:
                        prompt_tokens: 24
                        completion_tokens: 52
                        total_tokens: 76
                    content: >-
                      TCP establishes a connection and guarantees ordered,
                      intact delivery. UDP fires packets without a connection,
                      trading reliability for lower latency.
                    latency_ms: 650
                    usage:
                      prompt_tokens: 24
                      completion_tokens: 52
                      total_tokens: 76
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV::anthropic/claude-haiku-4.5
                  - model: google/gemini-3-flash-preview
                    latency_ms: 0
                    error: Upstream provider returned an error.
                    error_code: upstream_error
                    request_id: >-
                      req_01ARZ3NDEKTSV4RRFFQ69G5FAV::google/gemini-3-flash-preview
                comparison: >-
                  Both answers are correct. Claude's phrasing is slightly
                  clearer on the latency trade-off; GPT-4o-mini is more precise
                  on ordering guarantees.
                comparison_model: openai/gpt-4o-mini
                comparison_usage:
                  prompt_tokens: 180
                  completion_tokens: 60
                  total_tokens: 240
                comparison_fallback_used: false
                total_latency_ms: 1340
                partial: true
                skip_comparison: false
            text/event-stream:
              example: >+
                event: meta

                data:
                {"comparison_id":"cmp_01ARZ3NDEKTSV4RRFFQ6","models":["openai/gpt-4o-mini","anthropic/claude-haiku-4.5"],"comparison_model":"openai/gpt-4o-mini","skip_comparison":false}


                event: model_chunk

                data: {"model":"openai/gpt-4o-mini","delta":"TCP is
                connection-oriented...","latency_ms":812,"error":null,"error_code":null,"usage":{"prompt_tokens":24,"completion_tokens":47}}


                event: model_done

                data: {"results":[...]}


                event: comparison_chunk

                data: {"delta":"Both answers are
                correct...","finish_reason":null}


                event: done

                data:
                {"comparison_id":"cmp_01ARZ3NDEKTSV4RRFFQ6","total_latency_ms":1340,"partial":false,"comparison_model":"openai/gpt-4o-mini","comparison_fallback_used":false}

        '401':
          description: Missing or invalid API key
          content:
            application/json:
              example:
                error:
                  code: unauthorized
                  message: Invalid or missing API key.
                request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '402':
          description: Insufficient balance or spend cap reached
          content:
            application/json:
              examples:
                spend_cap_reached:
                  summary: Per-key spend cap reached
                  value:
                    error:
                      code: spend_limit_exceeded
                      message: >-
                        Spend cap of $10.0000 reached. Current spend: $10.0023.
                        Contact your administrator to increase the cap.
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
                no_balance:
                  summary: Insufficient credit balance
                  value:
                    error:
                      code: spend_limit_exceeded
                      message: >-
                        Insufficient balance. Top up your account to use paid
                        models.
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: API key is suspended
          content:
            application/json:
              example:
                error:
                  code: forbidden
                  message: API key is suspended.
                request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: Request validation failed
          content:
            application/json:
              example:
                error:
                  code: validation_error
                  message: Request validation failed.
                  details:
                    - type: missing
                      loc:
                        - body
                        - model
                      msg: Field required
                request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limit exceeded (RPM or RPD)
          content:
            application/json:
              examples:
                rpm_exceeded:
                  summary: Requests-per-minute limit hit
                  value:
                    error:
                      code: rate_limit_exceeded
                      message: RPM limit of 60 req/min exceeded.
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
                rpd_exceeded:
                  summary: Requests-per-day limit hit
                  value:
                    error:
                      code: rate_limit_exceeded
                      message: RPD limit of 1000 req/day exceeded.
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Upstream provider error or gateway timeout
          content:
            application/json:
              examples:
                upstream_error:
                  summary: Upstream provider returned an error
                  value:
                    error:
                      code: upstream_error
                      message: Upstream provider returned an error.
                      upstream_detail: >-
                        {"error":{"message":"No endpoints found that match your
                        data policy","code":400}}
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
                gateway_timeout:
                  summary: Upstream timed out
                  value:
                    error:
                      code: gateway_timeout
                      message: Upstream provider did not respond in time.
                    request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
                internal_error:
                  summary: >-
                    Internal platform error (DB failure — FastAPI default
                    format)
                  value:
                    detail: Internal Server Error
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '502':
          description: Upstream provider error
          content:
            application/json:
              example:
                error:
                  code: upstream_error
                  message: Upstream provider returned an error.
                request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: >-
            Upstream provider not available — required credentials not
            configured on this server
          content:
            application/json:
              example:
                error:
                  code: provider_not_available
                  message: >-
                    Provider 'vertex' is not available. The required credentials
                    may not be configured on this server.
                request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - BearerAuth: []
components:
  schemas:
    CompareRequest:
      properties:
        models:
          items:
            type: string
          type: array
          maxItems: 10
          minItems: 1
          title: Models
        messages:
          items:
            $ref: '#/components/schemas/Message'
          type: array
          title: Messages
        model_overrides:
          anyOf:
            - items:
                $ref: '#/components/schemas/ModelOverride'
              type: array
            - type: 'null'
          title: Model Overrides
        comparison_model:
          anyOf:
            - type: string
            - type: 'null'
          title: Comparison Model
        comparison_instructions:
          anyOf:
            - type: string
            - type: 'null'
          title: Comparison Instructions
        temperature:
          anyOf:
            - type: number
              maximum: 2
              minimum: 0
            - type: 'null'
          title: Temperature
        max_tokens:
          anyOf:
            - type: integer
              minimum: 1
            - type: 'null'
          title: Max Tokens
        stream:
          type: boolean
          title: Stream
          default: false
        template:
          anyOf:
            - type: string
            - type: 'null'
          title: Template
        variables:
          anyOf:
            - additionalProperties:
                type: string
              type: object
            - type: 'null'
          title: Variables
        skip_comparison:
          type: boolean
          title: Skip Comparison
          default: false
        cache:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Cache
      type: object
      required:
        - models
        - messages
      title: CompareRequest
      example:
        comparison_instructions: Rank the answers by clarity and correctness.
        messages:
          - content: Explain the difference between TCP and UDP in two sentences.
            role: user
        models:
          - openai/gpt-4o-mini
          - anthropic/claude-haiku-4.5
          - google/gemini-3-flash-preview
    CompareResponse:
      properties:
        comparison_id:
          type: string
          title: Comparison Id
          description: Unique ID for this comparison (`cmp_...`).
        object:
          type: string
          const: compare.completion
          title: Object
          default: compare.completion
        created:
          type: integer
          title: Created
          description: Unix timestamp (seconds) when the response was produced.
        models:
          items:
            type: string
          type: array
          title: Models
          description: Models that were compared, in request order (deduped).
        results:
          items:
            $ref: '#/components/schemas/ModelCompareResult'
          type: array
          title: Results
          description: Per-model results, in `models` order.
        comparison:
          anyOf:
            - type: string
            - type: 'null'
          title: Comparison
          description: >-
            Synthesized evaluation of all responses from the comparison LLM.
            Null when `skip_comparison` is true or fewer than two models
            succeeded.
        comparison_model:
          anyOf:
            - type: string
            - type: 'null'
          title: Comparison Model
          description: Model that produced `comparison`. Null when no synthesis ran.
        comparison_usage:
          anyOf:
            - $ref: '#/components/schemas/TokenUsage'
            - type: 'null'
          description: Token usage for the comparison LLM call.
        comparison_fallback_used:
          type: boolean
          title: Comparison Fallback Used
          description: >-
            True if the primary comparison model failed and a fallback produced
            the synthesis.
          default: false
        total_latency_ms:
          type: integer
          title: Total Latency Ms
          description: End-to-end latency for the whole compare request, in milliseconds.
        partial:
          type: boolean
          title: Partial
          description: True if at least one model in `results` returned an error.
          default: false
        skip_comparison:
          type: boolean
          title: Skip Comparison
          description: Echoes whether the comparison LLM step was skipped.
          default: false
      type: object
      required:
        - comparison_id
        - created
        - models
        - results
        - total_latency_ms
      title: CompareResponse
      example:
        comparison: Both answers are correct; Response 1 is more precise on ordering.
        comparison_fallback_used: false
        comparison_id: cmp_019ed1d24227774dba14
        comparison_model: openai/gpt-4o-mini
        comparison_usage:
          completion_tokens: 405
          prompt_tokens: 245
          total_tokens: 650
        created: 1781636687
        models:
          - openai/gpt-4o-mini
          - anthropic/claude-haiku-4.5
        object: compare.completion
        partial: false
        results:
          - content: TCP is a connection-oriented protocol...
            latency_ms: 812
            model: openai/gpt-4o-mini
            request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV::openai/gpt-4o-mini
            response_body:
              choices:
                - finish_reason: stop
                  index: 0
                  message:
                    content: TCP is a connection-oriented protocol...
                    role: assistant
              id: chatcmpl-DrTNOwFsT3v79HmQwOwMgEM2IbWJl
              model: gpt-4o-mini-2024-07-18
              object: chat.completion
              usage:
                completion_tokens: 47
                prompt_tokens: 24
                total_tokens: 71
            usage:
              completion_tokens: 47
              prompt_tokens: 24
              total_tokens: 71
          - content: >-
              TCP establishes a connection and guarantees ordered, intact
              delivery. UDP fires packets without a connection, trading
              reliability for lower latency.
            latency_ms: 650
            model: anthropic/claude-haiku-4.5
            request_id: req_01ARZ3NDEKTSV4RRFFQ69G5FAV::anthropic/claude-haiku-4.5
            response_body:
              choices:
                - finish_reason: stop
                  index: 0
                  message:
                    content: >-
                      TCP establishes a connection and guarantees ordered,
                      intact delivery. UDP fires packets without a connection,
                      trading reliability for lower latency.
                    role: assistant
              id: chatcmpl-019ed1d24b0371a390ab
              model: anthropic/claude-haiku-4.5
              object: chat.completion
              usage:
                completion_tokens: 52
                prompt_tokens: 24
                total_tokens: 76
            usage:
              completion_tokens: 52
              prompt_tokens: 24
              total_tokens: 76
        skip_comparison: false
        total_latency_ms: 9016
    ErrorEnvelope:
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
        request_id:
          type: string
          title: Request Id
          default: ''
      type: object
      required:
        - error
      title: ErrorEnvelope
    Message:
      properties:
        role:
          type: string
          enum:
            - system
            - user
            - assistant
            - tool
          title: Role
        content:
          anyOf:
            - type: string
            - items:
                $ref: '#/components/schemas/ContentPart'
              type: array
            - type: 'null'
          title: Content
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
        tool_call_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Tool Call Id
        tool_calls:
          anyOf:
            - items:
                $ref: '#/components/schemas/ToolCall'
              type: array
            - type: 'null'
          title: Tool Calls
        reasoning_details:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          title: Reasoning Details
        cache_control:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Cache Control
      type: object
      required:
        - role
      title: Message
    ModelOverride:
      properties:
        model:
          type: string
          title: Model
        temperature:
          anyOf:
            - type: number
              maximum: 2
              minimum: 0
            - type: 'null'
          title: Temperature
        max_tokens:
          anyOf:
            - type: integer
              minimum: 1
            - type: 'null'
          title: Max Tokens
        system_prompt:
          anyOf:
            - type: string
            - type: 'null'
          title: System Prompt
      type: object
      required:
        - model
      title: ModelOverride
      description: >-
        Per-model parameter overrides applied on top of the request-level
        defaults.
    ModelCompareResult:
      properties:
        model:
          type: string
          title: Model
          description: Model ID this result is for.
        response_body:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Response Body
          description: >-
            Full upstream chat-completion response (raw provider body, including
            `choices` and `usage`). Null when the call failed.
        content:
          anyOf:
            - type: string
            - type: 'null'
          title: Content
          description: >-
            Assistant message text extracted from `response_body`. Null on
            error.
        latency_ms:
          type: integer
          title: Latency Ms
          description: Wall-clock latency for this model's call, in milliseconds.
        error:
          anyOf:
            - type: string
            - type: 'null'
          title: Error
          description: Human-readable error message when the call failed, else null.
        error_code:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Code
          description: Machine-readable error code when the call failed, else null.
        usage:
          anyOf:
            - $ref: '#/components/schemas/TokenUsage'
            - type: 'null'
          description: Token usage for this model's call.
        request_id:
          type: string
          title: Request Id
          description: Per-model sub-request ID (`<request_id>::<model>`).
      type: object
      required:
        - model
        - latency_ms
        - request_id
      title: ModelCompareResult
      description: Outcome of a single fan-out model call.
    TokenUsage:
      properties:
        prompt_tokens:
          anyOf:
            - type: integer
            - type: 'null'
          title: Prompt Tokens
        completion_tokens:
          anyOf:
            - type: integer
            - type: 'null'
          title: Completion Tokens
        total_tokens:
          anyOf:
            - type: integer
            - type: 'null'
          title: Total Tokens
      type: object
      title: TokenUsage
    ErrorDetail:
      properties:
        code:
          type: string
          title: Code
        message:
          type: string
          title: Message
        param:
          anyOf:
            - type: string
            - type: 'null'
          title: Param
        details:
          anyOf:
            - items: {}
              type: array
            - type: 'null'
          title: Details
        provider_error:
          anyOf:
            - $ref: '#/components/schemas/ProviderError'
            - type: 'null'
        retry_after_seconds:
          anyOf:
            - type: integer
            - type: 'null'
          title: Retry After Seconds
      type: object
      required:
        - code
        - message
      title: ErrorDetail
    ContentPart:
      properties:
        type:
          type: string
          enum:
            - text
            - image_url
            - video_url
            - input_audio
          title: Type
        text:
          anyOf:
            - type: string
            - type: 'null'
          title: Text
        image_url:
          anyOf:
            - $ref: '#/components/schemas/ImageUrl'
            - type: 'null'
        video_url:
          anyOf:
            - $ref: '#/components/schemas/VideoUrl'
            - type: 'null'
        input_audio:
          anyOf:
            - $ref: '#/components/schemas/InputAudio'
            - type: 'null'
        fps:
          anyOf:
            - type: string
            - type: 'null'
          title: Fps
        cache_control:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Cache Control
      type: object
      required:
        - type
      title: ContentPart
    ToolCall:
      properties:
        id:
          type: string
          title: Id
        type:
          type: string
          const: function
          title: Type
          default: function
        function:
          additionalProperties: true
          type: object
          title: Function
        thought_signature:
          anyOf:
            - type: string
            - type: 'null'
          title: Thought Signature
      type: object
      required:
        - id
        - function
      title: ToolCall
    ProviderError:
      properties:
        provider:
          type: string
          title: Provider
        status:
          anyOf:
            - type: integer
            - type: 'null'
          title: Status
        message:
          anyOf:
            - type: string
            - type: 'null'
          title: Message
      type: object
      required:
        - provider
      title: ProviderError
      description: Upstream provider error forwarded for debugging.
    ImageUrl:
      properties:
        url:
          type: string
          title: Url
        detail:
          type: string
          enum:
            - auto
            - low
            - high
          title: Detail
          default: auto
      type: object
      required:
        - url
      title: ImageUrl
    VideoUrl:
      properties:
        url:
          type: string
          title: Url
      type: object
      required:
        - url
      title: VideoUrl
    InputAudio:
      properties:
        data:
          anyOf:
            - type: string
            - type: 'null'
          title: Data
        uri:
          anyOf:
            - type: string
            - type: 'null'
          title: Uri
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
        format:
          type: string
          enum:
            - wav
            - mp3
            - aiff
            - aac
            - ogg
            - flac
            - m4a
            - pcm16
            - pcm24
          title: Format
      type: object
      required:
        - format
      title: InputAudio
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Enter your MeshAPI key (`rsk_...`) — sent as `Authorization: Bearer
        <key>`.

````