{
  "openapi": "3.1.0",
  "info": {
    "title": "OM1 PhenOM API",
    "description": "## Authentication\n\nThis API uses OAuth2 Client Credentials flow. Obtain an access token from Auth0 and include it in all requests.\n\n**Token Endpoint:** `https://auth.om1.com/oauth/token`\n\n**Example Request:**\n```bash\ncurl https://auth.om1.com/oauth/token \\\n  --request POST \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n        \"client_id\": \"YOUR_CLIENT_ID\",\n        \"client_secret\": \"YOUR_CLIENT_SECRET\",\n        \"audience\": \"https://audience.om1-prod.om1.com/phenom-api-production\",\n        \"grant_type\": \"client_credentials\"\n    }'\n```\n\n**Using the Token:**\n```bash\ncurl https://api.phenom.om1.com/v1/outcome \\\n  --request GET \\\n  --header \"Authorization: Bearer YOUR_ACCESS_TOKEN\"\n```\n\n**Note:** Access tokens expire after 24 hours. You will need to request a new token when your current one expires.",
    "version": "0.6.0"
  },
  "paths": {
    "/v1/batch": {
      "post": {
        "tags": ["batch"],
        "summary": "Create Batch",
        "description": "Create a new batch for multi-file upload workflow.",
        "operationId": "create_batch_v1_batch_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchCreateResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": ["batch"],
        "summary": "List Batches",
        "description": "List all batches for the authenticated tenant with pagination.",
        "operationId": "list_batches_v1_batch_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of records to return per page. Defaults to 100, maximum is 100.",
              "default": 100,
              "title": "Page Size"
            },
            "description": "Number of records to return per page. Defaults to 100, maximum is 100."
          },
          {
            "name": "page_token",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Base64-encoded pagination token. Omit for first page.",
              "title": "Page Token"
            },
            "description": "Base64-encoded pagination token. Omit for first page."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CursorPage_BatchSummary_"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}": {
      "get": {
        "tags": ["batch"],
        "summary": "Get Batch",
        "description": "Get batch status and metadata.",
        "operationId": "get_batch_v1_batch__batch_id__get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchGetResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/validate": {
      "post": {
        "tags": ["batch"],
        "summary": "Validate Batch",
        "description": "Trigger validation of a batch.",
        "operationId": "validate_batch_v1_batch__batch_id__validate_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency.",
              "examples": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
              "title": "Idempotency-Key"
            },
            "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchValidateRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidateAcceptedResponse"
                }
              }
            }
          },
          "200": {
            "description": "Idempotent replay: a prior request with the same `Idempotency-Key` already succeeded; its original response is returned unchanged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidateAcceptedResponse"
                }
              }
            }
          },
          "409": {
            "description": "A request with the same `Idempotency-Key` is still being processed; retry shortly to receive the original response.",
            "content": {
              "application/json": {
                "example": {
                  "detail": "A request with this Idempotency-Key is still being processed. Retry shortly to receive the original response."
                }
              }
            }
          },
          "422": {
            "description": "The request body failed validation, or the `Idempotency-Key` was reused with a different payload (idempotency conflict).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                },
                "examples": {
                  "validation_error": {
                    "summary": "Request body failed validation",
                    "value": {
                      "detail": [
                        {
                          "loc": ["body", "outcome_ids"],
                          "msg": "Field required",
                          "type": "missing"
                        }
                      ]
                    }
                  },
                  "idempotency_conflict": {
                    "summary": "Idempotency-Key reused with a different payload",
                    "value": {
                      "detail": "Idempotency-Key was already used for a request with a different payload. Use a new key for a new request, or resend the original payload to retry."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/start": {
      "post": {
        "tags": ["batch"],
        "summary": "Start Batch",
        "description": "Start processing a batch.",
        "operationId": "start_batch_v1_batch__batch_id__start_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency.",
              "examples": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
              "title": "Idempotency-Key"
            },
            "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchStartRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartAcceptedResponse"
                }
              }
            }
          },
          "200": {
            "description": "Idempotent replay: a prior request with the same `Idempotency-Key` already succeeded; its original response is returned unchanged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartAcceptedResponse"
                }
              }
            }
          },
          "409": {
            "description": "A request with the same `Idempotency-Key` is still being processed; retry shortly to receive the original response.",
            "content": {
              "application/json": {
                "example": {
                  "detail": "A request with this Idempotency-Key is still being processed. Retry shortly to receive the original response."
                }
              }
            }
          },
          "422": {
            "description": "The request body failed validation, or the `Idempotency-Key` was reused with a different payload (idempotency conflict).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                },
                "examples": {
                  "validation_error": {
                    "summary": "Request body failed validation",
                    "value": {
                      "detail": [
                        {
                          "loc": ["body", "outcome_ids"],
                          "msg": "Field required",
                          "type": "missing"
                        }
                      ]
                    }
                  },
                  "idempotency_conflict": {
                    "summary": "Idempotency-Key reused with a different payload",
                    "value": {
                      "detail": "Idempotency-Key was already used for a request with a different payload. Use a new key for a new request, or resend the original payload to retry."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/from-patient": {
      "post": {
        "tags": ["patient"],
        "summary": "Create Job From Patient",
        "description": "Create a singleton patient job from an input patient history json object.",
        "operationId": "create_job_from_patient_v1_job_from_patient_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency.",
              "examples": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
              "title": "Idempotency-Key"
            },
            "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobFromPatientRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobCreateResponse"
                }
              }
            }
          },
          "200": {
            "description": "Idempotent replay: a prior request with the same `Idempotency-Key` already succeeded; its original response is returned unchanged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobCreateResponse"
                }
              }
            }
          },
          "409": {
            "description": "A request with the same `Idempotency-Key` is still being processed; retry shortly to receive the original response.",
            "content": {
              "application/json": {
                "example": {
                  "detail": "A request with this Idempotency-Key is still being processed. Retry shortly to receive the original response."
                }
              }
            }
          },
          "422": {
            "description": "The request body failed validation, or the `Idempotency-Key` was reused with a different payload (idempotency conflict).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                },
                "examples": {
                  "validation_error": {
                    "summary": "Request body failed validation",
                    "value": {
                      "detail": [
                        {
                          "loc": ["body", "outcome_ids"],
                          "msg": "Field required",
                          "type": "missing"
                        }
                      ]
                    }
                  },
                  "idempotency_conflict": {
                    "summary": "Idempotency-Key reused with a different payload",
                    "value": {
                      "detail": "Idempotency-Key was already used for a request with a different payload. Use a new key for a new request, or resend the original payload to retry."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/job": {
      "get": {
        "tags": ["job"],
        "summary": "List Jobs",
        "description": "List all jobs for the authenticated tenant with pagination.",
        "operationId": "list_jobs_v1_job_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter jobs by batch_id.",
              "title": "Batch Id"
            },
            "description": "Filter jobs by batch_id."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter jobs by status (QUEUED, RUNNING, SUCCEEDED, FAILED, etc.).",
              "title": "Status"
            },
            "description": "Filter jobs by status (QUEUED, RUNNING, SUCCEEDED, FAILED, etc.)."
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of records to return per page. Defaults to 100, maximum is 100.",
              "default": 100,
              "title": "Page Size"
            },
            "description": "Number of records to return per page. Defaults to 100, maximum is 100."
          },
          {
            "name": "page_token",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Base64-encoded pagination token. Omit for first page.",
              "title": "Page Token"
            },
            "description": "Base64-encoded pagination token. Omit for first page."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CursorPage_JobSummary_"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}": {
      "get": {
        "tags": ["job"],
        "summary": "Get Job",
        "description": "Get job metadata. Shows the status of the job.",
        "operationId": "get_job_v1_job__job_id__get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobGetResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}/results": {
      "get": {
        "tags": ["job"],
        "summary": "Get Job Results",
        "description": "Get paginated results back for the status of the batch. The results are by outcome and by patient id.",
        "operationId": "get_job_results_v1_job__job_id__results_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_JobResult_"
                }
              }
            }
          },
          "400": {
            "description": "Job is not in a terminal success status"
          },
          "404": {
            "description": "Job not found"
          },
          "422": {
            "description": "Result set too large for pagination \u2014 exceeds the `paginated_results_max_patients` limit. Use `GET /v1/job/{job_id}/results/download` instead."
          }
        }
      }
    },
    "/v1/job/{job_id}/results/download": {
      "get": {
        "tags": ["job"],
        "summary": "Get Job Results Download",
        "description": "Get presigned URLs to download result files. Returns inference results and, when available, other files related to the job. Use the `file_type` query parameter to filter by type.",
        "operationId": "get_job_results_download_v1_job__job_id__results_download_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "file_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter files by type (e.g., 'results', 'patient_history_diagnosis').",
              "title": "File Type"
            },
            "description": "Filter files by type (e.g., 'results', 'patient_history_diagnosis')."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}/explain": {
      "post": {
        "tags": ["job"],
        "summary": "Request On-Demand Explanations",
        "description": "Request LLM-generated explanations for a job that has already SUCCEEDED, without re-running inference. Returns 202 with an `explain_job_id` to poll via `GET /v1/job/{job_id}/explain/{explain_job_id}`. Rejects with 409 if an explanation request for this job is already in progress.",
        "operationId": "create_explain_job_v1_job__job_id__explain_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency.",
              "examples": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
              "title": "Idempotency-Key"
            },
            "description": "Optional client-generated key (UUIDv4 recommended) that dedups retries of a create request. Reusing it with the same payload replays the original response (200); reusing it with a different payload is a 422 conflict. 1-128 chars; omit to opt out of idempotency."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExplainRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Explain job accepted and queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplainCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Parent job is not in SUCCEEDED status"
          },
          "404": {
            "description": "Parent job not found (or belongs to another tenant)"
          },
          "200": {
            "description": "Idempotent replay: a prior request with the same `Idempotency-Key` already succeeded; its original response is returned unchanged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplainCreateResponse"
                }
              }
            }
          },
          "409": {
            "description": "Either an explanation request for this job is already in progress (per-parent in-flight guard), or a request with the same `Idempotency-Key` is still being processed; retry shortly.",
            "content": {
              "application/json": {
                "example": {
                  "detail": "A request with this Idempotency-Key is still being processed. Retry shortly to receive the original response."
                }
              }
            }
          },
          "422": {
            "description": "The request body failed validation, or the `Idempotency-Key` was reused with a different payload (idempotency conflict).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                },
                "examples": {
                  "validation_error": {
                    "summary": "Request body failed validation",
                    "value": {
                      "detail": [
                        {
                          "loc": ["body", "outcome_ids"],
                          "msg": "Field required",
                          "type": "missing"
                        }
                      ]
                    }
                  },
                  "idempotency_conflict": {
                    "summary": "Idempotency-Key reused with a different payload",
                    "value": {
                      "detail": "Idempotency-Key was already used for a request with a different payload. Use a new key for a new request, or resend the original payload to retry."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}/explain/{explain_job_id}": {
      "get": {
        "tags": ["job"],
        "summary": "Get Explain Job Status",
        "description": "Poll the status of an on-demand explain-job. Recommended client cadence: start at a 2s interval and exponentially back off (x1.5, cap 30s); never poll faster than 1 req/s (subject to the per-IP WAF rate limit).",
        "operationId": "get_explain_job_v1_job__job_id__explain__explain_job_id__get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "explain_job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Explain Job Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Explain job status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplainJobStatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "Explain job not found (wrong tenant, or job_id mismatch)"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}/validation": {
      "get": {
        "tags": ["job"],
        "summary": "Get Validation Report",
        "description": "Get the paginated row-level cohort-exclusion report for a VALIDATION job. Each row is a (patient_id, outcome_id) with a profile status of success, warning, or exclusion \u2014 no inference scores.",
        "operationId": "get_job_validation_v1_job__job_id__validation_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of validation report rows",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_ValidationResult_"
                }
              }
            }
          },
          "400": {
            "description": "Validation job is not in a terminal success status"
          },
          "404": {
            "description": "Validation job not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}/validation/download": {
      "get": {
        "tags": ["job"],
        "summary": "Download Validation Report",
        "description": "Get a presigned URL to download the VALIDATION job's cohort-exclusion report as CSV.",
        "operationId": "get_job_validation_download_v1_job__job_id__validation_download_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job/{job_id}/errors": {
      "get": {
        "tags": ["job"],
        "summary": "Get Job Errors",
        "description": "Return errors associated with the job.",
        "operationId": "get_job_errors_v1_job__job_id__errors_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of records to return per page. Defaults to 100, maximum is 100.",
              "default": 100,
              "title": "Page Size"
            },
            "description": "Number of records to return per page. Defaults to 100, maximum is 100."
          },
          {
            "name": "page_token",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Base64-encoded pagination token. Omit for first page.",
              "title": "Page Token"
            },
            "description": "Base64-encoded pagination token. Omit for first page."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_JobError_"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/outcome": {
      "get": {
        "tags": ["outcome"],
        "summary": "List available outcomes",
        "description": "Get all outcomes available to the tenant from the outcome catalog.\n\nReturns paginated outcome metadata: id, type, name, timeframe, cohort, description.",
        "operationId": "list_outcomes_v1_outcome_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of records to return per page. Defaults to 100, maximum is 100.",
              "default": 100,
              "title": "Page Size"
            },
            "description": "Number of records to return per page. Defaults to 100, maximum is 100."
          },
          {
            "name": "page_token",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Base64-encoded pagination token. Omit for first page.",
              "title": "Page Token"
            },
            "description": "Base64-encoded pagination token. Omit for first page."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_OutcomeCatalogOutcome_"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/upload": {
      "post": {
        "tags": ["batch"],
        "summary": "Create Upload",
        "description": "Create a new upload session and get a presigned URL for uploading a file. Single-file uploads are limited to 5GB. For larger files, split into chunks and upload each as a separate upload for the same object_type.",
        "operationId": "create_upload_v1_batch__batch_id__upload_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload session created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (bad object_type, batch status, etc.)"
          },
          "404": {
            "description": "Batch not found"
          },
          "501": {
            "description": "Multipart upload not available in beta"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": ["batch"],
        "summary": "List Uploads",
        "description": "List all uploads for a batch with pagination.",
        "operationId": "list_uploads_v1_batch__batch_id__upload_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": ["PENDING", "COMPLETED", "FAILED"],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter uploads by status (PENDING, COMPLETED, FAILED)",
              "title": "Status"
            },
            "description": "Filter uploads by status (PENDING, COMPLETED, FAILED)"
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Number of records to return per page. Defaults to 100, maximum is 100.",
              "default": 100,
              "title": "Page Size"
            },
            "description": "Number of records to return per page. Defaults to 100, maximum is 100."
          },
          {
            "name": "page_token",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Base64-encoded pagination token. Omit for first page.",
              "title": "Page Token"
            },
            "description": "Base64-encoded pagination token. Omit for first page."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Uploads retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CursorPage_UploadSummary_"
                }
              }
            }
          },
          "404": {
            "description": "Batch not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/upload/{upload_id}": {
      "get": {
        "tags": ["batch"],
        "summary": "Get Upload Status",
        "description": "Get the status of an upload session.",
        "operationId": "get_upload_status_v1_batch__batch_id__upload__upload_id__get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "upload_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Upload Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Upload status retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadStatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "Batch or upload not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["batch"],
        "summary": "Delete Upload",
        "description": "Delete an upload session and its associated S3 object.",
        "operationId": "delete_upload_v1_batch__batch_id__upload__upload_id__delete",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "upload_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Upload Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Upload deleted successfully"
          },
          "404": {
            "description": "Batch or upload not found"
          },
          "409": {
            "description": "Cannot delete uploads from a finalized batch"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/upload/{upload_id}/refresh": {
      "post": {
        "tags": ["batch"],
        "summary": "Refresh Upload",
        "description": "Refresh the presigned URL for an existing upload session.",
        "operationId": "refresh_upload_v1_batch__batch_id__upload__upload_id__refresh_post",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "upload_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Upload Id"
            }
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "New presigned URL generated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          },
          "404": {
            "description": "Batch or upload not found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/upload/{upload_id}/part/{part_number}/url": {
      "post": {
        "tags": ["batch"],
        "summary": "Get Part Url",
        "description": "**Coming Soon** - Get presigned URL for uploading a multipart part.",
        "operationId": "get_part_url_v1_batch__batch_id__upload__upload_id__part__part_number__url_post",
        "deprecated": true,
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "upload_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Upload Id"
            }
          },
          {
            "name": "part_number",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Part Number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartUrlResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch/{batch_id}/upload/{upload_id}/complete": {
      "post": {
        "tags": ["batch"],
        "summary": "Complete Upload",
        "description": "**Coming Soon** - Complete a multipart upload.",
        "operationId": "complete_upload_v1_batch__batch_id__upload__upload_id__complete_post",
        "deprecated": true,
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Batch Id"
            }
          },
          {
            "name": "upload_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Upload Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompleteResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "tags": ["usage"],
        "summary": "Get Usage",
        "description": "Returns time-bucketed usage data scoped to the authenticated tenant. Results are aggregated and refreshed hourly. Latency percentiles (p50/p95/p99) are weighted averages when aggregating across dimensions; exact when grouping by all dimensions.\n\nThe `event_types` filter selects which usage event family to read. Unset (or `all`) returns EVERY family in one response, each result row tagged with its `event_type` and never summed together; pass a single family to narrow to `inference_complete`, `data_delivery`, or `explanation_complete`. Mixing multiple explicit families in one request is rejected with 400 (use `all`).\n\nFor `data_delivery` rows (data-only om1_data jobs): `batch_count` is always `0` and latency percentiles are `null` (no batch/inference concept \u2014 not a data gap), and `patient_count` is the number of resolved/delivered patients.\n\nFor `explanation_complete` rows (explainability): `batch_count` is `0` and latency percentiles are `null`, and `patient_count` is the number of generated (patient, outcome) explanation pairs \u2014 NOT a patient count.\n\nUse `group_by=[event_type, status]` (and `statuses=[failed]`) to break the new families down by success vs failed.",
        "operationId": "get_usage_v1_usage_get",
        "security": [
          {
            "OAuth2 Bearer Token": []
          }
        ],
        "parameters": [
          {
            "name": "starting_at",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of the reporting window (inclusive, ISO 8601 UTC).",
              "title": "Starting At"
            },
            "description": "Start of the reporting window (inclusive, ISO 8601 UTC)."
          },
          {
            "name": "ending_at",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time"
                },
                {
                  "type": "null"
                }
              ],
              "description": "End of the reporting window (exclusive, ISO 8601 UTC). Defaults to now.",
              "title": "Ending At"
            },
            "description": "End of the reporting window (exclusive, ISO 8601 UTC). Defaults to now."
          },
          {
            "name": "bucket_width",
            "in": "query",
            "required": false,
            "schema": {
              "enum": ["1d", "1w", "1m"],
              "type": "string",
              "description": "Time granularity of each bucket: \"1d\" (daily), \"1w\" (weekly), \"1m\" (monthly).",
              "default": "1d",
              "title": "Bucket Width"
            },
            "description": "Time granularity of each bucket: \"1d\" (daily), \"1w\" (weekly), \"1m\" (monthly)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 90,
              "minimum": 1,
              "description": "Max number of time buckets to return. Default 30, max 90.",
              "default": 30,
              "title": "Limit"
            },
            "description": "Max number of time buckets to return. Default 30, max 90."
          },
          {
            "name": "page_token",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Cursor token from a previous response for pagination.",
              "title": "Page Token"
            },
            "description": "Cursor token from a previous response for pagination."
          },
          {
            "name": "outcome_ids",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter to specific outcome IDs.",
              "title": "Outcome Ids"
            },
            "description": "Filter to specific outcome IDs."
          },
          {
            "name": "model_versions",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by inference model version.",
              "title": "Model Versions"
            },
            "description": "Filter by inference model version."
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by job status: \"success\" or \"failed\".",
              "title": "Statuses"
            },
            "description": "Filter by job status: \"success\" or \"failed\"."
          },
          {
            "name": "batch_types",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by batch type: \"client_data\" or \"om1_data\".",
              "title": "Batch Types"
            },
            "description": "Filter by batch type: \"client_data\" or \"om1_data\"."
          },
          {
            "name": "event_types",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Select the usage event family to read. Unset (or \"all\") returns every family in one response (each row tagged with its event_type, never summed); a single value narrows to \"inference_complete\", \"data_delivery\", or \"explanation_complete\". Multiple explicit families are rejected with 400.",
              "title": "Event Types"
            },
            "description": "Select the usage event family to read. Unset (or \"all\") returns every family in one response (each row tagged with its event_type, never summed); a single value narrows to \"inference_complete\", \"data_delivery\", or \"explanation_complete\". Multiple explicit families are rejected with 400."
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "enum": ["outcome_id", "model_version", "status", "batch_type", "event_type"],
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Aggregate by dimensions: \"outcome_id\", \"model_version\", \"status\", \"batch_type\", \"event_type\".",
              "title": "Group By"
            },
            "description": "Aggregate by dimensions: \"outcome_id\", \"model_version\", \"status\", \"batch_type\", \"event_type\"."
          },
          {
            "name": "x-tenant-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Tenant-Id"
            }
          },
          {
            "name": "x-m2m-name",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-M2M-Name"
            }
          },
          {
            "name": "x-request-id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CursorPage_UsageTimeBucket_"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ArtifactManifest": {
        "properties": {
          "total_rows": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Rows",
            "description": "Total number of rows in the artifact (if applicable).",
            "example": 101234
          },
          "shards": {
            "items": {
              "$ref": "#/components/schemas/DownloadShard"
            },
            "type": "array",
            "title": "Shards",
            "description": "List of shards containing the artifact data."
          }
        },
        "type": "object",
        "required": ["shards"],
        "title": "ArtifactManifest",
        "description": "Manifest for a single download artifact."
      },
      "BatchCreateRequest": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 256
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Human-friendly name for the batch. If not provided, a timestamp will be used.",
            "default": "2026-07-30T17:41:10.320116+00:00",
            "example": "october_data_load"
          },
          "batch_type": {
            "type": "string",
            "enum": ["client_data", "om1_data"],
            "title": "Batch Type",
            "description": "Type of batch. 'client_data' for client-uploaded patient history, 'om1_data' for OM1 Real World Data Cloud linkage.",
            "default": "client_data",
            "example": "client_data"
          },
          "upload_method": {
            "anyOf": [
              {
                "type": "string",
                "const": "s3"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upload Method",
            "description": "Storage backend for batch uploads. Files are uploaded directly to S3.",
            "default": "s3",
            "example": "s3"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "BatchCreateRequest",
        "description": "Request payload to create a new batch for uploading data."
      },
      "BatchCreateResponse": {
        "properties": {
          "batch_id": {
            "type": "string",
            "title": "Batch Id",
            "description": "Unique identifier for the created batch.",
            "example": "batch_0199bb07-3b87-7e83-8842-ad9d52a3c472"
          },
          "status": {
            "type": "string",
            "enum": ["CREATED", "UPLOADING"],
            "title": "Status",
            "description": "Current status of the batch.",
            "example": "CREATED"
          },
          "batch_type": {
            "type": "string",
            "enum": ["client_data", "om1_data"],
            "title": "Batch Type",
            "description": "Type of batch.",
            "example": "client_data"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Human-friendly name of the batch, if provided.",
            "example": "october_data_load"
          },
          "discovery_rules": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DiscoveryRules"
              },
              {
                "type": "null"
              }
            ],
            "description": "Discovery configuration applied to this batch."
          },
          "limits": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Limits"
              },
              {
                "type": "null"
              }
            ],
            "description": "Enforced limits for this batch.",
            "example": {
              "max_files": 1000
            }
          },
          "retention": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Retention"
              },
              {
                "type": "null"
              }
            ],
            "description": "Retention policy for this batch.",
            "example": {
              "created_at": "2026-07-30T17:41:10.322909+00:00",
              "expires_at": "2026-08-29T17:41:10.322928+00:00",
              "ttl_days": 30
            }
          },
          "links": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Links"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hypermedia links for next actions on this batch.",
            "example": {
              "self": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472",
              "start": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/start",
              "upload": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/upload",
              "validate": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/validate"
            }
          }
        },
        "type": "object",
        "required": ["batch_id", "status", "batch_type"],
        "title": "BatchCreateResponse",
        "description": "Details of the newly created batch and related resource links."
      },
      "BatchGetResponse": {
        "properties": {
          "batch_id": {
            "type": "string",
            "title": "Batch Id",
            "description": "Unique identifier of the batch.",
            "example": "batch_0199bb07-3b87-7e83-8842-ad9d52a3c472"
          },
          "status": {
            "type": "string",
            "enum": ["CREATED", "UPLOADING"],
            "title": "Status",
            "description": "Current status of the batch.",
            "example": "UPLOADING"
          },
          "batch_type": {
            "type": "string",
            "enum": ["client_data", "om1_data"],
            "title": "Batch Type",
            "description": "Type of batch.",
            "example": "client_data"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Human-friendly name of the batch, if provided.",
            "example": "october_data_load"
          },
          "retention": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Retention"
              },
              {
                "type": "null"
              }
            ],
            "description": "Retention policy for this batch, if configured."
          },
          "links": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Links"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hypermedia links for available operations on this batch."
          }
        },
        "type": "object",
        "required": ["batch_id", "status", "batch_type"],
        "title": "BatchGetResponse",
        "description": "Current state and summary information for an existing batch."
      },
      "BatchStartRequest": {
        "properties": {
          "outcome_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "minItems": 1,
            "title": "Outcome Ids",
            "description": "Outcome catalog IDs to use when executing the batch job.",
            "example": ["UGn639Co"]
          },
          "outputs": {
            "anyOf": [
              {
                "items": {
                  "type": "string",
                  "enum": ["inference", "patient_history"]
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Outputs",
            "description": "Output artifacts to generate. Valid values: 'inference', 'patient_history'. Defaults to ['inference', 'patient_history'] for om1_data batches, ['inference'] for client_data batches.",
            "example": ["inference", "patient_history"]
          },
          "explainability": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExplainabilityConfig"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional per-job explainability config. Omit (or enabled=false) for byte-identical behavior to today. When enabled, explanations are generated inline during postprocessing (no separate /explain call required)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["outcome_ids"],
        "title": "BatchStartRequest",
        "description": "Request to start processing a batch after validation."
      },
      "BatchSummary": {
        "properties": {
          "batch_id": {
            "type": "string",
            "title": "Batch Id",
            "description": "Unique identifier of the batch.",
            "example": "batch_0199bb07-3b87-7e83-8842-ad9d52a3c472"
          },
          "status": {
            "type": "string",
            "enum": ["CREATED", "UPLOADING"],
            "title": "Status",
            "description": "Current status of the batch.",
            "example": "UPLOADING"
          },
          "batch_type": {
            "type": "string",
            "enum": ["client_data", "om1_data"],
            "title": "Batch Type",
            "description": "Type of batch.",
            "example": "client_data"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Human-friendly name of the batch, if provided.",
            "example": "october_data_load"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "ISO 8601 timestamp when the batch was created.",
            "example": "2025-01-22T10:30:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "ISO 8601 timestamp when the batch was last updated.",
            "example": "2025-01-22T10:30:00Z"
          }
        },
        "type": "object",
        "required": ["batch_id", "status", "batch_type", "created_at", "updated_at"],
        "title": "BatchSummary",
        "description": "Summary information for a batch in list responses."
      },
      "BatchValidateRequest": {
        "properties": {
          "outcome_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "minItems": 1,
            "title": "Outcome Ids",
            "description": "Outcome catalog IDs to validate against.",
            "example": ["UGn639Co"]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["outcome_ids"],
        "title": "BatchValidateRequest",
        "description": "Request to validate a batch against the specified outcome catalog."
      },
      "CohortExclusionConfig": {
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["none", "advisory"],
            "title": "Mode",
            "default": "advisory"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "CohortExclusionConfig",
        "description": "Per-job cohort-exclusion mode.\n\nCumulative ladder \u2014 each rung adds gating on top of the one below:\n\n- ``none``:     no cohort queries run; every patient scored (throughput mode).\n- ``advisory``: out-of-cohort patients flagged (warn tier); scores still returned.\n\nOmitting this config (or the whole field) resolves to ``advisory`` \u2014 byte-identical\nto the default warning-tier behavior. Lowering the mode to ``none`` buys throughput\nat the cost of inference quality.\n\nNOTE (persisted round-trip): the worker reconstructs this from the persisted DynamoDB\nJobRecord via ``model_validate``, so with ``extra=\"forbid\"`` any NEW field or enum\nvalue is additive-only and the worker deploy must lead/accompany the API deploy (same\nrolling-deploy rule as ``ExplainabilityConfig``). Unlike explainability this is\nopt-OUT: the getter degrades an absent/corrupt/unknown value to the safest *known*\nmode (fail-open), never silently to ``none``."
      },
      "CompletePart": {
        "properties": {
          "part_number": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Part Number",
            "description": "Part number (1-based).",
            "example": 1
          },
          "etag": {
            "type": "string",
            "title": "Etag",
            "description": "ETag returned after successful part upload.",
            "example": "\"etag1\""
          }
        },
        "type": "object",
        "required": ["part_number", "etag"],
        "title": "CompletePart",
        "description": "Information about a completed upload part."
      },
      "CompleteRequest": {
        "properties": {
          "parts": {
            "items": {
              "$ref": "#/components/schemas/CompletePart"
            },
            "type": "array",
            "title": "Parts",
            "description": "List of completed parts with their ETags.",
            "example": [
              {
                "etag": "\"etag1\"",
                "part_number": 1
              },
              {
                "etag": "\"etag2\"",
                "part_number": 2
              }
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["parts"],
        "title": "CompleteRequest",
        "description": "Request to complete a multipart upload."
      },
      "CompleteResponse": {
        "properties": {
          "upload_id": {
            "type": "string",
            "title": "Upload Id",
            "description": "Unique identifier for the upload session.",
            "example": "u_abc123"
          },
          "key": {
            "type": "string",
            "title": "Key",
            "description": "S3 key of the completed object.",
            "example": "tenants/org/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/patients/patients_2025_10.csv"
          },
          "etag": {
            "type": "string",
            "title": "Etag",
            "description": "ETag of the completed object.",
            "example": "\"final-mpu-etag-2\""
          },
          "size_bytes": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Size Bytes",
            "description": "Total size of the uploaded object in bytes.",
            "example": 21474836480
          }
        },
        "type": "object",
        "required": ["upload_id", "key", "etag", "size_bytes"],
        "title": "CompleteResponse",
        "description": "Response confirming successful upload completion."
      },
      "CursorPage_BatchSummary_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/BatchSummary"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "CursorPage[BatchSummary]"
      },
      "CursorPage_JobSummary_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/JobSummary"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "CursorPage[JobSummary]"
      },
      "CursorPage_UploadSummary_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/UploadSummary"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "CursorPage[UploadSummary]"
      },
      "CursorPage_UsageTimeBucket_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/UsageTimeBucket"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "CursorPage[UsageTimeBucket]"
      },
      "Diagnosis": {
        "properties": {
          "diagnosis_date": {
            "type": "string",
            "title": "Diagnosis Date",
            "description": "Date when diagnosis was recorded in YYYY-MM-DD format.",
            "example": "2020-01-01"
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Diagnosis code.",
            "example": "I10"
          },
          "code_type": {
            "type": "string",
            "title": "Code Type",
            "description": "Code system used for the diagnosis (e.g., ICD10, ICD9, SNOMED).",
            "example": "ICD10"
          }
        },
        "type": "object",
        "required": ["diagnosis_date", "code", "code_type"],
        "title": "Diagnosis",
        "description": "Medical diagnosis information."
      },
      "DiscoveryRules": {
        "properties": {
          "object_types": {
            "items": {
              "type": "string",
              "enum": ["patient", "lab_result", "procedure", "diagnosis", "medication", "token"]
            },
            "type": "array",
            "title": "Object Types",
            "description": "List of object types the batch accepts.",
            "example": ["patient", "lab_result", "procedure", "diagnosis", "medication"]
          },
          "file_patterns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "File Patterns",
            "description": "Allowed filename patterns used during discovery.",
            "example": ["*.csv"]
          },
          "max_object_size_bytes": {
            "type": "integer",
            "title": "Max Object Size Bytes",
            "description": "Maximum size in bytes for a single discovered object.",
            "example": 5368709120
          }
        },
        "type": "object",
        "required": ["object_types", "file_patterns", "max_object_size_bytes"],
        "title": "DiscoveryRules",
        "description": "Rules that control file discovery and acceptance for the batch."
      },
      "DownloadFile": {
        "properties": {
          "file_type": {
            "type": "string",
            "enum": [
              "results",
              "validation",
              "explanations",
              "patient_history_patient",
              "patient_history_lab_result",
              "patient_history_procedure",
              "patient_history_diagnosis",
              "patient_history_medication"
            ],
            "title": "File Type",
            "description": "Type of file.",
            "example": "results"
          },
          "format": {
            "type": "string",
            "title": "Format",
            "description": "File format.",
            "example": "csv"
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Human-readable description of the file.",
            "example": "Inference results"
          },
          "manifest": {
            "$ref": "#/components/schemas/ArtifactManifest",
            "description": "Manifest with shard information for this file."
          }
        },
        "type": "object",
        "required": ["file_type", "format", "description", "manifest"],
        "title": "DownloadFile",
        "description": "A downloadable file from a job."
      },
      "DownloadResponse": {
        "properties": {
          "files": {
            "items": {
              "$ref": "#/components/schemas/DownloadFile"
            },
            "type": "array",
            "title": "Files",
            "description": "List of downloadable files."
          }
        },
        "type": "object",
        "required": ["files"],
        "title": "DownloadResponse",
        "description": "Response for downloading job result files."
      },
      "DownloadShard": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "S3 key for the shard.",
            "example": "om1-results/tenants/org_abc/jobs/job_01J90Q2TTM/part-0001.csv"
          },
          "size": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Size",
            "description": "Size of the shard in bytes.",
            "example": 18432412
          },
          "etag": {
            "type": "string",
            "title": "Etag",
            "description": "ETag of the shard.",
            "example": "a1b2c3d4e5f6..."
          },
          "url": {
            "type": "string",
            "title": "Url",
            "description": "Presigned URL to download the shard.",
            "example": "https://s3.amazonaws.com/....X-Amz-Signature=..."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "title": "Expires At",
            "description": "ISO 8601 timestamp when the URL expires.",
            "example": "2025-10-06T17:10:00Z"
          }
        },
        "type": "object",
        "required": ["key", "size", "etag", "url", "expires_at"],
        "title": "DownloadShard",
        "description": "Individual shard in a download manifest."
      },
      "ExplainCreateResponse": {
        "properties": {
          "explain_job_id": {
            "type": "string",
            "title": "Explain Job Id",
            "description": "Unique identifier for the created explain-job.",
            "example": "explain_019be149ddd37e16b54d7cb338e75ee9"
          },
          "status": {
            "type": "string",
            "enum": ["QUEUED", "RUNNING", "SUCCEEDED", "FAILED"],
            "title": "Status",
            "description": "Current status of the explain-job (always QUEUED on create).",
            "example": "QUEUED"
          }
        },
        "type": "object",
        "required": ["explain_job_id", "status"],
        "title": "ExplainCreateResponse",
        "description": "Response when accepting an on-demand explain request (HTTP 202)."
      },
      "ExplainJobStatusResponse": {
        "properties": {
          "explain_job_id": {
            "type": "string",
            "title": "Explain Job Id",
            "description": "Unique explain-job identifier.",
            "example": "explain_019be149ddd37e16b54d7cb338e75ee9"
          },
          "job_id": {
            "type": "string",
            "title": "Job Id",
            "description": "Parent job identifier.",
            "example": "job_01J90Q2TTM"
          },
          "status": {
            "type": "string",
            "enum": ["QUEUED", "RUNNING", "SUCCEEDED", "FAILED"],
            "title": "Status",
            "description": "Current status of the explain-job.",
            "example": "RUNNING"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "ISO 8601 timestamp when the explain-job was created.",
            "example": "2025-01-15T10:30:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "ISO 8601 timestamp when the explain-job was last updated.",
            "example": "2025-01-15T10:32:00Z"
          },
          "error_message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error Message",
            "description": "Client-safe failure reason (populated only when status is FAILED)."
          }
        },
        "type": "object",
        "required": ["explain_job_id", "job_id", "status", "created_at", "updated_at"],
        "title": "ExplainJobStatusResponse",
        "description": "Status of an on-demand explain-job."
      },
      "ExplainRequest": {
        "properties": {
          "threshold": {
            "$ref": "#/components/schemas/ThresholdConfig",
            "description": "Threshold gating which (patient, outcome) rows receive an LLM explanation. tenant_id is NEVER accepted here -- it is derived server-side from the authenticated request and the parent job."
          },
          "include_considerations": {
            "type": "boolean",
            "title": "Include Considerations",
            "description": "Per-request opt-in (OFF by default) for the non-prescriptive considerations advisory co-produced with each explanation. Subordinate to explainability (the /explain call is the explainability opt-in) and further gated by a server-side setting. Separately chargeable.",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "ExplainRequest",
        "description": "Request to generate on-demand explanations for a SUCCEEDED job."
      },
      "ExplainabilityConfig": {
        "properties": {
          "enabled": {
            "type": "boolean",
            "title": "Enabled",
            "default": false
          },
          "threshold": {
            "$ref": "#/components/schemas/ThresholdConfig"
          },
          "include_considerations": {
            "type": "boolean",
            "title": "Include Considerations",
            "description": "Per-job opt-in (OFF by default) for the non-prescriptive considerations advisory co-produced with the explanation. SUBORDINATE to `enabled`: a row gets considerations only when this job is explainability-enabled AND this flag is True AND a server-side setting is ON. Never emitted without an explanation (null-coupled). Separately chargeable.",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "ExplainabilityConfig",
        "description": "Per-job opt-in explainability config (R6).\n\n`enabled=False` (the default) is a full no-op: no code path consumes this\nconfig until later stories, and an omitted/disabled config is byte-identical\nto today. `threshold` uses `default_factory` (not `| None`) so that an\nenabled config with no threshold supplied deterministically materializes to\n`risk_bin`/10 (top 10%) \u2014 the worker never has to branch on `None`.\n\nNOTE (R11, persisted round-trip): the worker reconstructs this from the\npersisted DynamoDB JobRecord via `model_validate`, so with `extra=\"forbid\"`\nany NEW field is additive-only and the worker deploy must lead/accompany the\nAPI deploy (same rolling-deploy rule) \u2014 else an old worker fails closed on it."
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "JobCreateResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id",
            "description": "Unique identifier for the created job.",
            "example": "job_01J90Q2TTM"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "VALIDATING",
              "PREPROCESSING",
              "LINKING",
              "INFERRING",
              "POSTPROCESSING",
              "SUCCEEDED",
              "FAILED"
            ],
            "title": "Status",
            "description": "Current status of the job.",
            "example": "QUEUED"
          }
        },
        "type": "object",
        "required": ["job_id", "status"],
        "title": "JobCreateResponse",
        "description": "Response when creating a job from patient history."
      },
      "JobError": {
        "properties": {
          "error_type": {
            "type": "string",
            "title": "Error Type",
            "description": "Category of the error.",
            "example": "validation_error"
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "Human-readable error message.",
            "example": "Required column 'patient_id' is missing from diagnosis"
          },
          "timestamp": {
            "type": "string",
            "title": "Timestamp",
            "description": "ISO 8601 timestamp when the error occurred.",
            "example": "2025-01-15T10:30:00Z"
          }
        },
        "type": "object",
        "required": ["error_type", "message", "timestamp"],
        "title": "JobError",
        "description": "Job error information."
      },
      "JobFromPatientRequest": {
        "properties": {
          "outcome_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "minItems": 1,
            "title": "Outcome Ids",
            "description": "List of outcome IDs to run against this patient.",
            "example": ["uDf9Cuc7", "f5tG5eLE"]
          },
          "patient_history": {
            "$ref": "#/components/schemas/PatientHistory"
          },
          "explainability": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExplainabilityConfig"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional per-job explainability config. Omit (or enabled=false) for byte-identical behavior to today."
          },
          "cohort_exclusion": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CohortExclusionConfig"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional per-job cohort-exclusion mode. Omit for 'advisory' (the default): out-of-cohort patients are flagged but still scored. 'none' skips cohort queries entirely for throughput, which may affect inference quality."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["outcome_ids", "patient_history"],
        "title": "JobFromPatientRequest",
        "description": "Request to create a job from patient history."
      },
      "JobGetResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id",
            "description": "Unique identifier of the job.",
            "example": "job_01J90Q2TTM"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "VALIDATING",
              "PREPROCESSING",
              "LINKING",
              "INFERRING",
              "POSTPROCESSING",
              "SUCCEEDED",
              "FAILED"
            ],
            "title": "Status",
            "description": "Current status of the job.",
            "example": "SUCCEEDED"
          },
          "started_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Started At",
            "description": "ISO 8601 timestamp when the worker began processing this job.",
            "example": "2025-01-15T10:30:00Z"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "ISO 8601 timestamp of the last status or step change.",
            "example": "2025-01-15T10:32:00Z"
          },
          "metrics": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobMetrics"
              },
              {
                "type": "null"
              }
            ],
            "description": "Job execution metrics, available when job is completed."
          },
          "results": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ResultLinks"
              },
              {
                "type": "null"
              }
            ],
            "description": "Links to access results, available when job is completed."
          },
          "error_message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error Message",
            "description": "Error message if job failed.",
            "example": "Validation failed: missing required column 'patient_id'"
          }
        },
        "type": "object",
        "required": ["job_id", "status"],
        "title": "JobGetResponse",
        "description": "Response when retrieving job metadata."
      },
      "JobMetrics": {
        "properties": {
          "records_processed": {
            "type": "integer",
            "title": "Records Processed",
            "description": "Total number of patient records submitted in the request.",
            "example": 1245678
          },
          "patients_scored": {
            "type": "integer",
            "title": "Patients Scored",
            "description": "Number of distinct patients scored in the results.",
            "example": 101234
          },
          "patients_excluded": {
            "type": "integer",
            "title": "Patients Excluded",
            "description": "Number of patients excluded from scoring.",
            "example": 1123
          },
          "patients_hard_excluded": {
            "type": "integer",
            "title": "Patients Hard Excluded",
            "description": "Number of distinct patients who were scored but hard-excluded on every outcome, so all of their result rows are exclusions.",
            "default": 0,
            "example": 42
          },
          "exclusions_by_reason": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Exclusions By Reason",
            "description": "Number of patients excluded, grouped by reason. The set of reason keys depends on the batch and the processing performed.",
            "example": {
              "no_chart_data": 1123
            }
          },
          "error_rows": {
            "type": "integer",
            "title": "Error Rows",
            "description": "Number of patient records that could not be processed due to data-level issues. Included in `records_processed`.",
            "example": 0
          }
        },
        "type": "object",
        "required": ["records_processed", "patients_scored", "patients_excluded", "error_rows"],
        "title": "JobMetrics",
        "description": "Metrics about job execution."
      },
      "JobResult": {
        "properties": {
          "patient_id": {
            "type": "string",
            "title": "Patient Id",
            "description": "Patient identifier.",
            "example": "abc123"
          },
          "outcome_id": {
            "type": "string",
            "title": "Outcome Id",
            "description": "Outcome identifier.",
            "example": "uDf9Cuc7"
          },
          "outcome_raw_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Outcome Raw Score",
            "description": "The raw score generated by the model for the outcome. Null for exclusion rows.",
            "example": 0.0423
          },
          "probability": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Probability",
            "description": "Predicted probability (0.0 to 1.0). Null for exclusion rows.",
            "example": 0.7421
          },
          "prob_upper_95_percent_bound": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Prob Upper 95 Percent Bound",
            "description": "Upper 95% confidence bound for probability. Null for exclusion rows.",
            "example": 0.7934
          },
          "prob_lower_95_percent_bound": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Prob Lower 95 Percent Bound",
            "description": "Lower 95% confidence bound for probability. Null for exclusion rows.",
            "example": 0.6912
          },
          "relative_probability": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Relative Probability",
            "description": "Relative probability compared to baseline. Null for exclusion rows.",
            "example": 2.18
          },
          "rel_upper_95_percent_bound": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Rel Upper 95 Percent Bound",
            "description": "Upper 95% confidence bound for relative probability. Null for exclusion rows.",
            "example": 2.36
          },
          "rel_lower_95_percent_bound": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Rel Lower 95 Percent Bound",
            "description": "Lower 95% confidence bound for relative probability. Null for exclusion rows.",
            "example": 2.02
          },
          "bin_id": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Bin Id",
            "description": "Risk bin identifier. Null for exclusion rows.",
            "example": 9
          },
          "num_bins": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Num Bins",
            "description": "Total number of risk bins. Null for exclusion rows.",
            "example": 100
          },
          "status": {
            "type": "string",
            "enum": ["success", "warning", "exclusion"],
            "title": "Status",
            "description": "Row-level status. ``success`` for normally scored rows; ``exclusion`` for patients excluded from scoring (e.g. LINKING-stage token/chart-data exclusions \u2014 score columns are null).",
            "default": "success",
            "example": "success"
          },
          "status_detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Detail",
            "description": "Human-readable detail explaining the status. Null for ``success`` rows; populated for ``exclusion`` rows.",
            "example": "No patient chart data found in Data API"
          },
          "explanation": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Explanation",
            "description": "Model-generated explanation for the score. Null when explainability is disabled, the row is below the eligibility threshold, the row is an exclusion, or generation failed. Preserved on ``warning`` / ``success`` rows.",
            "example": "Elevated risk driven by recent E11.65 and procedure history."
          },
          "considerations": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Considerations",
            "description": "Non-prescriptive considerations advisory accompanying the explanation. General, informational decision-support categories only -- not orders, dosing, or specific interventions. Opt-in and default off: null whenever ``explanation`` is null, and additionally null when considerations were not requested or are disabled server-side -- so it may be null on a row whose ``explanation`` is populated. Never non-null when ``explanation`` is null. Preserved on ``warning`` / ``success`` rows.",
            "example": "* Consider specialist follow-up\n* Monitor renal function"
          }
        },
        "type": "object",
        "required": ["patient_id", "outcome_id"],
        "title": "JobResult",
        "description": "Individual job result for a patient and outcome.\n\nScore fields are nullable to accommodate synthesized exclusion rows: when\n``status == \"exclusion\"`` (e.g. LINKING-stage exclusions), the patient was\nnever scored and all score columns are ``None``."
      },
      "JobSummary": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id",
            "description": "Unique job identifier.",
            "example": "job_01J90Q2TTM"
          },
          "batch_id": {
            "type": "string",
            "title": "Batch Id",
            "description": "Associated batch identifier.",
            "example": "batch_01J90Q2TT"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "VALIDATING",
              "PREPROCESSING",
              "LINKING",
              "INFERRING",
              "POSTPROCESSING",
              "SUCCEEDED",
              "FAILED"
            ],
            "title": "Status",
            "description": "Current status of the job.",
            "example": "SUCCEEDED"
          },
          "outcome_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Outcome Ids",
            "description": "List of outcome IDs being processed.",
            "example": ["uDf9Cuc7", "f5tG5eLE"]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "ISO 8601 timestamp when job was created.",
            "example": "2025-01-15T10:30:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "ISO 8601 timestamp when job was last updated.",
            "example": "2025-01-15T10:32:00Z"
          },
          "completed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Completed At",
            "description": "ISO 8601 timestamp when job completed (null if not completed).",
            "example": "2025-01-15T10:35:00Z"
          }
        },
        "type": "object",
        "required": ["job_id", "batch_id", "status", "outcome_ids", "created_at", "updated_at"],
        "title": "JobSummary",
        "description": "Summary of a job for listing endpoints."
      },
      "LabResult": {
        "properties": {
          "lab_date": {
            "type": "string",
            "title": "Lab Date",
            "description": "Date when the test was performed in YYYY-MM-DD format.",
            "example": "2025-07-03"
          },
          "loinc": {
            "type": "string",
            "title": "Loinc",
            "description": "LOINC code for the laboratory test.",
            "example": "718-7"
          },
          "value_abnormal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value Abnormal",
            "description": "Abnormal flag for the lab result (e.g., 'Y', 'N', 'H', 'L').",
            "example": "N"
          }
        },
        "type": "object",
        "required": ["lab_date", "loinc"],
        "title": "LabResult",
        "description": "Laboratory test result."
      },
      "Limits": {
        "properties": {
          "max_files": {
            "type": "integer",
            "title": "Max Files",
            "description": "Maximum number of files permitted in the batch.",
            "example": 1000
          },
          "max_total_size_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Total Size Bytes",
            "description": "Maximum total size in bytes across all files.",
            "example": 1073741824
          }
        },
        "type": "object",
        "required": ["max_files"],
        "title": "Limits",
        "description": "Server-enforced limits for the batch size and file counts."
      },
      "Links": {
        "properties": {
          "self": {
            "type": "string",
            "title": "Self",
            "description": "URL to retrieve this batch resource.",
            "example": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472"
          },
          "upload": {
            "type": "string",
            "title": "Upload",
            "description": "URL to initiate file uploads for this batch.",
            "example": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/upload"
          },
          "validate": {
            "type": "string",
            "title": "Validate",
            "description": "URL to trigger validation of uploaded batch contents.",
            "example": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/validate"
          },
          "start": {
            "type": "string",
            "title": "Start",
            "description": "URL to start processing the batch after validation.",
            "example": "http://127.0.0.1:8080/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/start"
          }
        },
        "type": "object",
        "required": ["self", "upload", "validate", "start"],
        "title": "Links",
        "description": "Hypermedia links for performing next actions on the batch."
      },
      "Medication": {
        "properties": {
          "medication_date": {
            "type": "string",
            "title": "Medication Date",
            "description": "Date when medication was started in YYYY-MM-DD format.",
            "example": "2023-03-01"
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Medication code.",
            "example": "C09AA02"
          },
          "code_type": {
            "type": "string",
            "title": "Code Type",
            "description": "Code system used for the medication (e.g., ATC, NDC, RXNORM).",
            "example": "ATC"
          }
        },
        "type": "object",
        "required": ["medication_date", "code", "code_type"],
        "title": "Medication",
        "description": "Medication information."
      },
      "OutcomeCatalogOutcome": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Outcome identifier",
            "example": "kixcWihK"
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Type",
            "description": "Outcome type.",
            "example": "risk"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Outcome display name.",
            "example": "Hospitalization risk"
          },
          "timeframe": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timeframe",
            "description": "Outcome timeframe.",
            "example": "30d"
          },
          "cohort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cohort",
            "description": "Outcome cohort.",
            "example": "inpatient"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Human-readable outcome description.",
            "example": "Hospitalization risk model."
          }
        },
        "type": "object",
        "required": ["id"],
        "title": "OutcomeCatalogOutcome",
        "description": "Outcome metadata returned from the Snowflake outcome catalog (API-facing fields only)."
      },
      "Page_JobError_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/JobError"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          },
          "total_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Rows",
            "description": "Total number of rows across all pages. May be omitted for performance reasons.",
            "example": 101234
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "Page[JobError]"
      },
      "Page_JobResult_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/JobResult"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          },
          "total_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Rows",
            "description": "Total number of rows across all pages. May be omitted for performance reasons.",
            "example": 101234
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "Page[JobResult]"
      },
      "Page_OutcomeCatalogOutcome_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/OutcomeCatalogOutcome"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          },
          "total_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Rows",
            "description": "Total number of rows across all pages. May be omitted for performance reasons.",
            "example": 101234
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "Page[OutcomeCatalogOutcome]"
      },
      "Page_ValidationResult_": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ValidationResult"
            },
            "type": "array",
            "title": "Items",
            "description": "List of items for the current page."
          },
          "next_page_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Page Token",
            "description": "Base64-encoded token for the next page. Null if this is the last page.",
            "example": "eyJzaGFyZF9pZHMiOlszXSwi"
          },
          "total_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Rows",
            "description": "Total number of rows across all pages. May be omitted for performance reasons.",
            "example": 101234
          }
        },
        "type": "object",
        "required": ["items"],
        "title": "Page[ValidationResult]"
      },
      "PartUrlResponse": {
        "properties": {
          "upload_id": {
            "type": "string",
            "title": "Upload Id",
            "description": "Unique identifier for the upload session.",
            "example": "u_abc123"
          },
          "key": {
            "type": "string",
            "title": "Key",
            "description": "S3 key where the object will be stored.",
            "example": "tenants/org/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/patients/patients_2025_10.csv"
          },
          "part_number": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Part Number",
            "description": "Part number for this upload (1-based).",
            "example": 1
          },
          "url": {
            "type": "string",
            "title": "Url",
            "description": "Presigned URL for uploading the part.",
            "example": "https://bucket.s3.amazonaws.com/key?X-Amz-Algorithm=..."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "title": "Expires At",
            "description": "ISO timestamp when the presigned URL expires.",
            "example": "2025-01-15T10:30:00Z"
          }
        },
        "type": "object",
        "required": ["upload_id", "key", "part_number", "url", "expires_at"],
        "title": "PartUrlResponse",
        "description": "Response containing presigned URL for part upload."
      },
      "Patient": {
        "properties": {
          "patient_id": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Patient Id",
            "description": "Unique identifier for the patient.",
            "example": "abc123"
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "Patient's birth date in YYYY-MM-DD format.",
            "example": "1964-05-18"
          },
          "sex": {
            "type": "string",
            "enum": ["M", "F", "U"],
            "title": "Sex",
            "description": "Patient's sex: M (Male), F (Female), U (Unknown/Unspecified).",
            "example": "F"
          }
        },
        "type": "object",
        "required": ["patient_id", "birth_date", "sex"],
        "title": "Patient",
        "description": "Patient demographic information."
      },
      "PatientHistory": {
        "properties": {
          "patient": {
            "$ref": "#/components/schemas/Patient"
          },
          "lab_results": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/LabResult"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lab Results",
            "description": "List of laboratory test results."
          },
          "diagnoses": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/Diagnosis"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Diagnoses",
            "description": "List of medical diagnoses."
          },
          "procedures": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/Procedure"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Procedures",
            "description": "List of medical procedures."
          },
          "medications": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/Medication"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Medications",
            "description": "List of medications."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["patient"],
        "title": "PatientHistory",
        "description": "Complete patient history including demographics and clinical data."
      },
      "Procedure": {
        "properties": {
          "procedure_date": {
            "type": "string",
            "title": "Procedure Date",
            "description": "Date when procedure was performed in YYYY-MM-DD format.",
            "example": "2024-12-15"
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Procedure code.",
            "example": "93000"
          },
          "code_type": {
            "type": "string",
            "title": "Code Type",
            "description": "Code system used for the procedure (e.g., CPT, HCPCS, ICD10PCS).",
            "example": "CPT"
          }
        },
        "type": "object",
        "required": ["procedure_date", "code", "code_type"],
        "title": "Procedure",
        "description": "Medical procedure information."
      },
      "ResultLinks": {
        "properties": {
          "api_pages": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Api Pages",
            "description": "Link to paginated API results.",
            "example": {
              "href": "/v1/job/job_01J90Q2TTM/results"
            }
          },
          "download": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Download",
            "description": "Link to download results.",
            "example": {
              "href": "/v1/job/job_01J90Q2TTM/results/download"
            }
          }
        },
        "type": "object",
        "required": ["api_pages", "download"],
        "title": "ResultLinks",
        "description": "Links to access job results."
      },
      "Retention": {
        "properties": {
          "ttl_days": {
            "type": "integer",
            "maximum": 60.0,
            "minimum": 1.0,
            "title": "Ttl Days",
            "description": "Number of days to retain batch data before expiration.",
            "default": 30,
            "example": 30
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "ISO 8601 timestamp when the batch was created.",
            "example": "2025-01-22T10:30:00Z"
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At",
            "description": "ISO 8601 timestamp when the batch will expire, if set.",
            "example": "2025-02-21T10:30:00Z"
          }
        },
        "type": "object",
        "required": ["created_at"],
        "title": "Retention",
        "description": "Retention policy and computed expiration for batch data."
      },
      "StartAcceptedResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id",
            "description": "Server-assigned identifier for the processing job.",
            "example": "job_xyz789"
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "RUNNING",
              "VALIDATING",
              "PREPROCESSING",
              "LINKING",
              "INFERRING",
              "POSTPROCESSING",
              "SUCCEEDED",
              "FAILED"
            ],
            "title": "Status",
            "description": "Current status of the processing job.",
            "example": "QUEUED"
          }
        },
        "type": "object",
        "required": ["job_id", "status"],
        "title": "StartAcceptedResponse",
        "description": "Acknowledgement response for an asynchronously started processing job."
      },
      "ThresholdConfig": {
        "properties": {
          "type": {
            "type": "string",
            "enum": ["risk_bin", "relative_risk"],
            "title": "Type",
            "default": "risk_bin"
          },
          "value": {
            "type": "number",
            "exclusiveMinimum": 0.0,
            "title": "Value",
            "default": 10.0
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "ThresholdConfig",
        "description": "Eligibility gate selecting which result rows get an explanation (R5).\n\n- risk_bin:      `value` is the top-N percent by risk bin (default 10 == top 10%).\n- relative_risk: `value` is the relative_probability floor (rows with rel-risk >= value).\n\n`value` carries a `gt=0.0` Field constraint as the cheap front gate; the\n`model_validator` below adds the type-conditional upper bound and re-runs on\n`model_validate`, so a corrupt persisted value (e.g. read back from the\nDynamoDB JobRecord) fails closed rather than reaching the worker."
      },
      "UploadRequest": {
        "properties": {
          "object_type": {
            "type": "string",
            "enum": ["patient", "lab_result", "procedure", "diagnosis", "medication", "token"],
            "minLength": 1,
            "title": "Object Type",
            "description": "The type of object being uploaded (patient history type or token).",
            "example": "patient"
          },
          "filename": {
            "type": "string",
            "minLength": 1,
            "title": "Filename",
            "description": "Name of the file being uploaded.",
            "example": "patients_2025_10.csv"
          },
          "content_type": {
            "type": "string",
            "title": "Content Type",
            "description": "MIME type of the file content.",
            "default": "text/csv",
            "example": "text/csv"
          },
          "mode": {
            "type": "string",
            "enum": ["single", "multipart"],
            "title": "Mode",
            "description": "Upload mode. Currently only 'single' is supported.",
            "default": "single",
            "example": "single"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["object_type", "filename"],
        "title": "UploadRequest",
        "description": "Request to initiate an upload (single or multipart)."
      },
      "UploadResponse": {
        "properties": {
          "upload_id": {
            "type": "string",
            "title": "Upload Id",
            "description": "Unique identifier for the upload session.",
            "example": "upload_019be149ddd37e16b54d7cb338e75ee9"
          },
          "object_type": {
            "type": "string",
            "title": "Object Type",
            "description": "Type of object being uploaded (patient, outcome, etc.).",
            "example": "patient"
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "Original filename.",
            "example": "patients_2025_10.csv"
          },
          "mode": {
            "type": "string",
            "enum": ["single", "multipart"],
            "title": "Mode",
            "description": "Upload mode: 'single' or 'multipart'.",
            "example": "single"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "title": "Expires At",
            "description": "ISO timestamp when the presigned URL expires.",
            "example": "2025-01-15T10:30:00Z"
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "Presigned URL for single mode uploads.",
            "example": "https://s3...sig..."
          },
          "part_size_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Part Size Bytes",
            "description": "Size in bytes for each part in multipart uploads.",
            "example": 134217728
          }
        },
        "type": "object",
        "required": ["upload_id", "object_type", "filename", "mode", "expires_at"],
        "title": "UploadResponse",
        "description": "Response for upload initiation."
      },
      "UploadStatusResponse": {
        "properties": {
          "upload_id": {
            "type": "string",
            "title": "Upload Id",
            "description": "Unique identifier for the upload session.",
            "example": "upload_019be149ddd37e16b54d7cb338e75ee9"
          },
          "object_type": {
            "type": "string",
            "title": "Object Type",
            "description": "Type of object being uploaded (patient, outcome, etc.).",
            "example": "patient"
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "Original filename.",
            "example": "patients_2025_10.csv"
          },
          "status": {
            "type": "string",
            "enum": ["PENDING", "COMPLETED", "FAILED"],
            "title": "Status",
            "description": "Current status of the upload (PENDING, COMPLETED, FAILED).",
            "example": "PENDING"
          },
          "bytes_uploaded": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Bytes Uploaded",
            "description": "Total bytes uploaded so far.",
            "example": 1048576
          },
          "parts_uploaded": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Parts Uploaded",
            "description": "List of part numbers that have been uploaded.",
            "example": [1, 2]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "ISO 8601 timestamp when the upload was created.",
            "example": "2025-01-22T10:30:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "ISO 8601 timestamp when the upload was last updated.",
            "example": "2025-01-22T10:30:00Z"
          },
          "url_expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url Expires At",
            "description": "ISO 8601 timestamp when the presigned URL expires. Use refresh endpoint to get a new URL if expired.",
            "example": "2025-01-22T10:30:00Z"
          }
        },
        "type": "object",
        "required": [
          "upload_id",
          "object_type",
          "filename",
          "status",
          "bytes_uploaded",
          "parts_uploaded",
          "created_at",
          "updated_at"
        ],
        "title": "UploadStatusResponse",
        "description": "Response for upload status check."
      },
      "UploadSummary": {
        "properties": {
          "upload_id": {
            "type": "string",
            "title": "Upload Id",
            "description": "Unique identifier for the upload.",
            "example": "upload_019be149ddd37e16b54d7cb338e75ee9"
          },
          "object_type": {
            "type": "string",
            "title": "Object Type",
            "description": "Type of object being uploaded (patient, outcome, etc.).",
            "example": "patient"
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "Original filename.",
            "example": "patients_2025_10.csv"
          },
          "status": {
            "type": "string",
            "enum": ["PENDING", "COMPLETED", "FAILED"],
            "title": "Status",
            "description": "Current status of the upload (PENDING, COMPLETED, FAILED).",
            "example": "COMPLETED"
          },
          "bytes_uploaded": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Bytes Uploaded",
            "description": "Number of bytes uploaded.",
            "example": 1048576
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "ISO 8601 timestamp when the upload was created.",
            "example": "2025-01-22T10:30:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "ISO 8601 timestamp when the upload was last updated.",
            "example": "2025-01-22T10:30:00Z"
          }
        },
        "type": "object",
        "required": ["upload_id", "object_type", "filename", "status", "bytes_uploaded", "created_at", "updated_at"],
        "title": "UploadSummary",
        "description": "Summary information for an upload in list responses."
      },
      "UsageResultEntry": {
        "properties": {
          "tenant_id": {
            "type": "string",
            "title": "Tenant Id",
            "description": "Tenant identifier (always present, from auth)."
          },
          "event_type": {
            "type": "string",
            "enum": [
              "inference",
              "cohort_warning",
              "cohort_exclusion",
              "data_delivery",
              "explanation",
              "considerations"
            ],
            "title": "Event Type",
            "description": "Usage event type for this row, reflecting the aggregation-table family the query read (selected via the event_types[] filter; unset returns all families, each row tagged with its own event_type): 'inference' (the USAGE_* dynamic tables), 'data_delivery' (data-only om1_data jobs \u2014 DATA_DELIVERY_AGGREGATION_*; note batch_count=0 and latency percentiles are null for these rows, and patient_count = resolved/delivered patients), 'explanation' (explainability \u2014 EXPLANATION_AGGREGATION_*; batch_count=0 and latency null, and patient_count = generated (patient, outcome) explanation pairs, NOT patients), or 'considerations' (the considerations family RECOMMENDED_ACTIONS_AGGREGATION_*; same shape as explanation, patient_count = generated considerations pairs). cohort_warning / cohort_exclusion are tracked separately (COHORT_WARNING_AGGREGATION) and are not surfaced here; the enum carries them so a future warning-facing consumer can reuse this type."
          },
          "outcome_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Outcome Id",
            "description": "Outcome identifier. Null if not included in group_by."
          },
          "model_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model Version",
            "description": "Inference model version. Null if not included in group_by."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Job status (success/failed). Null if not included in group_by."
          },
          "batch_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Batch Type",
            "description": "Batch type (client_data/om1_data). Null if not included in group_by."
          },
          "job_count": {
            "type": "integer",
            "title": "Job Count",
            "description": "Total inference jobs in this bucket."
          },
          "batch_count": {
            "type": "integer",
            "title": "Batch Count",
            "description": "Total batches across all jobs."
          },
          "patient_count": {
            "type": "integer",
            "title": "Patient Count",
            "description": "Total patients processed."
          },
          "failed_job_count": {
            "type": "integer",
            "title": "Failed Job Count",
            "description": "Jobs that terminated with status failed."
          },
          "p50_latency_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "P50 Latency Ms",
            "description": "Median job latency in ms. Null when no jobs exist in the bucket."
          },
          "p95_latency_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "P95 Latency Ms",
            "description": "95th percentile job latency in ms. Null when no jobs exist in the bucket."
          },
          "p99_latency_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "P99 Latency Ms",
            "description": "99th percentile job latency in ms. Null when no jobs exist in the bucket."
          }
        },
        "type": "object",
        "required": ["tenant_id", "event_type", "job_count", "batch_count", "patient_count", "failed_job_count"],
        "title": "UsageResultEntry",
        "description": "A single result row within a time bucket."
      },
      "UsageTimeBucket": {
        "properties": {
          "starting_at": {
            "type": "string",
            "format": "date-time",
            "title": "Starting At",
            "description": "Start of the bucket (inclusive, UTC)."
          },
          "ending_at": {
            "type": "string",
            "format": "date-time",
            "title": "Ending At",
            "description": "End of the bucket (exclusive, UTC)."
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/UsageResultEntry"
            },
            "type": "array",
            "title": "Results",
            "description": "One entry per unique combination of grouped dimensions."
          }
        },
        "type": "object",
        "required": ["starting_at", "ending_at", "results"],
        "title": "UsageTimeBucket",
        "description": "A single time bucket containing aggregated usage results."
      },
      "ValidateAcceptedResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id",
            "description": "Server-assigned identifier for the validation job.",
            "example": "job_019abc123def456"
          },
          "status": {
            "type": "string",
            "enum": ["QUEUED", "RUNNING", "SUCCEEDED", "FAILED"],
            "title": "Status",
            "description": "Current status of the validation job.",
            "example": "QUEUED"
          }
        },
        "type": "object",
        "required": ["job_id", "status"],
        "title": "ValidateAcceptedResponse",
        "description": "Acknowledgement response for an asynchronously started validation job."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": ["loc", "msg", "type"],
        "title": "ValidationError"
      },
      "ValidationResult": {
        "properties": {
          "patient_id": {
            "type": "string",
            "title": "Patient Id",
            "description": "Patient identifier.",
            "example": "abc123"
          },
          "outcome_id": {
            "type": "string",
            "title": "Outcome Id",
            "description": "Outcome identifier.",
            "example": "uDf9Cuc7"
          },
          "status": {
            "type": "string",
            "enum": ["success", "warning", "exclusion"],
            "title": "Status",
            "description": "Row-level profile status: ``success`` (would be scored), ``warning`` (would be scored with a cohort warning), or ``exclusion`` (would be hard-excluded).",
            "example": "warning"
          },
          "status_detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Detail",
            "description": "Cohort criteria summary for ``warning`` / ``exclusion`` rows; null for ``success`` rows.",
            "example": "Type 2 diabetes patients aged 18-75"
          }
        },
        "type": "object",
        "required": ["patient_id", "outcome_id", "status"],
        "title": "ValidationResult",
        "description": "Row in a standalone VALIDATION cohort-exclusion report.\n\nA VALIDATION job profiles which patients *would* be scored, warned, or\nexcluded per outcome, without running inference \u2014 so there are no score\ncolumns, only the row-level status. Deliberately distinct from\n``JobResult`` (whose nullable score fields would all be null here, and\nwhose schema would mislead clients about what the validation endpoint\nreturns)."
      }
    },
    "securitySchemes": {
      "OAuth2 Bearer Token": {
        "type": "http",
        "description": "Enter your Auth0 access token. Obtain a token by calling Auth0's `/oauth/token` endpoint with your client credentials. See the **Authentication** section in the API overview for details.",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "outcome",
      "description": "Outcome catalog endpoint"
    },
    {
      "name": "patient",
      "description": "Single patient inference workflow endpoint"
    },
    {
      "name": "job",
      "description": "Job management endpoints"
    },
    {
      "name": "batch",
      "description": "Batch inference workflow endpoints"
    },
    {
      "name": "usage",
      "description": "Usage metrics endpoints"
    }
  ]
}
