App Store Regional Pricing Finder

Made an app that pulls regional prices from the apple App Store for essentially every available country and converts the values to the selected country. Helpful for finding region hacks.

Enter the app id without 'id', for example:
https://apps.apple.com/au/app/google-gemini/id6477489729 = 6477489729

Public Demo

https://appstore-regional-pricing.vercel.app/

How it works

Uses the 'in app purchases' list from the public sites and scrapes data, rotating through country codes.

Notes

Data may be incomplete - only a certain number of available in app purchases are listed in this section; not every available product. It gives you a good idea of where's cheapest though.

The website is all react, so it's your own browser fetching data via a list of html proxies, then formatting and displaying it.

Currently uses public proxies to address cors (they simply fetch and forward the page as raw html), I'll eventually add an API route to the next.js app to do the same thing and eliminate reliance on rate limited third party proxies.

Known Bugs

Bulgaria is glitched - it has a comma instead of a dot for 100th of its currency, which the logic is interpreting as a comma for a large number (ie 1,000). I'll eventually update the country data to specifically fix the currency for each app store to avoid this, instead of using logic to detect it. Mauritania also glitched, doesn't interpret it as USD, rather thinks it's MRU

Proxy list only has 2 proxies to try and there's no error handling if both fail - that region simply won't appear in output

Products with the same name that are actually different get stacked, such as monthly and yearly plans of the same naming. Easily determinable by the price difference

Sorry if wrong sub, thought it's fitting as it relates to hunting for bargains.

Related Stores

Apple App Store
Apple App Store
Marketplace

Comments

  • If anyone's interested in further developing it, message me for the git link

  • Note it's buggy currently when stores use the same product name for monthly and yearly plans, it's coded to collapse these and show the cheapest only.

    I'll fix this at some point to show all. There's no plan info to scrape so it won't show what it is, but you can determine that from the price usually.

    Going to see if I can find an API endpoint to pull actual data with info

  • I like the idea. It has potential. I like the bare bones look without all the fluff you see on a lot of sites these days.

    Is there any way to cache the data from previous user searches to speed up seeing a result? It took a good minute to see data for google gemini. Purge the data every 24 hours or so to limit out of date data being presented, give users the option of refreshing the data with a fresh scrape. Might be out of scope of what you're intending for it and might add costs to store the data.

    Also would be good to see the cost in the selected currency eg. with AUD as the selected currency I would want to see the Australian price as a point of reference. But that's just my personal preference.

    • Caching data would be possible once I add my own API instead of using proxies

      Eventually I’ll recode it so the server does the data fetching and streams progress updates back to client for the progress bar. It would simply return a json object for the store item as the function currently does (has country, productName, price, currency). Would likely restructure it so country is the key so it’s very neat json though. Currently this is all done client side - your browser fetches all the raw html via proxies, processes it (bit of logic involved because of things like 1,000 in some countries, 100,00 (100.00) in others, etc), then calls a currency conversion API for conversion.

      Need to update it to call the AUD conversion and do it in reverse via that (it returns AUD to every currency), currently calls each individual currency and finds the AUD ratio instead - so one request per a currency.

      Caching is very easy after that because it’s just raw json; either runs the logic or returns the raw json. I’d also optimise cache heading settings so vercel caches it too for a period of time.

      Would also allow for API access for people to play with, simply send the app ID and get a json response of the scraped items.

      Note each app only shows the top 5-10 items, and it differs by country. Haven’t found a way to scrape all available products.

      Currency conversion would remain client side because the public APIs work really well and once it’s a single call it’ll never get rate limited

  • Very Impressive …

    You should flash the URL around to see if it comes up cheaper when people do posts about certain apps ;)

    • +2

      A lot I find is cheaper than turkey (ie Nigeria), but getting iTunes gift cards for that is near impossible

      There is some niche things though, such as google gemini ai having a new secret plus plan in Indonesia (between free and pro). It’s priced at around $6/mo instead of like $30, but has much less usage. Posted another thread with full details

  • @Dyl, is it possible to have your URL with the option of having a /id link ? that way you can share the URL directly with an option already preset

    just an idea :)

    • +1

      Would be an easy addition, it would be a param so ?id={id}

      Could either make the URL bar auto fill with it (currently it autofills with the ID of gemini on load), or even the scrape script autorun when it detects the param is set. I'd also add one for currency (output currency) to autoset that section too if I added it.

      Would work even better once I add an API endpoint and caching, that way shared links would load near instantly. The only loading required would be a single call to the currency API to convert the data (I plan to leave this client side because those APIs are insanely fast and stable)

      Won't be added for at least a little while, taking a bit of a break from coding with my mental health for now (though I keep ending up coding anyway xD)

      Before that I'm adding a dict (ie 'au': 'AUD') for the store currency based on country code so I can remove all the messy logic to try and detect it, it's in my dev branch already and 95% complete but trying to avoid coding for a little while. The local API and potentially a caching feature would be the priority after that because the proxies keep dying; I have to keep rotating to new ones. They also throw out a lot of 429 (too many requests) errors. The API could instead pull from apple directly server side, process the data, then send a simple JSON object for the client to use. Easy to make vercel cache that at the edge too for near instant calls, and potentially could add some specific object caching for it as well (hobby plan has decent limits tbh)

  • Quick Question, what currency exchange rate does it use and how often does it update?

    • It uses
      https://open.er-api.com/v6/

      Simply calls
      https://open.er-api.com/v6/latest/{currency} and that returns the ratio to every other currency, then the javascript selects the AUD ratio.

      Calls the API after every scrape completes (client side). It's all react (client side) currently, so it's your browser scraping the data (Via proxies) and calling the currency conversion API.

      Wasn't thinking when I implemented that part - it currently calls the API for every currency used (20+) and finds the ratio to AUD, rather than calling https://open.er-api.com/v6/latest/AUD and finding the ratio of AUD to that currency… Their API hasn't once rate limited though so isn't major

      Based on time stamps data can be ~6 hours outdated on their API, but it's upto date enough for this purpose

Login or Join to leave a comment