openapi: 3.1.0
info:
  title: Apex Catalyst Genomics & Drug Discovery API
  version: 1.0.0
  summary: Genomic variant search, biomarker tracking, bioinformatics analysis, and pipeline management
  description: |
    OpenAPI contract for Apex Catalyst v1 endpoints under api.parkerapex.com.
    Catalyst provides genomic variant querying, biomarker monitoring,
    bioinformatics analysis submission, and pipeline run tracking.

    **Core Differentiators**
    - All records are **dual-verified** (patient + provider)
    - Every data submission creates or resolves a **GPID** (Global Patient ID)
    - HIPAA-compliant audit trail on every mutation
servers:
  - url: https://api.parkerapex.com/catalyst/v1
    description: Production
  - url: https://sandbox.api.parkerapex.com/catalyst/v1
    description: Sandbox
tags:
  - name: Variants
    description: Genomic variant search and detail
  - name: Biomarkers
    description: Biomarker listing and tracking
  - name: Analysis
    description: Bioinformatics analysis submission and results
  - name: Pipelines
    description: Pipeline run status and monitoring
security:
  - BearerAuth: []
paths:
  /variants:
    get:
      tags: [Variants]
      operationId: listVariants
      summary: Search genomic variants
      description: |
        Query genetic variants with filtering by gene, chromosome, classification,
        and actionability. All results include dual-verification status.
      x-dual-verified: true
      x-gpid-required: true
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/XCatalystTenantId'
        - $ref: '#/components/parameters/XCorrelationId'
        - name: gene_symbol
          in: query
          required: false
          schema:
            type: string
          description: Filter by gene symbol (e.g. BRCA1, TP53)
          example: BRCA1
        - name: chromosome
          in: query
          required: false
          schema:
            type: string
          description: Filter by chromosome (e.g. chr17, chrX)
          example: chr17
        - name: variant_class
          in: query
          required: false
          schema:
            type: string
            enum: [pathogenic, likely_pathogenic, uncertain_significance, likely_benign, benign]
          description: Filter by clinical classification
        - name: variant_type
          in: query
          required: false
          schema:
            type: string
            enum: [SNV, INDEL, CNV, SV]
          description: Filter by variant type
        - name: actionable
          in: query
          required: false
          schema:
            type: boolean
          description: Filter to actionable variants only
        - name: patient_gpid
          in: query
          required: false
          schema:
            type: string
          description: Filter by patient GPID
          example: CMS-00012345
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: per_page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: Paginated list of genomic variants
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VariantListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
  /variants/{variantId}:
    get:
      tags: [Variants]
      operationId: getVariant
      summary: Get variant detail
      description: Retrieve full details for a single genetic variant including clinical significance, population frequency, and drug response data.
      x-dual-verified: true
      x-gpid-required: true
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/VariantId'
        - $ref: '#/components/parameters/XCatalystTenantId'
        - $ref: '#/components/parameters/XCorrelationId'
      responses:
        '200':
          description: Variant detail
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VariantDetail'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /biomarkers:
    get:
      tags: [Biomarkers]
      operationId: listBiomarkers
      summary: List biomarkers
      description: |
        Retrieve biomarker measurements with filtering by type, status, and patient.
        Supports time-range filtering for trend analysis.
      x-dual-verified: true
      x-gpid-required: true
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/XCatalystTenantId'
        - $ref: '#/components/parameters/XCorrelationId'
        - name: biomarker_type
          in: query
          required: false
          schema:
            type: string
            enum: [protein, metabolite, gene_expression, epigenetic, circulating_tumor]
          description: Filter by biomarker type
        - name: biomarker_name
          in: query
          required: false
          schema:
            type: string
          description: Filter by biomarker name (partial match)
        - name: status
          in: query
          required: false
          schema:
            type: string
            enum: [normal, abnormal, critical]
        - name: patient_gpid
          in: query
          required: false
          schema:
            type: string
          example: CMS-00012345
        - name: date_from
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: date_to
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: flagged
          in: query
          required: false
          schema:
            type: boolean
          description: Filter to flagged-for-review biomarkers only
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: per_page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: Paginated list of biomarkers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BiomarkerListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
  /analysis:
    post:
      tags: [Analysis]
      operationId: submitAnalysis
      summary: Submit bioinformatics analysis
      description: |
        Submit a new bioinformatics analysis job. The analysis is queued for
        asynchronous processing. Poll GET /analysis/{id} for results.
        A GPID is resolved or created for the patient on submission.
      x-dual-verified: true
      x-gpid-required: true
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/XCatalystTenantId'
        - $ref: '#/components/parameters/XCorrelationId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalysisSubmitRequest'
            examples:
              variant_calling:
                value:
                  patient_gpid: CMS-00012345
                  genomic_sample_id: GS-20260415-001
                  analysis_type: variant_calling
                  pipeline_name: GATK-HaplotypeCaller
                  pipeline_version: '4.5.0'
                  parameters:
                    reference_genome: GRCh38
                    min_quality: 30
                    min_depth: 10
      responses:
        '202':
          description: Analysis accepted for processing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalysisAcceptedResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
  /analysis/{analysisId}:
    get:
      tags: [Analysis]
      operationId: getAnalysisResults
      summary: Get analysis results
      description: Retrieve status and results for a bioinformatics analysis job.
      x-dual-verified: true
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/AnalysisId'
        - $ref: '#/components/parameters/XCatalystTenantId'
        - $ref: '#/components/parameters/XCorrelationId'
      responses:
        '200':
          description: Analysis status and results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalysisResultResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /pipeline-runs:
    get:
      tags: [Pipelines]
      operationId: listPipelineRuns
      summary: List pipeline runs
      description: Retrieve recent pipeline execution status across all analyses.
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/XCatalystTenantId'
        - $ref: '#/components/parameters/XCorrelationId'
        - name: status
          in: query
          required: false
          schema:
            type: string
            enum: [queued, running, completed, failed]
        - name: pipeline_name
          in: query
          required: false
          schema:
            type: string
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: per_page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: Paginated list of pipeline runs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineRunListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Plexus IAM JWT bearer token issued via OAuth 2.0 authorization code flow.
  parameters:
    VariantId:
      in: path
      name: variantId
      required: true
      schema:
        type: integer
      description: Genetic variant primary key
    AnalysisId:
      in: path
      name: analysisId
      required: true
      schema:
        type: string
      description: Analysis identifier (e.g. ANA-20260415-001)
    XCatalystTenantId:
      in: header
      name: X-Catalyst-Tenant-Id
      required: true
      schema:
        type: string
      description: Tenant identifier for multi-tenant isolation
    XCorrelationId:
      in: header
      name: X-Correlation-Id
      required: false
      schema:
        type: string
        format: uuid
      description: Optional correlation ID for distributed tracing
    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: true
      schema:
        type: string
        format: uuid
      description: Idempotency key for safe retries
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: Caller does not have required role/scope
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Conflict:
      description: Resource conflict (duplicate idempotency key)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnprocessableEntity:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: Too many requests
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    VariantSummary:
      type: object
      required: [id, chromosome, position, gene_symbol, variant_type, variant_class, dual_verified]
      properties:
        id:
          type: integer
        variant_id:
          type: string
          description: Unique variant identifier
        chromosome:
          type: string
        position:
          type: integer
          format: int64
        reference_allele:
          type: string
        alternate_allele:
          type: string
        gene_symbol:
          type: string
        variant_type:
          type: string
          enum: [SNV, INDEL, CNV, SV]
        variant_class:
          type: string
          enum: [pathogenic, likely_pathogenic, uncertain_significance, likely_benign, benign]
        actionable:
          type: boolean
        clinical_significance:
          type: string
        dbsnp_id:
          type: string
        population_frequency:
          type: number
          format: float
        patient_gpid:
          type: string
          description: GPID of the associated patient
        dual_verified:
          type: boolean
          description: Whether this record has been verified by both patient and provider
    VariantDetail:
      allOf:
        - $ref: '#/components/schemas/VariantSummary'
        - type: object
          properties:
            gene_id:
              type: string
              description: ENSEMBL gene ID
            transcript_id:
              type: string
            consequence:
              type: string
              description: Variant consequence (missense, nonsense, frameshift, etc.)
            amino_acid_change:
              type: string
            zygosity:
              type: string
              enum: [homozygous, heterozygous, hemizygous]
            quality_score:
              type: number
              format: float
            read_depth:
              type: integer
            allele_frequency:
              type: number
              format: float
            clinvar_id:
              type: string
            cosmic_id:
              type: string
            disease_association:
              type: string
            drug_response:
              type: string
            interpretation_status:
              type: string
              enum: [unreviewed, reviewed, validated]
            reviewed_by:
              type: string
            review_date:
              type: string
              format: date-time
            created_at:
              type: string
              format: date-time
            notes:
              type: string
    VariantListResponse:
      type: object
      required: [data, meta]
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/VariantSummary'
        meta:
          $ref: '#/components/schemas/PaginationMeta'
    BiomarkerSummary:
      type: object
      required: [id, biomarker_name, biomarker_type, measurement_value, unit, status, dual_verified]
      properties:
        id:
          type: integer
        biomarker_name:
          type: string
        biomarker_type:
          type: string
          enum: [protein, metabolite, gene_expression, epigenetic, circulating_tumor]
        measurement_value:
          type: number
          format: float
        unit:
          type: string
        reference_range_low:
          type: number
          format: float
        reference_range_high:
          type: number
          format: float
        status:
          type: string
          enum: [normal, abnormal, critical]
        flagged_for_review:
          type: boolean
        collection_date:
          type: string
          format: date-time
        sample_type:
          type: string
        assay_method:
          type: string
        patient_gpid:
          type: string
        dual_verified:
          type: boolean
    BiomarkerListResponse:
      type: object
      required: [data, meta]
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/BiomarkerSummary'
        meta:
          $ref: '#/components/schemas/PaginationMeta'
    AnalysisSubmitRequest:
      type: object
      required: [patient_gpid, genomic_sample_id, analysis_type, pipeline_name]
      properties:
        patient_gpid:
          type: string
          description: GPID of the patient (resolved or created on submission)
          example: CMS-00012345
        genomic_sample_id:
          type: string
          description: Identifier of the genomic data sample to analyse
        analysis_type:
          type: string
          enum: [variant_calling, cnv_analysis, pharmacogenomics, gene_expression, structural_variant]
        pipeline_name:
          type: string
          example: GATK-HaplotypeCaller
        pipeline_version:
          type: string
          example: '4.5.0'
        parameters:
          type: object
          additionalProperties: true
          description: Pipeline-specific configuration parameters
    AnalysisAcceptedResponse:
      type: object
      required: [analysis_id, status, status_url]
      properties:
        analysis_id:
          type: string
          example: ANA-20260415-001
        status:
          type: string
          const: queued
        patient_gpid:
          type: string
        status_url:
          type: string
          format: uri
          example: https://api.parkerapex.com/catalyst/v1/analysis/ANA-20260415-001
    AnalysisResultResponse:
      type: object
      required: [analysis_id, analysis_type, status, dual_verified]
      properties:
        analysis_id:
          type: string
        analysis_type:
          type: string
        pipeline_name:
          type: string
        pipeline_version:
          type: string
        status:
          type: string
          enum: [queued, running, completed, failed]
        started_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        execution_time_seconds:
          type: integer
        total_variants:
          type: integer
        pathogenic_variants:
          type: integer
        actionable_findings:
          type: integer
        quality_metrics:
          type: object
          additionalProperties: true
        findings_summary:
          type: string
        recommendations:
          type: string
        clinical_report_generated:
          type: boolean
        patient_gpid:
          type: string
        dual_verified:
          type: boolean
    PipelineRunSummary:
      type: object
      required: [analysis_id, analysis_type, pipeline_name, status]
      properties:
        analysis_id:
          type: string
        analysis_type:
          type: string
        pipeline_name:
          type: string
        pipeline_version:
          type: string
        status:
          type: string
          enum: [queued, running, completed, failed]
        started_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        execution_time_display:
          type: string
          description: Human-readable execution time (e.g. "2m 34s")
        total_variants:
          type: integer
        pathogenic_variants:
          type: integer
        patient_gpid:
          type: string
    PipelineRunListResponse:
      type: object
      required: [data, meta]
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PipelineRunSummary'
        meta:
          $ref: '#/components/schemas/PaginationMeta'
    PaginationMeta:
      type: object
      required: [page, per_page, total, total_pages]
      properties:
        page:
          type: integer
        per_page:
          type: integer
        total:
          type: integer
        total_pages:
          type: integer
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message]
          properties:
            code:
              type: string
              enum:
                - AUTH_REQUIRED
                - FORBIDDEN_ROLE
                - VALIDATION_ERROR
                - RESOURCE_NOT_FOUND
                - RESOURCE_CONFLICT
                - RATE_LIMITED
                - INTERNAL_ERROR
            message:
              type: string
            details:
              type: array
              items:
                $ref: '#/components/schemas/ErrorDetail'
            correlation_id:
              type: string
              format: uuid
    ErrorDetail:
      type: object
      properties:
        field:
          type: string
        constraint:
          type: string
