# MA pbp section d oon

`medicare_silver.pbp_section_d_oon` · Medicare Advantage, Part D, Medicaid · status partial

Section D OON: Part D out-of-network cost-share. Coverage: All years.

**Grain.** One row per (MA plan-segment x OON service-category x cost-tier x OON-option-line) within a single CMS quarterly PBP release. Verified minimal key = contract_id + plan_id + segment_id + pbp_d_opt_oon_identifier + pbp_d_opt_oon_cat_id + pbp_d_opt_oon_type_id + report_year + quarter, which equals 143,801 distinct = the full 143,801 row_count. Dropping ANY one of these 8 columns reduces the distinct count below the row count (e.g. drop quarter -> 74,002; drop cat_id -> 47,221; drop segment -> 128,588), so all 8 are necessary and sufficient.

**How to use it.** To get the current OON inpatient-hospital coinsurance a plan charges in 2026, take the latest vintage and filter to OON-offered lines: SELECT contract_id, plan_id, segment_id, pbp_d_opt_oon_cat_id, pbp_d_opt_oon_coins_min_pct, pbp_d_opt_oon_coins_max_pct FROM medicare_silver.pbp_section_d_oon WHERE report_year=2026 AND quarter=(SELECT MAX(quarter) FROM pbp_section_d_oon WHERE report_year=2026) AND pbp_d_opt_oon_yn='1' AND pbp_d_opt_oon_cat_id LIKE '16%'. This answers 'what coinsurance % do MA members pay for out-of-network inpatient hospital stays per plan' without double-counting quarterly re-releases.

**Traps.**
- QUARTER IS PART OF THE PHYSICAL GRAIN, NOT A BUSINESS DIMENSION. CMS re-releases the SAME benefit year across multiple quarters with byte-identical content (2018 appears in Q1-Q4, each exactly 4,124 rows; full table 143,801 rows collapses to 74,002 when quarter is dropped). To analyze plan benefits you almost always want ONE vintage per (plan, report_year) — pick the latest quarter / MAX(cms_vintage_sequence) per (contract_id,plan_id,segment_id,report_year). Aggregating without this DOUBLE/QUADRUPLE-COUNTS plans. There is NO is_current/is_latest flag to do this for you.
- NULL in the *_yn flags and cost columns carries MEANING, it is not just 'unknown'. pbp_d_opt_oon_yn: only '1'=OON-offered rows ever carry cost values (37,333 of 92,040); '2'=OON not offered and NULL=not-asserted (mostly pre-2018 years) both have ZERO cost values. coins_yn/copay_yn NULL (102,806 rows) means 'that cost form does not apply to this line', not missing. Always filter pbp_d_opt_oon_yn='1' before reading coinsurance/copay.
- bid_id, pbp_a_plan_type, effective_period_start/end, and observed_period look like keys but are NOT part of the minimal grain. bid_id is exactly contract_id||'_'||plan_id||'_'||segment_id (100% verified). The period dates are 1:1 functions of report_year. The profiler's 11-column 'verified_unique_by' is a SUPERSET; the true minimal key is 8 columns.
- COPAYS ARE RARE on OON; coinsurance is the real cost signal. Only 2,345 rows have copay amounts vs 34,992 with coinsurance pct. If you benchmark OON cost exposure on copay columns you will see almost all NULLs — use pbp_d_opt_oon_coins_min_pct/coins_max_pct (a percentage, 0-100), and note min<max means a provider/tier range while min=max is a single rate.
- pbp_d_opt_oon_cat_id is the CMS PBP service-category code, NOT a procedure/HCPCS code. Values are PBP category labels (16a/16b/16c=inpatient hospital tiers, 17=SNF, 18=home health, 14=preventive, etc. with numeric subtiers); type_id ('1' vs '2') splits the per-stay vs per-day cost variant. Don't join these to clinical code systems; they map to PBP benefit-category definitions and you must keep cat_id+type_id together to identify a benefit line.
- History depth is uneven and the panel widens over time. 2008-2017 have only Q1 with a few thousand rows; coverage jumps at 2018 (multi-quarter) and again at 2024-2026 (9k-11k rows/year). Earliest report_year=2008, latest=2026. Older years also have pbp_d_opt_oon_yn mostly NULL, so cost values are sparse before ~2018.

| column | type | meaning |
|---|---|---|
| contract_id | string | CMS MA contract ID (e.g. 'H0028'); 443 distinct. First component of bid_id. Part of grain. |
| plan_id | string | Plan number within the contract (zero-padded, e.g. '013'); 367 distinct. Part of grain. |
| segment_id | string | Plan segment (geographic/benefit segment, e.g. '0'); 21 distinct, usually '0'. Required in grain — dropping it loses ~15k rows. |
| pbp_d_opt_oon_identifier | string | OON option line number within the plan ('001'..'009'); 8 distinct, '001' dominates (89,765). A plan can declare multiple OON option lines; required in grain. |
| pbp_d_opt_oon_cat_id | string | PBP service-category code the OON cost-share applies to. Codes like 16a/16b/16c(+numeric subtier)=inpatient hospital tiers, 17a/17b=SNF, 18a/18b=home health, 14x=preventive/other, 47/48=other services. This is the benefit dimension; coinsurance varies sensibly by category (16c ~57-70%, 16b ~26%, 17b ~50%). Most populous and most load-bearing grain column. |
| pbp_d_opt_oon_type_id | string | Cost-structure type for the category: '2'=111,063 rows (dominant), '1'=32,738. Distinguishes per-period vs per-stay/per-day cost-sharing variant of the same category. Required in grain (small but real ~1k collisions otherwise). |
| version | double | CMS PBP software version number (double, e.g. 5.0, 6.0) for that plan's bid. Metadata, not a key. |
| report_year | double | Benefit/contract year the filing applies to (2008..2026), 19 distinct years. Core temporal key. Equals the year of observed_period/effective_period_start. |
| quarter | double | CMS release quarter (1-4) the snapshot came from. CRITICAL: the SAME benefit year is re-released across multiple quarters with identical content (e.g. 2018 appears in Q1-Q4, each exactly 4,124 rows). Part of the physical grain because the table stacks all quarterly vintages; NOT a within-year business distinction. |
| bid_id | string | REDUNDANT composite = contract_id//'_'//plan_id//'_'//segment_id (verified 143,801/143,801 exact match). Convenience join key, not independent — excluded from minimal grain. |
| orgtype | string | CMS organization type code: '01'=129,054 (local CCP/HMO-PPO, dominant), '04', '11', '06', '02'. Plan-level attribute, functionally tied to contract/plan. |
| pbp_a_ben_cov | string | PBP Section A benefit-coverage indicator: '1'=143,410 (nearly all), '2'=213, NULL=178. Plan-level attribute. |
| pbp_a_plan_type | string | CMS plan-type code: '04'=63,469 (regional PPO), '01'=40,170 (HMO), '02'=25,412 (local PPO), '09', '31', etc. Plan-level attribute, derivable from the plan — included in profiler superset but NOT needed in minimal grain. |
| pbp_d_opt_oon_coins_cov | string | Coinsurance-coverage qualifier code; almost always NULL (143,539 of 143,801), rare values '6'(258),'2'(4). Effectively a sparse flag — NULL is the normal/default state here. |
| pbp_d_opt_oon_coins_max_pct | double | Maximum OON coinsurance percentage member pays for the category. Range 0-100; non-null in 34,992 rows. THE key cost field (coinsurance is the common OON cost form). |
| pbp_d_opt_oon_coins_min_pct | double | Minimum OON coinsurance percentage. Range 0-100; non-null in 34,992 rows (same population as max). For most rows min=max (a single pct); a min<max indicates a range across providers/tiers. |
| pbp_d_opt_oon_coins_yn | string | Whether coinsurance applies to this OON line: '1'=yes(34,992), '2'=no(6,003), NULL=102,806 (not applicable / not asserted). NULL here means 'no coinsurance structure on this line', not missing data. |
| pbp_d_opt_oon_copay_max_amt | double | Maximum OON copay dollar amount. Range $0-$812.50; non-null in only 2,345 rows. Copays are RARE for OON (coinsurance dominates). |
| pbp_d_opt_oon_copay_min_amt | double | Minimum OON copay dollar amount. Range $0-$150; non-null in 2,345 rows (same sparse population as copay_max). |
| pbp_d_opt_oon_copay_yn | string | Whether a copay applies: '2'=no(38,650), '1'=yes(2,345), NULL=102,806. Mirror of coins_yn; '1' count exactly matches the 2,345 populated copay amounts. |
| pbp_d_opt_oon_cstshrs_yn | string | Whether any cost-sharing (coins OR copay) applies to the OON line: '1'=yes(51,033), '2'=no(40,995), NULL=51,773 (not asserted, mostly older years). Roll-up flag above the coins/copay YN pair. |
| pbp_d_opt_oon_yn | string | Whether the plan offers OON coverage for this line at all: '1'=yes(92,040; the only value where cost values appear — 37,333 carry coins/copay), '2'=no OON offered(9,810; zero cost values), NULL=41,951 (older years / not asserted, zero cost values). Filter pbp_d_opt_oon_yn='1' to get rows with real OON cost data. |
| observed_period | date | Date the data describes (Jan 1 of report_year). Exactly 1 distinct per report_year — fully determined by report_year, adds nothing to grain. Provenance/temporal column. |
| asserted_at | date | Ingestion/parse date into this silver table (2026-05-16 or 2026-05-20). 1-2 distinct per year. Pipeline metadata, NOT a business key. |
| effective_period_start | date | Benefit-year start (Jan 1 of report_year); 1 distinct per year, determined by report_year. Profiler listed it in the grain superset but it is redundant with report_year. |
| effective_period_end | date | Benefit-year end (Dec 31 of report_year); 1 distinct per year. Redundant with report_year. |
| cms_vintage_sequence | int | Integer vintage/release sequence (1-4) tracking which quarterly CMS release the row came from; moves in lockstep with quarter within a year. Provenance for ordering vintages. |
| parse_revision | int | Internal parser revision number (int, e.g. 2). Pipeline provenance metadata. |
| parser_artifact_hash | string | SHA-256 of the parser artifact/code version that produced the row. Lineage/reproducibility metadata. |
| source_url | string | CMS source ZIP the row was extracted from (e.g. https://www.cms.gov/files/zip/pbp-benefits-2022-quarter-2.zip). Provenance; encodes year+quarter of the release. |
| sha256_content_hash | string | SHA-256 content hash of the source file/record for integrity and dedup. Provenance metadata. |

Query it: `query_substrate` with `SELECT ... FROM medicare_silver.pbp_section_d_oon WHERE ... LIMIT 100`; read `describe_data_source("medicare_silver.pbp_section_d_oon")` first.
