{
  "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://om1inc.us.auth0.com/oauth/token`\n\n**Example Request:**\n```bash\ncurl https://om1inc.us.auth0.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.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.4.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": [] }],
        "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."
          }
        ],
        "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" } }
        ],
        "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" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchValidateRequest" } } }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ValidateAcceptedResponse" } } }
          },
          "422": {
            "description": "Validation Error",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } }
          }
        }
      }
    },
    "/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" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchStartRequest" } } }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StartAcceptedResponse" } } }
          },
          "422": {
            "description": "Validation Error",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } }
          }
        }
      }
    },
    "/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",
        "requestBody": {
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobFromPatientRequest" } } },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobCreateResponse" } } }
          },
          "422": {
            "description": "Validation Error",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } }
          }
        },
        "security": [{ "OAuth2 Bearer Token": [] }]
      }
    },
    "/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."
          }
        ],
        "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" } }
        ],
        "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" }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Page_JobResult_" } } }
          },
          "422": {
            "description": "Validation Error",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } }
          }
        }
      }
    },
    "/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')."
          }
        ],
        "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}/exclusions": {
      "get": {
        "tags": ["job"],
        "summary": "Get Job Exclusions",
        "description": "Return patients excluded from scoring and the reasons.",
        "operationId": "get_job_exclusions_v1_job__job_id__exclusions_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."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Page_JobExclusion_" } } }
          },
          "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."
          }
        ],
        "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."
          }
        ],
        "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" } }
        ],
        "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."
          }
        ],
        "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" } }
        ],
        "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" } }
        ],
        "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" } }
        ],
        "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 inference 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.",
        "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": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": { "enum": ["outcome_id", "model_version", "status", "batch_type"], "type": "string" }
                },
                { "type": "null" }
              ],
              "description": "Aggregate by dimensions: \"outcome_id\", \"model_version\", \"status\", \"batch_type\".",
              "title": "Group By"
            },
            "description": "Aggregate by dimensions: \"outcome_id\", \"model_version\", \"status\", \"batch_type\"."
          }
        ],
        "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-05-18T17:18:53.877454+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-05-18T17:18:53.883549+00:00",
              "expires_at": "2026-06-17T17:18:53.883569+00:00",
              "ttl_days": 30
            }
          },
          "links": {
            "anyOf": [{ "$ref": "#/components/schemas/Links" }, { "type": "null" }],
            "description": "Hypermedia links for next actions on this batch.",
            "example": {
              "self": "https://api.phenom.om1.com/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472",
              "start": "https://api.phenom.om1.com/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/start",
              "upload": "https://api.phenom.om1.com/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/upload",
              "validate": "https://api.phenom.om1.com/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"]
          },
          "idempotency_key": {
            "anyOf": [{ "type": "string", "maxLength": 128 }, { "type": "null" }],
            "title": "Idempotency Key",
            "description": "Optional client-provided idempotency key for deduplication. If not provided, a server-generated key will be used.",
            "example": "my-unique-request-id-123"
          }
        },
        "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."
      },
      "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",
              "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."
      },
      "ExclusionsByReason": {
        "properties": {
          "demographic_ineligible": {
            "anyOf": [{ "type": "integer" }, { "type": "null" }],
            "title": "Demographic Ineligible",
            "description": "Number of patients excluded due to demographic ineligibility.",
            "example": 986
          },
          "insufficient_history": {
            "anyOf": [{ "type": "integer" }, { "type": "null" }],
            "title": "Insufficient History",
            "description": "Number of patients excluded due to insufficient history.",
            "example": 137
          }
        },
        "type": "object",
        "title": "ExclusionsByReason",
        "description": "Exclusion counts grouped by reason."
      },
      "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",
              "SUCCEEDED_WITH_EXCLUSIONS",
              "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."
      },
      "JobExclusion": {
        "properties": {
          "patient_id": {
            "type": "string",
            "title": "Patient Id",
            "description": "Patient identifier.",
            "example": "def456"
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Reason for exclusion.",
            "example": "demographic_ineligible"
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "Detailed explanation of the exclusion.",
            "example": "Age outside outcome cohort range"
          },
          "outcomes_affected": {
            "items": { "type": "string" },
            "type": "array",
            "title": "Outcomes Affected",
            "description": "List of outcome IDs affected by this exclusion. Empty for LINKING-stage exclusions (patient excluded from all outcomes). Populated for outcome-cohort exclusions.",
            "default": [],
            "example": ["uDf9Cuc7"]
          }
        },
        "type": "object",
        "required": ["patient_id", "reason", "detail"],
        "title": "JobExclusion",
        "description": "Patient exclusion 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" },
          "idempotency_key": {
            "type": "string",
            "title": "Idempotency Key",
            "description": "Idempotency key for the job. This protects against duplicate requests, and must be provided by the client.",
            "example": "idem-b-20251107-abc123"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": ["outcome_ids", "patient_history", "idempotency_key"],
        "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",
              "SUCCEEDED_WITH_EXCLUSIONS",
              "FAILED"
            ],
            "title": "Status",
            "description": "Current status of the job.",
            "example": "SUCCEEDED_WITH_EXCLUSIONS"
          },
          "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 records processed.",
            "example": 1245678
          },
          "patients_scored": {
            "type": "integer",
            "title": "Patients Scored",
            "description": "Number of patients successfully scored.",
            "example": 101234
          },
          "patients_excluded": {
            "type": "integer",
            "title": "Patients Excluded",
            "description": "Number of patients excluded from scoring.",
            "example": 1123
          },
          "exclusions_by_reason": {
            "$ref": "#/components/schemas/ExclusionsByReason",
            "description": "Breakdown of exclusions by reason."
          },
          "error_rows": {
            "type": "integer",
            "title": "Error Rows",
            "description": "Number of rows with errors.",
            "example": 0
          }
        },
        "type": "object",
        "required": ["records_processed", "patients_scored", "patients_excluded", "exclusions_by_reason", "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.",
            "example": 0.0423
          },
          "probability": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Probability",
            "description": "Predicted probability (0.0 to 1.0).",
            "example": 0.7421
          },
          "prob_upper_95_percent_bound": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Prob Upper 95 Percent Bound",
            "description": "Upper 95% confidence bound for probability.",
            "example": 0.7934
          },
          "prob_lower_95_percent_bound": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Prob Lower 95 Percent Bound",
            "description": "Lower 95% confidence bound for probability.",
            "example": 0.6912
          },
          "relative_probability": {
            "type": "number",
            "minimum": 0.0,
            "title": "Relative Probability",
            "description": "Relative probability compared to baseline.",
            "example": 2.18
          },
          "rel_upper_95_percent_bound": {
            "type": "number",
            "minimum": 0.0,
            "title": "Rel Upper 95 Percent Bound",
            "description": "Upper 95% confidence bound for relative probability.",
            "example": 2.36
          },
          "rel_lower_95_percent_bound": {
            "type": "number",
            "minimum": 0.0,
            "title": "Rel Lower 95 Percent Bound",
            "description": "Lower 95% confidence bound for relative probability.",
            "example": 2.02
          },
          "bin_id": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Bin Id",
            "description": "Risk bin identifier.",
            "example": 9
          },
          "num_bins": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Num Bins",
            "description": "Total number of risk bins.",
            "example": 100
          }
        },
        "type": "object",
        "required": [
          "patient_id",
          "outcome_id",
          "probability",
          "prob_upper_95_percent_bound",
          "prob_lower_95_percent_bound",
          "relative_probability",
          "rel_upper_95_percent_bound",
          "rel_lower_95_percent_bound",
          "bin_id",
          "num_bins"
        ],
        "title": "JobResult",
        "description": "Individual job result for a patient and outcome."
      },
      "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",
              "SUCCEEDED_WITH_EXCLUSIONS",
              "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": "https://api.phenom.om1.com/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472"
          },
          "upload": {
            "type": "string",
            "title": "Upload",
            "description": "URL to initiate file uploads for this batch.",
            "example": "https://api.phenom.om1.com/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/upload"
          },
          "validate": {
            "type": "string",
            "title": "Validate",
            "description": "URL to trigger validation of uploaded batch contents.",
            "example": "https://api.phenom.om1.com/batches/batch_0199bb07-3b87-7e83-8842-ad9d52a3c472/validate"
          },
          "start": {
            "type": "string",
            "title": "Start",
            "description": "URL to start processing the batch after validation.",
            "example": "https://api.phenom.om1.com/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_JobExclusion_": {
        "properties": {
          "items": {
            "items": { "$ref": "#/components/schemas/JobExclusion" },
            "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[JobExclusion]"
      },
      "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]"
      },
      "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",
              "SUCCEEDED_WITH_EXCLUSIONS",
              "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."
      },
      "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)."
          },
          "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", "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" },
          "input": { "title": "Input" },
          "ctx": { "type": "object", "title": "Context" }
        },
        "type": "object",
        "required": ["loc", "msg", "type"],
        "title": "ValidationError"
      }
    },
    "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" }
  ]
}
