Before you build a Shopify app for coffee roasters, pitch a packaging service to them, or write "the market is huge" in a deck, it helps to know how many such stores there are and who the biggest ones are. This post answers that for coffee in five countries with a 40-line Python script and 21 API requests. The numbers are from a run made on 14 November 2026.
The data
Shopify Stores Database is a REST API over 57,202 Shopify stores that appear in two open popularity lists (Chrome UX Report top 1M and Majestic Million). Each record has the store name, description, country, currency, city and catalog size. Three endpoints:
-
GET /v1/stores: filtered list, most popular first, up to 25 stores per request -
GET /v1/stores/{domain}: is this domain in the database? -
GET /v1/stats: store counts per country and currency
The free plan gives 50 requests a month, which is enough for everything below.
One request
curl "https://shopify-stores-database.p.rapidapi.com/v1/stores?country=DE&q=coffee&limit=2" \ -H "X-RapidAPI-Key: $RAPIDAPI_KEY" \ -H "X-RapidAPI-Host: shopify-stores-database.p.rapidapi.com" { "data": [ { "domain": "berserker-coffee.com", "url": "https://berserker-coffee.com", "tld": "com", "trafficRank": 500000, "majesticRank": null, "name": "Berserker Coffee Company", "description": "Berserker Coffee ist der stärkste und leckerste Kaffee ...", "country": "DE", "currency": "EUR", "city": "Fürth", "productCount": 64, "myshopifyDomain": "berserkercoffee.myshopify.com", "position": 6829 }, { "domain": "thebarn.de", "name": "THE BARN Coffee Roasters", "country": "DE", "city": "Berlin", "productCount": 206, "position": 20548 } ], "count": 2, "nextCursor": 20548, "dataUpdatedAt": "2026-11-13" } (The second record is shortened here.) position is the store's place in the popularity ordering, and nextCursor is what you pass as after to get the next page. When nextCursor is null, there is nothing left.
The API does not return a total count. To count a niche you page through it, which is what the script does.
The script
Standard library only, so there is nothing to install.
import csv, json, os, statistics, sys, urllib.parse, urllib.request HOST = "shopify-stores-database.p.rapidapi.com" HEADERS = {"X-RapidAPI-Key": os.environ["RAPIDAPI_KEY"], "X-RapidAPI-Host": HOST} FIELDS = ["country", "position", "domain", "name", "city", "currency", "productCount", "trafficRank", "description"] def get(path, **params): url = f"https://{HOST}{path}?" + urllib.parse.urlencode(params) with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r: return json.load(r) def stores(keyword, country): """Every store matching the keyword in one country, most popular first.""" after = 0 while after is not None: page = get("/v1/stores", q=keyword, country=country, limit=25, after=after) yield from page["data"] after = page["nextCursor"] keyword, countries = sys.argv[1], sys.argv[2].upper().split(",") totals = {c["country"]: c["count"] for c in get("/v1/stats")["countries"]} rows = [] print(f"{'country':8}{'stores':>8}{'in niche':>10}{'share':>8}{'median products':>17}") for country in countries: found = list(stores(keyword, country)) rows += found sizes = [s["productCount"] for s in found if s["productCount"] is not None] median = int(statistics.median(sizes)) if sizes else "-" print(f"{country:8}{totals[country]:>8}{len(found):>10}" f"{100 * len(found) / totals[country]:>7.1f}%{median:>17}") with open(f"{keyword}_stores.csv", "w", newline="", encoding="utf-8") as f: w = csv.DictWriter(f, fieldnames=FIELDS, extrasaction="ignore") w.writeheader() w.writerows(rows) print(f"\n{len(rows)} stores written to {keyword}_stores.csv") export RAPIDAPI_KEY=your-key python niche_size.py coffee US,GB,DE,CA,AU The result
country stores in niche share median products US 16697 291 1.7% 83 GB 4296 62 1.4% 127 DE 2202 9 0.4% 126 CA 1637 26 1.6% 86 AU 1912 33 1.7% 119 421 stores written to coffee_stores.csv That took 21 requests (one for the country totals, twenty pages of stores) and a few seconds.
The first rows of the CSV for the US are Peet's Coffee, AeroPress, The Coffee Bean & Tea Leaf, Fellow, Death Wish Coffee and Trade Coffee: the list is ordered by popularity, so the names you would expect come first.
Reading the numbers honestly
Coffee is about 1.5% of popular Shopify stores in English-speaking countries. The share is nearly the same in the US, Canada and Australia (1.6 to 1.7%) and a little lower in the UK (1.4%).
Germany's 0.4% is a keyword artifact, not a market fact. The q filter looks for the word in the store name, description and domain. German stores write "Kaffee". Searching kaffee in Germany finds 15 stores, and 22 match either spelling, which brings Germany to 1.0%. For non-English markets, run the script once per local term and merge by domain.
Catalogs are small. The median US coffee store lists 83 products, and 172 of the 291 have 100 or fewer. If your product is priced per SKU or assumes a large catalog, this niche will disappoint you.
This is a count of popular stores, not of all stores. The database covers stores that are visible in public top-1M rankings. A roaster that opened last month with forty visitors a day is not in it. Treat 291 as "US coffee stores with measurable traffic or links", which is usually the set you can sell to anyway.
A keyword match is not a category. In this run, 9 of the 421 matches are furniture and homeware stores whose descriptions mention coffee tables. Skim the CSV before you quote the number to anyone; the description column makes that quick.
Variations
Stores with a large catalog and real traffic, any niche:
GET /v1/stores?country=US&minProducts=1000&maxTrafficRank=100000&limit=25 Everything priced in euros that mentions "bio":
GET /v1/stores?currency=EUR&q=bio&limit=25 Is a domain from your CRM a known Shopify store?
GET /v1/stores/gymshark.com A 404 here means "not in this database". It does not prove the site runs on something else.
What to do with the list
The CSV gives you domains, names and sizes. If you need to know which apps those stores run (Klaviyo, Recharge, a reviews app) or their public contact details, the companion guide shows that step: Build a targeted list of Shopify stores by country, niche and installed apps.
Costs and limits
- Free plan: 50 requests a month, up to 1,250 stores. The run above used 21.
- Paid plans start at $9.99 a month for 1,500 requests (37,500 stores).
- Data is rebuilt monthly; every response carries
dataUpdatedAt. - No emails or personal data in this API.
The API is here: Shopify Stores Database on RapidAPI. If a filter you need is missing, say so in the comments or in the API's Discussions tab.

