{
  "openapi": "3.1.1",
  "info": {
    "title": "Dialt HTTP API",
    "version": "1.0.0",
    "description": "Use the HTTP API to create session keys, retrieve transcripts and audio, and manage evals.\n\nSend requests to https://api.dialt.com/v1 with an API key in the `Authorization: Bearer <api_key>` header. Keep API keys on your backend; use short-lived session keys in browser SDKs.\n\nFollow the next link to get more results from paginated lists. For live conversations, see the [Realtime API](https://dialt.com/docs/api/reference/realtime/)."
  },
  "servers": [
    {
      "url": "https://api.dialt.com",
      "description": "Production Bearer-authenticated HTTP API"
    },
    {
      "url": "https://api.dev.dialt.com",
      "description": "Shared development Bearer-authenticated HTTP API"
    }
  ],
  "paths": {
    "/v1/session-keys": {
      "post": {
        "operationId": "createSessionKey",
        "summary": "Create a scoped realtime session credential",
        "description": "Exchange a backend-held persistent API key for a short-lived realtime credential bound to one client-selected session_id. The credential cannot authorize HTTP API operations. This route returns 404 on the app origin.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Scoped realtime session credential created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionKeyResponse"
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "private, no-store"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionKeyRequest"
              }
            }
          }
        }
      }
    },
    "/v1/voices": {
      "get": {
        "operationId": "listVoices",
        "summary": "List available regional and designed voices",
        "description": "Public stock voice catalog; not paginated. Availability is deployment-specific. Regional choices are us_female (shared default), us_male, british_male, british_female, mexican_female and brazilian_female. British Female and Mexican Spanish Female retain their keys with new identities. southern_us_female is accepted as an alias of us_female (Southern US to general US English accent); brazilian_male is accepted as an alias of brazilian_female (male to female, including feminine self-reference). Aliases are absent as duplicate picker options. Irish Male (classic), Chime, Servo, Circuit, Arabic voices and provisional Hinglish Male retain their identities. The voice route is independent of Dialt Fast or Dialt Smart. Regional voices use language or region plus gender as their display name and stable lower-snake-case keys. Provider library names, model identifiers and provider voice IDs are never included. Migration: https://dialt.com/docs/api/websocket/#voice-catalogue",
        "security": [
          {
            "bearerAuth": []
          },
          {}
        ],
        "responses": {
          "200": {
            "description": "Available voice catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoiceRoster"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        }
      }
    },
    "/v1/sessions": {
      "get": {
        "operationId": "listSessions",
        "summary": "List logical sessions",
        "description": "List account-owned logical calls, one entry per session. Descending original session started_at, then ascending logical UUID. Follow next verbatim. Late ingestion and edits can change membership during traversal.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Logical session page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "session_id",
            "schema": {
              "type": "string"
            },
            "description": "Exact account-scoped match against any identified child segment correlation ID. Matching does not alter the parent representation; a reused correlation may return multiple logical calls."
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            },
            "description": "Opaque signed continuation token from next. Do not decode or construct it. Bound to account, route, surface/origin, filters, ordering and limit; not an authorization grant. Malformed or mismatched cursors return 400."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Maximum results per response; preserve it while following a cursor."
          }
        ]
      }
    },
    "/v1/sessions/{uuid}": {
      "get": {
        "operationId": "getSession",
        "summary": "Get a logical session",
        "description": "Identify one logical call by its stable session UUID, including across successful resumes or transfers. Follow segments_url only when recorded portion details are needed.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Logical session details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/sessions/{uuid}/segments": {
      "get": {
        "operationId": "listSegments",
        "summary": "List session segments",
        "description": "List recorded portions of an account-owned session. Ascending segment started_at, then ascending segment UUID. Segment boundaries do not identify reconnects or infrastructure placement. Follow next verbatim. Late ingestion and edits can change membership during traversal.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Session segment page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SegmentPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            },
            "description": "Opaque signed continuation token from next. Do not decode or construct it. Bound to account, route, surface/origin, filters, ordering and limit; not an authorization grant. Malformed or mismatched cursors return 400."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Maximum results per response; preserve it while following a cursor."
          }
        ]
      }
    },
    "/v1/sessions/{uuid}/segments/{segment_uuid}": {
      "get": {
        "operationId": "getSegment",
        "summary": "Get a session segment",
        "description": "Read a recorded portion and its transcript, timings and available artifacts. The segment must belong to the specified session and account.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Segment details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SegmentDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "path",
            "name": "segment_uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/sessions/{uuid}/segments/{segment_uuid}/artifacts/{name}": {
      "get": {
        "operationId": "getSegmentArtifact",
        "summary": "Download a session segment audio track",
        "description": "Download an available microphone (mic) or assistant audio track via a 302 redirect. Both tracks are mono, with sample zero at segment time zero; sample rates may differ. Tracks are lossless FLAC or PCM16 WAV: use the names in the segment's artifacts list. The signed URL expires after 10 minutes; request a fresh redirect for each download and do not forward Dialt Authorization to storage. Set download=1 for an attachment named after the artifact; omit for inline playback. Redirects are private, no-store. Missing, unowned, unshipped and expired artifacts return the same 404. A fresh URL does not extend audio retention.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the signed audio URL (also returned as {\"url\": ...}).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArtifactRedirect"
                }
              }
            },
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "private, no-store"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "path",
            "name": "segment_uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "mic.flac",
                "assistant.flac",
                "mic.wav",
                "assistant.wav"
              ]
            }
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "description": "Set to 1 to sign an attachment response with the artifact filename; omit for inline playback.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ]
      }
    },
    "/v1/evals/cases": {
      "get": {
        "operationId": "listCases",
        "summary": "List eval cases",
        "description": "List account-owned eval cases. Descending created_at, then ascending UUID; renaming does not change order. Follow next verbatim. Late ingestion and edits can change membership during traversal.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval case page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalCasePage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            },
            "description": "Opaque signed continuation token from next. Do not decode or construct it. Bound to account, route, surface/origin, filters, ordering and limit; not an authorization grant. Malformed or mismatched cursors return 400."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Maximum results per response; preserve it while following a cursor."
          }
        ]
      },
      "post": {
        "operationId": "createCase",
        "summary": "Create an eval case",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Eval case created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalCase"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "409": {
            "$ref": "#/components/responses/409"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvalCaseRequest"
              }
            }
          }
        },
        "description": "Create an account-owned case for reuse in eval runs. Case names are unique per account: a duplicate name returns 409 with the existing case ID in error.details.existing_id. Send an Idempotency-Key header to retry safely.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]{1,128}$",
              "description": "Account-scoped retry key. Identical JSON request content returns the original case instead of creating another; different content returns 409, as does a replay after that case was deleted. Object-key order is ignored. Reuse the same key after a lost response; use a new key for a new case."
            }
          }
        ]
      }
    },
    "/v1/evals/cases/{uuid}": {
      "get": {
        "operationId": "getCase",
        "summary": "Get an eval case",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval case details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalCase"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Return an account-owned case."
      },
      "put": {
        "operationId": "replaceCase",
        "summary": "Replace an eval case",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval case replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalCase"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "409": {
            "$ref": "#/components/responses/409"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvalCaseRequest"
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Replace the case definition. Existing runs retain their case snapshots."
      },
      "delete": {
        "operationId": "deleteCase",
        "summary": "Delete an eval case",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Delete an account-owned case. Existing run snapshots remain available."
      }
    },
    "/v1/evals/suites": {
      "get": {
        "operationId": "listSuites",
        "summary": "List eval suites",
        "description": "List account-owned eval suites. Descending created_at, then ascending UUID; renaming does not change order. Follow next verbatim. Late ingestion and edits can change membership during traversal.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval suite page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalSuitePage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            },
            "description": "Opaque signed continuation token from next. Do not decode or construct it. Bound to account, route, surface/origin, filters, ordering and limit; not an authorization grant. Malformed or mismatched cursors return 400."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Maximum results per response; preserve it while following a cursor."
          }
        ]
      },
      "post": {
        "operationId": "createSuite",
        "summary": "Create an eval suite",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Eval suite created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalSuite"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "409": {
            "$ref": "#/components/responses/409"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvalSuiteRequest"
              }
            }
          }
        },
        "description": "Create an account-owned suite from account-owned cases. Suite names are unique per account: a duplicate name returns 409 with the existing suite ID in error.details.existing_id. Send an Idempotency-Key header to retry safely.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]{1,128}$",
              "description": "Account-scoped retry key. Identical JSON request content returns the original suite instead of creating another; different content returns 409, as does a replay after that suite was deleted. Object-key order is ignored. Reuse the same key after a lost response; use a new key for a new suite."
            }
          }
        ]
      }
    },
    "/v1/evals/suites/{uuid}": {
      "get": {
        "operationId": "getSuite",
        "summary": "Get an eval suite",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval suite details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalSuite"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Return an account-owned suite and its case references."
      },
      "put": {
        "operationId": "replaceSuite",
        "summary": "Replace an eval suite",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval suite replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalSuite"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "409": {
            "$ref": "#/components/responses/409"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvalSuiteRequest"
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Replace the suite definition and case membership. Existing runs retain their snapshots."
      },
      "delete": {
        "operationId": "deleteSuite",
        "summary": "Delete an eval suite",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Delete an account-owned suite without deleting its cases or existing runs."
      }
    },
    "/v1/evals/targets": {
      "get": {
        "operationId": "listEvalTargets",
        "summary": "List available eval targets",
        "description": "Unpaginated catalog. Availability depends on feature configuration and provider credentials; external comparisons have additional mode and billing constraints.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Available eval targets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalTargets"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        }
      }
    },
    "/v1/evals/starter": {
      "post": {
        "operationId": "ensureStarterSuite",
        "summary": "Ensure the starter eval suite",
        "description": "Creates the starter suite once; returns existing suite on repeats.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Starter eval suite created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalSuite"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "415": {
            "$ref": "#/components/responses/415"
          },
          "200": {
            "description": "Existing starter suite",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalSuite"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyRequest"
              }
            }
          }
        }
      }
    },
    "/v1/evals/runs": {
      "get": {
        "operationId": "listRuns",
        "summary": "List eval runs",
        "description": "List account-owned eval runs. Descending created_at, then ascending UUID. Follow next verbatim. Late ingestion and edits can change membership during traversal.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval run page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalRunPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "suite_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter runs created from this account-owned suite UUID."
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            },
            "description": "Opaque signed continuation token from next. Do not decode or construct it. Bound to account, route, surface/origin, filters, ordering and limit; not an authorization grant. Malformed or mismatched cursors return 400."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Maximum results per response; preserve it while following a cursor."
          }
        ]
      },
      "post": {
        "operationId": "createRun",
        "summary": "Create an eval run",
        "description": "Exactly one of suite_id and case_ids. External targets require enabled/configured providers, hosted execution, an explicit modality, supported tool/fixture subset and at most 40 total attempts; each target publishes what it supports in capabilities on GET /v1/evals/targets. Send dry_run: true to check the whole case-by-target matrix first: it returns every problem at once, or the plan with its warnings and the max_external_charge_micros to accept, and creates nothing. Send an idempotency_key (or Idempotency-Key header) to retry safely after an ambiguous timeout. Both Live targets also run in text, where the caller turn is sent as text and the reply is the transcript of the audio the model generated.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "dry_run: the run passed preflight. Nothing was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalRunPlan"
                }
              }
            }
          },
          "201": {
            "description": "Eval run created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalRunDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "402": {
            "$ref": "#/components/responses/402"
          },
          "415": {
            "$ref": "#/components/responses/415"
          },
          "409": {
            "description": "The retry key was already used with different request content.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvalRunRequest"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional alternative to the body idempotency_key. If both are supplied they must match.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]{1,128}$",
              "description": "Account-scoped retry key. Identical JSON request content replays the original run; different content returns 409. Object-key order is ignored; array order and explicit defaults are significant. Retained for the lifetime of the run. Reuse the same key after a lost response; use a new key for a new run."
            }
          }
        ]
      }
    },
    "/v1/evals/runs/{uuid}": {
      "get": {
        "operationId": "getRun",
        "summary": "Get an eval run",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval run details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalRunDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Return an account-owned run, including attempt results and progress."
      },
      "delete": {
        "operationId": "deleteRun",
        "summary": "Delete a finished eval run",
        "description": "Delete an account-owned terminal run and its attempt results. Queued or running runs, or runs with unfinished attempts, return 409: cancel and wait for completion first. Missing or already deleted runs return 404. Preserves cases, suites, session recordings and billing history; outstanding terminal credit holds are settled. Creation idempotency keys survive deletion and replay returns 409.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Run and attempt results deleted."
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "409": {
            "$ref": "#/components/responses/409"
          }
        }
      }
    },
    "/v1/evals/runs/{uuid}/cancel": {
      "post": {
        "operationId": "cancelRun",
        "summary": "Request eval run cancellation",
        "description": "Cancellation is a request, not proof every in-flight action or charge stopped. Queued/local runs become cancelled; running hosted runs set cancel_requested. Terminal/repeated requests preserve terminal state and settlement is idempotent.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval run cancellation state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalRunDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyRequest"
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/evals/runs/{uuid}/report": {
      "post": {
        "operationId": "submitLocalReport",
        "summary": "Submit a local eval report",
        "description": "Local runs only; JSON payload at most 2 MB. Idempotency key scoped to run: reusing it with the same normalized evidence returns the existing report; changed evidence returns 409. A different key for an already terminal attempt conflicts. Correlation session IDs are not logical UUIDs.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Eval report accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvalAttempt"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "409": {
            "$ref": "#/components/responses/409"
          },
          "415": {
            "$ref": "#/components/responses/415"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvalReportRequest"
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "uuid",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/sessions/stats": {
      "get": {
        "operationId": "getSessionStats",
        "summary": "Aggregate session statistics",
        "description": "Totals over the account's recorded session segments: session count, call time, turns, response times and per-stage timings, plus a per-day series. The same numbers the dashboard's Analytics card shows. Counts are per recorded segment; a resumed call contributes one segment per connection. Recording-aligned response times and event-clock estimates are reported separately and never pooled. Without from/to the totals are unbounded and the per-day series covers the last 90 days.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "from",
            "schema": {
              "type": "string"
            },
            "description": "Include segments started at or after this UTC date (YYYY-MM-DD) or ISO 8601 datetime."
          },
          {
            "in": "query",
            "name": "to",
            "schema": {
              "type": "string"
            },
            "description": "Include segments started at or before this UTC date (whole day) or ISO 8601 datetime. Defaults to now."
          }
        ],
        "responses": {
          "200": {
            "description": "Aggregates for the account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionStats"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "405": {
            "$ref": "#/components/responses/405"
          },
          "429": {
            "$ref": "#/components/responses/429"
          },
          "500": {
            "$ref": "#/components/responses/500"
          },
          "502": {
            "$ref": "#/components/responses/502"
          },
          "503": {
            "$ref": "#/components/responses/503"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Persistent Dialt API key beginning dk_. Existing ck_ keys remain valid. Keep it on your server."
      }
    },
    "schemas": {
      "SessionId": {
        "type": "string",
        "pattern": "^[A-Za-z0-9_-][A-Za-z0-9._-]{0,63}$",
        "minLength": 1,
        "maxLength": 64
      },
      "SessionKeyRequest": {
        "type": "object",
        "required": [
          "session_id"
        ],
        "properties": {
          "session_id": {
            "$ref": "#/components/schemas/SessionId"
          }
        },
        "additionalProperties": false
      },
      "SessionKeyResponse": {
        "type": "object",
        "required": [
          "api_key",
          "session_id",
          "expires_in"
        ],
        "properties": {
          "api_key": {
            "type": "string",
            "description": "Short-lived credential for the matching session_id."
          },
          "session_id": {
            "$ref": "#/components/schemas/SessionId"
          },
          "expires_in": {
            "type": "integer",
            "minimum": 1,
            "description": "Credential lifetime in seconds."
          }
        }
      },
      "Voice": {
        "type": "object",
        "required": [
          "key",
          "name",
          "kind",
          "descriptor",
          "language"
        ],
        "properties": {
          "key": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "regional",
              "designed"
            ]
          },
          "descriptor": {
            "type": "string",
            "description": "Display context such as additional regional context; may be empty."
          },
          "language": {
            "type": "string",
            "description": "BCP-47 primary language tag for the voice's synthesis language."
          }
        }
      },
      "VoiceRoster": {
        "type": "object",
        "required": [
          "voices",
          "default"
        ],
        "properties": {
          "voices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Voice"
            }
          },
          "default": {
            "type": "string"
          },
          "aliases": {
            "type": "object",
            "description": "Accepted migration keys mapped to selectable canonical keys. Display the effective voice when resolving an alias; aliases are not additional voices.",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "authentication_failed",
                  "permission_denied",
                  "not_found",
                  "method_not_allowed",
                  "invalid_request",
                  "unsupported_media_type",
                  "insufficient_credit",
                  "conflict",
                  "server_error",
                  "throttled"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": true,
                "description": "Optional validation details; human wording is not a branching contract."
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "ResponseTime": {
        "type": "object",
        "description": "Estimated response-time statistics for this session segment, in milliseconds: last partial speech-recognition result to first assistant audio sent. This is not forced-alignment conversation latency. The containing response_ms field is null when no qualifying turn exists.",
        "properties": {
          "n": {
            "type": "integer"
          },
          "mean": {
            "type": "number"
          },
          "p50": {
            "type": "number"
          },
          "max": {
            "type": "number"
          }
        },
        "required": [
          "n",
          "mean",
          "p50",
          "max"
        ]
      },
      "TranscriptEntry": {
        "type": "object",
        "required": [
          "role",
          "text"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant"
            ]
          },
          "t": {
            "type": [
              "number",
              "null"
            ],
            "description": "Seconds from segment start."
          },
          "text": {
            "type": "string",
            "description": "User: the final transcript of the turn. Assistant: what was actually spoken; a barge-in leaves a trailing [interrupted] marker."
          },
          "turn_id": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "User turns only, and only when the input was not voice (e.g. text)."
          },
          "response_ms": {
            "type": "number",
            "description": "Assistant turns only: this turn's response time (see ResponseTime)."
          },
          "interrupted": {
            "type": "boolean",
            "description": "Assistant turns only: the user barged in."
          },
          "welcome": {
            "type": "boolean",
            "description": "Assistant turns only: the session greeting."
          },
          "start_t": {
            "type": "number",
            "description": "Timeline anchor in seconds from session-segment start: speech onset for voice user turns, first audio sent for assistant turns. Omitted when unavailable; not a measurement of client playback."
          },
          "kind": {
            "type": "string",
            "enum": [
              "backchannel",
              "tool_call",
              "unfinished"
            ],
            "description": "backchannel (user): an absorbed acknowledgement that did not start a turn. tool_call (assistant): an action the assistant took; see tool, args, outcome, result; text is empty. unfinished (assistant): a reply that started but the record ended before its words were final and no barge cut it; text is empty."
          },
          "stages_ms": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            },
            "description": "Assistant turns only: the recorder's per-stage event-clock timings for this reply (asr, brain, ttft, ttfa, tts_connect), diagnostics that decompose response_ms."
          },
          "call_id": {
            "type": "string"
          },
          "tool": {
            "type": "string"
          },
          "args": {
            "type": "object"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "succeeded",
              "failed",
              "cancelled",
              "unknown"
            ]
          },
          "result": {
            "type": "string",
            "description": "Bounded rendering of the tool result (500 characters)."
          },
          "interruption_ms": {
            "type": "number",
            "description": "Interrupted assistant turns only: caller onset to playback stopped, event clock."
          },
          "managed": {
            "type": "boolean",
            "description": "tool_call entries: true for platform tools the assistant runs itself (web_search, end_call, ...)."
          }
        }
      },
      "SessionPage": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Session"
            },
            "maxItems": 100
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Follow this URL verbatim; null when traversal is exhausted."
          },
          "has_more": {
            "type": "boolean"
          }
        },
        "required": [
          "results",
          "next",
          "has_more"
        ],
        "description": "A live cursor page ordered by original session started_at descending, then session UUID ascending. next is null exactly when has_more is false.",
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "has_more": {
                  "const": false
                }
              }
            },
            "then": {
              "properties": {
                "next": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "next": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        ]
      },
      "StageTimeStat": {
        "type": "object",
        "properties": {
          "n": {
            "type": "integer"
          },
          "mean": {
            "type": "number"
          },
          "p50": {
            "type": "number"
          },
          "max": {
            "type": "number"
          }
        }
      },
      "Segment": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Stable identifier of this session segment, distinct from its parent session UUID."
          },
          "session_id": {
            "type": "string",
            "description": "Client-selected correlation ID, separate from server UUID; reused IDs do not establish membership."
          },
          "attempt": {
            "type": "integer",
            "description": "Connection attempt metadata; never used to infer logical session membership."
          },
          "provider": {
            "type": "string"
          },
          "modality": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "text",
              "voice",
              null
            ],
            "description": "How the conversation ran: `voice` (recorded audio) or `text` (text turns only, so there is no audio recording). Null for sessions recorded before this was kept."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "Start of this recorded portion; its transcript and audio timelines are relative to this segment, not to the logical session start."
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "duration_s": {
            "type": [
              "number",
              "null"
            ]
          },
          "turn_count": {
            "type": "integer"
          },
          "interrupted": {
            "type": [
              "integer",
              "null"
            ],
            "description": "How many assistant turns the user interrupted."
          },
          "truncated": {
            "type": "boolean",
            "description": "An audio track reached its recording limit; the session segment and transcript may continue beyond the captured audio."
          },
          "response_ms": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ResponseTime"
              },
              {
                "type": "null"
              }
            ]
          },
          "artifacts": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mic.flac",
                "assistant.flac",
                "mic.wav",
                "assistant.wav"
              ]
            },
            "description": "Available microphone (mic) and assistant audio tracks, in lossless FLAC or PCM16 WAV format. Both are mono and begin at segment time zero; sample rates may differ. Use these names rather than constructing filenames. Expired tracks and tracks that captured no audio are omitted."
          },
          "session_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID of the parent logical session."
          },
          "aligned_response_ms": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AlignedResponseTime"
              },
              {
                "type": "null"
              }
            ]
          },
          "brain": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recorded Dialt tier (fast or smart; genius on sessions recorded before that tier was retired), or null when unavailable. Logical sessions use the earliest segment; segments carry their own recorded values."
          },
          "actor_role": {
            "type": [
              "string",
              "null"
            ],
            "description": "eval_caller identifies a simulated caller. Null when not recorded or not applicable."
          }
        },
        "required": [
          "uuid",
          "session_id",
          "attempt",
          "provider",
          "modality",
          "started_at",
          "ended_at",
          "duration_s",
          "turn_count",
          "interrupted",
          "truncated",
          "response_ms",
          "artifacts",
          "session_uuid",
          "aligned_response_ms",
          "brain",
          "actor_role"
        ],
        "description": "A session segment is a recorded portion of a logical call with its own timeline, transcript and available artifacts. It can contain many turns and need not contain audio. It is distinct from a transcript or ASR segment. Segment boundaries do not guarantee a mapping to reconnects, transfers or servers; identify the call by its session UUID."
      },
      "SegmentDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Stable identifier of this session segment, distinct from its parent session UUID."
          },
          "session_id": {
            "type": "string",
            "description": "Client-selected correlation ID, separate from server UUID; reused IDs do not establish membership."
          },
          "attempt": {
            "type": "integer",
            "description": "Connection attempt metadata; never used to infer logical session membership."
          },
          "provider": {
            "type": "string"
          },
          "modality": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "text",
              "voice",
              null
            ],
            "description": "How the conversation ran: `voice` (recorded audio) or `text` (text turns only, so there is no audio recording). Null for sessions recorded before this was kept."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "Start of this recorded portion; its transcript and audio timelines are relative to this segment, not to the logical session start."
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "duration_s": {
            "type": [
              "number",
              "null"
            ]
          },
          "turn_count": {
            "type": "integer"
          },
          "interrupted": {
            "type": [
              "integer",
              "null"
            ],
            "description": "How many assistant turns the user interrupted."
          },
          "truncated": {
            "type": "boolean",
            "description": "An audio track reached its recording limit; the session segment and transcript may continue beyond the captured audio."
          },
          "response_ms": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ResponseTime"
              },
              {
                "type": "null"
              }
            ]
          },
          "artifacts": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mic.flac",
                "assistant.flac",
                "mic.wav",
                "assistant.wav"
              ]
            },
            "description": "Available microphone (mic) and assistant audio tracks, in lossless FLAC or PCM16 WAV format. Both are mono and begin at segment time zero; sample rates may differ. Use these names rather than constructing filenames. Expired tracks and tracks that captured no audio are omitted."
          },
          "session_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID of the parent logical session."
          },
          "mic_audio_s": {
            "type": [
              "number",
              "null"
            ],
            "description": "Recorded microphone audio duration in seconds; not a speech-only measure. Null if unavailable."
          },
          "assistant_audio_s": {
            "type": [
              "number",
              "null"
            ],
            "description": "Recorded assistant audio duration in seconds; not confirmation of client playback. Null if unavailable."
          },
          "transcript": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranscriptEntry"
            },
            "description": "In time order. Empty when no turn completed."
          },
          "stage_times_ms": {
            "type": "object",
            "description": "Processing-time statistics for this session segment, in milliseconds. These are server measurements, not forced-alignment conversation latency.",
            "properties": {
              "asr": {
                "$ref": "#/components/schemas/StageTimeStat"
              },
              "brain": {
                "$ref": "#/components/schemas/StageTimeStat"
              },
              "ttft": {
                "$ref": "#/components/schemas/StageTimeStat"
              },
              "ttfa": {
                "$ref": "#/components/schemas/StageTimeStat"
              },
              "tts_connect": {
                "$ref": "#/components/schemas/StageTimeStat"
              }
            }
          },
          "playable_audio": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mic.flac",
                "assistant.flac",
                "mic.wav",
                "assistant.wav"
              ]
            },
            "description": "Subset of artifacts suitable for a player. Tracks that captured no audio are neither listed nor served."
          },
          "policy_history": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PolicyHistory"
              },
              {
                "type": "null"
              }
            ]
          },
          "aligned_response_ms": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AlignedResponseTime"
              },
              {
                "type": "null"
              }
            ]
          },
          "metrics": {
            "$ref": "#/components/schemas/SessionMetrics"
          },
          "brain": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recorded Dialt tier (fast or smart; genius on sessions recorded before that tier was retired), or null when unavailable. Logical sessions use the earliest segment; segments carry their own recorded values."
          },
          "actor_role": {
            "type": [
              "string",
              "null"
            ],
            "description": "eval_caller identifies a simulated caller. Null when not recorded or not applicable."
          }
        },
        "required": [
          "uuid",
          "session_id",
          "attempt",
          "provider",
          "modality",
          "started_at",
          "ended_at",
          "duration_s",
          "turn_count",
          "interrupted",
          "truncated",
          "response_ms",
          "artifacts",
          "session_uuid",
          "mic_audio_s",
          "assistant_audio_s",
          "transcript",
          "stage_times_ms",
          "playable_audio",
          "policy_history",
          "aligned_response_ms",
          "metrics",
          "brain",
          "actor_role"
        ],
        "description": "A session segment is a recorded portion of a logical call with its own timeline, transcript and available artifacts. It can contain many turns and need not contain audio. It is distinct from a transcript or ASR segment. Segment boundaries do not guarantee a mapping to reconnects, transfers or servers; identify the call by its session UUID."
      },
      "Session": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "session_id": {
            "type": "string",
            "description": "Correlation ID of the earliest currently ingested segment by segment start time then UUID. A successful resume may change the child correlation ID; earlier late ingestion can change this representative field, never the logical UUID or original start time."
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "modality": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "text",
              "voice",
              null
            ],
            "description": "How the conversation ran, taken from its earliest segment: `voice` (recorded audio) or `text` (text turns only, so there is no audio recording). Null for sessions recorded before this was kept."
          },
          "segments_url": {
            "type": "string",
            "format": "uri"
          },
          "brain": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recorded Dialt tier (fast or smart; genius on sessions recorded before that tier was retired), or null when unavailable. Logical sessions use the earliest segment; segments carry their own recorded values."
          },
          "actor_role": {
            "type": [
              "string",
              "null"
            ],
            "description": "eval_caller identifies a simulated caller. Null when not recorded or not applicable."
          }
        },
        "required": [
          "uuid",
          "session_id",
          "started_at",
          "modality",
          "segments_url",
          "brain",
          "actor_role"
        ],
        "description": "Primary resource for one account-owned logical call across successful resumes or transfers. started_at is the original call start, not ingestion time. The resource becomes available after its first session segment is ingested; earlier requests may return 404. Historical records without known parentage remain in browser history but are excluded from logical-session resources. Follow segments_url for transcripts, timings and artifacts. No session-completeness flag, combined transcript, aggregate duration or audio export is currently provided."
      },
      "SegmentPage": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Segment"
            },
            "maxItems": 100
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Follow this URL verbatim; null when traversal is exhausted."
          },
          "has_more": {
            "type": "boolean"
          }
        },
        "required": [
          "results",
          "next",
          "has_more"
        ],
        "description": "A live cursor page ordered by segment started_at ascending, then segment UUID ascending. next is null exactly when has_more is false.",
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "has_more": {
                  "const": false
                }
              }
            },
            "then": {
              "properties": {
                "next": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "next": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        ]
      },
      "ArtifactRedirect": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "url"
        ],
        "description": "Short-lived signed audio URL, valid for 10 minutes. Fetch without forwarding Dialt Authorization. Audio retention is independent and defaults to 90 days; requesting a fresh URL does not extend it."
      },
      "EvalCaseRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "target": {
            "$ref": "#/components/schemas/EvalTargetMode",
            "required": [
              "instructions"
            ],
            "properties": {
              "instructions": {
                "type": "string",
                "minLength": 1,
                "pattern": "\\S"
              }
            }
          },
          "simulator": {
            "$ref": "#/components/schemas/EvalSimulatorMode",
            "required": [
              "instructions"
            ],
            "properties": {
              "instructions": {
                "type": "string",
                "minLength": 1,
                "pattern": "\\S"
              }
            }
          },
          "starter": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 300
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalCheck"
            },
            "minItems": 0,
            "maxItems": 100,
            "description": "Check the declared contract. Prefer deterministic checks for tool names/arguments and stored fields; reserve judges for meaning or order. See https://dialt.com/docs/api/evals/#case-contract."
          },
          "fixtures": {
            "type": "object",
            "additionalProperties": true,
            "description": "Tool-name to fixture mapping. Supply realistic results for each callable tool, including failures. A request receipt does not confirm a booking or completed action."
          },
          "limits": {
            "type": "object",
            "properties": {
              "max_turns": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "default": 20
              },
              "timeout_s": {
                "type": "number",
                "minimum": 10,
                "maximum": 3600,
                "default": 300,
                "description": "Conversation limit in seconds. The default runs on every target; external models accept at most capabilities.limits.timeout_s.max (300) on GET /v1/evals/targets."
              },
              "silence_s": {
                "type": "number",
                "minimum": 5,
                "maximum": 300,
                "default": 30
              }
            },
            "required": [],
            "additionalProperties": false
          }
        },
        "required": [
          "name",
          "target",
          "simulator"
        ],
        "additionalProperties": false,
        "description": "Exactly one nonblank opener: starter (simulated user first) or target.greeting (target first). Both openers are session greetings, capped at 300 characters in text and voice. Simulator tool and greeting options are controlled by the runner. See [evals](https://dialt.com/docs/api/evals/) for check and fixture semantics.",
        "oneOf": [
          {
            "required": [
              "starter"
            ],
            "properties": {
              "starter": {
                "type": "string",
                "pattern": "\\S"
              }
            },
            "not": {
              "required": [
                "target"
              ],
              "properties": {
                "target": {
                  "required": [
                    "greeting"
                  ],
                  "properties": {
                    "greeting": {
                      "type": "string",
                      "pattern": "\\S"
                    }
                  }
                }
              }
            }
          },
          {
            "required": [
              "target"
            ],
            "properties": {
              "target": {
                "required": [
                  "greeting"
                ],
                "properties": {
                  "greeting": {
                    "type": "string",
                    "pattern": "\\S"
                  }
                }
              },
              "starter": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^\\s*$"
              }
            }
          }
        ]
      },
      "EvalCase": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "target": {
            "$ref": "#/components/schemas/EvalTargetMode"
          },
          "simulator": {
            "$ref": "#/components/schemas/EvalSimulatorMode"
          },
          "starter": {
            "type": "string",
            "maxLength": 300
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalCheck"
            },
            "minItems": 0,
            "maxItems": 100,
            "description": "Check the declared contract. Prefer deterministic checks for tool names/arguments and stored fields; reserve judges for meaning or order. See https://dialt.com/docs/api/evals/#case-contract."
          },
          "fixtures": {
            "type": "object",
            "additionalProperties": true,
            "description": "Tool-name to fixture mapping. Supply realistic results for each callable tool, including failures. A request receipt does not confirm a booking or completed action."
          },
          "limits": {
            "type": "object",
            "properties": {
              "max_turns": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "default": 20
              },
              "timeout_s": {
                "type": "number",
                "minimum": 10,
                "maximum": 3600,
                "default": 300
              },
              "silence_s": {
                "type": "number",
                "minimum": 5,
                "maximum": 300,
                "default": 30
              }
            },
            "required": [],
            "additionalProperties": false
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "playground_url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute app-origin playground URL where the owner can talk to this case's target, playing the simulated caller while the case's fixtures answer tool calls. Requires a signed-in browser session with the case's owner (personal or organization) selected."
          }
        },
        "required": [
          "name",
          "target",
          "simulator",
          "starter",
          "checks",
          "fixtures",
          "limits",
          "id",
          "created_at",
          "updated_at",
          "playground_url"
        ]
      },
      "EvalSuiteRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "description": {
            "type": "string",
            "maxLength": 2000,
            "default": ""
          },
          "case_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "maxItems": 100,
            "default": []
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "EvalSuite": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "description": {
            "type": "string",
            "maxLength": 2000,
            "default": ""
          },
          "case_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "maxItems": 100,
            "default": []
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "name",
          "description",
          "case_ids",
          "id",
          "created_at",
          "updated_at"
        ]
      },
      "EvalRunRequest": {
        "type": "object",
        "properties": {
          "case_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "minItems": 1,
            "maxItems": 100
          },
          "suite_id": {
            "type": "string",
            "format": "uuid"
          },
          "modality": {
            "type": "string",
            "enum": [
              "text",
              "voice"
            ],
            "default": "text"
          },
          "execution": {
            "type": "string",
            "enum": [
              "hosted",
              "local"
            ],
            "default": "hosted"
          },
          "repetitions": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 1
          },
          "targets": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "dialt",
                "dialt-smart",
                "openai-live",
                "gemini-live"
              ]
            },
            "minItems": 1,
            "maxItems": 4,
            "uniqueItems": true,
            "default": [
              "dialt"
            ],
            "description": "Select current target IDs. Retired target IDs are rejected for new runs."
          },
          "max_external_charge_micros": {
            "type": "integer",
            "minimum": 0,
            "description": "Required to create a run with an external target (not with dry_run). Must equal the rate-card cap per external attempt multiplied by the number of external attempts (cases × repetitions × external targets) plus, with replace_unassessable, the external replacements its budget allows (min(max_replacements, external attempts)), in USD microdollars."
          },
          "idempotency_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[!-~]{1,128}$",
            "description": "Account-scoped retry key. Identical JSON request content replays the original run; different content returns 409. Object-key order is ignored; array order and explicit defaults are significant. Retained for the lifetime of the run. Reuse the same key after a lost response; use a new key for a new run."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "Run preflight only. Returns 200 with an EvalRunPlan, or 400 listing every problem (EvalPreflightProblem) in error.details.errors. Creates no run, reserves no credit and records no idempotency_key."
          },
          "replace_unassessable": {
            "type": "boolean",
            "default": false,
            "description": "Hosted runs only. Give an attempt that produced no evidence about the target, and whose cause is attributed to the harness, provider infrastructure or the simulated caller (infrastructure_error, worker_restarted, a harness or simulated caller connection failure, or a simulated caller that broke script), one fresh replacement attempt in the same slot. A passed or failed attempt, a target-side or unattributed failure and an attempt with an established target violation are never replaced. The original stays in the run as spent; run status and scores count the replacement."
          },
          "max_replacements": {
            "type": "integer",
            "minimum": 1,
            "description": "Requires replace_unassessable. Replacements allowed across the run, at most the number of scheduled attempts. Default: a quarter of the scheduled attempts, rounded up. Each slot is replaced at most once."
          }
        },
        "required": [],
        "additionalProperties": false,
        "description": "Exactly one of suite_id and case_ids. dialt-smart requires hosted execution. External targets require enabled/configured providers, hosted execution, an explicit modality, supported tool/fixture subset and at most 40 total attempts; each target publishes what it supports in capabilities on GET /v1/evals/targets. Send dry_run: true to check the whole case-by-target matrix first: it returns every problem at once, or the plan with its warnings and the max_external_charge_micros to accept, and creates nothing. Send an idempotency_key (or Idempotency-Key header) to retry safely after an ambiguous timeout. Both Live targets also run in text, where the caller turn is sent as text and the reply is the transcript of the audio the model generated.",
        "oneOf": [
          {
            "required": [
              "suite_id"
            ],
            "not": {
              "required": [
                "case_ids"
              ]
            }
          },
          {
            "required": [
              "case_ids"
            ],
            "not": {
              "required": [
                "suite_id"
              ]
            }
          }
        ],
        "allOf": [
          {
            "if": {
              "required": [
                "targets"
              ],
              "properties": {
                "targets": {
                  "contains": {
                    "enum": [
                      "openai-live",
                      "gemini-live"
                    ]
                  }
                }
              }
            },
            "then": {
              "required": [
                "modality"
              ],
              "properties": {
                "modality": {
                  "enum": [
                    "text",
                    "voice"
                  ]
                },
                "execution": {
                  "const": "hosted"
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "targets"
              ],
              "properties": {
                "targets": {
                  "contains": {
                    "enum": [
                      "openai-live",
                      "gemini-live"
                    ]
                  }
                }
              },
              "not": {
                "required": [
                  "dry_run"
                ],
                "properties": {
                  "dry_run": {
                    "const": true
                  }
                }
              }
            },
            "then": {
              "required": [
                "max_external_charge_micros"
              ]
            }
          },
          {
            "if": {
              "required": [
                "targets"
              ],
              "properties": {
                "targets": {
                  "contains": {
                    "enum": [
                      "dialt-smart"
                    ]
                  }
                }
              }
            },
            "then": {
              "properties": {
                "execution": {
                  "const": "hosted"
                }
              }
            }
          }
        ]
      },
      "EvalTarget": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "description": "Display label. In a text run, a target with text_output says so, for example `Gemini Live (text: transcribed audio output)`."
          },
          "adapter_version": {
            "type": "integer"
          },
          "modalities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "text",
                "voice"
              ]
            },
            "description": "Run modalities this target accepts. Absent on targets recorded before it was introduced, which ran in voice only."
          },
          "text_output": {
            "type": "string",
            "enum": [
              "transcribed_audio"
            ],
            "description": "Present when the target's text-mode reply is not native text. transcribed_audio: the Live model still synthesises audio in text runs; its reply is the output audio transcript and the audio is discarded."
          },
          "billing": {
            "type": "object",
            "additionalProperties": true,
            "description": "External comparison rate card in USD microdollars; see [evals](https://dialt.com/docs/api/evals/)."
          },
          "brain": {
            "type": "string",
            "enum": [
              "fast",
              "smart",
              "genius"
            ],
            "description": "Brain tier of a Dialt target. Absent for external targets and for dialt, which runs fast. genius appears only on runs made with the retired dialt-genius target."
          }
        },
        "required": [
          "id",
          "label",
          "adapter_version"
        ]
      },
      "EvalTargetAvailability": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "adapter_version": {
            "type": "integer"
          },
          "modalities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "text",
                "voice"
              ]
            },
            "description": "Run modalities this target accepts. Absent on targets recorded before it was introduced, which ran in voice only."
          },
          "text_output": {
            "type": "string",
            "enum": [
              "transcribed_audio"
            ],
            "description": "Present when the target's text-mode reply is not native text. transcribed_audio: the Live model still synthesises audio in text runs; its reply is the output audio transcript and the audio is discarded."
          },
          "billing": {
            "type": "object",
            "additionalProperties": true,
            "description": "External comparison rate card in USD microdollars; see [evals](https://dialt.com/docs/api/evals/). cap_seconds is the billable ceiling per attempt: the case conversation (capabilities.limits.timeout_s) plus the farewell drain and bounded shutdown."
          },
          "capabilities": {
            "$ref": "#/components/schemas/EvalTargetCapabilities"
          },
          "available": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "brain": {
            "type": "string",
            "enum": [
              "fast",
              "smart"
            ],
            "description": "Brain tier of a Dialt target. Absent for external targets and for dialt, which runs fast."
          }
        },
        "required": [
          "id",
          "label",
          "adapter_version",
          "available",
          "reason",
          "capabilities"
        ]
      },
      "EvalTargetCapabilities": {
        "type": "object",
        "description": "What the target runs. Run preflight is derived from this contract.",
        "properties": {
          "executions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "hosted",
                "local"
              ]
            }
          },
          "target_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Case target settings the target runs."
          },
          "tool_fields": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Tool declaration settings the target runs; null means every session tool setting."
          },
          "ignored": {
            "type": "object",
            "description": "Settings with no effect on this target, accepted with a warning. Keyed by target or tool, then setting name; the value is the string any for any value, or the list of accepted values (for example web_search: [false]). Any other unsupported setting fails preflight.",
            "properties": {
              "target": {
                "type": "object",
                "additionalProperties": true
              },
              "tool": {
                "type": "object",
                "additionalProperties": true
              }
            }
          },
          "tool_schema_keywords": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "JSON Schema keywords allowed in tool parameters; null means no restriction."
          },
          "tools_require_fixtures": {
            "type": "boolean",
            "description": "Every tool needs a case fixture of the same name."
          },
          "limits": {
            "type": "object",
            "properties": {
              "timeout_s": {
                "type": "object",
                "properties": {
                  "min": {
                    "type": "number"
                  },
                  "max": {
                    "type": "number"
                  }
                },
                "description": "Accepted case limits.timeout_s, the conversation limit."
              },
              "attempts_per_run": {
                "type": "integer",
                "description": "Maximum attempts in a run that includes this target."
              }
            }
          }
        },
        "required": [
          "executions",
          "target_fields",
          "tool_fields",
          "ignored",
          "tool_schema_keywords",
          "tools_require_fixtures",
          "limits"
        ]
      },
      "EvalPreflightProblem": {
        "type": "object",
        "properties": {
          "target": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target ID, or null for a problem with the case or request itself."
          },
          "case": {
            "type": [
              "string",
              "null"
            ],
            "description": "Case name."
          },
          "field": {
            "type": [
              "string",
              "null"
            ],
            "description": "Path of the offending setting, for example target.tools[0].expected_duration or limits.timeout_s."
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "target",
          "case",
          "field",
          "message"
        ]
      },
      "EvalRunPlan": {
        "type": "object",
        "description": "The run a dry_run request would create.",
        "properties": {
          "valid": {
            "type": "boolean",
            "const": true
          },
          "errors": {
            "type": "array",
            "maxItems": 0,
            "items": {
              "$ref": "#/components/schemas/EvalPreflightProblem"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalPreflightProblem"
            },
            "description": "Ignored settings, recorded on the run when it is created."
          },
          "modality": {
            "type": "string",
            "enum": [
              "text",
              "voice"
            ]
          },
          "execution": {
            "type": "string",
            "enum": [
              "hosted",
              "local"
            ]
          },
          "repetitions": {
            "type": "integer"
          },
          "targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTarget"
            }
          },
          "attempts": {
            "type": "integer"
          },
          "billing": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Rate card for a run with an external target."
          },
          "max_external_charge_micros": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Value to send as max_external_charge_micros when creating the run. Includes the external replacement budget when replace_unassessable is set."
          },
          "replacements": {
            "type": [
              "object",
              "null"
            ],
            "description": "The replacement budget when replace_unassessable is set: per_slot and max_replacements. Null otherwise.",
            "properties": {
              "per_slot": {
                "type": "integer"
              },
              "max_replacements": {
                "type": "integer"
              }
            }
          },
          "credit": {
            "type": [
              "object",
              "null"
            ],
            "description": "For a run with an external target: the credit creation requires (external reservation plus planned Dialt sessions) and whether the current balance covers it. An estimate; creation checks again. Null for Dialt-only runs.",
            "properties": {
              "required_micros": {
                "type": "integer"
              },
              "sufficient": {
                "type": "boolean"
              }
            },
            "required": [
              "required_micros",
              "sufficient"
            ]
          }
        },
        "required": [
          "valid",
          "errors",
          "warnings",
          "modality",
          "execution",
          "repetitions",
          "targets",
          "attempts",
          "replacements",
          "billing",
          "max_external_charge_micros",
          "credit"
        ]
      },
      "EvalRun": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "passed",
              "failed",
              "inconclusive",
              "cancelled",
              "error"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "passed",
              "failed",
              "cancelled",
              "error"
            ]
          },
          "execution": {
            "type": "string",
            "enum": [
              "hosted",
              "local"
            ]
          },
          "modality": {
            "type": "string",
            "enum": [
              "text",
              "voice"
            ]
          },
          "repetitions": {
            "type": "integer"
          },
          "targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTarget"
            }
          },
          "suite": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": true,
                "description": "Frozen suite identity and description."
              },
              {
                "type": "null"
              }
            ]
          },
          "billing": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": true,
                "description": "Frozen rate card for external comparisons, null otherwise."
              },
              {
                "type": "null"
              }
            ]
          },
          "summary": {
            "type": "object",
            "additionalProperties": true,
            "description": "Eval outcome counts and assessment evidence summary."
          },
          "cancel_requested": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "case_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalPreflightProblem"
            },
            "description": "Case settings a target ignores, recorded by preflight when the run was created."
          },
          "criterion_scores": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetScore"
            },
            "description": "One entry per target, in run target order. Derived at read time, so historical runs are scored by the same rule."
          },
          "pass_rates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetPassRate"
            },
            "description": "Strict pass counts per target, in run target order, with each case's counts and a 95% Wilson interval for sampling uncertainty. Derived at read time from attempt statuses."
          },
          "caller_adherence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetCallerAdherence"
            },
            "description": "One entry per target, in run target order: how often the simulated caller followed its script. An attempt where it did not, or where that was not established, is inconclusive."
          },
          "replacements": {
            "$ref": "#/components/schemas/EvalRunReplacements"
          },
          "response_latency": {
            "$ref": "#/components/schemas/EvalRunResponseLatency"
          },
          "caller_response_latency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EvalRunResponseLatency"
              }
            ],
            "description": "Every target measured from the simulated caller's recording (simulator_session_recording_aligned)."
          },
          "case_snapshot_sha256": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$",
            "description": "Content hash (SHA-256) of the run's frozen cases, excluding case ids and timestamps, so runs over identical case content share it."
          }
        },
        "required": [
          "id",
          "outcome",
          "status",
          "execution",
          "modality",
          "repetitions",
          "targets",
          "suite",
          "billing",
          "summary",
          "cancel_requested",
          "created_at",
          "started_at",
          "finished_at",
          "case_names",
          "criterion_scores",
          "pass_rates",
          "caller_adherence",
          "replacements",
          "response_latency",
          "caller_response_latency",
          "case_snapshot_sha256",
          "warnings"
        ]
      },
      "EvalAttempt": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "case_id": {
            "type": "string",
            "format": "uuid"
          },
          "case_name": {
            "type": "string"
          },
          "playground_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "The case's playground_url (see EvalCase), to talk to the case's current version yourself, which differs from the snapshot this attempt ran on if the case was edited since. Null when the case has since been deleted."
          },
          "target_id": {
            "type": "string"
          },
          "target_label": {
            "type": "string"
          },
          "provider_session_id": {
            "type": "string"
          },
          "provider_usage": {
            "type": "object",
            "additionalProperties": true,
            "description": "Provider usage evidence."
          },
          "target_config": {
            "type": "object",
            "additionalProperties": true,
            "description": "For hosted runs, the frozen customer target input. Private provider execution configuration is not returned. Local reports retain customer-owned configuration."
          },
          "billing": {
            "type": "object",
            "additionalProperties": true,
            "description": "Reservation/settlement evidence."
          },
          "repetition": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "passed",
              "failed",
              "inconclusive",
              "cancelled",
              "error"
            ],
            "description": "Timeout/stall, invalid caller coverage or incomplete evidence makes an otherwise non-error, non-cancelled attempt inconclusive. A stall attributed to the target (ending.failure.side target) is failed. With valid coverage and complete evidence, an established target failure takes precedence over unknown target checks; otherwise an unknown judge result makes the attempt inconclusive. Individual established verdicts remain visible; inconclusive attempts are excluded from model pass-rate denominators. Infrastructure errors remain error; cancellation remains cancelled."
          },
          "target_session_id": {
            "type": "string"
          },
          "simulator_session_id": {
            "type": "string"
          },
          "session_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri",
              "description": "Absolute app-origin dashboard URL, separate from the API origin."
            }
          },
          "transcript": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Eval transcript evidence."
            }
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Eval event evidence. Fields that name a supplier in Dialt's own pipeline are omitted."
            }
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Deterministic check results."
            }
          },
          "judges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalJudgeResult"
            }
          },
          "termination_reason": {
            "type": "string",
            "description": "How execution ended, separate from criterion verdicts. timeout means the conversation limit (timeout_s) expired before either side ended the call; it is not proof of assistant failure. An ending already under way when timeout_s passes finishes as completed or simulator_ended. ending reports the conversation, speech drain and connection close separately."
          },
          "error": {
            "type": "string",
            "description": "For hosted runs, a fixed failure code (the code of ending.failure, or evaluation_failed when no failure is classified), never exception text. Local report errors are customer-supplied content."
          },
          "ending": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EvalAttemptEnding"
              },
              {
                "type": "null"
              }
            ],
            "description": "How a hosted attempt ended, in separate parts. Null for local runs and for attempts that have not run yet."
          },
          "correlation_id": {
            "type": "string",
            "description": "Stable identifier for this attempt. Quote it when you report a problem: Dialt's logs for the attempt's failures carry the same value."
          },
          "replacement": {
            "type": "integer",
            "minimum": 0,
            "description": "0 for a scheduled attempt; n for the nth replacement of its slot (case, target, repetition)."
          },
          "replaces_attempt_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The attempt this one replaces."
          },
          "replaced_by_attempt_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The replacement of this attempt, which holds its slot."
          },
          "replacement_decision": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EvalReplacementDecision"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this attempt qualified for replacement: whether it was replaced or why not. Null otherwise."
          },
          "counts_in_slot": {
            "type": "boolean",
            "description": "False for a replaced attempt: it stays visible as spent, and its replacement counts in run status, pass/fail and criterion scores."
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "conversation_duration_s": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Total conversation time in seconds: runner opening dispatch after connections are ready through termination and queued speech drain. Includes tool waits and silence; excludes setup, provider finalization and grading. Null for attempts without a measurement. Compare the same cases and modality, alongside outcome."
          },
          "criterion_score": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EvalCriterionScore"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null when the case declares no judge criteria."
          },
          "response_latency": {
            "$ref": "#/components/schemas/EvalAttemptResponseLatency"
          },
          "caller_response_latency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EvalAttemptResponseLatency"
              }
            ],
            "description": "simulator_session_recording_aligned for any target: the target's response as the simulated caller heard it."
          }
        },
        "required": [
          "id",
          "case_id",
          "case_name",
          "target_id",
          "target_label",
          "provider_session_id",
          "provider_usage",
          "target_config",
          "billing",
          "repetition",
          "status",
          "target_session_id",
          "simulator_session_id",
          "session_urls",
          "transcript",
          "events",
          "checks",
          "judges",
          "termination_reason",
          "error",
          "started_at",
          "finished_at",
          "criterion_score",
          "response_latency",
          "caller_response_latency",
          "playground_url",
          "ending",
          "correlation_id",
          "replacement",
          "replaces_attempt_id",
          "replaced_by_attempt_id",
          "replacement_decision",
          "counts_in_slot"
        ]
      },
      "EvalAttemptEnding": {
        "type": "object",
        "description": "How an attempt ended. The conversation, the drain of its final speech and the external connection close are reported separately, with a classified failure when one occurred. Every value is a fixed code or a timing.",
        "properties": {
          "conversation": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "ended",
                      "stopped",
                      "cancelled"
                    ],
                    "description": "ended: a side ended the call, or max_turns was reached. stopped: a guard or failure stopped it. cancelled: the run was cancelled."
                  },
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "The termination_reason."
                  },
                  "ended_by": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "target",
                      "simulator",
                      "harness",
                      null
                    ]
                  },
                  "duration_s": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                },
                "required": [
                  "outcome",
                  "reason",
                  "ended_by",
                  "duration_s"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "drain": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "drained",
                      "grace_expired",
                      "limit_reached",
                      "cancelled"
                    ]
                  }
                },
                "required": [
                  "outcome"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the final speech after an ending was delivered within its grace window. Null when no ending was observed."
          },
          "shutdown": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "closed",
                      "failed"
                    ]
                  }
                },
                "required": [
                  "outcome"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The external target connection's close. Null for Dialt targets."
          },
          "failure": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "enum": [
                      "timeout",
                      "stalled",
                      "simulator_silent",
                      "silence_guard",
                      "repetition_guard",
                      "connection_error",
                      "connection_closed",
                      "infrastructure_error",
                      "worker_restarted",
                      "shutdown_failed"
                    ]
                  },
                  "side": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "target",
                      "simulator",
                      "harness",
                      null
                    ],
                    "description": "The side whose connection or relay failed; harness for the eval worker. For stalled, the side that owed the next speech: target when the target recognized the caller's latest speech and never replied or stopped mid-sentence, simulator when the simulated caller recognized the target's latest speech and never replied. Null when not attributable to one side, for example after a reconnect, an error, a pending tool call or speech the other side never recognized (see last_activity)."
                  },
                  "component": {
                    "type": "string",
                    "enum": [
                      "conversation",
                      "connection",
                      "session",
                      "relay",
                      "cancellation_check",
                      "worker",
                      "attempt",
                      "provider_finalization"
                    ]
                  },
                  "phase": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "conversation",
                      "ending",
                      "shutdown",
                      null
                    ]
                  },
                  "cause": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "infrastructure_error only: the public error code."
                  }
                },
                "required": [
                  "code",
                  "side",
                  "component",
                  "phase"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "recovery": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "state": {
                    "type": "string",
                    "enum": [
                      "worker_restarted"
                    ]
                  },
                  "replayed": {
                    "type": "boolean",
                    "description": "True when the attempt returns to the queue and runs again (Dialt targets). External target attempts are not replayed."
                  }
                },
                "required": [
                  "state",
                  "replayed"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "last_activity": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "target": {
                    "type": "object",
                    "properties": {
                      "last_output_ms": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "When this side last produced speech or text, in ms from the attempt start."
                      },
                      "last_recognition_ms": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "When this side last recognized the other side's speech."
                      },
                      "last_send_ms": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "When the harness last delivered audio into this side's session. Delivery does not prove recognition."
                      }
                    },
                    "required": [
                      "last_output_ms",
                      "last_recognition_ms",
                      "last_send_ms"
                    ]
                  },
                  "simulator": {
                    "type": "object",
                    "properties": {
                      "last_output_ms": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "When this side last produced speech or text, in ms from the attempt start."
                      },
                      "last_recognition_ms": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "When this side last recognized the other side's speech."
                      },
                      "last_send_ms": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "When the harness last delivered audio into this side's session. Delivery does not prove recognition."
                      }
                    },
                    "required": [
                      "last_output_ms",
                      "last_recognition_ms",
                      "last_send_ms"
                    ]
                  }
                },
                "required": [
                  "target",
                  "simulator"
                ]
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "conversation",
          "drain",
          "shutdown",
          "failure",
          "recovery",
          "last_activity"
        ]
      },
      "EvalRunDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "passed",
              "failed",
              "inconclusive",
              "cancelled",
              "error"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "passed",
              "failed",
              "cancelled",
              "error"
            ]
          },
          "execution": {
            "type": "string",
            "enum": [
              "hosted",
              "local"
            ]
          },
          "modality": {
            "type": "string",
            "enum": [
              "text",
              "voice"
            ]
          },
          "repetitions": {
            "type": "integer"
          },
          "targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTarget"
            }
          },
          "suite": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": true,
                "description": "Frozen suite identity and description."
              },
              {
                "type": "null"
              }
            ]
          },
          "billing": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": true,
                "description": "Frozen rate card for external comparisons, null otherwise."
              },
              {
                "type": "null"
              }
            ]
          },
          "summary": {
            "type": "object",
            "additionalProperties": true,
            "description": "Eval outcome counts and assessment evidence summary."
          },
          "cancel_requested": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "case_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalPreflightProblem"
            },
            "description": "Case settings a target ignores, recorded by preflight when the run was created."
          },
          "snapshot": {
            "type": "object",
            "additionalProperties": true,
            "description": "Immutable run input snapshot, including cases, targets, suite and assessment version."
          },
          "attempts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalAttempt"
            }
          },
          "criterion_scores": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetScore"
            },
            "description": "One entry per target, in run target order. Derived at read time, so historical runs are scored by the same rule."
          },
          "pass_rates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetPassRate"
            },
            "description": "Strict pass counts per target, in run target order, with each case's counts and a 95% Wilson interval for sampling uncertainty. Derived at read time from attempt statuses."
          },
          "caller_adherence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetCallerAdherence"
            },
            "description": "One entry per target, in run target order: how often the simulated caller followed its script. An attempt where it did not, or where that was not established, is inconclusive."
          },
          "replacements": {
            "$ref": "#/components/schemas/EvalRunReplacements"
          },
          "response_latency": {
            "$ref": "#/components/schemas/EvalRunResponseLatency"
          },
          "caller_response_latency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EvalRunResponseLatency"
              }
            ],
            "description": "Every target measured from the simulated caller's recording (simulator_session_recording_aligned)."
          },
          "case_snapshot_sha256": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$",
            "description": "Content hash (SHA-256) of the run's frozen cases, excluding case ids and timestamps, so runs over identical case content share it."
          }
        },
        "required": [
          "id",
          "outcome",
          "status",
          "execution",
          "modality",
          "repetitions",
          "targets",
          "suite",
          "billing",
          "summary",
          "cancel_requested",
          "created_at",
          "started_at",
          "finished_at",
          "case_names",
          "snapshot",
          "attempts",
          "criterion_scores",
          "pass_rates",
          "caller_adherence",
          "replacements",
          "response_latency",
          "caller_response_latency",
          "case_snapshot_sha256",
          "warnings"
        ]
      },
      "EvalReportRequest": {
        "type": "object",
        "properties": {
          "idempotency_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "case_id": {
            "type": "string",
            "format": "uuid"
          },
          "repetition": {
            "type": "integer",
            "minimum": 1,
            "default": 1
          },
          "status": {
            "type": "string",
            "enum": [
              "passed",
              "failed",
              "inconclusive",
              "cancelled",
              "error"
            ]
          },
          "transcript": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Local transcript evidence."
            },
            "maxItems": 500
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Local event evidence."
            },
            "maxItems": 2000
          },
          "check_results": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Check result evidence."
            },
            "maxItems": 100
          },
          "judge_results": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "Assessment evidence."
            },
            "maxItems": 100
          },
          "target_session_id": {
            "type": "string"
          },
          "simulator_session_id": {
            "type": "string"
          },
          "termination_reason": {
            "type": "string"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "idempotency_key",
          "case_id",
          "status"
        ],
        "additionalProperties": false,
        "description": "Local runs only; JSON payload at most 2 MB. Idempotency key scoped to run: reusing it with the same normalized evidence returns the existing report; changed evidence returns 409. A different key for an already terminal attempt conflicts. Correlation session IDs are not logical UUIDs."
      },
      "EmptyRequest": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "EvalCasePage": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalCase"
            },
            "maxItems": 100
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Follow this URL verbatim; null when traversal is exhausted."
          },
          "has_more": {
            "type": "boolean"
          }
        },
        "required": [
          "results",
          "next",
          "has_more"
        ],
        "description": "A live cursor page ordered by created_at descending, then UUID ascending. next is null exactly when has_more is false.",
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "has_more": {
                  "const": false
                }
              }
            },
            "then": {
              "properties": {
                "next": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "next": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        ]
      },
      "EvalSuitePage": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalSuite"
            },
            "maxItems": 100
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Follow this URL verbatim; null when traversal is exhausted."
          },
          "has_more": {
            "type": "boolean"
          }
        },
        "required": [
          "results",
          "next",
          "has_more"
        ],
        "description": "A live cursor page ordered by created_at descending, then UUID ascending. next is null exactly when has_more is false.",
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "has_more": {
                  "const": false
                }
              }
            },
            "then": {
              "properties": {
                "next": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "next": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        ]
      },
      "EvalRunPage": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalRun"
            },
            "maxItems": 100
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Follow this URL verbatim; null when traversal is exhausted."
          },
          "has_more": {
            "type": "boolean"
          }
        },
        "required": [
          "results",
          "next",
          "has_more"
        ],
        "description": "A live cursor page ordered by created_at descending, then UUID ascending. next is null exactly when has_more is false.",
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "has_more": {
                  "const": false
                }
              }
            },
            "then": {
              "properties": {
                "next": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "next": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        ]
      },
      "EvalTargets": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/EvalTargetAvailability"
        }
      },
      "RealtimeDialtMode": {
        "type": "object",
        "required": [
          "kind",
          "instructions"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "dialt"
          },
          "modality": {
            "type": "string",
            "enum": [
              "voice",
              "text"
            ],
            "default": "voice",
            "description": "The I/O surface for this session. text uses input_text and emits no audio; voice uses microphone and assistant audio. The model, instructions, tools, history, and conversation events are otherwise the same."
          },
          "voice": {
            "type": "string",
            "minLength": 1,
            "description": "Optional stock voice key from GET /v1/voices. Explicit selection takes precedence over a saved preference, then US Female (us_female) is the shared default, independently of Dialt Fast or Dialt Smart. A resumed session retains its confirmed stock voice identity unless explicitly changed. Empty, unknown, retired or unavailable keys fail with nonretryable invalid_voice; there is no fallback. Accepted aliases: southern_us_female maps to us_female (Southern US to general US English accent); brazilian_male maps to brazilian_female (male to female)."
          },
          "instructions": {
            "type": "string",
            "minLength": 1,
            "pattern": "\\S",
            "description": "Required. The agent's role: who it is, whose side it is on, its goals, what it knows, the policy it follows and its stance toward the other party. Dialt's platform prompt (speech output, conversation mechanics, capabilities, the voice's register and call facts) carries no role. A fresh start without non-empty instructions fails with nonretryable missing_instructions and closes with 1008; a start with resume_token inherits the session's instructions. Guidance: https://dialt.com/docs/api/websocket/#instructions"
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RealtimeToolDefinition"
            }
          },
          "web_search": {
            "type": "boolean",
            "description": "Enables the explicit managed web_search tool. False does not disable search inside other platform-managed reasoning tools when those capabilities are enabled."
          },
          "end_call": {
            "default": false,
            "description": "Declares the managed end_call(farewell) tool so the agent can end the session. true uses Dialt's default ending condition (the caller asks you to end the call); {\"when\": \"<condition>\"} states the host's own, declared to the agent as part of the tool (1-400 chars). On that turn the server sends one goodbye. Reply text in that turn that ends a sentence is the goodbye, and the farewell is not sent after it; reply text that stops mid-sentence is followed by the farewell, which completes it; with no reply text the farewell is the goodbye. Text streamed before the call follows the same rule, and the farewell is sent if none of that text was heard. The server then sends advisory session_end_requested with the farewell argument. The server waits a short grace in which a real user turn cancels the request, then otherwise closes with code 1000. Neither done nor session_end_requested confirms that the peer heard or acted on the farewell; a client owns local playback drain after normal close. Off: the agent cannot end the session; the host ends it with wrap_up or by closing. The tool name end_call is reserved while enabled, like web_search (invalid_tools).",
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "object",
                "required": [
                  "when"
                ],
                "additionalProperties": false,
                "properties": {
                  "when": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 400
                  }
                }
              }
            ]
          },
          "greeting": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "boolean",
                "const": false
              }
            ],
            "description": "Optional pre-authored opening assistant turn. In voice sessions it uses ordinary reply playback: callers may barge it, buffered audio is cleared, and only the heard prefix is retained in conversation context. A completed opener is retained in full. In text sessions it is emitted and retained as a completed assistant turn. False disables the opener."
          },
          "silence_nudge_s": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Per-session override of the server's silence check-in delay (deployment default 10s). Must be less than silence_end_s; omit to keep the server default. An invalid value (non-positive, or not less than silence_end_s) falls back to the server default rather than rejecting the session."
          },
          "silence_end_s": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Per-session override of the server's silence sign-off + session-end delay (deployment default 20s), counted after the check-in. Must be greater than silence_nudge_s; omit to keep the server default. An invalid value falls back to the server default rather than rejecting the session."
          },
          "tool_choice": {
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "auto",
                  "none",
                  "required"
                ]
              },
              {
                "type": "object",
                "required": [
                  "allowed"
                ],
                "properties": {
                  "allowed": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "object",
                "required": [
                  "tool"
                ],
                "properties": {
                  "tool": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            ],
            "description": "Controls when Dialt may call your tools. Requires a non-empty `tools` list; `allowed`/`tool` names must be CLIENT-declared tools (broker-managed protocol tools are not valid targets; unknown names fail the session with invalid_tool_choice). The durable (non-one-shot) choice survives a resume via the session stash. `required`/`allowed`/`tool` constrain the FIRST planning round of each caller turn; later rounds of the same turn are unconstrained so the spoken reply can still be composed. A one-shot also applies to an explicitly host-requested reply, while autonomous jobs do not consume it. `none` withholds the client-declared tools while broker-managed protocol tools (job cancellation, permission resolution, managed search) stay available. Speculative drafts are planned under the active choice and dropped when it changes."
          },
          "policy": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rules"
            ],
            "description": "Define conditions and actions once. Include them in agent instructions and/or enable background guidance. Both settings default true. Background guidance is quiet, references its source caller or assistant turn, and does not execute tools or request a reply.",
            "properties": {
              "subject": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "include_instructions": {
                "type": "boolean",
                "default": true
              },
              "background_guidance": {
                "type": "boolean",
                "default": true
              },
              "rules": {
                "type": "array",
                "minItems": 1,
                "maxItems": 12,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "when",
                    "do"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{0,39}$"
                    },
                    "when": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    },
                    "do": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    }
                  }
                }
              }
            }
          }
        },
        "additionalProperties": false
      },
      "RealtimeToolDefinition": {
        "type": "object",
        "allOf": [
          {
            "if": {
              "properties": {
                "deferred": {
                  "const": false
                }
              }
            },
            "then": {
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "deferred_timeout"
                    ]
                  },
                  {
                    "required": [
                      "notify_on_complete"
                    ]
                  }
                ]
              }
            }
          },
          {
            "if": {
              "required": [
                "permission_source"
              ]
            },
            "then": {
              "required": [
                "requires_permission"
              ],
              "properties": {
                "requires_permission": {
                  "const": true
                }
              }
            }
          },
          {
            "not": {
              "required": [
                "recorded_bridge",
                "expected_duration"
              ]
            }
          }
        ],
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Client tool name. Platform-managed names such as end_call and web_search are reserved when those capabilities are enabled."
          },
          "description": {
            "type": "string",
            "default": "",
            "description": "State when to call, prerequisites, effects and what each result confirms. Distinguish requesting an action from completing it. Put tool-specific rules here, not only in session instructions."
          },
          "parameters": {
            "type": "object",
            "description": "JSON Schema for arguments. Describe field meaning, units and allowed values; mark required fields explicitly. State whether partial input is accepted and when to submit it."
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Allows early speculative execution. Use only for harmless, cheap lookups."
          },
          "requires_permission": {
            "type": "boolean",
            "default": false,
            "description": "Hold the exact call until its configured approval source authorizes it."
          },
          "resolver_only": {
            "type": "boolean",
            "default": false,
            "description": "This tool only receives the caller's answer to one of the host's own questions (an interaction resolver). The model never sees it and cannot call it; Dialt constructs the exact call when the caller answers. Cannot combine with requires_permission or read_only."
          },
          "recorded_bridge": {
            "type": "string",
            "enum": [
              "auto",
              "always",
              "never"
            ],
            "default": "auto",
            "description": "Policy for Dialt's prerecorded latency cover only. auto races the complete answer against the tier response budget and plays cover if the budget wins; always plays cover when the tool route commits; never waits silently for the result or timeout. Model-authored text before a call remains conversation speech. Cannot be combined with expected_duration."
          },
          "expected_duration": {
            "type": "string",
            "enum": [
              "instant",
              "seconds",
              "long"
            ],
            "deprecated": true,
            "description": "Deprecated compatibility alias for recorded_bridge. instant maps to auto; seconds and long map to always. Cannot be combined with recorded_bridge."
          },
          "status_label": {
            "type": "string",
            "minLength": 1,
            "description": "Short user-safe label Dialt may use when reporting pending work. Defaults to the tool name."
          },
          "timeout": {
            "type": "number",
            "minimum": 1,
            "maximum": 600,
            "default": 30,
            "description": "Observation deadline. Expiry releases waiting with an unknown outcome but does not cancel accepted work; a later terminal result can still resolve the call."
          },
          "deferred": {
            "type": "boolean",
            "default": false,
            "description": "Allow the host to detach a call from its current voice turn."
          },
          "deferred_timeout": {
            "type": "number",
            "minimum": 1,
            "maximum": 86400,
            "default": 7200,
            "description": "Observation window after an accepted tool_deferred frame. Valid only when deferred is true and at least timeout. Expiry does not cancel work; the existing call/handle remains correlated for a late result."
          },
          "notify_on_complete": {
            "type": "boolean",
            "default": true,
            "description": "Proactively wake the brain when background work completes; the result always enters context. Valid only when deferred is true. Also governs an application-approved call that returns its result immediately rather than deferring."
          },
          "permission_source": {
            "type": "string",
            "enum": [
              "caller",
              "application"
            ],
            "default": "caller",
            "description": "Requires requires_permission=true. caller uses caller consent and independent AI verification; application waits for resolve_tool_permission from the authenticated session host. Caller consent cannot satisfy application approval."
          }
        },
        "additionalProperties": false
      },
      "EvalTargetMode": {
        "type": "object",
        "required": [],
        "properties": {
          "kind": {
            "type": "string",
            "const": "dialt"
          },
          "modality": {
            "type": "string",
            "enum": [
              "voice",
              "text"
            ],
            "description": "Overridden by the run modality."
          },
          "voice": {
            "type": "string"
          },
          "instructions": {
            "type": "string",
            "description": "Required and non-empty in a case request. The target agent's role: who it is, whose side it is on, its goals, what it knows and what it should do on the call. The platform prompt carries no role, so every target needs instructions."
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RealtimeToolDefinition"
            }
          },
          "web_search": {
            "type": "boolean",
            "description": "Enables the explicit managed web_search tool. False does not disable search inside other platform-managed reasoning tools when those capabilities are enabled."
          },
          "end_call": {
            "default": true,
            "description": "Enabled by default for eval targets. Declares the managed end_call(farewell) tool so the agent can end the session. true uses Dialt's default ending condition (the caller asks you to end the call); {\"when\": \"<condition>\"} states the host's own, declared to the agent as part of the tool (1-400 chars). On that turn the server sends one goodbye. Reply text in that turn that ends a sentence is the goodbye, and the farewell is not sent after it; reply text that stops mid-sentence is followed by the farewell, which completes it; with no reply text the farewell is the goodbye. Text streamed before the call follows the same rule, and the farewell is sent if none of that text was heard. The server then sends advisory session_end_requested with the farewell argument. The server waits a short grace in which a real user turn cancels the request, then otherwise closes with code 1000. Neither done nor session_end_requested confirms that the peer heard or acted on the farewell; a client owns local playback drain after normal close. Off: the agent cannot end the session; the host ends it with wrap_up or by closing. The tool name end_call is reserved while enabled, like web_search (invalid_tools).",
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "object",
                "required": [
                  "when"
                ],
                "additionalProperties": false,
                "properties": {
                  "when": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 400
                  }
                }
              }
            ]
          },
          "greeting": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 300,
            "pattern": "\\S"
          },
          "silence_nudge_s": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Seconds of user silence before the check-in. Must be positive; when both delays are supplied, silence_end_s must exceed silence_nudge_s. Omit to use the eval runner default."
          },
          "silence_end_s": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Seconds of continued silence after the check-in before sign-off and session end. Must be positive and, when both delays are supplied, greater than silence_nudge_s. Omit to use the eval runner default."
          },
          "tool_choice": {
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "auto",
                  "none",
                  "required"
                ]
              },
              {
                "type": "object",
                "required": [
                  "allowed"
                ],
                "properties": {
                  "allowed": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "object",
                "required": [
                  "tool"
                ],
                "properties": {
                  "tool": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            ],
            "description": "Controls when Dialt may call your tools. Requires a non-empty `tools` list; `allowed`/`tool` names must be CLIENT-declared tools (broker-managed protocol tools are not valid targets; unknown names fail the session with invalid_tool_choice). The durable (non-one-shot) choice survives a resume via the session stash. `required`/`allowed`/`tool` constrain the FIRST planning round of each caller turn; later rounds of the same turn are unconstrained so the spoken reply can still be composed. A one-shot also applies to an explicitly host-requested reply, while autonomous jobs do not consume it. `none` withholds the client-declared tools while broker-managed protocol tools (job cancellation, permission resolution, managed search) stay available. Speculative drafts are planned under the active choice and dropped when it changes."
          },
          "policy": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rules"
            ],
            "description": "Define conditions and actions once. Include them in agent instructions and/or enable background guidance. Both settings default true. Background guidance is quiet, references its source caller or assistant turn, and does not execute tools or request a reply.",
            "properties": {
              "subject": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "include_instructions": {
                "type": "boolean",
                "default": true
              },
              "background_guidance": {
                "type": "boolean",
                "default": true
              },
              "rules": {
                "type": "array",
                "minItems": 1,
                "maxItems": 12,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "when",
                    "do"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{0,39}$"
                    },
                    "when": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    },
                    "do": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    }
                  }
                }
              }
            }
          },
          "turn_detection": {
            "type": "string",
            "enum": [
              "server",
              "client"
            ],
            "default": "server",
            "description": "Use server endpointing or client-signaled turn boundaries."
          }
        },
        "additionalProperties": false,
        "description": "Target session options. The run supplies the effective modality. External comparisons support a restricted subset; see [evals](https://dialt.com/docs/api/evals/)."
      },
      "EvalSimulatorMode": {
        "type": "object",
        "required": [],
        "properties": {
          "kind": {
            "type": "string",
            "const": "dialt"
          },
          "modality": {
            "type": "string",
            "enum": [
              "voice",
              "text"
            ],
            "description": "Overridden by the run modality."
          },
          "voice": {
            "type": "string",
            "description": "Roster key from GET /v1/voices for the simulated caller. It sets the caller's speaking voice, language and register in text and voice runs. New run snapshots pin omitted or null values to US Male (us_male), a generic English caller; historical snapshots retain their original choice. Set it explicitly for your callers' language and dialect, and set target.voice too for language or register cases. Omission does not detect a language. Rebaseline results after changing the caller voice."
          },
          "instructions": {
            "type": "string",
            "description": "Required and non-empty in a case request. The simulated caller's role: who the caller is, what they want and how they behave on the call."
          },
          "silence_nudge_s": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Seconds of user silence before the check-in. Must be positive; when both delays are supplied, silence_end_s must exceed silence_nudge_s. Omit to use the eval runner default."
          },
          "silence_end_s": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Seconds of continued silence after the check-in before sign-off and session end. Must be positive and, when both delays are supplied, greater than silence_nudge_s. Omit to use the eval runner default."
          },
          "policy": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rules"
            ],
            "description": "Define conditions and actions once. Include them in agent instructions and/or enable background guidance. Both settings default true. Background guidance is quiet, references its source caller or assistant turn, and does not execute tools or request a reply.",
            "properties": {
              "subject": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "include_instructions": {
                "type": "boolean",
                "default": true
              },
              "background_guidance": {
                "type": "boolean",
                "default": true
              },
              "rules": {
                "type": "array",
                "minItems": 1,
                "maxItems": 12,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "when",
                    "do"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{0,39}$"
                    },
                    "when": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    },
                    "do": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    }
                  }
                }
              }
            }
          },
          "turn_detection": {
            "type": "string",
            "enum": [
              "server",
              "client"
            ],
            "default": "server",
            "description": "Use server endpointing or client-signaled turn boundaries."
          }
        },
        "additionalProperties": false,
        "description": "Simulator mode; tool, greeting and end-call options are controlled by the eval runner and are rejected when supplied here."
      },
      "PolicyHistory": {
        "type": "object",
        "required": [
          "configured",
          "monitoring",
          "active_count",
          "events"
        ],
        "properties": {
          "configured": {
            "type": "boolean"
          },
          "monitoring": {
            "type": "string",
            "enum": [
              "not_reported",
              "incomplete",
              "complete",
              "unavailable"
            ]
          },
          "active_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "t"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "policy_flag",
                    "policy_error",
                    "policy_check",
                    "policy_settled",
                    "policy_tool_blocked"
                  ]
                },
                "t": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Seconds from segment start."
                },
                "rule": {
                  "type": "string"
                },
                "evidence": {
                  "type": "string"
                },
                "occurrence_id": {
                  "type": "string"
                },
                "tool_call_id": {
                  "type": "string"
                },
                "tool_status": {
                  "type": "string"
                },
                "action": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "tool": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                },
                "delivered": {
                  "type": "boolean"
                },
                "reply_started": {
                  "type": "boolean"
                },
                "retraction_delivered": {
                  "type": "boolean"
                },
                "continues": {
                  "type": "boolean"
                },
                "healthy": {
                  "type": "boolean"
                },
                "revision": {
                  "type": "integer"
                },
                "rules": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "EvalCheck": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "contains",
              "not_contains",
              "regex",
              "tool_called",
              "tool_not_called",
              "policy_flag",
              "fixture_complete",
              "max_turns",
              "judge",
              "caller_probe"
            ]
          },
          "value": {
            "description": "Check-specific comparison value, string representation at most 2000 characters."
          },
          "criterion": {
            "description": "One observable requirement: trigger, expected or forbidden behavior, and evidence that establishes it. State whether it applies throughout the conversation or after a specific event. Make required confirmation and ordering explicit; distinguish request acceptance from completion. At most 2000 characters; caller_probe requires a nonempty string."
          },
          "args": {
            "type": "object",
            "additionalProperties": true,
            "description": "Expected tool argument subset; only for tool_called/tool_not_called."
          },
          "weight": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Optional criterion weight for judge and deterministic checks, above 0 and at most 1000, default 1; not accepted on caller_probe. Scales this criterion in criterion scores; strict outcomes are unaffected.",
            "maximum": 1000
          }
        },
        "additionalProperties": true,
        "description": "Check objects allow extension fields. Use value except judge/caller_probe, which use criterion. Policy checks must reference a configured rule.",
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "enum": [
                    "judge",
                    "caller_probe"
                  ]
                }
              }
            },
            "then": {
              "required": [
                "criterion"
              ],
              "properties": {
                "criterion": {
                  "not": {
                    "type": "null"
                  }
                }
              }
            },
            "else": {
              "required": [
                "value"
              ],
              "properties": {
                "value": {
                  "not": {
                    "type": "null"
                  }
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "caller_probe"
                }
              }
            },
            "then": {
              "properties": {
                "criterion": {
                  "type": "string",
                  "pattern": "\\S",
                  "maxLength": 2000
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "args"
              ]
            },
            "then": {
              "properties": {
                "type": {
                  "enum": [
                    "tool_called",
                    "tool_not_called"
                  ]
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "weight"
              ]
            },
            "then": {
              "properties": {
                "type": {
                  "not": {
                    "const": "caller_probe"
                  }
                }
              }
            }
          }
        ]
      },
      "EvalJudgeResult": {
        "type": "object",
        "additionalProperties": true,
        "description": "One criterion assessment. Developers supply criteria; the grader applies the evidence contract independently to each. Additional fields carry version and caller-probe citation metadata. Dialt's grader model and thinking configuration are omitted. Historical and locally reported results may omit metadata.",
        "properties": {
          "type": {
            "type": "string",
            "description": "judge assesses a developer criterion. simulator_adherence assesses caller fidelity and target opportunity: unreceived or unprocessed required caller input at caller/harness cutoff makes this coverage result null even when generated caller words comply. caller_probe assesses required challenge delivery and recognition. Both caller types are judged against opportunity: a caller that never had a turn in which the obligation applied is not failed."
          },
          "name": {
            "type": "string"
          },
          "criterion": {
            "type": "string"
          },
          "pass": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "true: established compliance; false: an established violation; null: inconclusive because evidence is insufficient or assessment is unavailable. Missing success evidence is not proof of failure. An omitted action requires evidence of necessary input receipt and opportunity to act. A timeout does not override an already established pass or violation. An explicit deadline criterion requires evidence of its trigger and expiry. On simulator_adherence and caller_probe, null with opportunity=false means the obligation did not apply."
          },
          "opportunity": {
            "type": "boolean",
            "const": false,
            "description": "Present only on a simulator_adherence or caller_probe result with pass=null: the caller had no opportunity to act on the obligation (its trigger never occurred, or the target closed the call before the caller had a turn in which it applied). Such a result does not make the attempt inconclusive, is not counted in caller adherence and is never a replacement reason. Results judged before assessment version 14 never carry it."
          },
          "rationale": {
            "type": "string",
            "description": "Decisive evidence or the evidence missing for this criterion."
          },
          "error": {
            "type": "string",
            "description": "Present when the assessment is unavailable; hosted grading returns pass=null and `assessment_unavailable`."
          },
          "assessment_version": {
            "type": "integer",
            "description": "Version of the assessment contract; old results are not regraded in place."
          },
          "weight": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "The check's declared weight, when set. Local reports may supply it on judge and check results; it must be above 0 and at most 1000. Absent means 1.",
            "maximum": 1000
          }
        }
      },
      "AlignedResponseTime": {
        "type": "object",
        "description": "Completed recording alignment: last caller word end to first spoken reply word start, in milliseconds. Prefer this over response_ms when n > 0; never pool the two sources. Null field means alignment is not complete or not requested. With zero usable transitions n is 0 and mean/p50/max are null. Coverage includes missing and excluded transitions. Uses the server recording clock, not client playback; does not redefine benchmark metrics.",
        "properties": {
          "n": {
            "type": "integer",
            "minimum": 0
          },
          "mean": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "p50": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "max": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "turns": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "minimum": 0
            },
            "description": "Aligned gaps keyed by the actual first spoken reply turn_id, including bridge replies. Missing/excluded turns have no entry."
          },
          "coverage": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "aligned": {
                "type": "integer",
                "minimum": 0
              },
              "missing": {
                "type": "integer",
                "minimum": 0
              },
              "excluded": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "aligned",
              "missing",
              "excluded"
            ]
          },
          "provenance": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Always null in the public API; implementation provenance is omitted."
          },
          "clock": {
            "type": [
              "string",
              "null"
            ]
          },
          "clock_bases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "n",
          "mean",
          "p50",
          "max",
          "turns",
          "coverage",
          "provenance",
          "clock",
          "clock_bases"
        ]
      },
      "SessionStatsDistribution": {
        "type": "object",
        "description": "Distribution over one pool of per-turn values, in milliseconds: p50 is the median (mean of the two middle values for an even count, the same rule as per-segment figures), p90 is nearest-rank. Null when no turn was measured.",
        "properties": {
          "n": {
            "type": "integer",
            "minimum": 0
          },
          "mean": {
            "type": [
              "number",
              "null"
            ]
          },
          "p50": {
            "type": [
              "number",
              "null"
            ]
          },
          "p90": {
            "type": [
              "number",
              "null"
            ]
          },
          "max": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "n",
          "mean",
          "p50",
          "p90",
          "max"
        ]
      },
      "SessionStatsResponseGroup": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SessionStatsDistribution"
          },
          {
            "type": "object",
            "properties": {
              "sessions": {
                "type": "integer",
                "minimum": 0,
                "description": "Segments that contributed at least one measured turn."
              }
            },
            "required": [
              "sessions"
            ]
          }
        ]
      },
      "SessionStatsDay": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "sessions": {
            "type": "integer",
            "minimum": 0
          },
          "response_p50_ms": {
            "type": [
              "number",
              "null"
            ],
            "description": "Median estimated response time of turns in segments started that day."
          },
          "aligned_p50_ms": {
            "type": [
              "number",
              "null"
            ],
            "description": "Median recording-aligned response time for that day, when any turn was aligned."
          }
        },
        "required": [
          "date",
          "sessions",
          "response_p50_ms",
          "aligned_p50_ms"
        ]
      },
      "SessionStats": {
        "type": "object",
        "properties": {
          "from": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Lower bound applied, null when unbounded."
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "sessions": {
            "type": "integer",
            "minimum": 0,
            "description": "Recorded segments in the window."
          },
          "call_time_s": {
            "type": "number",
            "description": "Sum of segment durations in seconds."
          },
          "avg_call_s": {
            "type": [
              "number",
              "null"
            ]
          },
          "turns": {
            "type": "integer",
            "minimum": 0,
            "description": "Caller turns."
          },
          "avg_turns": {
            "type": [
              "number",
              "null"
            ]
          },
          "tool_calls": {
            "type": "integer",
            "minimum": 0,
            "description": "Tool calls the assistant made, summed over the window."
          },
          "avg_tool_calls": {
            "type": [
              "number",
              "null"
            ],
            "description": "Tool calls per segment."
          },
          "interruptions": {
            "type": "integer",
            "minimum": 0,
            "description": "Caller barge-ins that stopped a reply, summed over the window."
          },
          "avg_interruptions": {
            "type": [
              "number",
              "null"
            ],
            "description": "Interruptions per segment."
          },
          "assistant_words_per_turn": {
            "type": "object",
            "description": "Mean spoken assistant words per turn, averaged within each recorded segment and then equally across segments with a spoken reply. Tool actions and unfinished replies are excluded.",
            "properties": {
              "sessions": {"type": "integer", "minimum": 0},
              "mean": {"type": ["number", "null"]}
            },
            "required": ["sessions", "mean"]
          },
          "response_ms": {
            "type": "object",
            "description": "Caller wait per turn. aligned: last caller word end to first reply word start, measured from the recording. estimated: last speech-recognition update to first assistant audio sent, event clock. Never pooled together.",
            "properties": {
              "aligned": {
                "$ref": "#/components/schemas/SessionStatsResponseGroup"
              },
              "estimated": {
                "$ref": "#/components/schemas/SessionStatsResponseGroup"
              }
            },
            "required": [
              "aligned",
              "estimated"
            ]
          },
          "latency_ms": {
            "type": "object",
            "description": "Per-stage event-clock timings of each reply, pooled per turn; diagnostics that decompose the estimated response time.",
            "properties": {
              "basis": {
                "type": "string",
                "enum": [
                  "event_clock_estimate"
                ]
              },
              "stages": {
                "type": "object",
                "additionalProperties": {
                  "$ref": "#/components/schemas/SessionStatsDistribution"
                },
                "description": "Keys among asr, brain, ttft, ttfa, tts_connect; a key is absent when no turn carried it."
              }
            },
            "required": [
              "basis",
              "stages"
            ]
          },
          "per_day": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionStatsDay"
            },
            "description": "One entry per UTC day in the window, zeros included, oldest first."
          },
          "interruption_ms": {
            "$ref": "#/components/schemas/SessionStatsDistribution",
            "description": "Pooled caller onset to playback stop for every judged interruption, event clock."
          },
          "checks": {
            "type": "object",
            "description": "Deterministic turn checks pooled over every segment in the window, with how many ran on aligned times and how many still wait for alignment.",
            "properties": {
              "endpointing": {
                "$ref": "#/components/schemas/ReviewGroup"
              },
              "barge": {
                "$ref": "#/components/schemas/ReviewGroup"
              },
              "aligned_sessions": {
                "type": "integer",
                "minimum": 0
              },
              "alignment_pending": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "endpointing",
              "barge",
              "aligned_sessions",
              "alignment_pending"
            ],
            "additionalProperties": false
          },
          "review": {
            "type": "object",
            "description": "Pooled judge results over the reviewed segments in the window, with `pending` (segments still being reviewed, so a partial pool is not read as final), `failed`, and per-family agreement with the turn checks.",
            "properties": {
              "reviewed": {
                "type": "integer",
                "minimum": 0
              },
              "outcome": {
                "type": "object",
                "properties": {
                  "resolved": {
                    "type": "integer"
                  },
                  "unresolved": {
                    "type": "integer"
                  },
                  "resolved_rate": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "unresolved_rate": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                },
                "required": [
                  "resolved",
                  "unresolved",
                  "resolved_rate",
                  "unresolved_rate"
                ]
              },
              "endpointing": {
                "$ref": "#/components/schemas/ReviewGroup"
              },
              "barge": {
                "$ref": "#/components/schemas/ReviewGroup"
              },
              "tool_calls": {
                "$ref": "#/components/schemas/ReviewGroup"
              },
              "pending": {
                "type": "integer",
                "minimum": 0
              },
              "failed": {
                "type": "integer",
                "minimum": 0
              },
              "agreement": {
                "type": "object",
                "properties": {
                  "endpointing": {
                    "$ref": "#/components/schemas/ReviewAgreement"
                  },
                  "barge": {
                    "$ref": "#/components/schemas/ReviewAgreement"
                  }
                }
              }
            },
            "required": [
              "reviewed",
              "outcome",
              "endpointing",
              "barge",
              "tool_calls",
              "pending",
              "failed",
              "agreement"
            ]
          }
        },
        "required": [
          "from",
          "to",
          "sessions",
          "call_time_s",
          "avg_call_s",
          "turns",
          "avg_turns",
          "tool_calls",
          "avg_tool_calls",
          "interruptions",
          "avg_interruptions",
          "assistant_words_per_turn",
          "response_ms",
          "latency_ms",
          "per_day",
          "interruption_ms",
          "checks",
          "review"
        ]
      },
      "MetricDistribution": {
        "type": "object",
        "description": "n/mean/p50/max over this segment's per-turn values, milliseconds; null when nothing was measured.",
        "properties": {
          "n": {
            "type": "integer",
            "minimum": 0
          },
          "mean": {
            "type": [
              "number",
              "null"
            ]
          },
          "p50": {
            "type": [
              "number",
              "null"
            ]
          },
          "max": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "n",
          "mean",
          "p50",
          "max"
        ]
      },
      "SessionMetrics": {
        "type": "object",
        "description": "Per-segment counterpart of every SessionStats total, same names and rules: turns, duration, tool calls, interruptions, response time (aligned and estimated kept apart) and per-stage reply timings.",
        "properties": {
          "turns": {
            "type": "integer",
            "minimum": 0
          },
          "duration_s": {
            "type": [
              "number",
              "null"
            ]
          },
          "tool_calls": {
            "type": "integer",
            "minimum": 0
          },
          "interruptions": {
            "type": "integer",
            "minimum": 0,
            "description": "Caller barge-ins that stopped a reply."
          },
          "assistant_words_per_turn": {
            "type": "object",
            "description": "Words counted with Dialt's deterministic Unicode conversation counter in spoken assistant turns, excluding tool actions and unfinished replies. Consecutive assistant entries form one turn.",
            "properties": {
              "turns": {"type": "integer", "minimum": 0},
              "mean": {"type": ["number", "null"]}
            },
            "required": ["turns", "mean"]
          },
          "response_ms": {
            "type": "object",
            "properties": {
              "aligned": {
                "$ref": "#/components/schemas/MetricDistribution"
              },
              "estimated": {
                "$ref": "#/components/schemas/MetricDistribution"
              }
            },
            "required": [
              "aligned",
              "estimated"
            ]
          },
          "latency_stages_ms": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/MetricDistribution"
            },
            "description": "Keys among asr, brain, ttft, ttfa, tts_connect; absent when no turn carried the stage."
          },
          "interruption_ms": {
            "$ref": "#/components/schemas/MetricDistribution",
            "description": "Caller onset (as the barge detector dated it) to playback stopped, event clock."
          },
          "checks": {
            "$ref": "#/components/schemas/TurnChecks"
          },
          "review": {
            "$ref": "#/components/schemas/SessionReviewSummary"
          }
        },
        "required": [
          "turns",
          "duration_s",
          "tool_calls",
          "interruptions",
          "assistant_words_per_turn",
          "response_ms",
          "latency_stages_ms",
          "interruption_ms",
          "checks",
          "review"
        ]
      },
      "ReviewGroup": {
        "type": "object",
        "description": "Judge counts for one decision family with precision (right decisions / decisions made) and recall (right decisions / decisions that should have been made). Keys beyond judged/precision/recall name the labels of that family.",
        "properties": {
          "judged": {
            "type": "integer",
            "minimum": 0
          },
          "precision": {
            "type": [
              "number",
              "null"
            ]
          },
          "recall": {
            "type": [
              "number",
              "null"
            ]
          },
          "accuracy": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "judged",
          "precision",
          "recall"
        ],
        "additionalProperties": {
          "type": [
            "integer",
            "number",
            "null"
          ]
        }
      },
      "SessionReviewSummary": {
        "type": "object",
        "description": "The latest automatic review of this segment. Every recording is judged within minutes of ingest. `waiting`: recent and about to be queued; `pending`/`running`: in progress; `complete`: the call outcome, the endpointing, barge and tool-call decision counts and their agreement with the deterministic turn checks are present; `failed`: the judge gave no usable verdict; `none`: this segment will not be reviewed (reviews off, or older than the automatic lookback).",
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "none",
              "waiting",
              "pending",
              "running",
              "complete",
              "failed"
            ]
          },
          "version": {
            "type": "string",
            "description": "Omitted in the public API."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "resolved",
              "unresolved"
            ]
          },
          "endpointing": {
            "$ref": "#/components/schemas/ReviewGroup"
          },
          "barge": {
            "$ref": "#/components/schemas/ReviewGroup"
          },
          "tool_calls": {
            "$ref": "#/components/schemas/ReviewGroup"
          },
          "agreement": {
            "type": "object",
            "properties": {
              "endpointing": {
                "$ref": "#/components/schemas/ReviewAgreement"
              },
              "barge": {
                "$ref": "#/components/schemas/ReviewAgreement"
              }
            }
          }
        },
        "required": [
          "state"
        ]
      },
      "ReviewAgreement": {
        "type": "object",
        "description": "Items the deterministic turn checks and the judge both labelled, and how many matched.",
        "properties": {
          "compared": {
            "type": "integer",
            "minimum": 0
          },
          "agreed": {
            "type": "integer",
            "minimum": 0
          },
          "rate": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "compared",
          "agreed",
          "rate"
        ],
        "additionalProperties": false
      },
      "TurnChecks": {
        "type": "object",
        "description": "Deterministic endpointing and barge checks over the segment's timeline (docs/session-reviews.md), available from ingest on. `timeline` says which clock they ran on: `event_clock` until the recording alignment completes (`alignment` gives its state), then `aligned`.",
        "properties": {
          "endpointing": {
            "$ref": "#/components/schemas/ReviewGroup"
          },
          "barge": {
            "$ref": "#/components/schemas/ReviewGroup"
          },
          "timeline": {
            "type": "string",
            "enum": [
              "aligned",
              "event_clock"
            ]
          },
          "alignment": {
            "type": "string",
            "enum": [
              "none",
              "pending",
              "running",
              "complete",
              "failed"
            ]
          }
        },
        "required": [
          "endpointing",
          "barge",
          "timeline",
          "alignment"
        ],
        "additionalProperties": false
      },
      "EvalCriterionScore": {
        "type": "object",
        "description": "Criterion-level score for one attempt, derived from its judge results and deterministic check results. caller_probe and simulator_adherence assess the caller and stay in strict outcomes only. true is a pass, false a fail, and null or an assessment error unknown. With total weight W, passed weight P and unknown weight U: score is P/W when U is 0, otherwise null with the interval lower=P/W, upper=(P+U)/W and coverage=(W-U)/W. An attempt without stored results (error, cancellation, still running) keeps the case's declared criteria as unknown. An invalid regex or unsettled policy monitoring is unknown. Without an assessable target conversation (no target speech or tool call, a conversation cut short by a timeout, stall not attributed to the target, connection loss or cancellation, or an inconclusive attempt), a deterministic check keeps only a verdict it establishes on its own: a forbidden phrase, tool call or turn count that happened stays a failure, and a required phrase, tool call or stored field that was observed stays a pass. Every other deterministic verdict is unknown.",
        "properties": {
          "scoring_version": {
            "type": "integer",
            "description": "Scoring rule that produced this score. 1 counted judge criteria only; 2 also counts deterministic target checks. Scores are computed when read, so every run reports the current version; compare exported scores only within one version."
          },
          "criteria": {
            "type": "integer",
            "minimum": 0,
            "description": "Judge criteria and deterministic checks counted."
          },
          "passed": {
            "type": "integer",
            "minimum": 0,
            "description": "Criteria established as met."
          },
          "failed": {
            "type": "integer",
            "minimum": 0,
            "description": "Criteria established as violated."
          },
          "unknown": {
            "type": "integer",
            "minimum": 0,
            "description": "Criteria without an established verdict."
          },
          "score": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Weighted pass fraction; null while any criterion is unknown."
          },
          "lower": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Weighted pass fraction counting unknowns as failures."
          },
          "upper": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Weighted pass fraction counting unknowns as passes."
          },
          "coverage": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Resolved share of criterion weight."
          }
        },
        "required": [
          "scoring_version",
          "criteria",
          "passed",
          "failed",
          "unknown",
          "score",
          "lower",
          "upper",
          "coverage"
        ]
      },
      "EvalCasePassRate": {
        "type": "object",
        "description": "Strict pass counts for one case and target, with a 95% Wilson score interval over its assessed attempts.",
        "properties": {
          "case_id": {
            "type": "string"
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "description": "Scheduled attempts."
          },
          "assessed": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts that passed or failed."
          },
          "passed": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts that passed."
          },
          "unknown": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts not assessed: inconclusive, error, cancelled, queued or running."
          },
          "pass_rate": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Passed over assessed; null with nothing assessed."
          },
          "pass_rate_lower": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Lower bound of the 95% Wilson score interval; null with nothing assessed."
          },
          "pass_rate_upper": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Upper bound of the 95% Wilson score interval; null with nothing assessed."
          }
        },
        "required": [
          "case_id",
          "attempts",
          "assessed",
          "passed",
          "unknown",
          "pass_rate",
          "pass_rate_lower",
          "pass_rate_upper"
        ]
      },
      "EvalTargetPassRate": {
        "type": "object",
        "description": "Strict pass counts for one target, pooled over cases with equal case weight, and per case. The interval covers sampling uncertainty over assessed attempts; unknown attempts are counted separately and widen the criterion score interval instead.",
        "properties": {
          "target_id": {
            "type": "string"
          },
          "cases": {
            "type": "integer",
            "minimum": 0,
            "description": "Scheduled cases for this target."
          },
          "assessed_cases": {
            "type": "integer",
            "minimum": 0,
            "description": "Cases with at least one assessed attempt; the pooling denominator."
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "description": "Scheduled attempts."
          },
          "assessed": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts that passed or failed."
          },
          "passed": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts that passed."
          },
          "unknown": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts not assessed: inconclusive, error, cancelled, queued or running."
          },
          "pass_rate": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Mean of the assessed cases' pass rates, each case weighted equally; null with nothing assessed."
          },
          "pass_rate_lower": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Lower bound of the 95% Wilson score interval at the effective sample size of the equal case weighting; null with nothing assessed."
          },
          "pass_rate_upper": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Upper bound of the 95% Wilson score interval at the effective sample size of the equal case weighting; null with nothing assessed."
          },
          "by_case": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalCasePassRate"
            },
            "description": "One entry per case. Returned on the run detail only."
          }
        },
        "required": [
          "target_id",
          "cases",
          "assessed_cases",
          "attempts",
          "assessed",
          "passed",
          "unknown",
          "pass_rate",
          "pass_rate_lower",
          "pass_rate_upper"
        ]
      },
      "EvalTargetScore": {
        "type": "object",
        "description": "Run criterion score for one target. Repetitions are averaged within each case, then every scheduled case has equal weight; unavailable evidence stays unknown rather than dropping the case. score is set only when every included criterion is resolved; otherwise read lower and upper. Cases without criteria are counted as unscored, not averaged. counts keeps the strict attempt outcomes alongside.",
        "properties": {
          "target_id": {
            "type": "string"
          },
          "scoring_version": {
            "type": "integer",
            "description": "Scoring rule that produced this score. 1 counted judge criteria only; 2 also counts deterministic target checks. Scores are computed when read, so every run reports the current version; compare exported scores only within one version."
          },
          "cases": {
            "type": "integer",
            "minimum": 0,
            "description": "Scheduled cases for this target."
          },
          "scored_cases": {
            "type": "integer",
            "minimum": 0,
            "description": "Cases with at least one criterion; the averaging denominator."
          },
          "resolved_cases": {
            "type": "integer",
            "minimum": 0,
            "description": "Scored cases with no unknown criterion."
          },
          "unscored_cases": {
            "type": "integer",
            "minimum": 0,
            "description": "Cases without criteria."
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "description": "Scheduled attempts for this target."
          },
          "unscored_attempts": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts without criteria."
          },
          "score": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Mean case score; null unless every included criterion is resolved."
          },
          "lower": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Mean case lower bound; null without scored cases."
          },
          "upper": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Mean case upper bound; null without scored cases."
          },
          "criterion_coverage": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Mean case share of resolved criterion weight."
          },
          "counts": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Strict attempt status counts for this target."
          }
        },
        "required": [
          "target_id",
          "scoring_version",
          "cases",
          "scored_cases",
          "resolved_cases",
          "unscored_cases",
          "attempts",
          "unscored_attempts",
          "score",
          "lower",
          "upper",
          "criterion_coverage",
          "counts"
        ]
      },
        "EvalRunReplacements": {
          "type": "object",
          "description": "Replacement of unassessable attempts. enabled is false for a run created without replace_unassessable, including every historical run.",
          "properties": {
            "enabled": {
              "type": "boolean"
            },
            "per_slot": {
              "type": [
                "integer",
                "null"
              ],
              "description": "Replacements allowed per slot (1)."
            },
            "max_replacements": {
              "type": [
                "integer",
                "null"
              ],
              "description": "Replacements allowed across the run."
            },
            "slots": {
              "type": "integer",
              "minimum": 0,
              "description": "Scheduled attempts: cases × repetitions × targets."
            },
            "attempted": {
              "type": "integer",
              "minimum": 0,
              "description": "Replacement attempts created."
            },
            "skipped": {
              "type": "integer",
              "minimum": 0,
              "description": "Attempts that qualified for replacement but were not replaced."
            },
            "skip_reasons": {
              "type": "object",
              "additionalProperties": {
                "type": "integer"
              },
              "description": "Skipped attempts by reason: run_cancelled, slot_budget_exhausted, run_budget_exhausted, external_charge_limit or insufficient_credit."
            },
            "attempts_spent": {
              "type": "integer",
              "minimum": 0,
              "description": "Attempts that started, replaced ones included."
            }
          },
          "required": [
            "enabled",
            "per_slot",
            "max_replacements",
            "slots",
            "attempted",
            "skipped",
            "skip_reasons",
            "attempts_spent"
          ]
        },
        "EvalReplacementDecision": {
          "type": "object",
          "properties": {
            "cause": {
              "type": "string",
              "enum": [
                "infrastructure_error",
                "worker_restarted",
                "harness_connection",
                "caller_connection",
                "caller_broke_script",
                "caller_stalled"
              ]
            },
            "outcome": {
              "type": "string",
              "enum": [
                "replaced",
                "skipped"
              ]
            },
            "reason": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                null,
                "run_cancelled",
                "slot_budget_exhausted",
                "run_budget_exhausted",
                "external_charge_limit",
                "insufficient_credit"
              ],
              "description": "Why a qualifying attempt was not replaced; null when it was."
            },
            "label": {
              "type": "string",
              "description": "For display, for example \"Replaced: simulated caller broke script\"."
            }
          },
          "required": [
            "cause",
            "outcome",
            "reason",
            "label"
          ]
        },
      "EvalTargetCallerAdherence": {
        "type": "object",
        "description": "Whether the simulated caller followed its script, for one target's attempts. Each judged hosted attempt of a case with caller instructions carries one simulated caller coverage verdict (a judges entry of type simulator_adherence): followed when it passed, broke_script when it failed, unknown when it was not established or the assessment was unavailable. Attempts without a verdict (no caller instructions, or never judged) are not counted, a verdict with opportunity=false is left out (an attempt with no other verdict is not counted), and an attempt cut short by an error, cancellation, stall or timeout counts only an established verdict, except a stall attributed to the simulated caller, which counts in full. A local run counts nothing. Derived at read time, so historical runs count by the same rule.",
        "properties": {
          "target_id": {
            "type": "string"
          },
          "assessed": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts with a caller coverage verdict."
          },
          "followed": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts where the caller followed its script."
          },
          "broke_script": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts where the caller materially deviated from its script or skipped a required challenge."
          },
          "unknown": {
            "type": "integer",
            "minimum": 0,
            "description": "Attempts whose caller coverage was not established."
          },
          "rate": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "followed / assessed; null when nothing was assessed."
          }
        },
        "required": [
          "target_id",
          "assessed",
          "followed",
          "broke_script",
          "unknown",
          "rate"
        ]
      },
      "EvalAttemptResponseLatency": {
        "type": "object",
        "description": "Aligned response latency of one voice attempt: last caller word end to first target word start, from forced alignment of an ordinary Dialt session recording. measurement says which recording: target_session_recording_aligned is a Dialt target's own session recording, the same measurement as that session's aligned_response_ms, on the target's recording clock. simulator_session_recording_aligned is the simulated caller's session recording: the caller's speech on its assistant track and the target's speech, as paced back to the caller, on its mic track, both on the caller's recording clock, so the gap is the target's response as the caller heard it. An external target (OpenAI Live, Gemini Live) has no Dialt recording and uses the caller's measurement. Neither is a real caller's device latency. Derived at read time; alignment runs after ingestion, so a finished attempt reports pending until it completes. A missing measurement is never zero.",
        "properties": {
          "measurement": {
            "type": "string",
            "enum": [
              "target_session_recording_aligned",
              "simulator_session_recording_aligned"
            ],
            "description": "Which recording was measured; see the schema description."
          },
          "state": {
            "type": "string",
            "enum": [
              "complete",
              "pending",
              "unavailable"
            ],
            "description": "complete: the recording alignment finished (n can still be 0). pending: the attempt, ingestion or alignment has not finished. unavailable: no measurement will exist; reason says why."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "text_modality",
              "attempt_running",
              "no_target_session",
              "no_simulator_session",
              "recording_not_ingested",
              "recording_not_found",
              "alignment_not_scheduled",
              "alignment_pending",
              "alignment_failed",
              "alignment_disabled",
              "no_alignable_audio",
              "no_audio",
              "no_alignment_timeline",
              "partial_recording",
              null
            ],
            "description": "Why the state is pending or unavailable; partial_recording when some reconnect segments of a complete measurement could not be aligned. Null otherwise. recording_not_ingested becomes recording_not_found an hour after the attempt finished; alignment_not_scheduled becomes unavailable a day after ingestion. no_alignment_timeline: the caller's alignment kept no segment timeline."
          },
          "n": {
            "type": "integer",
            "minimum": 0,
            "description": "Aligned reply turns measured: the eligible turns."
          },
          "mean": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Mean gap in milliseconds; null when n is 0."
          },
          "p50": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Median gap in milliseconds (mean of the middle two for an even n); null when n is 0."
          },
          "p90": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "90th percentile gap in milliseconds (nearest rank); null when n is 0."
          },
          "max": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Largest gap in milliseconds; null when n is 0."
          },
          "turns": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "minimum": 0
            },
            "description": "Gap in milliseconds. For target_session_recording_aligned, keyed by the first spoken reply's turn id (a bridge counts as response start); for simulator_session_recording_aligned, keyed by the caller session's turn id for the target speech it heard. Reconnect segments prefix the segment attempt, for example 2/turn-3."
          },
          "coverage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EvalLatencyCoverage"
              },
              {
                "type": "null"
              }
            ]
          },
          "provenance": {
            "type": [
              "object",
              "null"
            ],
            "description": "Always null in the public API; implementation provenance is omitted."
          },
          "clock": {
            "type": [
              "string",
              "null"
            ],
            "description": "recording_not_client_playout for current alignments."
          },
          "clock_basis": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "How the window of each measured boundary heard through the microphone was located on the recording clock, for example received_audio_cursor. The gap itself is aligned word edges."
          },
          "session_uuid": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The logical session measured (the target's or the simulated caller's), when found."
          }
        },
        "required": [
          "measurement",
          "state",
          "reason",
          "n",
          "mean",
          "p50",
          "p90",
          "max",
          "turns",
          "coverage",
          "provenance",
          "clock",
          "clock_basis",
          "session_uuid"
        ]
      },
      "EvalLatencyCoverage": {
        "type": "object",
        "description": "Reply transitions by alignment status: aligned (measured), missing (a boundary could not be resolved) and excluded (for example overlapping speech).",
        "properties": {
          "aligned": {
            "type": "integer",
            "minimum": 0
          },
          "missing": {
            "type": "integer",
            "minimum": 0
          },
          "excluded": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "aligned",
          "missing",
          "excluded"
        ]
      },
      "EvalTargetLatency": {
        "type": "object",
        "description": "Aligned response latency pooled over every measured reply turn of one target's attempts.",
        "properties": {
          "target_id": {
            "type": "string"
          },
          "measurement": {
            "type": "string",
            "enum": [
              "target_session_recording_aligned",
              "simulator_session_recording_aligned"
            ],
            "description": "The measurement pooled for this target: its attempts' measurement."
          },
          "state": {
            "type": "string",
            "enum": [
              "complete",
              "pending",
              "unavailable"
            ],
            "description": "pending while any attempt is pending; complete when at least one attempt measured and none are pending; unavailable otherwise."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "The shared reason when every attempt is unavailable for the same reason, for example text_modality."
          },
          "n": {
            "type": "integer",
            "minimum": 0,
            "description": "Aligned reply turns measured: the eligible turns."
          },
          "mean": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Mean gap in milliseconds; null when n is 0."
          },
          "p50": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Median gap in milliseconds (mean of the middle two for an even n); null when n is 0."
          },
          "p90": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "90th percentile gap in milliseconds (nearest rank); null when n is 0."
          },
          "max": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Largest gap in milliseconds; null when n is 0."
          },
          "excluded_turns": {
            "type": "integer",
            "minimum": 0,
            "description": "Reply transitions that were not measured (missing plus excluded)."
          },
          "coverage": {
            "$ref": "#/components/schemas/EvalLatencyCoverage"
          },
          "attempts": {
            "type": "object",
            "description": "Attempts by latency state.",
            "properties": {
              "complete": {
                "type": "integer",
                "minimum": 0
              },
              "pending": {
                "type": "integer",
                "minimum": 0
              },
              "unavailable": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "complete",
              "pending",
              "unavailable"
            ]
          }
        },
        "required": [
          "target_id",
          "measurement",
          "state",
          "reason",
          "n",
          "mean",
          "p50",
          "p90",
          "max",
          "excluded_turns",
          "coverage",
          "attempts"
        ]
      },
      "EvalRunResponseLatency": {
        "type": "object",
        "description": "Aligned response latency of a run: reply turns pooled across attempts, plus one pool per target in run target order, each labelled with its measurement. In response_latency a Dialt target uses its own session recording and an external target the simulated caller's, so a run with both is mixed and reports no pooled gaps (n, mean, p50, p90 and max are null); compare targets. caller_response_latency measures every target from the simulated caller's recording: the one axis on which Dialt and external targets compare. See EvalAttemptResponseLatency for the measurement boundaries.",
        "properties": {
          "measurement": {
            "type": "string",
            "enum": [
              "target_session_recording_aligned",
              "simulator_session_recording_aligned",
              "mixed"
            ],
            "description": "The targets' shared measurement, or mixed when they differ."
          },
          "state": {
            "type": "string",
            "enum": [
              "complete",
              "pending",
              "unavailable"
            ],
            "description": "pending while any attempt is pending; complete when at least one attempt measured and none are pending; unavailable otherwise."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "The shared reason when every attempt is unavailable for the same reason, for example text_modality."
          },
          "n": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Aligned reply turns measured: the eligible turns. Null when measurement is mixed."
          },
          "mean": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Mean gap in milliseconds; null when n is 0; also null when measurement is mixed."
          },
          "p50": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Median gap in milliseconds (mean of the middle two for an even n); null when n is 0; also null when measurement is mixed."
          },
          "p90": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "90th percentile gap in milliseconds (nearest rank); null when n is 0; also null when measurement is mixed."
          },
          "max": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Largest gap in milliseconds; null when n is 0; also null when measurement is mixed."
          },
          "excluded_turns": {
            "type": "integer",
            "minimum": 0,
            "description": "Reply transitions that were not measured (missing plus excluded)."
          },
          "coverage": {
            "$ref": "#/components/schemas/EvalLatencyCoverage"
          },
          "attempts": {
            "type": "object",
            "description": "Attempts by latency state.",
            "properties": {
              "complete": {
                "type": "integer",
                "minimum": 0
              },
              "pending": {
                "type": "integer",
                "minimum": 0
              },
              "unavailable": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "complete",
              "pending",
              "unavailable"
            ]
          },
          "targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvalTargetLatency"
            }
          }
        },
        "required": [
          "measurement",
          "state",
          "reason",
          "n",
          "mean",
          "p50",
          "p90",
          "max",
          "excluded_turns",
          "coverage",
          "attempts",
          "targets"
        ]
      }
    },
    "responses": {
      "400": {
        "description": "Invalid input",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "401": {
        "description": "Missing, invalid, revoked or unsupported credential",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "headers": {
          "WWW-Authenticate": {
            "schema": {
              "type": "string"
            },
            "description": "Authentication challenge for this surface."
          }
        }
      },
      "402": {
        "description": "Insufficient credit",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "403": {
        "description": "Browser authentication/CSRF or permission rejected",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "404": {
        "description": "Unknown, unowned or unavailable resource; eval feature may be disabled",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "405": {
        "description": "Method not allowed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "headers": {
          "Allow": {
            "schema": {
              "type": "string"
            },
            "description": "Supported HTTP methods for this resource."
          }
        }
      },
      "409": {
        "description": "Mutation conflicts with current state",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "415": {
        "description": "JSON content type required",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "429": {
        "description": "Throttled when a deployment supplies a rate limit; honor Retry-After",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "string"
            },
            "description": "Retry delay, when provided by the rate limiter."
          }
        }
      },
      "500": {
        "description": "Application failure",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "502": {
        "description": "Upstream failure; gateway responses may be non-JSON.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "503": {
        "description": "Service unavailable; gateway responses may be non-JSON.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
