# OIG List of Excluded Individuals/Entities (LEIE)

`drug_silver.dim_oig_leie` · Provider identity · status live · 249,886 rows

The HHS-OIG List of Excluded Individuals/Entities — providers/entities BARRED from billing federal healthcare programs, with NPI/UPIN, name or business name, exclusion type and date, and any reinstatement/waiver. The integrity / accountability layer: screen a book's providers for exclusions, and join to the facility/provider spine by NPI.

**Grain.** One row per excluded party record per source snapshot. The minimal verified unique key across the full 166,452-row table is (row_uid, vintage_tag): row_uid alone yields only 83,226 distinct values because it is a STABLE per-record content hash that repeats once in each of the 2 snapshots. Within a single snapshot (or filtered to is_current=true) the grain is just row_uid = 83,226 distinct = the current LEIE size. Note an excluded PERSON can occupy multiple rows (945 name+dob pairs appear 2x, some 3-4x) — row_uid is per exclusion-action record, not per human.

**How to use it.** Compliance screen against the cost substrate: 'is this provider/pharmacy sanctioned?' Example — SELECT lastname, firstname, busname, npi, state, exclusion_type, exclusion_date FROM drug_silver.dim_oig_leie WHERE is_current = true AND npi = '1972902351'; returns the matching exclusion record (statute + date) if the NPI is on the current LEIE, or empty if clean. To screen a list of NPIs that appear in rate/claims tables, inner-join them to this table on npi WHERE is_current = true to flag excluded billers; supplement with name+state+dob matching because ~90% of LEIE rows have no NPI.

**Traps.**
- row_uid is NOT a global primary key. It is a stable per-record content hash that repeats once per snapshot, so the full table has 166,452 rows but only 83,226 distinct row_uid. Use (row_uid, vintage_tag) globally, or filter is_current=true and then row_uid is unique.
- ALWAYS filter is_current=true (or pick one vintage_tag). The table holds 2 snapshots that are CONTENT-IDENTICAL (0 row_uids added/removed between 05-16 and 05-18, same sha256_content_hash). Querying without the filter silently double-counts every excluded party.
- Periodicity is NOT weekly — the profiler was fooled. It measured effective_period_start, which equals exclusion_date (the OIG action date, 1977→2026, an event spread). The real load cadence lives in observed_period and is only 2 snapshots 2 days apart; today this is effectively a single static full-file load.
- reinstatement_date is always NULL and effective_period_end is always the sentinel 2099-12-31. This is by LEIE design: reinstated parties are DELETED from the file, not flagged, so the file = currently-excluded only. Never infer 'still excluded' from these columns; presence in the current snapshot IS the exclusion signal.
- npi is the join key to the cost substrate but is ~90% NULL (only 8,607 of 83,226 rows). Joining exclusions to NPI-keyed rate/claims data will miss most excluded parties; name+state+dob matching is needed for the rest. Also a person can hold multiple rows (same name+dob 2-4x) and a few NPIs map to >1 record, so neither npi nor name+dob is a unique key.
- exclusion_type is a categorical SSA statute code, not numeric. It mixes 1128a*/1128b* sub-paragraphs with quality codes (1156/1160) and settlement-breach flags ('BRCH SA','BRCH CIA') and a '1128Aa' value — handle as strings and map to OIG's published authority legend (e.g. 1128a1 = program-related conviction, 1128b4 = license revocation).

| column | type | meaning |
|---|---|---|
| row_uid | string | Deterministic content hash identifying one exclusion record. UNIQUE within a snapshot (83,226) but NOT globally — the SAME row_uid reappears in every snapshot for an unchanged record. Join to vintage_tag for a global key. |
| entity_kind | string | 'individual' (79,825) or 'business' (3,401). Drives which name fields are populated. |
| lastname | string | Excluded person surname. Populated for ALL individuals, NULL for ALL businesses. |
| firstname | string | Excluded person first name. Populated for all individuals, NULL for businesses. |
| midname | string | Person middle name. Often NULL even for individuals (sparse). |
| busname | string | Excluded business/organization name (e.g. a pharmacy, DME company, home health agency). Populated for ALL businesses, NULL for ALL individuals. Mutually exclusive with lastname/firstname. |
| general_category | string | OIG provider-category label, TRUNCATED free text (e.g. 'IND- LIC HC SERV PRO', 'NURSING PROFESSION', 'PHARMACY', 'DME COMPANY', 'HOSPITAL', 'BUS OWNER/EXEC'). Descriptive, not a code system. |
| specialty | string | OIG specialty label, also truncated free text ('NURSE/NURSES AIDE' dominates at 34,537, 'PHARMACIST', 'CHIROPRACTIC', etc.). ~4,079 NULL = unspecified. |
| upin | string | Legacy Unique Physician Identification Number (pre-NPI). Very sparse — ~5,945 individuals, 13 businesses. Deprecated identifier. |
| npi | string | National Provider Identifier of the excluded party — the JOIN key to the rest of the cost substrate. MOSTLY NULL: only 8,607 of 83,226 rows (~10%) carry an NPI; 8,429 distinct (a few NPIs map to >1 record). All populated values are 10 digits; no zero-sentinel. Older exclusions predate NPI, hence the sparsity. |
| dob | date | Person date of birth, used with name to disambiguate identity. Range 1901-01-01 to 2005-09-11; ~4,263 NULL (all businesses + some individuals). |
| address | string | Last known street address of the excluded party (free text, sometimes 'C/O ...'). |
| city | string | City of the excluded party. |
| state | string | 2-letter US state of the party's address. |
| zip_code | string | ZIP code (string, preserves leading zeros). |
| exclusion_type | string | Social Security Act authority code for the exclusion. Dominant values: 1128b4 (33,136 — license revocation/surrender), 1128a1 (25,732 — program-related conviction), 1128a2/a3/a4, 1128b14 (default on health-ed loan), 1128b8, 1128b1. Plus rare 1156/1160 (quality), 1128Aa, and settlement-breach flags 'BRCH SA'/'BRCH CIA'. NOT a simple numeric — treat as a categorical statute code. |
| exclusion_date | date | Date OIG imposed the exclusion (the event date). Equals effective_period_start for 100% of rows. Range 1977-07-01 to 2026-05-20. |
| reinstatement_date | date | Date the party was reinstated. ALWAYS NULL in this data — by LEIE design, reinstated parties are DELETED from the file rather than flagged, so the file only holds currently-excluded parties. Column carries no signal here. |
| waiver_date | date | Date of an OIG-granted exclusion waiver. Extremely rare (3 rows). Almost always NULL. |
| waiver_state | string | State that requested the waiver. Extremely rare (4 rows). Almost always NULL. |
| observed_period | date | Snapshot date — when Vlada pulled the LEIE file. THE true time dimension: only 2 values, 2026-05-16 and 2026-05-18. Use this (not exclusion_date) to reason about data vintage. |
| asserted_at | date | Date the record was asserted into the silver table; equals observed_period in this data. |
| effective_period_start | date | Bitemporal start of the exclusion's validity = exclusion_date exactly (100% match). Spans 1977→2026; this is an EVENT-date spread, which the profiler misread as 'weekly' periodicity. |
| effective_period_end | date | Bitemporal end of validity. ALWAYS the sentinel 2099-12-31 (100%), meaning every exclusion is treated as open-ended/active (it ends only by being removed from the file). It is NOT a real reinstatement date. |
| cms_vintage_sequence | int | Vintage sequence counter. Constant = 1 across the whole table. |
| parse_revision | int | Parser revision number. Constant = 1. |
| parser_artifact_hash | string | Hash of the parser build/artifact. 2 distinct values — the ONLY content column distinguishing the two otherwise-identical snapshots (a parser re-run). |
| source_url | string | Origin URL — single value https://oig.hhs.gov/exclusions/downloadables/UPDATED.csv. This 'UPDATED.csv' is the full LEIE database file (complete current roster), not an incremental update. |
| sha256_content_hash | string | SHA-256 of the source CSV bytes. CONSTANT (1 distinct) across the entire table — both snapshots ingested byte-identical source content. |
| source_id | string | Logical source identifier. Constant = 'oig_leie'. |
| is_current | boolean | Boolean snapshot flag. true = the latest snapshot (2026-05-18, 83,226 rows); false = the prior snapshot (2026-05-16, 83,226 rows). ALWAYS filter is_current=true to get the live LEIE; otherwise every record is doubled. |
| bronze_object_key | string | S3 key of the bronze CSV this row was parsed from. Constant = 1 (single bronze object). |
| s3_version_id | string | S3 object version id of the bronze file. Constant = 1. |
| vintage_tag | string | Human-readable snapshot label ('oig_leie_2026-05-16' / 'oig_leie_2026-05-18'). The second half of the global grain key; 1:1 with observed_period/is_current here. |
| drug_source_version_id | string | Cross-source drug version linkage. 100% NULL in this table — not populated for the LEIE source. |

Tools that read it: excluded_prescriber_payment_screen

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