Zip-Code Pricing: Why Your Scraped Prices Are Wrong

Zip-Code Pricing: Why Your Scraped Prices Are Wrong

Original observations, October 8, 2026 · 9 min read

Every scraper has a location, whether you set one or not. The retailer infers it from the IP address, cookies or a default, picks a store, and prices the page for that store. If you don’t record which one, a price “change” in your data may be nothing more than a different warehouse.

Key takeaways

  • Walmart assigned our visitor store 3081 (ZIP 95829, California). Target assigned store 1771 in Cedar Rapids, Iowa. Amazon showed prices in Czech koruna. We chose none of these.
  • None of those pages was an error. They loaded, parsed and returned a price, which is why location bugs survive for months.
  • Location is one of several contexts: market and currency, channel (app vs web), customer status and seller all change the number.
  • Personalized pricing is real enough that New York now requires a disclosure, and Instacart ended price tests after a 2025 study. Scrapers see the “guest” price.
  • Fix it with procedure: choose canonical locations, set them deliberately, read them back from each page and store them with every price.

What three retailers assumed about our visitor

On October 8, 2026 we opened Walmart, Target and Amazon in a clean browser session from Europe, without choosing a store, ZIP or delivery address, and looked at what each site had decided on our behalf.

Three cards showing default locations assigned to an anonymous visitor: Walmart store 3081 at ZIP 95829 California, Target store 1771 Cedar Rapids South at ZIP 52404 Iowa, and Amazon delivering to Czech Republic with prices in CZK
Defaults we observed on October 8, 2026. A scraper from a different IP will be assigned something else.
  • Walmart set an assortmentStoreId=3081 cookie, and the product page payload carried zipCode 95829, state CA. The price on the page was that store’s price.
  • Target wrote zipCode 52404 and store_id 1771 into the page’s serverLocationVariables, plus a list of nearby store IDs. Target’s server HTML contained no price at all; it is fetched afterwards for that store.
  • Amazon set the delivery location to the Czech Republic, displayed prices in koruna and showed a “cannot be shipped to your selected delivery location” notice on an Echo Dot page.

Two other big retailers didn’t get that far: Home Depot returned an “Access Denied” page and Gap redirected us to an international landing page. Those at least fail loudly. The first three return a perfectly normal-looking page with a perfectly parseable price for a context you never intended.

A price is a function of its context

Diagram of six factors that determine a scraped price: location, market and currency, channel, customer status, offer and seller, and fulfillment and time
If two observations differ in any of these, they are not directly comparable.

Store and ZIP

Large US chains price, stock and promote by store or zone. Public scraping write-ups show how big the gaps can be for identical items: one vendor’s Target walkthrough found the same product at $7.69 at a New York store and $6.89 at a Houston store, while nationally priced items fell back to a single online pricing location.1 Grocery, home improvement and pharmacy are the most location-sensitive categories; Walmart and Target sit in the middle; Amazon’s location effect shows up more in delivery options, offers and currency than in store-level prices.

Channel: web, app and store

Channel can matter as much as geography. In February 2019, Minneapolis TV station KARE 11 found that some Target app prices rose when the shopper’s phone entered a store. A Dyson vacuum went up $148 and a car seat $72; across ten items the parking-lot total was $262 lower than inside the store. Target then started labeling app prices as “online” or “in-store.” A scraper hitting the website sees the online price. Your customers in the aisle may see another.

Market and currency

For international sellers, the “market” is the location. Shopify’s Markets documentation tells developers not to compute an international price from the base price and to request each market’s price instead, because markets can have their own price lists, rounding and currency. In our test of 50 Shopify brand stores, the public catalog feed returned prices in each shop’s base currency regardless of where we browsed from. Details are in our Shopify /products.json research.

Customer status and personal data

This is the least visible context and the fastest-moving policy area:

  • In December 2025, a study by Groundwork Collaborative and Consumer Reports with nearly 200 shoppers in four US cities found about three quarters of grocery items on Instacart offered at varying prices to different shoppers. Instacart ended those item price tests on December 22, 2025, according to ABC News.
  • New York’s Algorithmic Pricing Disclosure Act, in effect since late 2025, requires businesses that set prices with personal data to show the words “THIS PRICE WAS SET BY AN ALGORITHM USING YOUR PERSONAL DATA” next to the price, as summarized by Duane Morris.
  • The FTC’s preliminary surveillance pricing findings in January 2025 described intermediaries using location, browsing behavior and demographics to tailor prices.

A logged-out scraper sees a guest price. That is usually the right baseline for competitive analysis, but it should be a choice you document, not an accident.

Online versus offline

Even without personalization, online and in-store prices diverge. The Billion Prices Project compared more than 24,000 products at 56 large retailers in 10 countries and found online and offline price levels identical about 70% of the time.2 That research is older and measures online vs offline, not ZIP vs ZIP, but the lesson carries over: one URL does not mean one price.

How to make location explicit in your pipeline

  1. Choose canonical locations. One ZIP per region that matters to the decision, for example your top three markets. Write them down with the matching store IDs.
  2. Set them the way a shopper would. Use the site’s own store or delivery selector in the session, so the cookies and payload agree.
  3. Read the location back from every page. Don’t trust that the session kept it. Walmart, Target and Amazon all expose the active location in the page; parse it like any other field.
  4. Reject mismatches. If the page’s store or currency differs from the configured one, the observation is invalid, not “a price.”
  5. Store context next to the number. Every row, every time.
ColumnExampleWhy
observed_at2026-10-08T14:05ZPromotions start and end by the hour
store_id / zip3081 / 95829Store-level price and stock
country / currencyUS / USDCatches converted or market prices
channelwebApp and in-store prices can differ
sessionguestMember and personalized prices
seller / fulfillment1P / shipMarketplace offers and pickup prices differ
price_typecurrent, regular, memberDon’t compare a sale price to a list price
price_raw“Now $49.99”Lets you re-parse when parsing rules change

How many locations do you need?

Fewer than you’d think, but more than zero. Before committing to dozens of ZIPs, run a small experiment: take 20 representative products, check them in five locations on the same day with the same variant, seller and fulfillment method, and measure how many prices differ and by how much. If almost nothing differs, one canonical location per retailer is enough. If a category varies widely, add locations for that category only.

It’s a cheap experiment and worth running before you scale. And the defaults above are a good reason to check today what your current data actually represents. The same principle runs through our guides on Walmart and Amazon, and through every price monitoring project we run.

FAQ

Do Walmart prices differ by ZIP code?

Walmart assigns every visitor a store, and assortment, availability and some prices vary by store. Record the store ID with every price and keep it fixed so you can tell real price changes from store changes.

Does Amazon change prices by location?

Amazon prices the featured offer for a delivery location. For US addresses the item price is often the same nationwide, but offers, delivery options and availability vary, and non-US locations can show converted currencies and import notices.

Why does my scraper get different prices than my browser?

Usually because the two have different locations, sessions or channels. Your browser remembers your store and may be logged in; your scraper gets a default store from its IP address and a guest session.

Is personalized pricing legal in the US?

Generally yes, with growing disclosure rules. New York requires a specific notice when prices are set by an algorithm using personal data, and the FTC has studied the practice. It is one more reason to document the session type behind every scraped price.

Notes

  1. Example from a scraping vendor’s public Target tutorial; a single observation, not a measured average across stores. ↩
  2. Cavallo, “Are Online and Offline Prices Similar?”, American Economic Review, 2017. Some versions of the paper report 72%; the figure depends on the sample and method. ↩

Want prices with their context attached?

Every JsonEngine price record carries store, ZIP, currency, seller and timestamp, and observations from the wrong location are rejected before delivery.

Ask about location-accurate pricing →