# PBP dental (cleaned view)

`medicare_semantic.vw_pbp_dental` · Medicare Advantage, Part D, Medicaid · status live

Cleaned source-faithful PBP dental rows: era-normalized, CMS codes decoded, with offered_status/numeric_amount_observability/null_amount_reason/annualization_policy/combined_limit_policy/confidence_tier. The agent reasoning surface for dent

**Grain.** One row per MA plan-segment per benefit year/quarter snapshot per PBP dental section. The MINIMAL verified-unique key is contract_id + plan_id + segment_id + report_year + quarter + source_pbp_section (231,468 distinct = 231,468 total rows, exact). source_pbp_section is the benefit-component axis: 'B16' = the single overall dental row (186,498 rows, all years), and 'B16A'/'B16B'/'B16C' = three sub-benefit rows (14,990 each) that exist ONLY for report_year 2025-2026. A plan in 2024 or earlier contributes 1 dental row; a plan in 2025/2026 contributes 4 (overall + 3 sub-benefits). version is NOT part of the grain — there is exactly one version per plan-snapshot, it is just CMS's carried bid-version number.

**How to use it.** To get each MA plan's overall dental cost share for the 2026 benefit year: SELECT contract_id, plan_id, segment_id, cost_share_string, copay_amount, coinsurance_pct, limit_quantity_per_year, limit_period_label FROM medicare_semantic.vw_pbp_dental WHERE report_year=2026 AND source_pbp_section='B16'. This returns one row per plan-segment with the filed dental member cost share and frequency limit. For the 2025+ sub-benefit breakdown (Medicare-covered vs diagnostic/preventive vs comprehensive), drop the section filter and read B16A/B16B/B16C rows instead.

**Traps.**
- NOT one row per plan. A 2024-or-earlier plan has 1 dental row (B16); a 2025/2026 plan has 4 (B16 overall + B16A/B/C sub-benefits). You MUST include source_pbp_section in the grain key, and filter to source_pbp_section='B16' (or dental_sub_benefit IS NULL) if you want exactly one overall-dental row per plan. Aggregating cost_share across all sections double-counts.
- version looks like a snapshot/history axis but is NOT — there is exactly one version per (contract,plan,segment,report_year,quarter), already deduped. The real time axis is report_year + quarter. There is no is_current column; dedup to a single bid version has already been done upstream.
- The entire benefit_amount dollar family (benefit_amount, _kind, _period_code, _period_label, _annualized, _pmpm) AND max_oop_applies are 100% NULL in this view — confirmed by numeric_amount_observability='offered_without_numeric_amounts'. Do NOT read a dental dollar allowance/cap from this table; it only carries copay/coinsurance and frequency limits.
- Benefit-type columns are split into TWO families by era: the *_cy2025 columns (comprehensive_cy2025, diagnostic_cy2025) populate ONLY for report_year 2025-2026; the non-suffixed columns (oral_exam, comprehensive_diagnostic, diagnostic, preventive_care) populate ONLY for report_year <=2024 — same Mandatory/Optional concept, different CMS layout. Coalesce across the pair (or filter by year) or you will see spurious nulls.
- Several columns are single-valued constants and carry no filtering power: benefit_category='dental', network_type='in_network', offered_status='offered', source_silver_table, aggregation_policy='separate_components', numeric_amount_observability, annualization_policy, combined_limit_policy, consumer_document_reconciliation_status='not_checked', confidence_tier='source_faithful', and lmi_authorities='' (empty).
- Redundant columns to avoid mistaking for independent dimensions: dental_sub_benefit maps 1:1 to source_pbp_section (adds no grain), and dental_limit_periodicity_label is an exact duplicate of limit_period_label. consumer_document_reconciliation_status='not_checked' everywhere means these are raw bid filings, NOT reconciled against consumer Summary-of-Benefits documents.

| column | type | meaning |
|---|---|---|
| contract_id | string | CMS MA contract id (e.g. 'H0016'). 1,972 distinct. Part of the grain. Pairs with plan_id/segment_id to identify the plan. |
| plan_id | string | Plan number within the contract (e.g. '001', 3-char zero-padded). 656 distinct values; only unique WITHIN a contract. Part of the grain. |
| segment_id | string | PBP segment id (e.g. '0'), distinguishes service-area segments of the same plan. 27 distinct. Part of the grain. 26,631 distinct contract+plan+segment combinations exist. |
| version | double | CMS PBP bid version number for that plan-snapshot (double, 0-26). NOT a history axis and NOT part of the grain — there is exactly ONE version per (contract,plan,segment,report_year,quarter). Higher within a year = later corrected filing already collapsed to one row here. |
| report_year | double | Benefit/contract year the plan applies to (double, 2001-2026). The PRIMARY time axis (the profiler's 'quarter 1-4' is only the within-year republish, not the history span). |
| quarter | double | CMS republish quarter within report_year (1-4). Most data is Q1; older years carry Q1-Q4 reissues, 2025/2026 so far only Q1. Part of the grain (same plan can appear in multiple quarterly reissues). |
| benefit_category | string | CONSTANT = 'dental' for every row (this is the dental view). Carries no information here; exists for union-compatibility with sibling PBP views. |
| cost_share_string | string | Human-readable member cost share as filed, e.g. '$25.0 copay', '20.0%', '$0 copay'. Populated on 84,533 rows; NULL when the bid did not populate a numeric cost share (cost_share_populated_in_bid=false). |
| copay_amount | double | Dollar copay parsed from the cost share (double). Populated on 70,978 rows. Mutually exclusive with coinsurance_pct — a row carries one or the other. |
| coinsurance_pct | double | Coinsurance percentage parsed from the cost share (double, e.g. 20.0 = 20%). Populated on 13,593 rows. Mutually exclusive with copay_amount. |
| limit_text | string | Free-text limit description from the bid. Effectively unpopulated in observed data (the structured limit_* columns carry the limit instead). |
| auth_required | boolean | Boolean: prior authorization required for this dental benefit component. NULL = not specified in the bid (not the same as false). |
| referral_required | boolean | Boolean: referral required. NULL = not specified. |
| network_type | varchar(10) | CONSTANT = 'in_network' for every row. This view exposes only in-network cost share; no out-of-network rows. |
| max_oop_applies | boolean | Boolean intended to flag whether the benefit counts toward MOOP. 100% NULL in this view — structurally unpopulated, do not rely on it. |
| limit_quantity | double | Raw limit quantity as filed in the source stripe (double). Largely superseded by limit_quantity_per_year; sparsely populated. |
| limit_unit | string | Unit for limit_quantity (e.g. visits). Sparsely populated; the normalized frequency lives in limit_quantity_per_year / frequency_per_year_annualized. |
| limit_period_code | string | CMS periodicity code for the limit (string): 1=Every three years, 2=Every two years, 3=Every year, 4=Every six months, 5=Every three months, 6=Other/Describe. NULL on 125,815 rows (no quantified limit). |
| limit_period_label | string | Decoded label of limit_period_code (e.g. 'Every year', 'Every six months', 'Other, Describe'). NULL when no limit period. |
| limit_quantity_per_year | double | Limit normalized to a per-year frequency (double, 0.33-8.0, median 2 — e.g. 2 cleanings/yr). Populated on 93,608 rows. This is the analysis-ready frequency cap. |
| benefit_amount | double | Intended dollar benefit/coverage cap. 100% NULL in this view — the dollar-allowance concept is NOT populated here (see numeric_amount_observability='offered_without_numeric_amounts'). Major trap: do not read a $ cap from this table. |
| benefit_amount_kind | string | Intended kind of benefit_amount (allowance vs cap). 100% NULL. |
| benefit_amount_period_code | string | Intended period code for benefit_amount. 100% NULL. |
| benefit_amount_period_label | string | Intended period label for benefit_amount. 100% NULL. |
| benefit_amount_annualized | double | Intended annualized dollar benefit. 100% NULL. |
| benefit_amount_pmpm | double | Intended per-member-per-month dollar benefit. 100% NULL. |
| normalization_status | varchar(14) | Governance flag: 'normalized' (216,478 — limit normalized via CMS periodicity code) or 'not_applicable' (14,990 — the B16A sub-rows with no limit quantity). |
| normalization_basis | varchar(34) | Why/how normalized: 'cms_periodicity_code' (limit converted using the period code) or 'no_limit_quantity_in_source_stripe'. Two values only. |
| aggregation_policy | varchar(42) | CONSTANT = 'separate_components' — each dental sub-benefit/section is kept as its own row rather than aggregated. Explains the multi-row-per-plan grain. |
| offered_status | varchar(15) | CONSTANT = 'offered' — every row represents an offered benefit (the view does not carry not-offered placeholders). |
| numeric_amount_observability | varchar(31) | CONSTANT = 'offered_without_numeric_amounts' for all rows. Confirms the benefit_amount dollar family is structurally empty in this dental view. |
| null_amount_reason | string | Why a numeric amount/limit is null: 'offered_no_numeric' (134,508), 'not_null_numeric_amount' (70,978 — actually has a copay), 'inherited_limit_elsewhere' (25,982 — limit applies on a sibling component). Useful for interpreting nulls. |
| annualization_policy | varchar(17) | CONSTANT = 'not_numeric' (no dollar amount to annualize, consistent with empty benefit_amount). |
| combined_limit_policy | varchar(29) | CONSTANT = 'none_detected' — no cross-component combined-limit collapsing applied. |
| consumer_document_reconciliation_status | varchar(11) | CONSTANT = 'not_checked' — these PBP values have NOT been reconciled against consumer documents (SB/EOC). Treat as source-faithful bid data, not consumer-verified. |
| confidence_tier | varchar(23) | CONSTANT = 'source_faithful' — values are faithfully carried from the CMS bid, no inference/enrichment beyond decoding. |
| benefit_layer | string |  |
| cost_share_populated_in_bid | boolean | Boolean: did the bid actually populate a cost share? true on 84,533 rows (aligns exactly with cost_share_string being non-null), false on 146,935. Use to distinguish 'no cost share filed' from 'free'. |
| dental_blanket_filing | boolean |  |
| dental_card_amount | double |  |
| dental_card_group_index | string |  |
| dental_card_group_name | string |  |
| dental_card_period_code | string |  |
| dental_coinsurance_max | double |  |
| dental_coinsurance_min | double |  |
| dental_comprehensive_benefit_type_code_cy2025 | string | CMS Mandatory/Optional supplemental-benefit type CODE for COMPREHENSIVE dental, CY2025 layout. Populated ONLY for report_year 2025-2026 (B16C rows). NULL otherwise. |
| dental_comprehensive_benefit_type_label_cy2025 | string | Decoded label for the above: Mandatory / Optional / Both / Additional. Only 2025-2026. |
| dental_comprehensive_diagnostic_type_code | string | Pre-CY2025 comprehensive-diagnostic benefit-type code. Populated for report_year <=2024 (the older B16 sub-field), NULL for 2025+. |
| dental_comprehensive_diagnostic_type_label | string | Decoded Mandatory/Optional/Both/Additional label for the pre-2025 comprehensive-diagnostic field (<=2024). |
| dental_comprehensive_max | double |  |
| dental_comprehensive_max_csg_group | string |  |
| dental_comprehensive_max_in_csg | boolean |  |
| dental_comprehensive_offered_package | string |  |
| dental_copay_max | double |  |
| dental_copay_min | double |  |
| dental_cost_share_basis | string |  |
| dental_deductible_amount | double |  |
| dental_deductible_applies | boolean |  |
| dental_diagnostic_benefit_type_code | string | Pre-CY2025 diagnostic benefit-type code (report_year <=2024). |
| dental_diagnostic_benefit_type_code_cy2025 | string | CY2025-layout diagnostic benefit-type code (B16B rows, report_year 2025-2026 only). |
| dental_diagnostic_benefit_type_label | string | Decoded label (Mandatory/Optional/Both/Additional) for the pre-2025 diagnostic field. |
| dental_diagnostic_benefit_type_label_cy2025 | string | Decoded label for the CY2025 diagnostic field (2025-2026). |
| dental_enrollee_max_amount | double |  |
| dental_enrollee_max_applies | boolean |  |
| dental_limit_desc | string |  |
| dental_limit_per_year_from_desc | double |  |
| dental_limit_periodicity_label | string | EXACT DUPLICATE of limit_period_label (same values/counts: 'Every year', 'Every six months', etc.). Redundant convenience column. |
| dental_limit_unlimited | boolean |  |
| dental_max_basis | string |  |
| dental_max_scope | string |  |
| dental_max_unlimited | boolean |  |
| dental_offered | boolean |  |
| dental_offered_package | string |  |
| dental_office_visit_coinsurance_pct | double |  |
| dental_office_visit_copay | double |  |
| dental_office_visit_cost_share_applies | boolean |  |
| dental_optional_only | boolean |  |
| dental_oral_exam_benefit_type_code | string | Pre-CY2025 oral-exam benefit-type code (report_year <=2024). No CY2025 counterpart column. |
| dental_oral_exam_benefit_type_label | string | Decoded Mandatory/Optional/Both/Additional label for oral exam (<=2024). |
| dental_package_id | string |  |
| dental_package_name | string |  |
| dental_package_type_code | string |  |
| dental_package_type_label | string |  |
| dental_preventive_care_benefit_type_code | string | Pre-CY2025 preventive-care benefit-type code (report_year <=2024). |
| dental_preventive_care_benefit_type_label | string | Decoded Mandatory/Optional/Both/Additional label for preventive care (<=2024). |
| dental_preventive_max | double |  |
| dental_preventive_max_csg_group | string |  |
| dental_preventive_max_in_csg | boolean |  |
| dental_preventive_offered_package | string |  |
| dental_row_grain | varchar(15) |  |
| dental_service_benefit_type_code | string |  |
| dental_service_benefit_type_label | string |  |
| dental_service_code | string |  |
| dental_service_codes_offered | string |  |
| dental_service_codes_optional | string |  |
| dental_service_group | string |  |
| dental_service_id | string |  |
| dental_service_label | string |  |
| dental_service_scope | string |  |
| dental_sub_benefit | string | Which dental sub-benefit the row describes: NULL='overall' (B16, 186,498 rows), 'medicare_covered' (B16A), 'diagnostic_preventive' (B16B), 'comprehensive' (B16C). Maps 1:1 to source_pbp_section, so it is redundant WITH the grain key, not additive. |
| dental_targeting | varchar(36) |  |
| frequency_per_year_annualized | double | Annualized frequency limit (double, 0.33-8.0). Same population (93,608) and range as limit_quantity_per_year — its frequency twin. NULL when no quantified frequency. |
| source_pbp_section | varchar(4) | The PBP section/sub-section the row came from and the benefit-component axis of the grain: B16 (overall dental, all years), B16A (Medicare-covered), B16B (diagnostic/preventive), B16C (comprehensive). B16A/B/C exist ONLY for 2025-2026. |
| source_silver_table | string | CONSTANT = 'medicare_silver.pbp_section_b16_dental' — the upstream silver table this view is built from. |
| lmi_authorities | string | Local-Market-Intelligence authority tags. EMPTY STRING '' for every row (LMI enrichment is not applied to this PBP dental view). |
| source_url | string | Provenance: the CMS PBP-benefits ZIP this snapshot was extracted from (e.g. 'https://www.cms.gov/files/zip/pbp-benefits-2025.zip', '.../pbp-benefits-2023-quarter-4.zip'). One distinct URL per report_year/quarter. |
| sha256_content_hash | string | Content hash of the source record for provenance/dedup integrity. Not a business key. |

Tools that read it: get_pbp_benefit

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