Risk Adjustment Data Marts
Risk adjustment analytics are exposed via flattened, query-friendly views derived from the underlying FHIR MeasureReport resources and the clinical data behind them. The views are published through the VBC Risk Snowflake listing and refresh once a day. See Accessing the VBC Risk listing below for how to add it to your Snowflake account, and Migrating from the public preview schema at the end of this page if you query the ZUS_VBC_INSIGHTS_PUBLIC_PREVIEW schema today.
Every view has a builder_id where the row belongs to a builder, so a parent account can tell its sub-builders apart. Rows are filtered to the builders your account is allowed to see.
Accessing the VBC Risk listing
The views are delivered as a Snowflake private listing named VBC Risk, separate from the FHIR Core listing that carries your relational FHIR data. It is granted per Snowflake account on request, so it does not appear until Zus adds your account.
Before you start
- Your organization needs its own Snowflake account on the Business Critical edition with a signed BAA with Snowflake. If you reach Zus data another way, such as a Zus-hosted reader account, ask your account manager about VBC Risk availability.
- Ask your Zus account manager to add your account to the listing. Send the same details used for the FHIR Core listing: Snowflake region, account locator, organization name, and account name. The Access via Snowflake (private listing) page shows where to find them.
- Accepting a listing requires
ACCOUNTADMINor a role that can accept shares and create databases from listings.
Accepting the listing
- In Snowsight, open Data Products and then Private Sharing (labelled Data Sharing > External Sharing in some accounts).
- Find the VBC Risk listing from Zus Health and click Get.
- Choose a database name. The examples on this page use
VBC_RISK. - Grant the database to the roles that will query it:
GRANT IMPORTED PRIVILEGES ON DATABASE VBC_RISK TO ROLE <role_name>;In some regions the first acceptance takes about ten minutes while Snowflake starts replication.
Using the views
All eight views are in the PUBLIC schema of the database you created. Column descriptions are stored as Snowflake comments, so the data dictionary is available in Snowsight and with DESCRIBE VIEW.
SHOW VIEWS IN SCHEMA VBC_RISK.PUBLIC;
DESCRIBE VIEW VBC_RISK.PUBLIC.RISK_GAP;
SELECT builder_id, gap_type, COUNT(*) AS gaps
FROM VBC_RISK.PUBLIC.RISK_GAP
WHERE reporting_year = 2026
AND gap_status = 'open-gap'
AND NOT is_acute
AND superseded_by_risk_gap_id IS NULL
GROUP BY builder_id, gap_type;A few things to know:
- Rows are filtered for you. Every view returns only the builders your Snowflake account is entitled to, so there is no builder filter to apply unless you want a subset. A builder added to your account appears after the next daily refresh.
- The views refresh once a day. They are rebuilt from the Zus platform each morning US time. A listing is a live reference, not a copy, so you see each refresh as soon as it completes with no re-acceptance.
- The views are the contract. Zus keeps the names and columns stable and may add columns without notice. Select columns by name rather than
SELECT *in anything that depends on column order.
The listing contains eight views:
| VIEW | ONE ROW PER |
|---|---|
risk_gap | Risk gap |
risk_gap_status | Status change on a risk gap |
risk_gap_hierarchy | Superseded risk gap |
risk_gap_diagnosis_code | ICD-10 code on a risk gap |
risk_gap_evidence | FHIR resource cited by a risk gap |
patient_raf_score | Patient, builder and measurement period |
patient_detail | Patient, builder and reporting year |
payer_risk_gap | Payer-reported risk gap |
Risk Gap Views
risk_gap
One row per CMS-HCC v28 individual risk gap (MeasureReport), with its current status, HCC reference data, supersession, evidence counts, payer closure, latest encounter diagnoses and user review activity. Count gaps here, never off a join to risk_gap_evidence.
Identity and classification
| FIELD | NOTES |
|---|---|
id | Risk gap identifier (the MeasureReport resource ID). |
patient_id, upid | Patient resource ID and Universal Patient Identifier. |
builder_id | The builder that owns the gap. |
code_hcc, hcc_version | HCC code and model version, typically "28". |
hcc_description | CMS label for code_hcc, for example "Diabetes with Chronic Complications". |
hcc_coefficient | Coefficient for code_hcc in the community non-dual aged segment. For ranking only; do not sum. |
is_acute | TRUE if code_hcc is on the Zus acute list. |
gap_type | recapture, suspect, or net-new. |
gap_status | Current status: open-gap, closed-gap, expected-to-close-1st-party, expected-to-close-3rd-party, accepted-for-review, dismissed, or pending. |
confidence_level | 1 to 5 (5 = highest confidence). Typically 5 for rules-based or payer gaps, 1 to 5 for AI-generated suspects. |
superseded_by_risk_gap_id | The gap for a higher HCC in the CMS-HCC hierarchy on the same patient and period, if one exists. |
period_start, reporting_year | Start date of the calendar-year measurement period, and that year as an integer. |
summary | Gap-level narrative summary derived from all available evidence. Note that the format of these summaries may change and should not be relied upon for data ingestion. |
summary_source | How the summary was generated: template (assembled from structured evidence) or ai (LLM-generated). |
Evidence
| FIELD | NOTES |
|---|---|
evidence_count | Evaluated evidence: the resources that identified the gap. More does not necessarily mean a better suspect. |
related_resource_count | Context resources shown with the gap but not used to identify it. |
payer_evidence_count | Evaluated evidence that is a Claim, ExplanationOfBenefit or MeasureReport: your own payer data. |
first_party_clinical_evidence_count | Evaluated clinical evidence owned by builder_id. |
third_party_clinical_evidence_count | Evaluated clinical evidence owned by another builder. |
closed_from_payer_data_at | When Zus first closed the gap on receiving payer data (a claim file, risk-eligible diagnoses, or a payer gap file). Null if payer data hasn't closed it. Later status changes don't overwrite it. |
Latest encounter diagnoses
The latest encounter diagnosis (a Condition with LOINC category 29308-4) in the gap's evaluated evidence, split by who owns it. First-party means your builder owns the Condition; third-party means another builder does.
| FIELD | NOTES |
|---|---|
latest_first_party_encounter_diagnosis_recorded_at | Recorded date of the latest first-party encounter diagnosis. Null when none supports the gap. |
latest_first_party_encounter_diagnosis_condition_id | Its Condition resource ID. |
latest_third_party_encounter_diagnosis_recorded_at | Recorded date of the latest third-party encounter diagnosis. Null when none supports the gap. |
latest_third_party_encounter_diagnosis_provider | Recorder, else asserter, of that diagnosis: the linked Practitioner's given and family name. Null when the Condition links no Practitioner resource. |
latest_third_party_encounter_diagnosis_organization | Managing organization of the Patient that diagnosis belongs to, usually the organization the data came from. |
latest_third_party_encounter_diagnosis_condition_id | Its Condition resource ID. |
Review activity
| FIELD | NOTES |
|---|---|
first_viewed_at, last_viewed_at | First and last time a user opened the gap's detail in the Zus app. Null if never opened. |
accepted_at, accepted_by | First time a user set the status to accepted-for-review, and that user's email. |
acceptance_reason, acceptance_note | Substatus and note on that acceptance, for example sent-to-provider-for-review. Optional in the app, so often null. |
dismissed_at, dismissed_by | First time a user set the status to dismissed, and that user's email. |
dismissal_reason, dismissal_note | Substatus and note on that dismissal, for example resolved, acute-in-nature, or inaccurate-or-insufficient-evidence. Optional in the app, so often null. |
Timestamps
| FIELD | NOTES |
|---|---|
created_at | When the risk gap was first calculated. |
last_updated_at | When the MeasureReport resource was last updated. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Population listing | List all current-year gaps for a population. |
| Segmentation | Segment by gap type, status, or evidence source. |
| Prioritization | Rank open gaps by hcc_coefficient and confidence_level. |
| Reviewer throughput | Measure how quickly gaps are viewed, accepted, or dismissed. |
| Trends | Trend monitoring by period. |
risk_gap_status
One row per status update event per risk gap (full history). The most recent value is also on risk_gap.gap_status.
| FIELD | NOTES |
|---|---|
risk_gap_id | Link to risk_gap.id. |
created_at, created_by | When the status was created, and by whom: a user's email when made by a person, otherwise an identifier for the Zus system responsible. |
status | open-gap, closed-gap, accepted-for-review, dismissed, or pending |
source | What produced the update: zus-rules, zus-ai, payer-gap, claim-file, risk-diagnoses, or user-update. |
note (optional) | Free-text note. |
substatus_one, substatus_two, substatus_three (optional) | Additional categorization codes, for example resolved or acute-in-nature. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Audit trail | Audit trail of review workflows. |
| Operational metrics | Measuring time-to-close or time-to-review. |
| Status evolution | Understanding how gaps evolve (e.g., open → accepted → closed). |
| Attribution | Which systems and users are changing gap status. |
risk_gap_hierarchy
Represents superseding relationships between gaps based on HCC hierarchy. Each superseded gap links to the nearest superseding gap for the same patient and period, so a chain of three gaps appears as two links. The same link is also on risk_gap.superseded_by_risk_gap_id.
| FIELD | NOTES |
|---|---|
risk_gap_id | The superseded gap. |
superseded_by_risk_gap_id | The superseding gap. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Top-level filtering | Filter to top-level gaps only. |
| Accurate counts | Avoid double-counting related HCCs in reporting. |
risk_gap_diagnosis_code
Normalized mapping of ICD-10 codes to risk gaps (one row per ICD-10 per gap).
| FIELD | NOTES |
|---|---|
risk_gap_id | Link to risk_gap.id. |
code_icd_10 | ICD-10 diagnosis code, for example E11.9. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Drilldown | Drilldown from HCC gap → supporting ICD-10s. |
| Comparisons | Compare coding patterns across providers. |
risk_gap_evidence
Normalized mapping from risk gaps to evidence resources. Clinical evidence (evaluated) means a Zus process used the resource to identify the gap, such as a Condition or Claim showing a previous diagnosis. Related resources (related) are context expected to be useful when evaluating the gap, such as a recent A1c for a diabetes gap, and may support or refute it.
| FIELD | NOTES |
|---|---|
risk_gap_id | Link to risk_gap.id. |
resource_type, resource_id | The referenced FHIR resource. resource_type is lowercased, for example condition or documentreference. |
type | evaluated for directly supporting evidence or related for related resources providing context. |
has_first_party_source | TRUE if your builder owns this resource (or, for a lens Condition or MedicationStatement, one of the raw resources it aggregates), FALSE if not. |
summary | One-line narrative summary for this evidence reference. Note that the format of these summaries may change and should not be relied upon for data ingestion. |
last_updated | When the risk gap was last updated. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Reviewer experiences | Build reviewer experiences (evidence panels). |
| Analytics | Analytics on evidence completeness and on first-party versus third-party support. |
Linking back to FHIR
You can construct a direct FHIR reference from resource_type and resource_id:
https://api.zusapi.com/fhir/{resource_type}/{resource_id}
The latest_*_encounter_diagnosis_condition_id columns on risk_gap resolve the same way, at /fhir/Condition/{id}.
RAF Score Views
patient_raf_score
One row per patient, builder, and measurement period, calculated by the risk gap calculator and published from the resulting RAF Score MeasureReport. All three scores use the CMS-HCC v28 community model (CNA) with the patient's demographic factors and differ only in which gaps' HCCs they count.
| FIELD | NOTES |
|---|---|
id | ID of the RAF Score MeasureReport resource. |
patient_id, upid | Patient resource ID and Universal Patient Identifier. |
builder_id | The builder that owns the score. |
raf_score_model | The RAF model used to calculate the scores. |
actual_raf_score | RAF score from HCCs closed via payer data: claims, risk diagnoses, or payer risk gaps. |
expected_raf_score | RAF score from HCCs that are closed or expected to close: closed gaps plus gaps with an encounter diagnosis recorded in the period that payer data hasn't confirmed yet. |
potential_raf_score | RAF score if every gap that hasn't been dismissed were closed. |
period_start | Start date for the calendar-year period. |
created_at | When the score was calculated. |
last_updated | When the MeasureReport resource was last updated. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Population overview | Aggregate RAF opportunity across a patient panel. |
| Gap prioritization | Identify patients with the largest potential_raf_score - actual_raf_score. |
| Trend tracking | Monitor score changes over time. |
Patient Views
patient_detail
One row per patient, builder, and reporting year, for every patient with a risk gap or RAF score that year. The data flags, suspecting run, and appointments are per person, matched on upid. Gap counts and RAF are not here: join risk_gap and patient_raf_score.
| FIELD | NOTES |
|---|---|
patient_id, upid | Patient resource ID and Universal Patient Identifier. One builder can hold several Patient resources for the same person; they share a upid. |
builder_id | The builder that owns the patient. |
reporting_year | CMS measurement year as an integer, for example 2026. |
suspecting_last_run_at | When the latest AI suspecting job that processed the reporting year finished for the patient. Null if none. |
has_first_party_data | TRUE if your builder owns at least one DocumentReference, Condition, medication resource, or Encounter for the patient, in any year. |
has_third_party_data | TRUE if another builder has a Patient resource for the same person. |
has_payer_data | TRUE if your builder has at least one payer risk gap or claim for the patient, in any year. |
last_appointment_start_time | Start of the most recent appointment before refreshed_at, excluding cancelled, no-show, and entered-in-error appointments. Null if none or no appointment feed. |
next_appointment_start_time | Start of the earliest appointment at or after refreshed_at, with the same exclusions. Null usually means no appointment feed, not no visit. |
refreshed_at | When the row was built. The appointment columns are relative to it. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Coverage | Which patients have first-party, third-party, or payer data behind their gaps. |
| Suspecting monitoring | Confirm AI suspecting has run for a panel. |
| Outreach | Prioritize patients with an upcoming appointment and open gaps. |
Payer Risk Gap Views
payer_risk_gap
Payer-provided evidence of a risk gap. Payers return risk adjustment data describing which diagnoses and encounters are eligible as risk gaps. Customers standardize that data as CSV and provide it to Zus, which matches it to a patient, deduplicates it, and stores it as a MeasureReport.
| FIELD | NOTES |
|---|---|
id | ID of the Payer Risk Gap MeasureReport resource. |
patient_id, upid | Patient resource ID (resolved by Zus from the identifier in the file) and Universal Patient Identifier. |
builder_id | The builder that owns the payer risk gap. |
code_hcc, code_hcc_version | HCC code reported by the payer and its model version, typically V28. |
code_icd_10 | The contributing ICD-10-CM code, normalized to include the decimal. |
payer_reported_status | The status according to the payer file: open or closed. Does not always match the resulting gap's status. |
payer_reported_recapture_flag | TRUE if the payer determined the gap was recaptured, FALSE if not, null when the payer didn't report it. |
last_claim_date | The date the ICD-10 code last appeared on a claim, or the customer's closest approximation. |
reason | Human-readable description of the evidence behind the payer gap. |
gap_source | The ingestion path that produced this record, for example payer-risk-gap-csv-file. |
period_start | Start date for the calendar-year period. |
created_at | When the payer risk gap was created. |
last_updated | When the MeasureReport resource was last updated. |
| TYPICAL USE CASE | DESCRIPTION |
|---|---|
| Risk Gap Source Tracking | Identify payer gap data provided to create certain risk_gap entries. |
| Import tracking | Successfully imported Payer Risk Gap CSVs create Payer Risk Gaps which ultimately reach the payer_risk_gap view. This allows you to check if a CSV completed successfully. |
Migrating from the public preview schema
Before the VBC Risk listing, risk views were published in the ZUS_VBC_INSIGHTS_PUBLIC_PREVIEW schema alongside the relational FHIR data. The preview schema stays in place for a migration period after the listing is generally available, and Zus will announce its retirement date in advance. Plan to move queries over before then.
The listing is not a rename. Views were dropped, renamed, and widened, and a few columns changed type. The sections below cover what to change.
What moved where
| PREVIEW VIEW | LISTING VIEW | WHAT CHANGED |
|---|---|---|
risk_gap | risk_gap | Every preview column is kept with the same name. 27 columns were added: HCC reference data, evidence counts, payer closure, latest encounter diagnoses, review activity, and reporting_year. |
risk_gap_status_update | risk_gap_status | Renamed. Same columns. |
risk_gap_hierarchy | risk_gap_hierarchy | Unchanged. The same link is also on risk_gap.superseded_by_risk_gap_id. |
risk_gap_diagnosis_code | risk_gap_diagnosis_code | Keeps risk_gap_id and code_icd_10. Drops sources, recorded_date, has_first_party_source, and has_third_party_source. See replacements below. |
risk_gap_evidence | risk_gap_evidence | Drops has_third_party_source. Everything else is kept. |
risk_gap_source | none | Removed. See replacements below. |
risk_gap_archive | none | Not published. Deleted gaps are no longer visible. |
raf_score | patient_raf_score | Renamed. Adds builder_id, drops measure. The three scores keep their names. |
raf_score_v28, raf_score_v24 | none | Removed. These were estimates recomputed from HCC factor tables, not the calculator's scores. See replacements below. |
payer_risk_gap | payer_risk_gap | Drops measure. payer_reported_recapture_flag is now BOOLEAN instead of the strings '1' and '0'. |
| none | patient_detail | New. One row per patient, builder, and reporting year with data coverage flags, suspecting run time, and appointments. |
HIERARCHY_V28, DIAGNOSIS_FACTORS_V28, ICD10_HCC_MAPPING, SUSPECT_CONDITION_HCC, ALL_AI_SOURCED_CONDITIONS | none | Reference and working tables that were visible in the preview schema are not part of the listing. risk_gap carries hcc_description, hcc_coefficient, and is_acute for the common lookups. |
Replacements for dropped columns and views
- Source attribution (
risk_gap_source, andsourcesonrisk_gap_diagnosis_code). Userisk_gap_status, whosesourcecolumn records which system produced each status change:zus-rules,zus-ai,payer-gap,claim-file,risk-diagnoses, oruser-update. The earliest status row for a gap is the system that created it. For "did payer data close this gap", userisk_gap.closed_from_payer_data_atdirectly. - First-party versus third-party evidence (
has_third_party_sourceonrisk_gap_evidenceandrisk_gap_diagnosis_code).risk_gap_evidence.has_first_party_sourceis kept and now resolves ownership from the resource itself, including the raw resources behind a lens summary. Third-party ishas_first_party_source = FALSE; NULL means the owner could not be resolved. For counts,risk_gapcarriesfirst_party_clinical_evidence_count,third_party_clinical_evidence_count, andpayer_evidence_count, so most queries no longer need the evidence view at all. - Encounter diagnosis dates (
recorded_dateonrisk_gap_diagnosis_code).risk_gapcarrieslatest_first_party_encounter_diagnosis_recorded_atandlatest_third_party_encounter_diagnosis_recorded_at, each with theConditionID behind it, and the third-party row also names the provider and organization. These are per gap rather than per ICD-10 code. - RAF estimates (
raf_score_v28,raf_score_v24). Usepatient_raf_score, which is the calculator's own score.potential_raf_score - actual_raf_scorereplacesraf_gap. There is no v24 equivalent; the listing is CMS-HCC v28 only. For HCC counts, count distinctcode_hcconrisk_gapwith the status filter you need. - Deleted gaps (
risk_gap_archive). Not available. A gap that disappears fromrisk_gapbetween refreshes was removed by recalculation.
Query changes
- Qualified names.
ODS_EXPORTS.ZUS_VBC_INSIGHTS_PUBLIC_PREVIEW.RISK_GAPbecomes<your database>.PUBLIC.RISK_GAP. - Top-level gaps. The preview required an anti-join to
risk_gap_hierarchy. Usesuperseded_by_risk_gap_id IS NULLonrisk_gapinstead. - Year filtering.
period_startis still a string, butreporting_yearis an integer, soWHERE reporting_year = 2026replacesWHERE period_start = '2026-01-01'. - Recapture flag. Compare
payer_reported_recapture_flagtoTRUEandFALSE, not to'1'and'0'.
Before, on the preview:
SELECT g.id, g.code_hcc, g.gap_status
FROM ODS_EXPORTS.ZUS_VBC_INSIGHTS_PUBLIC_PREVIEW.RISK_GAP g
WHERE g.period_start = '2026-01-01'
AND g.gap_status = 'open-gap'
AND NOT EXISTS (
SELECT 1 FROM ODS_EXPORTS.ZUS_VBC_INSIGHTS_PUBLIC_PREVIEW.RISK_GAP_HIERARCHY h
WHERE h.risk_gap_id = g.id
);After, on the listing:
SELECT id, code_hcc, hcc_description, gap_status
FROM VBC_RISK.PUBLIC.RISK_GAP
WHERE reporting_year = 2026
AND gap_status = 'open-gap'
AND superseded_by_risk_gap_id IS NULL;Updated about 9 hours ago