Your UNFI Insights sell-through report is at store and UPC level. It names the store, gives you its address, and tells you how many cases moved there last week. It reads exactly like point-of-sale data.
It is not point-of-sale data. Every number in it is what UNFI shipped to
that store, not what the store sold. UNFI's own column header says so out loud:
the measure is called Cases Shipped Selected Period, and the word in the
middle is the one that matters. A store that took twelve cases and sold three
looks identical to a store that took twelve and sold twelve, until the reorder
does not come.
That distinction is the difference between a distribution problem and a velocity problem, and this portal can only see one of them. Everything below assumes you want to know which.
Crisp, who build UNFI Insights, publish a glossary of the columns inside it. This guide is not that. It covers where Insights sits relative to the two other places a UNFI supplier gets data, which reports carry information you cannot get anywhere else, and the period behaviour that decides whether your numbers are right.
How UNFI Insights works
Three separate systems stand between your login and your data, and knowing that explains almost every awkward thing about getting numbers out.
The three-hop path
UNFI Insights is not a UNFI application. Reaching your data crosses three platforms owned by two companies:
- myUNFI (
myunfi.com) is the supplier portal, and your login lives here. Authentication is Azure AD B2C, username first and password on a second screen. - Crisp (
platform.gocrisp.com/unfi-insights) is the analytics product. Opening it from an authenticated myUNFI session signs you in silently, which is why you never see a second login and why a stale session fails in a confusing way rather than asking you to log in again. - Looker (
analytics.gocrisp.com) renders the dashboards, embedded inside Crisp. The tables you look at are Looker visualisations over a BigQuery warehouse.
Two practical consequences. The Insights session can expire independently of your myUNFI session, so a dashboard that will not load is usually an authentication problem wearing the costume of a data problem. And because the surface is an embedded Looker, everything about export behaviour is Looker's behaviour rather than UNFI's, which the next two sections are about.
When the session has quietly expired
Worth its own section, because the failure does not look like a login failure and people spend real time debugging the wrong thing.
When the Crisp session lapses, the application still paints. You get the navigation, the page furniture, and often the shell of the dashboard, because that chrome is drawn from state the browser already had. Only then does it check the session, find it gone, and redirect. What you experience is a page that looks like it loaded and then either sits with empty tiles or bounces you to a sign-in screen a beat later.
Three symptoms that all mean the same thing:
- Tiles that spin indefinitely, or render their titles and never their data.
- A dashboard that loads fully but returns nothing for a period you know has data.
- Any of the above clearing the moment you open the portal in a fresh tab.
The fix is to re-enter through myUNFI rather than reloading the Insights URL.
Because the sign-in is silent, going back to myunfi.com and opening Insights
again re-establishes the whole chain; hammering refresh on the Crisp URL often
does not, since the stale session is still technically present.
The same shape catches automated pulls, and more expensively: a saved session that has lapsed can look valid right up until the point the data does not arrive, so a scheduled export can fail for days while reporting that it authenticated. If you automate anything against this portal, assert on the data rather than on reaching the page.
Why there is no API on the supplier login
There is no API behind UNFI Insights. The supplier login grants a Looker embed with permission to read the dashboards that were built for you and nothing else, so there is no endpoint to point a script at and no way to enumerate the underlying model.
Two real alternatives exist, and both are separate commercial conversations rather than a setting you can switch on.
Crisp destination feeds deliver the same data to a warehouse or SFTP on a schedule. This is a paid Crisp upgrade and is not included with the Insights access UNFI provides.
UNFI Harmony Core is UNFI's own read-only integration API. It is a different onboarding entirely, through your UNFI supplier manager, with its own credentials. If a durable feed matters to you, this is the one to ask about, and the ask goes to UNFI rather than to Crisp.
Until one of those is in place, getting data out means a person opening a dashboard and downloading it, which is why the export mechanics below are worth knowing precisely.
What Insights gives you that nothing else does
A UNFI supplier can end up looking at three different sources, and only one of them is exclusive.
UNFI Insights is the analytics product this guide covers. Three of its reports carry information you genuinely cannot get anywhere else: Distribution Expansion, Category Performance and Spoilage Risk. Distribution Expansion is the only place UNFI tells you which of its stores are not buying you. Category Performance is the only place it shows your volume next to the whole category's. Spoilage Risk is the only place it puts an expiry date on stock you have already been paid for but can still be charged back on.
The myUNFI supplier portal carries the transactional records: purchase orders, invoices, payment status. Insights restates most of this in its own reports, so if you are only after an invoice you do not need Insights at all.
SVHarbor is UNFI's older supplier extranet, still in use for some document and order workflows depending on the account. Where its data overlaps Insights, Insights is the friendlier surface.
The practical version: if a number is available in more than one of these, pull it from wherever it is easiest, but the three exclusive reports are the reason to open Insights at all.
Natural and Conventional are separate logins
This guide documents the Natural channel. That is a real limit, not an omission, and it is worth stating plainly because nothing in the interface makes it obvious.
UNFI runs its supplier analytics separately for its Natural and Conventional channels. They are different logins over different datasets, and a supplier selling into both gets two sets of credentials and sees two unconnected views of its own business. Everything in this guide (every report, every column, every period rule) was recorded from a Natural-channel account.
If you sell into both channels, two things to hold onto. No report here totals across channels, so a company-wide number means pulling twice and adding them up yourself. And you should not assume the Conventional reports carry the same columns as the ones documented here. Treat that as unverified rather than as covered.
There is a smaller version of the same split inside the Natural channel. The
distribution-centre region filter offers EAST and WEST, and a supplier whose
product moves through both will find that regional pulls are the practical unit
of work, because they are also how you get under the row cap.
Reading the filter panel
Every dashboard carries the same filter bar, and it is worth reading once because the filters change what a report means, not just how much of it you see.
Four filters change the numbers themselves:
- Period Start Date takes a range, and the range is what the "selected
period" in every measure name refers to.
Cases Shipped Selected Periodis cases within whatever this is set to. - Date Granularity switches between weekly and monthly buckets. Changing it changes the meaning of every period column on the page.
- Only Show Full Periods? defaults to Yes and silently drops the week in progress. This is the source of the "why is this week empty" question.
- Group by changes the grain of the summary tiles. It does not change the detail grid, which is why the two can appear to disagree.
The rest narrow the population without changing definitions: Product, Brand, Chain, Distribution Center, Distribution Center Region, Channel, Supplier Number, Store, Store State and Store City. These are the ones to reach for when slicing around the row cap.
The thing to internalise: none of these choices are recorded in an export. A file pulled with a chain filter applied looks exactly like a complete file three months later. That is why the export section below insists on putting the filters in the filename.
Sell-through reports
Four reports describe what moved and where. All four are the closest this portal gets to demand, and none of them is demand.
Store Weekly Sell-Through
Cases, dollars and weight shipped to each store for each of your items, one row per store and UPC per week. The richest grain in the portal and the report most people mean when they say "the UNFI data".
This is the sell-in ceiling made concrete. Every row is a real store with a real address, which is what makes it feel like retail data, and every measure counts what UNFI delivered into that store rather than what the store rang up.
The three measures are Cases Shipped Selected Period, Sales Dollars Selected Period and Weight Selected Period. Dollars are wholesale, what UNFI billed
the retailer, so they are not retail revenue and will not reconcile to anything
the retailer reports.
A worked example. Sunrise Cookies ships two items into a 40-store natural chain. In one week the report returns 63 rows, because not every store took every item. Sea salt shows 88 cases across 34 stores; ginger shows 41 cases across 29 stores. The average store took 2.6 cases of sea salt that week. If the next week shows 12 cases across 9 stores, that is not a 86% demand collapse, it is an ordering cycle: those stores bought two weeks of cover and did not need more. Weekly shipment data is spiky in a way weekly sales data is not, and reading one week as a trend is the most common mistake made with this report.
The trap unique to this report is the period filter. The dashboard defaults to
Only Show Full Periods? = Yes, which excludes the in-progress week entirely. A
pull on Wednesday returns nothing for the current week, and that empty result is
correct rather than broken. Weeks run Sunday to Saturday.
One column worth knowing about: the store identity used in the grain is a
synthetic key UNFI calls Uniqueness Key, not the store number, because store
numbers are not unique across chains. It is available through the underlying
query but is not one of the columns a manual download gives you.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Store | Name of the retail store. | store_name | VARCHAR |
Chain | Retail chain the store belongs to. Also the dashboard filter UNFI sub-slices a capped grid by. | chain | VARCHAR |
Source Number | Store number as it appears in the source system. Note the portal heads this column Source Number, not Store Number. | store_numbergrain key | VARCHAR |
Address | Street address of the retail store. | store_address | VARCHAR |
City | City of the retail store. | store_city | VARCHAR |
State | State of the retail store. | store_state | VARCHAR |
Zip | ZIP code of the retail store. | store_zip | VARCHAR |
Uniqueness Key | UNFI synthetic key identifying the store uniquely. Part of the grain, because store numbers are not unique on their own. | store_keygrain key | VARCHAR |
Channel | UNFI channel the store buys through, e.g. the Natural channel. This extract only ever covers the channel the login is provisioned for. | channel | VARCHAR |
Distribution Center | UNFI distribution center that shipped the item. | dc | VARCHAR |
| no header | Product name as UNFI holds it in its item master. | product | VARCHAR |
UPC | Consumer UPC for the item. Distinct from the UNFI product code, which is the internal item number. | upc | VARCHAR |
Product Code | UNFI product code. This is UNFI internal item number, NOT the UPC, and the two do not interchange. | product_codegrain key | VARCHAR |
UOM | Unit of measure the shipped quantity is expressed in. | uom | VARCHAR |
Cases Shipped Selected Period | Cases SHIPPED to the store in the selected period. UNFI reports what it moved, not what the register sold, so this is not POS scan data. | cases | DOUBLE |
Sales Dollars Selected Period | Wholesale sales dollars SHIPPED in the selected period. UNFI bills the retailer at wholesale, so this is not retail revenue. | dollars | DOUBLE |
Weight Selected Period | Shipped weight for the selected period. | weight | DOUBLE |
Units Per Store Per Week Selected Period | Units sold per store per week in the selected period — a RATE, not a total. Merged onto this stream from the Velocity dashboard, so it is not derivable from the other columns in the row. | units_per_store_per_week | DOUBLE |
Dollars Per Store Per Week Selected Period | Sales dollars per store per week in the selected period — a RATE, not a total. Merged onto this stream from the Velocity dashboard, so it is not derivable from the other columns in the row. | dollars_per_store_per_week | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Category Performance
Your volume next to the entire category's volume, at the same store and week, with the year-over-year change on both. One of the three reports exclusive to Insights.
Every other report tells you about you. This one tells you about the shelf. The
pairing is the point: My Volume for Selected Period against Category Volume for Selected Period, on the same row, for the same store and week. Your share
of that store's category is a division you can do yourself, and the direction it
moves is the number worth watching.
A worked example. In one chain for one week, Sunrise Cookies shows My Volume
of $1,240 against Category Volume of $31,000, a 4.0% share. Last year the
same week was $1,050 against $24,600, a 4.3% share. Volume grew 18% and share
fell, because the category grew 26%. A report that showed only your own line
would have looked like a good week.
The trap here is coverage rather than arithmetic. This report exceeds the portal's row cap in a single week, so a naive pull silently returns the top slice rather than everything. See the 500-row cap for what that looks like and how to work around it.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Chain | Retail chain the store belongs to. Also the dashboard filter UNFI sub-slices a capped grid by. | chain | VARCHAR |
Store | Name of the retail store. | store_name | VARCHAR |
Source Number | Store number as it appears in the source system. Note the portal heads this column Source Number, not Store Number. | store_numbergrain key | VARCHAR |
Store Address | Street address of the retail store. | store_address | VARCHAR |
Store City | City of the retail store. | store_city | VARCHAR |
Store State | State of the retail store. | store_state | VARCHAR |
Store Zip | ZIP code of the retail store. | store_zip | VARCHAR |
Channel | UNFI channel the store buys through, e.g. the Natural channel. This extract only ever covers the channel the login is provisioned for. | channel | VARCHAR |
Distribution Center | UNFI distribution center. | distribution_center | VARCHAR |
Product | Product name as UNFI holds it in its item master. | product | VARCHAR |
Product Category | UNFI category the product sits in. | product_category | VARCHAR |
Product Subcategory | UNFI subcategory the product sits in. | product_subcategory | VARCHAR |
Product Code | UNFI product code. This is UNFI internal item number, NOT the UPC, and the two do not interchange. | product_codegrain key | VARCHAR |
My Volume for Selected Period | Your own volume in the selected period, at this row grain. Compare against the category value on the same row. | my_value_selected_period | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Distribution Expansion
Every store UNFI serves that could carry you, flagged for whether it actually bought in the period. The whitespace list, and the second report exclusive to Insights.
Read it by its flag column, which UNFI heads Has Sales for Selected Filters? (Yes / No). The rows marked No are the product: stores UNFI already delivers
to, in your category, that are not buying your items. Each one is a distribution
call with the logistics already solved.
A worked example. Filtered to one region, the report returns 260 stores, of which 178 have sales and 82 do not. Those 82 are the target list. The category-value columns on the same rows size the opportunity: if the average buying store does $46 of your items a week, the 82 non-buyers are roughly $3,800 a week of addressable distribution, before any assumption about conversion.
Two cautions. This is a snapshot with no history, so "stores that stopped" is not this report's job. That is Retention and Attrition. And like Category Performance it exceeds the row cap, so an unsliced pull under-reports the very stores you are looking for.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Chain | Retail chain the store belongs to. Also the dashboard filter UNFI sub-slices a capped grid by. | chain | VARCHAR |
Store | Name of the retail store. | store_namegrain key | VARCHAR |
Source Number | Store number as it appears in the source system. Note the portal heads this column Source Number, not Store Number. | store_numbergrain key | VARCHAR |
Store Address | Street address of the retail store. | store_address | VARCHAR |
Store City | City of the retail store. | store_city | VARCHAR |
Store State | State of the retail store. | store_state | VARCHAR |
Store Zip | ZIP code of the retail store. | store_zip | VARCHAR |
Channel | UNFI channel the store buys through, e.g. the Natural channel. This extract only ever covers the channel the login is provisioned for. | channel | VARCHAR |
Distribution Center | UNFI distribution center. | distribution_center | VARCHAR |
Category Volume for Selected Period | Total category volume across all suppliers in the selected period, at this row grain. The denominator your own volume is compared against. | category_value_selected_period | DOUBLE |
Category Volume Change YOY | Absolute change in total category volume versus the same period last year. | category_value_yoy_var | DOUBLE |
Category Volume % Change YOY | Percent change in total category volume versus the same period last year. | category_value_yoy_percent_var | DOUBLE |
My Volume for Selected Period | Your own volume in the selected period, at this row grain. Compare against the category value on the same row. | my_value_selected_period | DOUBLE |
My Volume Change YOY | Absolute change in your own volume versus the same period last year. | my_yoy_var | DOUBLE |
My Volume % Change YOY | Percent change in your own volume versus the same period last year. | my_yoy_percent_var | DOUBLE |
Has Sales for Selected Filters? (Yes / No) | Whether the store had any sales of your items under the selected filters. This is what makes the report an expansion target list: a store present here with No is carried by UNFI but not buying you. | store_brand_presence | VARCHAR |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Retention and Attrition
Per store and UPC: when it first bought, when it last bought, how many weeks it has been silent, and the average gap between its orders. The lapse report.
The column that does the work is Weeks Since Last Purchase, and it only means
something next to Avg Weeks Between. A store that orders every eight weeks and
last ordered six weeks ago is on schedule. A store that orders every two weeks
and last ordered six weeks ago has stopped, and nobody has noticed.
A worked example. Sunrise Cookies has 210 store-item combinations. Twelve show
Weeks Since Last Purchase above 8. Of those, seven have an Avg Weeks Between
of 6 or more and are simply slow accounts. The remaining five average 2.4 weeks
between orders and have been silent for nine. Those five are the list, and the
ratio is what identifies them, not the raw silence.
The trap is that lapse is invisible in the sell-through report. A store that stops buying does not appear as a zero there; it stops producing rows altogether. Absence of a row is not a value you can filter on, which is exactly why this report exists.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Store Fingerprint | UNFI synthetic key identifying the store uniquely. Part of the grain, because store numbers are not unique on their own. | store_keygrain key | VARCHAR |
Chain Name | Retail chain the store belongs to. Also the dashboard filter UNFI sub-slices a capped grid by. | chain | VARCHAR |
Store Display Name | Name of the retail store. | store_name | VARCHAR |
Store Address | Street address of the retail store. | store_address | VARCHAR |
City | Store city. | city | VARCHAR |
Zip | Store ZIP code. | zip | VARCHAR |
Upc | Consumer UPC for the item. Distinct from the UNFI product code, which is the internal item number. | upcgrain key | VARCHAR |
State | Store state. | state | VARCHAR |
Channel | UNFI channel the store buys through, e.g. the Natural channel. This extract only ever covers the channel the login is provisioned for. | channel | VARCHAR |
Description | Product description as UNFI holds it in its item master. | description | VARCHAR |
First Sales Period Date | First period in which this store bought this item. | first_sales_period_date | DATE |
Last Sales Period Date | Most recent period in which this store bought this item. Read with weeks since last purchase to judge attrition. | last_sales_period_date | DATE |
Weeks Since Last Purchase | Weeks since this store last bought this item. The attrition signal in this report. | weeks_since_last_purchase | DOUBLE |
Current Status Filter | not documented | current_status_filter | VARCHAR |
Avg Weeks Between | Average number of weeks between this store purchasing this item, across its purchase history. | avg_weeks_between | DOUBLE |
Sum Total Quantity Shipped | Total cases shipped to the store. | sum_total_quantity_shipped | DOUBLE |
Sum Total Purchases | Count of purchases the store made. | sum_total_purchases | DOUBLE |
Sum New and Existing Sales | Sales dollars across both newly acquired and retained stores. | sum_new_and_existing_sales | DOUBLE |
Sum Potential Lost Sales | Estimated sales lost to stores that stopped buying. | sum_potential_lost_sales | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Inventory and supply
Five reports about UNFI's warehouses. All are snapshots, and none can be recovered for a day you did not pull.
DC Inventory
On-hand, on-order and forecast quantities per distribution centre and item, with weeks of supply. Daily snapshot, one row per DC, product and availability state.
This is the report that answers "can UNFI actually fill an order next week".
On Hand Quantity is the current position; On Order Quantity is what is
already inbound and not yet received; Weeks of Supply divides on-hand by
average weekly sales.
Weeks of supply has a failure mode worth naming. It goes to zero on a stocked-out item, not to a large number. Sorting ascending to find your supply risks puts genuinely out-of-stock items at the top mixed with items that merely turn fast, and the two need opposite responses.
A worked example. Sunrise Cookies sea salt at an eastern DC shows 240 cases on hand and average weekly sales of 60, so four weeks of supply. The same item at a western DC shows 18 on hand against average weekly sales of 55, under a third of a week, with 300 on order. The first is healthy, the second is about to miss orders unless that inbound lands, and only the on-order column tells you which.
Note the averages are taken over the dashboard's lookback window rather than the
snapshot day, so Avg On Hand Quantity and On Hand Quantity answer different
questions and will not agree.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Distribution Center | UNFI distribution center. | distribution_center | VARCHAR |
Availability | Availability bucket UNFI reports the on-hand quantity under (part of the snapshot grain, so one product appears once per bucket). | availabilitygrain key | VARCHAR |
Number | UNFI number for the distribution center. Part of the DC inventory grain. | distribution_center_numbergrain key | VARCHAR |
Address | Street address of the distribution center. | distribution_center_address | VARCHAR |
City | City of the distribution center. | distribution_center_city | VARCHAR |
State | State of the distribution center. | distribution_center_state | VARCHAR |
Zip | ZIP code of the distribution center. | distribution_center_zip | VARCHAR |
| no header | Product name as UNFI holds it in its item master. | productgrain key | VARCHAR |
On Hand Quantity | Cases on hand at the DC as of the snapshot date. | latest_on_hand_quantity | DOUBLE |
On Hand Dollars | Inventory value on hand at the DC as of the snapshot date. | latest_on_hand_dollars | DOUBLE |
Avg On Hand Quantity | Average on-hand case count across the dashboard lookback window, not the count on the snapshot date. | average_on_hand_quantity_within_lookback | DOUBLE |
Avg On Hand Dollars | Average on-hand inventory value across the dashboard lookback window, not the value on the snapshot date. | average_on_hand_dollars_within_lookback | DOUBLE |
On Order Quantity | Cases already on order into the DC as of the snapshot date, not yet received. | latest_on_order_quantity | DOUBLE |
Forecast Quantity | Forecast inventory quantity as of the snapshot. | latest_forecast_quantity | DOUBLE |
Forecast Dollars | Forecast inventory value as of the snapshot. | latest_forecast_dollars | DOUBLE |
Avg Wholesale Price | Average wholesale price per case UNFI paid over the lookback window. | average_wholesale_price_per_case | DOUBLE |
Avg Sales Amount per Case | Average sales dollars per case over the lookback window. | average_sales_amount_per_case | DOUBLE |
Avg Weekly Sales | Average cases sold per week over the inventory lookback window. The denominator of weeks of supply. | average_sales_quantity_per_week_within_inventory_lookback | DOUBLE |
Weeks of Supply | Weeks of supply: on-hand quantity divided by average weekly sales. Falls to zero on a stocked-out item, not to a high number. | weeks_of_supply | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Spoilage Risk
On-hand stock with an expiry date attached and the wholesale value at risk, one row per item, distribution centre and expiry lot. The third report exclusive to Insights.
This is the one that costs money quietly. UNFI has already bought this inventory, so a brand can reasonably assume it is no longer their problem, and then a spoilage chargeback arrives against stock that expired in a warehouse.
Weeks to Expiration is the column to sort on, and it goes negative: a negative
value is stock that has already expired and is still sitting there. Net Wholesale Dollars at Risk is what you are exposed to on that lot.
A worked example. Sunrise Cookies shows three lots at one DC: 40 cases at 11 weeks, 25 cases at 4 weeks, and 8 cases at −2 weeks. The 8 expired cases are a chargeback already in flight. The 25 at four weeks are the actionable ones, because four weeks is enough time to place them with a promotion and not enough to sell through at the current rate.
The trap is the snapshot rule in its most expensive form. There is no way to ask what was expiring last month, so a chargeback that arrives in March cannot be traced back through this report unless somebody captured February.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Report Date | Date UNFI generated the report. | report_date | DATE |
Product | Product name as UNFI holds it in its item master. | product | VARCHAR |
UPC | Consumer UPC for the item. Distinct from the UNFI product code, which is the internal item number. | upc | VARCHAR |
Product Code | UNFI product code. This is UNFI internal item number, NOT the UPC, and the two do not interchange. | product_codegrain key | VARCHAR |
Distribution Center | UNFI distribution center. | distribution_centergrain key | VARCHAR |
Expiration Date | Expiration date of the on-hand lot. Part of the spoilage-risk grain, so one product appears once per expiring lot. | expiration_dategrain key | DATE |
Weeks to Expiration | Weeks until the on-hand lot expires. Negative or zero means already expired stock still on hand. | weeks_to_expiration | DOUBLE |
Quantity on Hand | Cases on hand for the expiring lot. | sum_quantity_on_hand | DOUBLE |
Net Wholesale Dollars at Risk | Net wholesale value of on-hand stock at risk of expiring. | latest_sum_net_wholesale_dollars_at_risk | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Potential Lost Sales
Where UNFI's on-hand inventory falls short of its own forecast demand, sized in cases and wholesale dollars. Daily snapshot, one row per item and distribution centre.
The deficit is UNFI's forecast minus UNFI's stock, which makes this the report that tells you about sales you were never able to make. It is the inventory problem stated in the units a commercial conversation uses.
A worked example. One item at one DC shows a deficit of 45 cases and $1,100 of wholesale dollars at risk. That is not lost revenue you can invoice for. It is the size of the gap between what UNFI expected to move and what it had, which is the argument for a larger purchase order rather than a claim.
The narrowest report in the portal, four columns, and the one most often misread as a receivable. It is a forecasting signal, not money owed.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Product | Product description as UNFI holds it in its item master. | descriptiongrain key | VARCHAR |
Distribution Center | UNFI distribution center that shipped the item. | dcgrain key | VARCHAR |
Total Quantity on Hand Deficit to Forecast | Cases by which on-hand inventory falls short of forecast demand. The size of the gap, not the sales lost to it. | sum_quantity_on_hand_deficit | DOUBLE |
Total Wholesale Dollars at Risk | Wholesale value of the sales at risk from the on-hand deficit. | sum_wholesale_dollars_at_risk | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Fill Rate
Cases ordered against cases received for a given service date, split by promotional and regular lines. Snapshot, one row per item, DC, service date and promo type.
This measures you, not UNFI. Quantity Ordered is what UNFI asked you for
and Quantity Received is what arrived, so a low fill rate is your delivery
performance, and it is the number UNFI's buyers see.
The split by promo type is the part that matters. A worked example: an item shows 92% fill overall for a week, which looks fine. Split by promo type it is 99% on regular lines and 61% on the promotional line. The promotion under-shipped and the blended number hid it, which means the promotion under-performed for a supply reason that will get read as a demand reason.
Because promo type is part of the grain, do not sum the fill-rate column across rows: averaging a rate over lines of different sizes gives you a number that is not any account's fill rate. Recompute from received over ordered.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Product | Product description as UNFI holds it in its item master. | descriptiongrain key | VARCHAR |
Distribution Center | UNFI distribution center that shipped the item. | dcgrain key | VARCHAR |
Service Date | Delivery service date the ordered and received quantities are measured against. Part of the fill-rate grain. | service_dategrain key | DATE |
Promo Type | Promotion type the ordered quantity was placed under. Part of the fill-rate grain, so promotional and regular lines are separate rows. | promo_typegrain key | VARCHAR |
Quantity Received | Cases actually received for the service date. The numerator of fill rate. | sum_quantity_received | DOUBLE |
Quantity Ordered | Cases the retailer ordered for the service date. | sum_quantity_ordered | DOUBLE |
Fill Rate | Fill rate: quantity received divided by quantity ordered for the service date. | sum_fill_rate | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Purchase Orders
Open and historical purchase orders with original and revised quantities, key dates, and whether they arrived on time and in full. Snapshot, one row per PO and item.
The pair worth reading together is Original Qty Ordered and Revised Qty Ordered. The difference is what UNFI cut after raising the order, and it is
invisible in every other report: sell-through shows what shipped, never what
was asked for and withdrawn.
A worked example. A PO is raised for 200 cases and revised to 150 before receipt; 150 arrive on the requested date. Fill rate reads 100%, on-time reads yes, and 50 cases of intended distribution quietly disappeared. Reading the two quantity columns together is the only way to see it.
On-Time Status and Delivered in Full are the two service flags, and they are
independent: an order can be complete and late, or on time and short.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
PO Status | Current status of the purchase order. | purchase_order_status | VARCHAR |
PO Number | UNFI purchase order number. Part of the purchase-order grain. | purchase_order_numbergrain key | VARCHAR |
Distribution Center | UNFI distribution center. | distribution_center | VARCHAR |
Product Code | UNFI product code. This is UNFI internal item number, NOT the UPC, and the two do not interchange. | product_codegrain key | VARCHAR |
Product | Product name as UNFI holds it in its item master. | product | VARCHAR |
UPC | Consumer UPC for the item. Distinct from the UNFI product code, which is the internal item number. | upc | VARCHAR |
Original Qty Ordered | Quantity on the purchase order as first raised, before any revision. | original_quantity_ordered | DOUBLE |
Revised Qty Ordered | Quantity on the purchase order after revision. Compare against the original quantity to see what UNFI cut. | revised_quantity_ordered | DOUBLE |
PO Create Date | Date the purchase order was raised. | purchase_order_create_date | DATE |
Order Requested Date | Date delivery was requested for. | order_requested_date | DATE |
Qty Received | Quantity actually received against the purchase order. | quantity_received | DOUBLE |
Revised ETA Date | Current expected arrival date for the purchase order, after any revision. | revised_eta_date | DATE |
Received Date | Date the purchase order was received. | received_date | DATE |
PO Amount | Total value of the purchase order. | purchase_order_amount | DOUBLE |
Line Purchase Price | Purchase price on the order line. | line_purchase_price | DOUBLE |
Weight | Weight on the purchase order line. | weight | DOUBLE |
Transaction Master Cases | Master case count on the transaction. | transaction_master_cases | VARCHAR |
Ship From City | City the shipment originates from. | ship_from_city | VARCHAR |
Ship From State | State the shipment originates from. | ship_from_state | VARCHAR |
On-Time Status | Whether the purchase order arrived on time. | on_time_status | VARCHAR |
Delivered in Full | Whether the purchase order was delivered complete. | delivered_in_full | VARCHAR |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Money
Three reports about what UNFI charges you and what it owes you. These are also the three most likely to disagree with your own ledger.
Chargebacks
Monthly chargeback records: the MCB code, the rate, the invoice, and the wholesale dollars the rate was applied to. One row per invoice, item, store and code.
Chargebacks are deductions taken against agreed programmes (promotional
allowances, damage, spoilage), and Mcb Code is the field that says which
programme. Total Chargeback Dollars is what was taken; Wholesale Dollars is
the base it was calculated from; Chargeback Percent is the rate between them.
Having all three on one row is what makes a chargeback checkable.
A worked example. A line shows $8,400 of wholesale dollars, a 15% rate and $1,260 charged back. If the agreed allowance for that programme was 10%, the overcharge is $420 and you can point at the exact invoice. Without the base and the rate on the same row you would only see the $1,260 and have nothing to dispute with.
This report behaves unlike every other one in the portal. It has a month
filter that does nothing: one pull returns a rolling window of roughly twelve
months, and every row carries its own month in the Date column. Treating it
like a snapshot and stamping all its rows with the pull date duplicates the
entire history on every run. Read the month off the row.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Date | Month this chargeback record belongs to, as a first-of-month date. Chargebacks is a rolling ledger whose rows each carry their own month, not a snapshot. | date | DATE |
Product | Product name as UNFI holds it in its item master. | product | VARCHAR |
UPC | Consumer UPC for the item. Distinct from the UNFI product code, which is the internal item number. | upc | VARCHAR |
Product Code | UNFI product code. This is UNFI internal item number, NOT the UPC, and the two do not interchange. | product_codegrain key | VARCHAR |
Brand | Brand name as UNFI holds it in its item master. | brand | VARCHAR |
Pack Size | Pack size as UNFI holds it in its item master. | pack_size | VARCHAR |
DC Region | Region grouping for the distribution center. | dc_region | VARCHAR |
DC | UNFI distribution center that shipped the item. | dc | VARCHAR |
Chain | Retail chain the store belongs to. Also the dashboard filter UNFI sub-slices a capped grid by. | chain | VARCHAR |
Source Number | Store number as it appears in the source system. Note the portal heads this column Source Number, not Store Number. | store_number | VARCHAR |
Store | Name of the retail store. | store_namegrain key | VARCHAR |
Store Address | Street address of the retail store. | store_address | VARCHAR |
Store City | City of the retail store. | store_city | VARCHAR |
Store State | State of the retail store. | store_state | VARCHAR |
Store Zip | ZIP code of the retail store. | store_zip | VARCHAR |
Mcb Code | Manufacturer chargeback (MCB) code identifying the deal or reason the chargeback was raised. Part of the chargebacks grain. | mcb_codegrain key | VARCHAR |
Mcb Category | Category of the manufacturer chargeback (MCB) this record was raised under. | mcb_category | VARCHAR |
Invoice Number | UNFI invoice number. | invoice_numbergrain key | VARCHAR |
Total Chargeback Quantity | Total quantity the chargeback was calculated on. | sum_chargeback_quantity | DOUBLE |
Chargeback Percent | Chargeback rate applied to the wholesale dollars on this invoice line. | chargeback_percent | DOUBLE |
Wholesale Dollars | Wholesale dollars the chargeback percentage is applied to. | sum_wholesale_dollars | DOUBLE |
Total Chargeback Dollars | Total chargeback dollars deducted for this record. | sum_chargeback_dollars | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Deductions
Dollars deducted per payment and invoice, by distribution centre. Daily snapshot, one row per payment, full invoice number and DC.
Deductions and chargebacks are not the same thing and the portal reports them separately. A chargeback is a charge against a programme; a deduction is money withheld from a payment. Reconciling them is joining on the invoice, and the invoice number here carries a suffix that the chargeback report's does not.
The narrow shape is deliberate: this report exists to tell you what was withheld and against what, and the reason lives in the chargeback record.
A worked example. A payment shows three deduction lines totalling $2,180 against one DC. Two match chargeback records for spoilage and a promotional allowance. The third, $190, has no matching chargeback line, which is precisely the row worth querying. An unexplained deduction is the recoverable kind.
Reconciling the two reports is a specific piece of work, so it is worth spelling out. The join key is the invoice, and the two reports do not spell it the same way: Open Payables carries the invoice number and its suffix as separate columns that together make the identity, while Deductions carries a single full invoice number with the suffix already folded in. Match on the concatenation, not on the bare number, or one invoice's several lines will fan out against each other.
The timing also differs, and this is what makes reconciliation feel broken the first time. Chargebacks is a rolling monthly ledger, so a charge appears under the month it belongs to. Deductions is a daily snapshot of what has been withheld as of today. A chargeback raised in March can be deducted in April, so the two will not agree within a single month and are not supposed to. Compare across a quarter.
What you are looking for is deductions with no chargeback behind them. A charge you agreed to is not a dispute, however large; a deduction with no programme attached is either a coding error or a claim nobody documented, and both are worth raising while the payment is recent.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Distribution Center Region | Region grouping for the distribution center. | distribution_center_region | VARCHAR |
Distribution Center State | State of the distribution center. | distribution_center_state | VARCHAR |
Distribution Center City | City of the distribution center. | distribution_center_city | VARCHAR |
Distribution Center Key | UNFI internal key for the distribution center. Part of the deductions grain. | distribution_center_keygrain key | VARCHAR |
Distribution Center | UNFI distribution center. | distribution_center | VARCHAR |
Payment Number | UNFI payment number the deduction was taken on. Part of the deductions grain. | payment_numbergrain key | VARCHAR |
Invoice Number (full) | Full invoice number including its suffix. Part of the deductions grain. | invoice_number_fullgrain key | VARCHAR |
Total Deduction Dollars | Total dollars deducted on this payment. | sum_deduction_dollars | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Open Payables
Invoices UNFI has not yet paid: gross amount, term discount, net payable, and the dates that decide which of those applies. Daily snapshot.
Invoice Amount is gross, Term Discount Amount is what UNFI takes for paying
early, Net Payables is what actually arrives. The two dates that matter are
Discount Date and Due Date, and they are different deadlines.
A worked example. An invoice of $4,000 carries an $80 term discount, so net payable is $3,920 if UNFI pays by the discount date and $4,000 after it. Across sixty open invoices the discount line is around $4,800, worth reconciling rather than assuming.
The grain has a subtlety: identity is the invoice number and its suffix together, so one invoice number can legitimately appear on several rows. A count of distinct invoice numbers will not match a count of rows, and neither is wrong.
| As it appears in the export | What it means | Scout column | Type |
|---|---|---|---|
Region | Region grouping for the distribution center. | distribution_center_region | VARCHAR |
Distribution Center | UNFI distribution center. | distribution_centergrain key | VARCHAR |
Remit To Code | Remit-to code the payment is directed to. | remit_to_code | VARCHAR |
Invoice Number | UNFI invoice number. | invoice_numbergrain key | VARCHAR |
Suffix | Invoice suffix. Part of the open-payables grain together with the invoice number, so one invoice number can carry several rows. | suffixgrain key | VARCHAR |
PO Number | UNFI purchase order number. Part of the purchase-order grain. | purchase_order_number | VARCHAR |
Invoice Status | Current status of the invoice. | invoice_status | VARCHAR |
Invoice Date | Date the invoice was raised. | invoice_date | DATE |
Discount Date | Date by which payment earns the term discount. | discount_date | DATE |
Due Date | Date the invoice is due. | due_date | DATE |
Invoice Amount | Gross invoice amount before discounts. | transaction_invoice_amount | DOUBLE |
Term Discount Amount | Term discount available on the invoice. | transaction_discount_amount | DOUBLE |
Net Payables | Net amount payable on the invoice after discounts. | net_payable_amount | DOUBLE |
period_start_date | not documented | period_start_date | DATE |
period_end_date | not documented | period_end_dategrain key | DATE |
period_grain | not documented | period_grain | VARCHAR |
Dashboards that are not separate reports
The Insights dashboard picker lists more views than there are underlying reports, and the difference matters when you are deciding what to pull.
Velocity, Distribution, and the year-over-year views
The picker shows Sales, Velocity and Distribution, each with a year-over-year variant. That reads like six datasets. It is closer to one.
Velocity is the sell-through grid with rate measures instead of totals: units and dollars per store per week. Useful on screen, and derivable from sell-through if you have the store count, which is why Scout merges its two rate measures into the sell-through stream rather than carrying it separately.
Distribution re-presents the same shipment data counted by store presence rather than volume. Its quantity measure is the same case count as sell-through.
The year-over-year variants are the same grids with prior-year columns and change columns added. The prior-year figures are a different window of the same measure, not a different measure.
So the honest answer is that one weekly sell-through pull carries the information in all six, and the separate dashboards are presentations rather than sources. The exception is the year-over-year comparison columns themselves, which are genuinely additional and which the snapshot reports keep for exactly that reason.
Concepts that decide whether your numbers are right
Sell-in versus sell-through at UNFI
UNFI is a distributor. It buys your product, warehouses it, and sells it on to retailers. It never operates the till, so it cannot see a single consumer transaction, and no report in Insights contains one.
What the portal calls sell-through is shipment out of UNFI's warehouse into a store. That is one step closer to the consumer than your invoice to UNFI, which is why it is more useful than pure sell-in, and it is still not demand.
The gap shows up as timing. A store that takes four weeks of cover generates one large week and three empty ones in this data, while its actual sales were steady. Over a quarter the two converge; over a week they can disagree completely.
It also shows up at the two ends of a product's life, in opposite directions. When you win new distribution, shipments spike as stores build their first order, and demand has not moved at all yet: the pipeline is filling. When a retailer delists you, shipments stop immediately while consumers keep buying whatever is left on the shelf for weeks. Read as demand, the first looks like a success that then collapses, and the second looks like a cliff that never happened.
The practical test is whether the question you are asking is about placement or about consumption. How many stores carry me, how much did they take, where am I absent, what is at risk in the warehouse. The portal answers all of those well, because they are all facts about UNFI's own operation. How fast does it sell once it is on the shelf, does the price change move units, did the promotion work. Those need scan data, and no amount of care with these columns will substitute.
For how this data behaves once it reaches a syndicated panel, see reading KeHE and UNFI movement data in SPINS, which covers the same distinction from the panel side rather than restating it here.
Snapshot versus windowed, and what cannot be backfilled
A windowed report takes a period parameter, so you can ask for any past week whenever you like. A snapshot report takes no date parameter at all: it returns the current state, and the only date attached is the day you pulled it.
Nine of the twelve reports here are snapshots. Only Store Weekly Sell-Through and Category Performance are windowed, and Chargebacks is a rolling ledger that carries its own dates. Everything about inventory, expiry, lapse, whitespace, payables and deductions is current-state only.
The consequence is the single most expensive fact in this guide. A snapshot day you did not capture is a day you cannot ever get. There is no parameter that asks what inventory looked like last Tuesday, because the portal does not remember. If inventory history, spoilage exposure or attrition trends will ever matter to you, the capture has to start before you need it.
An empty snapshot is also a legitimate answer rather than a failure. Zero rows of spoilage risk means there is none today, which is a real observation worth recording as such.
The week UNFI means
Weeks run Sunday to Saturday, and the dashboard's Only Show Full Periods?
filter defaults to Yes, which excludes the week in progress.
Together those produce a result that reads as a bug. Pull on a Wednesday and the current week returns nothing at all. Nothing is broken; the week is not finished, and the default asks for finished weeks only. Turning the filter off returns a partial week that will change before it settles, which is fine for a live view and wrong for anything you store.
The Sunday-to-Saturday convention matters beyond this portal, because almost nothing else a brand uses agrees with it. Retailer POS weeks commonly end on a different day, syndicated panels have their own calendar, and a finance month is a month. Comparing a UNFI week to a retailer week without checking the boundary compares two different seven-day windows and attributes the difference to performance.
A worked example. A promotion runs Monday to Sunday. In UNFI's calendar that straddles two weeks, so the shipment supporting it appears partly in the week before the promotion started. Read week by week, the promotion looks like it began early and then underperformed. Aligned to the promotion window, the same numbers are unremarkable.
The practical rule: convert to dates as early as possible and stop thinking in week numbers. Every report carries a period end date once ingested, and comparing on dates rather than on week labels removes the whole class of error.
There is one more consequence for anything automated. Because the in-progress week is excluded by default, a job that runs mid-week and asks for "this week" gets an empty result that is indistinguishable from a failure unless it checks which period it actually received.
UNFI product code versus UPC
Every item carries two identifiers and they are not interchangeable. UPC is the
consumer barcode. Product Code is UNFI's internal item number, and it is what
purchase orders, chargebacks and inventory records key on.
Join on the wrong one and you get silence rather than an error. The product code is also the safer grain within UNFI, because a single UPC can map to more than one UNFI item across pack configurations.
Both are text, not numbers. Storing either as numeric drops leading zeros and
breaks the join in a way that is hard to see afterwards. A UPC that arrives as
0200000123451 and gets stored as an integer becomes 200000123451, which
matches nothing, and the failure is silent because a join that finds no rows
looks the same as a period with no sales.
A worked example of why the direction matters. Sunrise Cookies sells a 6-count and a 12-count of the same recipe. Both carry the same case UPC in the retailer's system but are two distinct UNFI product codes, because UNFI orders, warehouses and charges back at pack level. Summing shipments by UPC merges two items that have different costs, different velocities and different spoilage profiles. Summing by product code keeps them apart. Within UNFI, product code is almost always the grain you want; UPC is the key you use to leave UNFI and join to anything else.
One further caution. Insights carries a rendered Product/UPC column that
concatenates a description and an identifier for display. It is a label, not a
key, and it is not stable enough to join on.
What UNFI Insights cannot tell you
Worth stating as a list, because most of the wrong conclusions drawn from this portal are answers to questions it was never able to answer.
It cannot tell you what sold. No consumer transaction reaches UNFI. Every measure is a shipment, and the register is invisible. If you need units scanned, that comes from the retailer or from a syndicated panel.
It cannot tell you why a store stopped. Retention and Attrition tells you a store went quiet and how unusual that is for it. Whether it delisted you, switched to a competitor, or is buying you through a different wholesaler entirely is not in here.
It cannot tell you about the other channel. A Natural-channel login sees Natural. Conventional is a separate login over separate data, and no total on this dashboard spans both.
It cannot tell you what your product retails for. Dollars are wholesale throughout. Retail price, margin and promotional price live with the retailer.
It cannot tell you yesterday's inventory. Nine of twelve reports are snapshots with no history, and the portal keeps none.
It cannot tell you why a purchase order was cut. You can see that
Original Qty Ordered exceeded Revised Qty Ordered. The reason is a
conversation with your UNFI buyer.
The pattern is that Insights is precise about what UNFI did and silent about why, and about anything past the point where UNFI hands the case to the store. Read it as the best available account of distribution, and get demand from somewhere else.
The 500-row cap
Each dashboard tile returns at most 500 rows. That limit is not adjustable on a supplier login, and the portal does not announce when it applies.
For most reports it never bites. For Category Performance and Distribution Expansion it bites in a single period, because both are store-grain across every store UNFI serves.
The symptom is a number that is stable when it should not be. A store count that sits at exactly 500, or a total that stops growing as you widen the date range, is truncation rather than a plateau. The workaround is to slice: pull one chain at a time, or one state at a time, and add the slices up. Each slice comes in under the cap and the union is complete.
Where the DC sits in the hierarchy
Rows carry both a retail hierarchy and a UNFI one, and mixing them is a common double-count. Chain and store describe where the product went; distribution centre and region describe where it came from.
One store is served by one DC, but one chain spans several. So summing by chain and by DC gives two correct answers to two different questions, and joining them without care multiplies rows.
The DC also appears under more than one column name across reports:
Distribution Center in some, DC in others, with a separate key column in the
deductions report. They refer to the same facilities.
A worked example of the double-count. Sunrise Cookies ships into 120 stores of one chain, served by three DCs. Summing shipments by chain gives one number. Summing by DC gives three numbers that add to the same total. Joining the sell-through report to DC inventory on the DC alone, without also constraining the item, multiplies every store row by every inventory row for that facility, and the total balloons by a factor nobody notices because it is still a plausible-looking number.
The rule that avoids it: the retail hierarchy and the UNFI hierarchy meet at the row, not at the aggregate. Join on item and store, or on item and DC, but never aggregate one side before joining.
Region is the coarsest level and the most useful one operationally, because it
is a filter that reliably gets a capped report under the row limit. EAST and
WEST split the country roughly in half, and two pulls will usually cover a
report that one pull truncates.
Reading a measure name
UNFI's measure names are unusually literal, and learning to read them saves looking most columns up.
Three suffixes carry all the period meaning. Selected Period is the window the
filter bar is currently set to. Prior Year is the same window shifted back a
year. Change in and Percent Change in are the difference between those two,
precomputed.
So Cases Shipped Selected Period and Cases Shipped Prior Year are the same
measure over two windows, and Percent Change in Cases Shipped is derived from
them. That also means the three do not sum to anything meaningful and should
never be added together.
The prefix says what is counted: Cases Shipped is units, Sales Dollars is
wholesale value, Weight is shipped weight. Where a name begins with Avg or
Total, the aggregation is already applied, and re-aggregating an average
across rows of different sizes gives a number that is not any account's average.
One naming inconsistency worth knowing: the store number column is headed
Source Number, with no word in it suggesting a store at all. It is the store
identifier as the source system spells it, and it is the column most people
fail to find on their first export.
Getting the data out
Exporting a report
Export happens per tile rather than per dashboard. Hover the tile you want, open its actions menu, and choose Download data; the file carries that tile's columns, not the whole dashboard's.
The export honours the filters currently applied, and that is the part worth being careful about. Nothing in the file records which filters were set, so an export filtered to one region is indistinguishable afterwards from a complete one.
The header row is the portal's own column names, exactly as the reference tables
throughout this guide show them. Two of them are worth knowing in advance: the
store number column is headed Source Number rather than anything containing
the word "store", and one product column comes through with no header at all,
which is a quirk of the underlying field rather than a corrupted file.
What the export does not carry
The filters are not in the file. Neither is the period for a snapshot report, because a snapshot has no date column, so the only record that a file is Tuesday's is the name you give it.
Three specific gaps, in the order they cause trouble:
No filters. A file pulled with a chain, region or brand filter applied is byte-for-byte the same shape as a complete one. Three months later there is no way to tell whether a small file means a small business or a narrow filter.
No period on snapshots. Nine of the twelve reports carry no date column at all. The pull date is the only thing that makes two snapshot files comparable, and it exists nowhere inside them.
No units statement. Quantity columns do not say whether they hold cases or eaches, and the answer is not the same in every report. Shipment measures are cases; some inventory and order columns are not. Where it matters, check against a known item rather than assuming.
A worked example of how that compounds. Two spoilage-risk exports sit in a folder, one 300 rows and one 40. Without pull dates, the reasonable reading is that exposure fell sharply. The actual explanation could be that the second was filtered to one DC, or pulled a week later after stock cleared, or taken before a large receipt landed. Nothing in either file distinguishes those.
The remedy is a naming convention applied at the moment of export: report, pull
date, and any filter you applied, so unfi-spoilage-risk_2026-08-05_dc-east.csv
rather than download (3).csv. None of it is recoverable later, and it costs
nothing at the moment you have the information.
Where Scout fits
Scout is a demand-side analytics layer. It does not give you access to UNFI Insights, it is not an EDI gateway, and it is not part of your supply chain. Access to the portal comes from UNFI.
What Scout does with this data is join it to everything else. A brand's UNFI shipments sit alongside its KeHE sell-in, its direct retailer POS and its syndicated panel data on one set of column names, so the distribution question and the velocity question can be asked together.
The reference tables throughout this guide are generated from Scout's own normalised schema for these reports, which is why the portal's column name and Scout's sit side by side in each one.