What should we test on every IQVIA, Symphony, specialty pharmacy, and 867 feed before it loads?

Test every delivery for five things before it reaches a report: that it arrived on time and only once, that it is complete against the vendor's control count or its own history, that no column was renamed, that units did not change, and that past periods did not move. Then add the one check each feed type needs.

Key points

  • A specialty pharmacy file that should carry 40,000 rows and arrives with 26,000 loads with no error, so completeness has to be tested, not assumed from a green pipeline.
  • A vendor column renamed from RX_CNT to RxCount makes the transform fill the field with nulls, and the pipeline produces a clean, empty metric instead of failing.
  • Syndicated sales data is part actual and part projection, and vendors rerun the projection when better inputs arrive, so a closed period can change inside a file that loads perfectly.
  • Where a vendor sends no control count, bound volume against that feed's own history, because a specialty feed legitimately shrinks on a holiday week.
  • Run the arrival checks on the raw stage, so a bad delivery stops somewhere the field never sees.

Most of the data behind your launch came from someone else. IQVIA, ICON/Symphony, a dozen specialty pharmacies, your 3PL, your patient hub. You did not create it, you cannot control its schedule, and when it is wrong it rarely errors.

The post on the commercial data most likely to be wrong catalogues the ways it fails. The useful observation is that five of them repeat across every feed. So you run the same five checks on every delivery, then add the check each feed type needs.

Five checks on every delivery

FailureWhat you seeTest
Late, missing, or loaded twiceNothing. The pipeline is green.Freshness monitor; max load date is today; one delivery per expected period
Partial file26,000 rows where 40,000 belong, no errorRow count against the vendor control record, or volume bounds learned from the feed’s history
Renamed columnRX_CNT becomes RxCount; the field fills with nullsSchema drift test
Unit or scale changeUnits become packages, dollars become cents; one product jumps 10xMetric trend against that product’s own history
History movedLast quarter’s actuals change inside a clean fileDiff overlapping periods against the snapshot you kept

The first four are extract-to-load checks. They run in seconds and should be exact where the vendor gives you a control count. Sum the amount column on both sides at fixed precision, so two engines don’t disagree over floating point.

The fifth is the one most teams skip. Third-party sales data is part actual, part projection. The vendor reruns the projection when better inputs arrive, and your actuals change underneath you. The restatement answer covers how to split that test between the restated months and the stable tail.

Use learned bounds, not fixed thresholds. A hardcoded “expect at least 50,000 rows” goes stale as the data grows, then fires false alarms or gets commented out. One rare-disease biotech’s warehouse shipped with 150 checks and had about 20 still enabled, because the rest fired on the same upstream problems every morning.

What each feed type adds

The data sources reference lists 37 commercial feeds with the failure characteristic of each. These are the ones you asked about.

FeedHow it arrivesIts own failureAdd this check
IQVIA, ICON/Symphony prescription and prescriber dataWeekly and monthly, often wide, periods across columnsRestatement on refresh; payer or specialty mix shifts from a mapping changeNormalize to long format first, then Distribution Shift on the mix
Medical and pharmacy claims, such as Komodo HealthWeekly or monthly, large, lagged by adjudicationMalformed NPI, NDC, or ICD values that fail the join silentlyIdentifier validation before the join (why pattern checks miss them)
Specialty pharmacy dispense and statusOne file per pharmacy, each with its own format and calendarShip, fill, and dispense dates mean different things; one patient under three tokensMap to one event date and one calendar before comparing (867 and specialty answer)
3PL and distribution, EDI 867 and 852Weekly, EDI, positional formatsUnits switch to packages, price arrives in centsMetric Trend per product against its own history
Patient services and hubDaily or weekly from the hub vendorMilestone dates out of sequence, such as ship before enrollmentCustom Condition on milestone order
Copay and adjudicationWeekly from the copay vendorRedemptions that never reconcile to a dispenseReference Match from redemption to dispense

Two of the hardest failures are not in any single feed. A prescriber who appears in two sources under two records, and a territory realignment that moves a rep’s numbers, both pass every check above. Those are relationship tests, covered in finding duplicate HCP records and testing alignment before the comp run.

Where the checks run

Run arrival checks on the raw stage, before anything reaches a mart. A two-stage FITT architecture keeps raw data exactly as it arrived, so a bad delivery fails somewhere the field never sees, and the snapshot you need for the history diff is already there.

In DataOps TestGen, freshness, volume, and schema monitors run on every table in the table group, with volume bounds learned from each table’s history, so you do not hand-write them per feed. Reference Match, Aggregate Balance, Distribution Shift, and Custom Condition cover the relational and feed-specific checks, as the testing post lays out. If your vendors drop files to S3 or a folder rather than a database, checking vendor files before they load shows the setup.

The test that matters most is the one you can answer in a minute: did every row from last night’s delivery land? If you can’t say, find out before the field does.

Frequently asked questions

Short answers to the follow-up questions people ask next.

How do you catch a partial vendor file that loads with no error?

Count it. Compare the row count in staging to the vendor's control record and sum the amount column on both sides at fixed precision. Where there is no control count, bound the volume against that feed's own history. A specialty pharmacy file of 26,000 rows against a normal 40,000 is not automatically wrong, but it is automatically worth a look before it loads.

How do you know a weekly vendor feed arrived, and arrived only once?

Check the calendar, not the pipeline. A weekly file should land exactly once a week and a monthly file once a month. Feeds go missing and feeds get loaded twice, and neither throws an error. Freshness and volume monitors catch both, and a check that the max load date is today catches a file that is three days stale.

What happens when a vendor renames a column?

Usually nothing visible, which is the problem. Last week the column was RX_CNT and this week it is RxCount. The transform maps the old name, finds nothing, and fills the field with nulls. The pipeline succeeds and produces a well-formatted, empty metric. A schema drift test fails the load the moment the column changes.

Why can't we just forbid changes to historical periods?

Because syndicated vendors revise the most recent months on every refresh by design. Their data is part actual and part projection, and they rerun the projection when better inputs arrive. A rule forbidding change fires every week. Test the stable tail and the restatement window separately, with a snapshot of each period as you received it.

Which test catches a patient hub feed with impossible dates?

A sequence rule, because the values are all valid on their own. A ship date before an enrollment date is not a format error, so null, type, and pattern checks pass it. A Custom Condition test that states the milestone order, such as ship date on or after enrollment date, fails the rows that break it.

Talk to the people who test this data every week

DataKitchen builds and runs commercial data platforms for small and midsize pharma, with the tests in place from day one.