openapi: 3.0.3

info:
  title: GLP-1 Coverage Criteria API
  version: "1.0"
  description: |
    A normalized database of GLP-1 prior-authorization criteria across U.S.
    commercial, Medicare, and Medicaid payers — every record human-reviewed,
    dated, and tied to its source policy.

    `POST /coverage` resolves a payer × drug × indication (× optional plan
    type) to structured coverage criteria: step therapy, BMI and A1C
    thresholds, qualification pathways, required documentation, quantity
    limits, approval durations, and provenance. `POST /resolve` maps the plan
    name printed on a member's insurance card to the right payer before a
    coverage lookup.

    ### Payer resolution built in

    You don't need to know our payer keys. Send the payer name as it appears
    on the card — `"Kaiser Permanente Colorado"`, or an alias like
    `"Cigna HealthSpring"` — and the API resolves it, reporting `match_type`
    and `confidence` so your integration can decide when to trust the match.
    Medicaid managed-care plan names resolve to the state Medicaid criteria
    that actually govern them (`mco_fallback`). Resolution is exact-match
    only (canonical names and curated aliases): a name that cannot be matched
    to a specific payer returns no match rather than a near-miss — a wrong
    criteria set is worse than no answer.

    ### Why POST with a JSON body

    All selectors travel in the JSON request body — never the URL. The API
    rejects any query string with `400`, because URLs are logged by edge
    infrastructure before application-level filtering can run. Combined with
    a deny-by-default parameter allowlist (unexpected body keys are rejected,
    not ignored), this means nothing patient-identifying can end up in an
    infrastructure log even by accident. The API accepts plan selectors only
    — never patient or clinical data.

    ### Honest verdicts

    Every `coverage` entry carries one of seven `coverage_state` values,
    including explicit `no_data` (we haven't captured this combination — a
    gap, not a denial) and `off_label` — the API never converts silence into
    a coverage answer. Only human-reviewed records
    (`provenance.source_type: reviewed_policy`) carry criteria detail.

    Access is by API key, metered per request with a daily limit. Request a
    key at https://myglp1coverage.com/#request-access.
  contact:
    name: API access
    url: https://myglp1coverage.com/#request-access
  license:
    name: Proprietary — licensed access only
    url: https://myglp1coverage.com/terms

servers:
  - url: https://api.myglp1coverage.com/api/v1
    description: Production

security:
  - BearerAuth: []
  - ApiKeyAuth: []

tags:
  - name: Coverage
    description: Coverage-criteria lookup
  - name: Resolution
    description: Payer resolution from card/plan names

paths:
  /coverage:
    post:
      tags: [Coverage]
      operationId: lookupCoverage
      summary: Look up coverage criteria
      description: |
        Resolves the payer and drug, then returns one coverage entry per plan
        type (or only the requested `plan_type`). Selectors go in the JSON
        body; any query-string parameter is rejected with `400`.

        If the payer was matched via an alias that pins a line of business
        (e.g. a Medicare Advantage product name), an explicitly contradictory
        `plan_type` returns `409` rather than silently answering for the
        wrong line. Medicare Part D and Medicare Advantage share PA criteria
        and are treated as one line.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CoverageLookupRequest"
            example:
              payer: "Kaiser Permanente Colorado"
              drug: "Wegovy"
              indication: "weight_loss"
              plan_type: "commercial"
      responses:
        "200":
          description: Resolved payer/drug and one coverage entry per plan type.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CoverageLookupResponse"
              examples:
                wegovy-kaiser-co-weight-loss:
                  summary: "Wegovy · weight loss · Kaiser Permanente Colorado (commercial) — conditional on benefit"
                  description: >
                    Covered, but only for members whose benefit plan includes
                    weight-loss medication coverage (`coverage_scope:
                    rider_required`). Verbatim production response.
                  value:
                    {
                      "query": {
                        "payer": "Kaiser Permanente Colorado",
                        "drug": "Wegovy",
                        "indication": "weight_loss",
                        "plan_type": "commercial"
                      },
                      "resolved": {
                        "payer": {
                          "payer_id": 44,
                          "name": "Kaiser Permanente Colorado",
                          "payer_type": "regional",
                          "match_type": "exact_name",
                          "confidence": 1.0,
                          "mco_fallback": false
                        },
                        "drug": {
                          "id": 2,
                          "brand_name": "Wegovy",
                          "generic_name": "semaglutide"
                        }
                      },
                      "coverage": [
                        {
                          "plan_type": "commercial",
                          "formulary": "HMO (all plans)",
                          "formulary_varies": false,
                          "coverage_state": "conditional_on_benefit",
                          "is_covered": true,
                          "is_preferred": false,
                          "coverage_scope": "rider_required",
                          "coverage_scope_note": "Patient must have benefit plan with coverage for weight loss medications",
                          "basis": null,
                          "requirements": {
                            "age": {
                              "min": 12,
                              "max": null
                            },
                            "bmi": {
                              "min": 30.0,
                              "min_with_comorbidity": 27.0,
                              "min_asian": null,
                              "percentile_min": null
                            },
                            "a1c": {
                              "min": null,
                              "max": null,
                              "for_combination_therapy": null
                            },
                            "step_therapy": {
                              "requires_metformin_trial": false,
                              "metformin_trial_duration_days": null,
                              "metformin_exception_conditions": [],
                              "requires_prior_glp1_trial": true,
                              "prior_glp1_drugs": [
                                "generic liraglutide (Victoza)"
                              ],
                              "prior_glp1_count_required": 1,
                              "prior_weight_loss_drugs": [
                                "phentermine",
                                "diethylpropion",
                                "Qsymia",
                                "Contrave"
                              ],
                              "prior_weight_loss_trial_months": 3
                            },
                            "cardiovascular": {
                              "requires_cv_disease": false,
                              "cv_qualifying_events": [],
                              "requires_gdmt": false,
                              "gdmt_medications": []
                            },
                            "osa": {
                              "requires_osa_diagnosis": false,
                              "ahi_min": null,
                              "requires_pap_trial": false
                            },
                            "mash": {
                              "requires_mash_diagnosis": false,
                              "fibrosis_stage_min": null,
                              "fibrosis_stage_max": null,
                              "confirmation_methods": []
                            },
                            "renal": {
                              "egfr_min": null,
                              "egfr_max": null,
                              "uacr_min": null
                            },
                            "lifestyle": {
                              "requires_program": false,
                              "duration_months": null
                            },
                            "diagnosis": {
                              "requires_diagnosis_code": false,
                              "codes": [],
                              "confirmation_methods": [
                                "clinical_diagnosis"
                              ],
                              "requires_lab_verification": false,
                              "excludes_diabetes": false
                            },
                            "comorbidities_accepted": [
                              "HTN",
                              "dyslipidemia",
                              "T2DM"
                            ],
                            "exclusions": {
                              "other": [
                                "Concurrent use with another GLP-1 or GLP/GIP (e.g., tirzepatide) product",
                                "Concurrent use of DPP-4 inhibitor (alogliptin, linagliptin, saxagliptin, sitagliptin)",
                                "Step therapy failure exceptions do not apply for convenience or needle phobia",
                                "Wegovy (semaglutide) tablets excluded per P&T",
                                "Patient must have benefit plan with coverage for weight loss medications"
                              ],
                              "pregnancy": false,
                              "type_1_diabetes": false,
                              "bariatric_surgery": false
                            }
                          },
                          "qualification_pathways": [
                            {
                              "all_of": [
                                "Patient is 12 years of age or older",
                                "Patient has benefit plan with coverage for weight loss medications",
                                "Not currently using a DPP-4 inhibitor (alogliptin, linagliptin, saxagliptin, or sitagliptin)",
                                "Patient will NOT use Wegovy with another GLP-1 or GLP/GIP (e.g., tirzepatide) product",
                                "Current weight on file within the past 4 weeks (objectively measured in-office)",
                                "BMI >= 30 kg/m2 OR (BMI >= 27 kg/m2 AND at least one weight-related comorbidity: hypertension, dyslipidemia, or type 2 diabetes)",
                                "Provider attests patient is on a reduced calorie diet and has increased physical activity",
                                "Documented intolerance, contraindication, or failure to lose and maintain at least 5% body weight after trial of all required step therapy agents, OR provider submits justification per criteria"
                              ],
                              "any_of": [
                                "Step therapy completed in order: (a) phentermine 37.5 mg/day OR diethylpropion 75 mg/day for >= 3 months, then (b) Qsymia (phentermine 15 mg/topiramate 92 mg/day) for >= 3 months, then (c) Contrave (naltrexone 32 mg/bupropion 360 mg/day) for >= 3 months, then (d) generic liraglutide (Victoza) 3 mg/day for >= 3 months",
                                "Provider justification: required drug(s) contraindicated or will likely cause adverse reaction/harm",
                                "Provider justification: required drug(s) ineffective based on known clinical characteristics",
                                "Provider justification: patient tried and failed required drug(s) or same-class agent, discontinued due to lack of efficacy, diminished effect, or adverse event",
                                "Patient is stable on requested drug after completing step therapy or receiving a step therapy exception"
                              ],
                              "pathway_name": "Initial approval for weight loss (age 12+)"
                            }
                          ],
                          "required_documentation": [
                            "Current (within past 4 weeks) BMI (kg/m2) — objectively measured in-office weight check",
                            "Documentation of weight-related comorbidities if BMI is 27-<30 kg/m2 (hypertension, dyslipidemia, or type 2 diabetes)",
                            "Documentation of failed trials of step therapy agents (medication, strength, dates of treatment, reason for discontinuation) OR provider justification why alternatives are not suitable with supporting clinical documentation",
                            "Provider attestation that patient is on a reduced calorie diet and has increased physical activity",
                            "Confirmation that patient is not currently on a DPP-4 inhibitor",
                            "Confirmation that patient will not use Wegovy concurrently with another GLP-1 or GLP/GIP product"
                          ],
                          "quantity_limits": [
                            {
                              "strengths": [
                                "all strengths"
                              ],
                              "supply_28_day": "1 box / 4 pens / 3 mL (max daily dose 0.11 mL); renewal: 1 box / 1 pen / 3 mL per 28 days",
                              "supply_84_day": null
                            }
                          ],
                          "approval": {
                            "initial_months": 6,
                            "continuation_months": 12,
                            "continuation_clinical_benefit": "Patient must have achieved and maintained at least 5% weight loss from baseline (objectively measured with in-office weight checks). BMI check within past 4 weeks required. Initial step therapy requirements (phentermine, Qsymia, Contrave, generic liraglutide trials) are NOT re-verified at renewal.",
                            "continuation_weight_loss_percent": 5.0,
                            "minimum_maintenance_dose_mg": null,
                            "minimum_therapy_weeks": null
                          },
                          "provenance": {
                            "source_type": "reviewed_policy",
                            "documented": true,
                            "effective_date": "2026-02-01",
                            "expiration_date": null,
                            "last_verified_at": "2026-06-05T14:01:33.189Z"
                          }
                        }
                      ]
                    }
                ozempic-bcbs-wy-diabetes:
                  summary: "Ozempic · diabetes · BCBS Wyoming (commercial) — preferred, covered with requirements"
                  description: >
                    Preferred agent covered under standard criteria with two
                    qualification pathways (continuation of therapy, or new
                    therapy via step-therapy failure/exception). Verbatim
                    production response.
                  value:
                    {
                      "query": {
                        "payer": "BCBS Wyoming",
                        "drug": "Ozempic",
                        "indication": "diabetes",
                        "plan_type": "commercial"
                      },
                      "resolved": {
                        "payer": {
                          "payer_id": 37,
                          "name": "BCBS Wyoming",
                          "payer_type": "bcbs_independent",
                          "match_type": "exact_name",
                          "confidence": 1.0,
                          "mco_fallback": false
                        },
                        "drug": {
                          "id": 1,
                          "brand_name": "Ozempic",
                          "generic_name": "semaglutide"
                        }
                      },
                      "coverage": [
                        {
                          "plan_type": "commercial",
                          "formulary": "Standard",
                          "formulary_varies": false,
                          "coverage_state": "covered_with_requirements",
                          "is_covered": true,
                          "is_preferred": true,
                          "coverage_scope": "standard",
                          "coverage_scope_note": null,
                          "basis": null,
                          "requirements": {
                            "age": {
                              "min": null,
                              "max": null
                            },
                            "bmi": {
                              "min": null,
                              "min_with_comorbidity": null,
                              "min_asian": null,
                              "percentile_min": null
                            },
                            "a1c": {
                              "min": 6.5,
                              "max": null,
                              "for_combination_therapy": null
                            },
                            "step_therapy": {
                              "requires_metformin_trial": false,
                              "metformin_trial_duration_days": 90,
                              "metformin_exception_conditions": [
                                "intolerance",
                                "hypersensitivity",
                                "contraindication",
                                "ASCVD",
                                "CKD",
                                "MASH"
                              ],
                              "requires_prior_glp1_trial": false,
                              "prior_glp1_drugs": [],
                              "prior_glp1_count_required": null,
                              "prior_weight_loss_drugs": [],
                              "prior_weight_loss_trial_months": null
                            },
                            "cardiovascular": {
                              "requires_cv_disease": false,
                              "cv_qualifying_events": [
                                "myocardial_infarction",
                                "stroke",
                                "revascularization",
                                "TIA",
                                "unstable_angina",
                                "amputation",
                                "coronary_artery_disease"
                              ],
                              "requires_gdmt": false,
                              "gdmt_medications": []
                            },
                            "osa": {
                              "requires_osa_diagnosis": false,
                              "ahi_min": null,
                              "requires_pap_trial": false
                            },
                            "mash": {
                              "requires_mash_diagnosis": false,
                              "fibrosis_stage_min": "F2",
                              "fibrosis_stage_max": "F3",
                              "confirmation_methods": []
                            },
                            "renal": {
                              "egfr_min": null,
                              "egfr_max": null,
                              "uacr_min": null
                            },
                            "lifestyle": {
                              "requires_program": false,
                              "duration_months": null
                            },
                            "diagnosis": {
                              "requires_diagnosis_code": false,
                              "codes": [],
                              "confirmation_methods": [
                                "lab_confirmation"
                              ],
                              "requires_lab_verification": true,
                              "excludes_diabetes": false
                            },
                            "comorbidities_accepted": [],
                            "exclusions": {
                              "other": [
                                "Combination use with a DPP-4 containing agent (e.g., Januvia, Onglyza, Tradjenta, etc.) for the requested indication",
                                "Combination use with another GLP-1 receptor agonist",
                                "Any FDA labeled contraindication to the requested agent"
                              ],
                              "pregnancy": false,
                              "type_1_diabetes": false,
                              "bariatric_surgery": false
                            }
                          },
                          "qualification_pathways": [
                            {
                              "all_of": [
                                "Diagnosis of type 2 diabetes",
                                "A1C >= 6.5% confirmed by lab test",
                                "Requested agent is eligible for continuation of therapy (Ozempic is listed as eligible)",
                                "No FDA labeled contraindications to the requested agent",
                                "Not using in combination with a DPP-4 containing agent",
                                "Not using in combination with another GLP-1 receptor agonist"
                              ],
                              "any_of": [
                                "Patient has been treated with a preferred agent within the past 90 days (not starting on samples)",
                                "Prescriber states patient has been treated with a preferred agent within the past 90 days and is at risk if therapy is discontinued"
                              ],
                              "pathway_name": "Continuation of therapy"
                            },
                            {
                              "all_of": [
                                "Diagnosis of type 2 diabetes",
                                "A1C >= 6.5% confirmed by lab test",
                                "No FDA labeled contraindications to the requested agent",
                                "Not using in combination with a DPP-4 containing agent",
                                "Not using in combination with another GLP-1 receptor agonist",
                                "Patient age is within FDA labeling for the requested indication OR there is support for use at patient's age"
                              ],
                              "any_of": [
                                "Tried and had inadequate response to ONE prerequisite agent containing metformin or insulin",
                                "Intolerance or hypersensitivity to metformin or insulin",
                                "FDA labeled contraindication to BOTH metformin AND insulin",
                                "Patient has established cardiovascular disease (e.g., MI, stroke, revascularization, TIA, unstable angina, amputation, CAD) OR multiple CV risk factors (HTN, dyslipidemia, family history of CVD, smoking) AND requested agent will be used to reduce risk of MACE",
                                "Patient has chronic kidney disease (CKD) AND requested agent will be used to reduce risk of sustained eGFR decline, ESKD, and cardiovascular death",
                                "Patient has diagnosis of noncirrhotic MASH with moderate to advanced liver fibrosis (F2 to F3)"
                              ],
                              "pathway_name": "New therapy — step therapy failure or exception"
                            }
                          ],
                          "required_documentation": [
                            "Lab test confirming T2DM diagnosis (e.g., A1C >= 6.5%) or medical records",
                            "Documentation of type 2 diabetes diagnosis",
                            "Documentation of one of: inadequate response to metformin or insulin trial, intolerance/hypersensitivity to metformin or insulin, contraindication to both metformin and insulin, established CV disease or multiple CV risk factors, CKD diagnosis, or noncirrhotic MASH with F2-F3 fibrosis — OR documentation of prior preferred agent use within past 90 days for continuation",
                            "Confirmation that patient will not use requested agent in combination with a DPP-4 containing agent",
                            "Confirmation that patient will not use requested agent in combination with another GLP-1 receptor agonist"
                          ],
                          "quantity_limits": [
                            {
                              "strengths": [
                                "2 MG/3ML"
                              ],
                              "supply_28_day": "1 pen per 28 days",
                              "supply_84_day": null
                            },
                            {
                              "strengths": [
                                "4 MG/3ML"
                              ],
                              "supply_28_day": "1 pen per 28 days",
                              "supply_84_day": null
                            },
                            {
                              "strengths": [
                                "8 MG/3ML"
                              ],
                              "supply_28_day": "1 pen per 28 days",
                              "supply_84_day": null
                            }
                          ],
                          "approval": {
                            "initial_months": 12,
                            "continuation_months": 12,
                            "continuation_clinical_benefit": "Patient has been treated with a preferred agent within the past 90 days (starting on samples is not approvable), OR prescriber states patient has been treated with a preferred agent within the past 90 days and is at risk if therapy is discontinued. Initial A1C and step therapy requirements are not re-verified at continuation.",
                            "continuation_weight_loss_percent": null,
                            "minimum_maintenance_dose_mg": null,
                            "minimum_therapy_weeks": null
                          },
                          "provenance": {
                            "source_type": "reviewed_policy",
                            "documented": true,
                            "effective_date": "2026-05-11",
                            "expiration_date": null,
                            "last_verified_at": "2026-06-04T22:04:01.858Z"
                          }
                        }
                      ]
                    }
                wegovy-nd-medicaid-cv:
                  summary: "Wegovy · CV risk reduction · North Dakota Medicaid — covered with requirements"
                  description: >
                    Medicaid MACE-reduction criteria with an age band, BMI
                    window, required cardiovascular history, concurrent GDMT,
                    and Ozempic step therapy. Verbatim production response.
                  value:
                    {
                      "query": {
                        "payer": "North Dakota Medicaid",
                        "drug": "Wegovy",
                        "indication": "cv_risk_reduction",
                        "plan_type": "medicaid"
                      },
                      "resolved": {
                        "payer": {
                          "payer_id": 131,
                          "name": "North Dakota Medicaid",
                          "payer_type": "regional",
                          "match_type": "exact_name",
                          "confidence": 1.0,
                          "mco_fallback": false
                        },
                        "drug": {
                          "id": 2,
                          "brand_name": "Wegovy",
                          "generic_name": "semaglutide"
                        }
                      },
                      "coverage": [
                        {
                          "plan_type": "medicaid",
                          "formulary": "Standard",
                          "formulary_varies": false,
                          "coverage_state": "covered_with_requirements",
                          "is_covered": true,
                          "is_preferred": false,
                          "coverage_scope": "standard",
                          "coverage_scope_note": null,
                          "basis": null,
                          "requirements": {
                            "age": {
                              "min": 55,
                              "max": 74
                            },
                            "bmi": {
                              "min": 27.0,
                              "min_with_comorbidity": null,
                              "min_asian": null,
                              "percentile_min": null
                            },
                            "a1c": {
                              "min": null,
                              "max": null,
                              "for_combination_therapy": null
                            },
                            "step_therapy": {
                              "requires_metformin_trial": false,
                              "metformin_trial_duration_days": null,
                              "metformin_exception_conditions": [],
                              "requires_prior_glp1_trial": true,
                              "prior_glp1_drugs": [
                                "Ozempic",
                                "Rybelsus"
                              ],
                              "prior_glp1_count_required": 1,
                              "prior_weight_loss_drugs": [],
                              "prior_weight_loss_trial_months": null
                            },
                            "cardiovascular": {
                              "requires_cv_disease": true,
                              "cv_qualifying_events": [
                                "MI",
                                "stroke",
                                "PAD"
                              ],
                              "requires_gdmt": true,
                              "gdmt_medications": [
                                "lipid-lowering therapy",
                                "antiplatelet therapy"
                              ]
                            },
                            "osa": {
                              "requires_osa_diagnosis": false,
                              "ahi_min": null,
                              "requires_pap_trial": false
                            },
                            "mash": {
                              "requires_mash_diagnosis": false,
                              "fibrosis_stage_min": null,
                              "fibrosis_stage_max": null,
                              "confirmation_methods": []
                            },
                            "renal": {
                              "egfr_min": null,
                              "egfr_max": null,
                              "uacr_min": null
                            },
                            "lifestyle": {
                              "requires_program": false,
                              "duration_months": null
                            },
                            "diagnosis": {
                              "requires_diagnosis_code": false,
                              "codes": [],
                              "confirmation_methods": [
                                "lab_confirmation"
                              ],
                              "requires_lab_verification": true,
                              "excludes_diabetes": true
                            },
                            "comorbidities_accepted": [],
                            "exclusions": {
                              "other": [
                                "Patients WITH diabetes are excluded from this MACE indication (must use diabetes criteria)",
                                "BMI ≥35 kg/m2 is excluded",
                                "Only the 2.4mg strength is indicated for MACE reduction"
                              ],
                              "pregnancy": false,
                              "type_1_diabetes": false,
                              "bariatric_surgery": false
                            }
                          },
                          "qualification_pathways": [
                            {
                              "all_of": [
                                "Member is between ages ≥55 and <75",
                                "Member does not have diabetes, as evidenced by A1C within normal range without diabetes medication",
                                "Member has initial BMI ≥27 kg/m2 and <35 kg/m2",
                                "Member is concurrently taking lipid-lowering and antiplatelet therapy",
                                "Dose escalation to 2mg of Ozempic (semaglutide) must be tolerated before Wegovy injection will be authorized (2.4mg is the only strength indicated for reduction of MACE)"
                              ],
                              "any_of": [
                                "Prior myocardial infarction (MI)",
                                "Prior stroke AND peripheral arterial disease (PAD), as evidenced by intermittent claudication with ankle-brachial index <0.85, peripheral arterial revascularization procedure, or amputation due to atherosclerotic disease"
                              ],
                              "pathway_name": "Wegovy injection for MACE - requires Ozempic 2mg step therapy"
                            },
                            {
                              "all_of": [
                                "All initial MACE criteria above must be met",
                                "Member must have failed a 12-month trial of semaglutide injection, as evidenced by paid claims or pharmacy printouts",
                                "Dose escalation to 14mg of Rybelsus (semaglutide) must be tolerated before Wegovy tablets will be authorized"
                              ],
                              "any_of": [
                                "Unable to achieve weight loss ≥5% from baseline",
                                "Unable to achieve reduction of BMI ≥5% from baseline",
                                "Experienced a cardiovascular event following a 5% weight loss or 5% BMI reduction since starting medication"
                              ],
                              "pathway_name": "Wegovy tablets for MACE - non-preferred, requires 12-month semaglutide injection trial"
                            }
                          ],
                          "required_documentation": [
                            "A1C lab result within normal range (confirming no diabetes) without diabetes medication",
                            "Documentation of baseline BMI ≥27 kg/m2 and <35 kg/m2",
                            "Documentation of qualifying CV event (prior MI; OR prior stroke AND PAD with ABI <0.85, revascularization, or amputation)",
                            "Documentation of concurrent lipid-lowering therapy use",
                            "Documentation of concurrent antiplatelet therapy use",
                            "Tobacco cessation counseling documentation (if current tobacco user, within past year)",
                            "For Wegovy injection: documentation of dose escalation to Ozempic 2mg tolerated",
                            "For Wegovy tablets (non-preferred): documentation of 12-month failed trial of semaglutide injection; documentation of Rybelsus 14mg tolerated"
                          ],
                          "quantity_limits": [],
                          "approval": {
                            "initial_months": 12,
                            "continuation_months": 12,
                            "continuation_clinical_benefit": "Failure of Wegovy tablets (for renewal/non-preferred step) defined as: unable to achieve weight loss ≥5% from baseline, OR unable to achieve reduction of BMI ≥5% from baseline, OR experienced a cardiovascular event following a 5% weight loss or 5% BMI reduction since starting medication.",
                            "continuation_weight_loss_percent": 5.0,
                            "minimum_maintenance_dose_mg": 2.4,
                            "minimum_therapy_weeks": null
                          },
                          "provenance": {
                            "source_type": "reviewed_policy",
                            "documented": true,
                            "effective_date": "2026-04-01",
                            "expiration_date": null,
                            "last_verified_at": "2026-06-03T22:49:10.573Z"
                          }
                        }
                      ]
                    }
        "400":
          description: >
            Invalid request — unknown `indication` or `plan_type`, an
            unexpected body parameter (deny-by-default allowlist), or any
            query-string parameter (selectors must travel in the body, never
            the URL).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "indication must be one of: diabetes, weight_loss, cv_risk_reduction, mash, osa, ckd"
        "401":
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "Invalid or missing API key."
        "404":
          description: The payer or drug could not be resolved.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "Payer not found."
        "409":
          description: >
            The requested `plan_type` contradicts the line of business pinned
            by the resolved payer alias.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "plan_type 'commercial' conflicts with 'Cigna HealthSpring', which resolves to a medicare_advantage plan."
        "429":
          description: Daily request limit reached for this API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "Daily request limit reached."

  /resolve:
    post:
      tags: [Resolution]
      operationId: resolvePayer
      summary: Resolve a plan/card name to a payer
      description: |
        Maps the plan name printed on a member's insurance card to the payer
        whose criteria govern it, before a coverage lookup. Surfaces the
        Medicaid MCO → state-Medicaid fallback (`mco_fallback`) and, for
        aliases that pin a line of business, the `resolved_plan_type` to use.
        Returns `match: null` with `reason: "no_match"` when the name cannot
        be matched exactly — never a fuzzy guess.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              additionalProperties: false
              properties:
                name:
                  type: string
                  description: Plan or payer name as printed on the card.
            example:
              name: "Cigna HealthSpring"
      responses:
        "200":
          description: Resolution result (including explicit no-match).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ResolveResponse"
              examples:
                pinned-alias:
                  summary: Alias pinned to a line of business
                  value:
                    query: { name: "Cigna HealthSpring" }
                    match:
                      payer_id: 12
                      name: "Cigna"
                      payer_type: "national"
                      match_type: "exact_alias_pinned"
                      confidence: 0.98
                      resolved_plan_type: "medicare_advantage"
                      mco_fallback: false
                no-match:
                  summary: Name that cannot be matched exactly
                  value:
                    query: { name: "Acme Health Plan" }
                    match: null
                    reason: "no_match"
        "400":
          description: name is missing.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "name is required."
        "401":
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "Invalid or missing API key."
        "429":
          description: Daily request limit reached for this API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: "Daily request limit reached."

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: "`Authorization: Bearer <key>` — the preferred form."
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: Alternative to the Authorization header; same key.

  schemas:
    CoverageLookupRequest:
      type: object
      required: [indication]
      additionalProperties: false
      description: >
        Plan selectors only — never patient or clinical data. Unexpected keys
        are rejected with 400 (deny-by-default). Identify the payer by `payer`
        (name/alias) or `payer_id`, and the drug by `drug` (name) or
        `drug_id`.
      properties:
        payer:
          type: string
          description: Payer name or alias as printed on the card (e.g. "Kaiser Permanente Colorado", "Cigna HealthSpring"). Resolved with match_type/confidence reported in the response.
        payer_id:
          type: integer
          description: Stable payer id from a previous response or /resolve — skips name resolution.
        drug:
          type: string
          description: Drug brand or generic name (e.g. "Wegovy", "Ozempic").
        drug_id:
          type: integer
          description: Stable drug id from a previous response — skips name resolution.
        indication:
          type: string
          enum: [diabetes, weight_loss, cv_risk_reduction, mash, osa, ckd]
          description: Clinical indication to look up criteria for.
        plan_type:
          type: string
          enum: [commercial, medicare_part_d, medicare_advantage, marketplace, medicaid, essential_plan, fep]
          description: Optional — omit to receive one coverage entry per plan type the payer has criteria for. Conflicts with an alias-pinned line return 409.
        formulary_id:
          type: integer
          description: Optional formulary id, for payers that maintain more than one formulary. Defaults to the payer's default formulary when coverage varies.
        formulary:
          type: string
          description: Accepted but currently unused — reserved for formulary selection by name. Use formulary_id.
        bin:
          type: string
          description: Accepted but currently unused — reserved for card-based (BIN) resolution.
        pcn:
          type: string
          description: Accepted but currently unused — reserved for card-based (PCN) resolution.
        rx_group:
          type: string
          description: Accepted but currently unused — reserved for card-based (Rx Group) resolution.
        name:
          type: string
          description: Accepted on /resolve (the card/plan name). Not used by /coverage.

    CoverageLookupResponse:
      type: object
      required: [query, resolved, coverage]
      properties:
        query:
          type: object
          description: Echo of the selectors you sent (omitted keys are absent).
          properties:
            payer: { type: string, description: Payer name/alias as sent. }
            drug: { type: string, description: Drug name as sent. }
            indication: { type: string, description: Indication as sent. }
            plan_type: { type: string, description: Plan type as sent (absent when omitted). }
        resolved:
          type: object
          description: What the API resolved your selectors to.
          required: [payer, drug]
          properties:
            payer:
              $ref: "#/components/schemas/PayerMatch"
            drug:
              type: object
              required: [id, brand_name, generic_name]
              properties:
                id:
                  type: integer
                  description: Stable drug id — reusable as drug_id in later requests.
                brand_name:
                  type: string
                  description: Brand name (e.g. Wegovy).
                generic_name:
                  type: string
                  description: Generic name (e.g. semaglutide).
        coverage:
          type: array
          description: >
            One entry per plan type (or only the requested one). Entries whose
            coverage_state is a stored verdict (covered,
            covered_with_requirements, conditional_on_benefit, not_covered)
            carry the full criteria payload; derived verdicts
            (covered_under_diabetes_criteria, off_label, no_data) are
            verdict-only.
          items:
            $ref: "#/components/schemas/CoverageEntry"

    PayerMatch:
      type: object
      description: >
        How the payer name resolved. Fields with null values are omitted from
        the JSON (resolved_plan_type appears only when an alias pinned a line;
        resolves_to_state_medicaid only when mco_fallback is true).
      required: [payer_id, name, payer_type, match_type, confidence]
      properties:
        payer_id:
          type: integer
          description: Stable payer id — reusable as payer_id in later requests.
        name:
          type: string
          description: Canonical payer name the input resolved to.
        payer_type:
          type: string
          description: Payer category (e.g. national, regional, bcbs_independent).
        match_type:
          type: string
          enum: [exact_name, exact_alias, exact_alias_pinned, id, no_match]
          description: How the match was made. exact_name — canonical name; exact_alias — curated alias; exact_alias_pinned — alias that also pins a line of business; id — looked up by payer_id.
        confidence:
          type: number
          format: float
          description: Match confidence, 0.0–1.0 (1.0 exact name, 0.98 curated alias).
        resolved_plan_type:
          type: string
          description: Present only when the matched alias pins a line of business (e.g. medicare_advantage) — the line the criteria are filed under.
        mco_fallback:
          type: boolean
          description: True when a Medicaid managed-care plan name resolved to the state Medicaid program whose criteria govern it.
        resolves_to_state_medicaid:
          type: string
          description: Present only when mco_fallback is true — the state Medicaid payer the plan resolved to.

    ResolveResponse:
      type: object
      required: [query]
      properties:
        query:
          type: object
          description: Echo of the name you sent.
          properties:
            name: { type: string }
        match:
          # Standard OAS 3.0 pattern for "PayerMatch or null". Some linters
          # (e.g. redocly) warn that the no-match example's `match: null`
          # doesn't conform — a validator limitation, not a spec error.
          type: object
          nullable: true
          allOf:
            - $ref: "#/components/schemas/PayerMatch"
          description: The resolved payer, or null when no exact match exists.
        reason:
          type: string
          description: Present only when match is null — always "no_match".

    CoverageEntry:
      type: object
      required: [plan_type, formulary_varies, coverage_state]
      properties:
        plan_type:
          type: string
          enum: [commercial, medicare_part_d, medicare_advantage, marketplace, medicaid, essential_plan, fep]
          description: Plan type this entry answers for.
        formulary:
          type: string
          nullable: true
          description: Formulary the answer is based on (the payer's default when coverage varies across formularies).
        formulary_varies:
          type: boolean
          description: True when the payer's formularies disagree for this combination — the entry then reflects the default formulary, and the member's specific formulary should be checked.
        coverage_state:
          type: string
          enum:
            - covered
            - covered_with_requirements
            - conditional_on_benefit
            - not_covered
            - covered_under_diabetes_criteria
            - off_label
            - no_data
          description: >
            The verdict. covered — covered with no documented clinical gating.
            covered_with_requirements — covered once the documented criteria
            are met. conditional_on_benefit — covered only if the member's
            pharmacy-benefit design includes it (see coverage_scope).
            not_covered — excluded under this plan type and indication.
            covered_under_diabetes_criteria — derived: an on-label,
            diabetes-restricted use is covered via the plan's diabetes
            criteria (policy silence is never treated as a denial). off_label
            — the drug is not FDA-labeled for this indication; no policy
            basis exists. no_data — this combination hasn't been captured
            yet: an honest gap, not a denial. The last three are verdict-only
            entries without the criteria payload below.
        is_covered:
          type: boolean
          description: Authoritative coverage flag for this drug × indication × plan type.
        is_preferred:
          type: boolean
          nullable: true
          description: Whether the drug is a preferred agent on this formulary. Null when the policy does not state a tier.
        coverage_scope:
          type: string
          enum: [standard, rider_required, rider_excluded]
          description: >
            How broadly the coverage applies. standard — applies to the plan
            type as a whole; rider_required — covered only when the member's
            benefit design includes the relevant coverage (often an optional
            employer benefit); rider_excluded — excluded when the member's
            benefit design carves the coverage out.
        coverage_scope_note:
          type: string
          nullable: true
          description: Policy-sourced explanation of the benefit-design condition, when one applies.
        basis:
          type: string
          nullable: true
          description: Stated policy basis for the determination, when the source document provides one.
        requirements:
          $ref: "#/components/schemas/Requirements"
        qualification_pathways:
          type: array
          description: Distinct routes to approval. A patient qualifies via any single pathway by meeting all of its all_of conditions plus at least one any_of condition.
          items:
            $ref: "#/components/schemas/QualificationPathway"
        required_documentation:
          type: array
          description: Documentation the payer requires with the prior-authorization submission.
          items:
            type: string
        quantity_limits:
          type: array
          description: Dispensing limits, per strength grouping. Empty when the policy sets none.
          items:
            $ref: "#/components/schemas/QuantityLimit"
        approval:
          $ref: "#/components/schemas/Approval"
        provenance:
          $ref: "#/components/schemas/Provenance"

    Requirements:
      type: object
      description: Normalized clinical requirements extracted from the payer's policy. Null values mean the policy sets no such threshold.
      required: [age, bmi, a1c, step_therapy, cardiovascular, osa, mash, renal, lifestyle, diagnosis, comorbidities_accepted, exclusions]
      properties:
        age:
          $ref: "#/components/schemas/AgeRequirement"
        bmi:
          $ref: "#/components/schemas/BmiRequirement"
        a1c:
          $ref: "#/components/schemas/A1cRequirement"
        step_therapy:
          $ref: "#/components/schemas/StepTherapyRequirement"
        cardiovascular:
          $ref: "#/components/schemas/CardiovascularRequirement"
        osa:
          $ref: "#/components/schemas/OsaRequirement"
        mash:
          $ref: "#/components/schemas/MashRequirement"
        renal:
          $ref: "#/components/schemas/RenalRequirement"
        lifestyle:
          $ref: "#/components/schemas/LifestyleRequirement"
        diagnosis:
          $ref: "#/components/schemas/DiagnosisRequirement"
        comorbidities_accepted:
          type: array
          description: Weight-related comorbidities the payer accepts alongside the lower BMI threshold (e.g. HTN, dyslipidemia, T2DM).
          items:
            type: string
        exclusions:
          $ref: "#/components/schemas/Exclusions"

    AgeRequirement:
      type: object
      properties:
        min:
          type: integer
          nullable: true
          description: Minimum patient age in years, when the policy sets one.
        max:
          type: integer
          nullable: true
          description: Maximum patient age in years, when the policy sets one.

    BmiRequirement:
      type: object
      properties:
        min:
          type: number
          format: float
          nullable: true
          description: Minimum BMI in kg/m² without a qualifying comorbidity.
        min_with_comorbidity:
          type: number
          format: float
          nullable: true
          description: Lower BMI threshold in kg/m² that applies when the patient has at least one comorbidity from comorbidities_accepted.
        min_asian:
          type: number
          format: float
          nullable: true
          description: Alternate minimum BMI in kg/m² for patients of Asian descent, when the policy defines one.
        percentile_min:
          type: integer
          nullable: true
          description: Minimum BMI percentile for pediatric patients, when the policy defines one.

    A1cRequirement:
      type: object
      properties:
        min:
          type: number
          format: float
          nullable: true
          description: Minimum hemoglobin A1C in percent (e.g. 6.5 confirms a T2DM diagnosis).
        max:
          type: number
          format: float
          nullable: true
          description: Maximum hemoglobin A1C in percent, when the policy caps eligibility.
        for_combination_therapy:
          type: number
          format: float
          nullable: true
          description: A1C threshold in percent that applies specifically when the drug is added to existing therapy.

    StepTherapyRequirement:
      type: object
      properties:
        requires_metformin_trial:
          type: boolean
          description: Whether a prior metformin trial is required before approval.
        metformin_trial_duration_days:
          type: integer
          nullable: true
          description: Required length of the metformin trial in days.
        metformin_exception_conditions:
          type: array
          description: Conditions that waive the metformin requirement (e.g. intolerance, contraindication, ASCVD, CKD).
          items:
            type: string
        requires_prior_glp1_trial:
          type: boolean
          description: Whether a trial of another GLP-1 agent is required first.
        prior_glp1_drugs:
          type: array
          description: GLP-1 agents that satisfy the prior-trial requirement.
          items:
            type: string
        prior_glp1_count_required:
          type: integer
          nullable: true
          description: Number of distinct prior GLP-1 trials required.
        prior_weight_loss_drugs:
          type: array
          description: Non-GLP-1 weight-loss agents that must be tried first (e.g. phentermine, Qsymia, Contrave).
          items:
            type: string
        prior_weight_loss_trial_months:
          type: integer
          nullable: true
          description: Required duration of each prior weight-loss-agent trial in months.

    CardiovascularRequirement:
      type: object
      properties:
        requires_cv_disease:
          type: boolean
          description: Whether established cardiovascular disease is required to qualify.
        cv_qualifying_events:
          type: array
          description: Cardiovascular events or diagnoses the payer accepts as qualifying (e.g. MI, stroke, PAD).
          items:
            type: string
        requires_gdmt:
          type: boolean
          description: Whether concurrent guideline-directed medical therapy is required.
        gdmt_medications:
          type: array
          description: GDMT therapies the patient must be taking concurrently (e.g. lipid-lowering therapy, antiplatelet therapy).
          items:
            type: string

    OsaRequirement:
      type: object
      properties:
        requires_osa_diagnosis:
          type: boolean
          description: Whether an obstructive sleep apnea diagnosis is required.
        ahi_min:
          type: integer
          nullable: true
          description: Minimum apnea-hypopnea index (events/hour) to qualify.
        requires_pap_trial:
          type: boolean
          description: Whether a positive-airway-pressure (CPAP/BiPAP) trial is required first.

    MashRequirement:
      type: object
      properties:
        requires_mash_diagnosis:
          type: boolean
          description: Whether a MASH (metabolic dysfunction-associated steatohepatitis) diagnosis is required.
        fibrosis_stage_min:
          type: string
          nullable: true
          description: Minimum liver fibrosis stage (e.g. F2) to qualify.
        fibrosis_stage_max:
          type: string
          nullable: true
          description: Maximum liver fibrosis stage (e.g. F3) — beyond this the drug is not covered for MASH.
        confirmation_methods:
          type: array
          description: Accepted methods of confirming the MASH diagnosis (e.g. biopsy, imaging).
          items:
            type: string

    RenalRequirement:
      type: object
      properties:
        egfr_min:
          type: integer
          nullable: true
          description: Minimum estimated glomerular filtration rate in mL/min/1.73m².
        egfr_max:
          type: integer
          nullable: true
          description: Maximum eGFR in mL/min/1.73m² (used to define CKD eligibility windows).
        uacr_min:
          type: integer
          nullable: true
          description: Minimum urine albumin-to-creatinine ratio in mg/g.

    LifestyleRequirement:
      type: object
      properties:
        requires_program:
          type: boolean
          description: Whether a documented diet-and-exercise / lifestyle-modification program is required.
        duration_months:
          type: integer
          nullable: true
          description: Required length of the lifestyle program in months.

    DiagnosisRequirement:
      type: object
      properties:
        requires_diagnosis_code:
          type: boolean
          description: Whether a specific diagnosis code must accompany the submission.
        codes:
          type: array
          description: Accepted diagnosis codes (ICD-10), when the policy enumerates them.
          items:
            type: string
        confirmation_methods:
          type: array
          description: How the diagnosis must be confirmed (e.g. clinical_diagnosis, lab_confirmation).
          items:
            type: string
        requires_lab_verification:
          type: boolean
          description: Whether lab results documenting eligibility must be submitted.
        excludes_diabetes:
          type: boolean
          description: Whether a diabetes diagnosis disqualifies the patient under this indication (e.g. MACE-only criteria).

    Exclusions:
      type: object
      properties:
        other:
          type: array
          description: Policy-specific exclusions, verbatim from the source document (e.g. concurrent GLP-1 use, benefit carve-outs).
          items:
            type: string
        pregnancy:
          type: boolean
          description: Whether pregnancy is a stated exclusion.
        type_1_diabetes:
          type: boolean
          description: Whether type 1 diabetes is a stated exclusion.
        bariatric_surgery:
          type: boolean
          description: Whether prior or planned bariatric surgery is a stated exclusion.

    QualificationPathway:
      type: object
      description: One complete route to approval. All all_of conditions plus at least one any_of condition must be met.
      properties:
        pathway_name:
          type: string
          description: Short label for the pathway (e.g. "Continuation of therapy").
        all_of:
          type: array
          description: Conditions that must ALL be met under this pathway.
          items:
            type: string
        any_of:
          type: array
          description: Conditions of which AT LEAST ONE must be met under this pathway. Empty when the pathway has no alternative branch.
          items:
            type: string

    QuantityLimit:
      type: object
      properties:
        strengths:
          type: array
          description: Drug strengths the limit applies to ("all strengths" when uniform).
          items:
            type: string
        supply_28_day:
          type: string
          nullable: true
          description: Maximum quantity dispensable per 28-day supply, verbatim from the policy.
        supply_84_day:
          type: string
          nullable: true
          description: Maximum quantity dispensable per 84-day (90-day-class) supply, when the policy defines one.

    Approval:
      type: object
      properties:
        initial_months:
          type: integer
          nullable: true
          description: Length of the initial authorization in months.
        continuation_months:
          type: integer
          nullable: true
          description: Length of each renewal authorization in months.
        continuation_clinical_benefit:
          type: string
          nullable: true
          description: What the payer requires as demonstrated clinical benefit at renewal, verbatim from the policy.
        continuation_weight_loss_percent:
          type: number
          format: float
          nullable: true
          description: Minimum percent weight loss from baseline that must be maintained for renewal.
        minimum_maintenance_dose_mg:
          type: number
          format: float
          nullable: true
          description: Minimum maintenance dose in mg the patient must be on (e.g. 2.4 for Wegovy MACE criteria).
        minimum_therapy_weeks:
          type: integer
          nullable: true
          description: Minimum weeks on therapy before a continuation request is considered.

    Provenance:
      type: object
      description: Where the record came from and when it was last confirmed against its source.
      required: [source_type, documented]
      properties:
        source_type:
          type: string
          enum: [reviewed_policy]
          description: How the record was produced. Criteria detail is only returned for reviewed_policy — records a human reviewer confirmed against the source policy document.
        documented:
          type: boolean
          description: Whether a source policy document or URL is on file for this record.
        effective_date:
          type: string
          format: date
          nullable: true
          description: Date the source policy took effect.
        expiration_date:
          type: string
          format: date
          nullable: true
          description: Stated expiration or review date of the source policy, when one is published.
        last_verified_at:
          type: string
          format: date-time
          nullable: true
          description: Timestamp of the most recent human verification against the source policy (ISO 8601, UTC).

    Error:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Human-readable explanation of the failure.
