One product id, thirty storefronts, thirty prices
iHerb sells one catalogue into about 30 countries, and the price is not the same in any two of them.
8 active endpoints, on 1, 2 and 3 credit tiers.
- POST/iherb/v1/search
- POST/iherb/v1/category
- POST/iherb/v1/detail
- POST/iherb/v1/batch_detail
- POST/iherb/v1/price_by_country
- POST/iherb/v1/reviews
- POST/iherb/v1/categories
- +1 more
What iHerb endpoints does ReefAPI ship?
8 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
iHerb API
3 of 8 endpoints, ready to run
The same product priced across up to twelve national storefronts in one call — price, ISO currency, the local display price, stock state, and whether the product is listed in that country at all. No currency conversion is applied: every figure is the number iHerb prints in that market.
// Press "Try it" and this pane shows exactly what the // live site returned this second — including an empty // result, if that is the truth. No key, no account.
How the iHerb API works
iHerb is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 280 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Find where a supplement is cheapest, and whether you can actually get it there
Cross-border sourcing fails on two things before it fails on price: the product turns out not to be listed in that country at all, or it is listed but out of stock. So the walk ends on availability rather than starting from it.
{"keyword": "vitamin c", "country": "US", "rating_band": 5, "in_stock_only": true}The five-star band on the US storefront, in stock only — 5,818 products sit in that band before the stock filter. Each row carries the product id you need next, plus the price, currency, brand and rating count.
{"product_id": "<id from a search row>", "countries": ["US","GB","DE","JP","AU","SG"]}One row per storefront with the price, the ISO currency and the stock state. Countries where iHerb does not list the product say so explicitly rather than going missing, which is the answer you need before you plan a route.
{"product_id": "<same id>", "country": "<the cheapest market>"}The full record on that storefront — supplement facts as rows, ingredients, pack size and shipping weight for a landed-cost calculation, plus the restricted-countries list and the banned flag that say whether it can ship where you want it.
A product you know is stocked, priced in each market's own currency with no invented exchange rate, with the pack size and shipping weight to cost the freight and the restriction flags to tell you whether it can legally arrive.
curl -X POST https://api.reefapi.com/iherb/v1/price_by_country \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"product_id":1135,"countries":["US","JP"]}'{
"ok": true,
"data": { … },
"meta": {
"api": "iherb",
"endpoint": "price_by_country",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}What changes when you change the country, and what does not
Everything on this page was measured against the live storefronts on one day. The first two rows are the ones that decide whether this API fits what you are building, so they go first.
| Field | What comes back | What it means |
|---|---|---|
| price_amount + currency | A number and an ISO currency code, always together, never merged into one string. The same product id: US 11.02 USD, GB 12.71 GBP, DE 13.74 EUR, JP 1856 JPY, KR 14460 KRW, AU 23.80 AUD, CA 19.85 CAD, IN 1355.54 INR, BR 79.03 BRL, TR 677.35 TRY | The currency is part of the answer, not something you infer from the country. Ukraine is the row that proves the point: the Ukrainian storefront prices in USD, not the local currency, so a country-to-currency lookup table on your side would have been wrong there. price_display carries iHerb's own formatted string alongside, so you can show exactly what the storefront shows. |
| rating_count | An integer — but it is shared across a product group, not per variant | Against us, and worth knowing before you build on it. Products 475 and 16539 are different sizes of the same supplement and both report exactly 25,485 ratings, because iHerb counts reviews per product family. If you sum rating_count across a brand's catalogue you will double-count. Use it per product, not as a total. |
| supplement_facts | Rows parsed out of iHerb's nutrition panel — name, amount, daily value. 6 of 6 on vitamin C, probiotics, whey protein and fish oil; 5 of 6 on green tea; 3 of 6 on pet health; 2 of 6 on coffee; 0 of 6 on shampoo | Present when the product has a panel and absent when it does not — a shampoo has no supplement facts, so 0 of 6 there is the source being right. The pooled figure across 48 products in 8 categories is 34 of 48, which is why the per-category breakdown is printed rather than the average. |
| in_stock + stock_status + stock_left_count | A boolean, a label (in_stock, in_stock_low, not_available, out_of_stock) and, only when stock is low, a remaining-units integer | stock_left_count was null on all 48 US products sampled, because iHerb prints a remaining count only when a product is actually running low — we saw it live on the German storefront as 9 units on a product that was plentiful in the US. Treat it as a low-stock signal, not an inventory feed. back_in_stock_date comes back where iHerb publishes one. |
| country_of_origin | Always null | Against us. The field exists in iHerb's data and is empty on all 48 products we sampled, so we return null rather than guessing it from the brand's address. If country of origin is what you need, this API does not have it. |
| ingredients, suggested_use, warnings | Plain text, with iHerb's markup removed. ingredients 44 of 48, suggested_use 48 of 48, warnings 43 of 48 | iHerb publishes these as HTML fragments; every string this API returns is stripped of tags and entities, checked across 48 product records, a full search payload and a reviews payload. Coffee is the category that thins out — 2 of 6 for ingredients. |
Thirty storefronts, 1,483 categories, and the fields iHerb does not publish
Measured against the live engine: 48 product records across 8 categories, prices checked against what each product page itself prints, and every filter measured unfiltered against filtered. The rows that go against us come first.
Two fields you might expect and will not get. country_of_origin exists in iHerb's data and was empty on all 48 products sampled, so we return null rather than deriving it from the brand's address. stock_left_count was null on all 48 US products too, because iHerb publishes a remaining-units number only when a product is genuinely low — we saw it live as 9 units on the German storefront for a product that was plentiful in the US. It is a low-stock signal, not an inventory feed. What you do always get is a stock boolean and a status label on 48 of 48.
Products 475 and 16539 are different sizes of the same supplement and both report exactly 25,485 ratings, because iHerb counts reviews per product group rather than per variant. That is the source's design, not a parsing error, and it means summing rating_count across a catalogue double-counts. Use it per product.
We took eight products across three storefronts and compared every price and currency this API returns against what the product page itself prints for shoppers: 11.02 USD, 18.59 USD, 6.42 USD, 15.99 USD, 8.05 USD, 17.14 USD, 3302 JPY and 40.62 GBP. Eight of eight matched on both the amount and the currency. Ratings were checked against a second independent surface on the same eight products and matched on seven; the eighth differed by three reviews on a product with 387,615 of them, because three arrived between the two calls.
The same vitamin C category returns 785 products in the US, 765 in Germany, 755 in Japan, 754 in Singapore, 751 in Canada, 746 in Korea and 736 in the UK. Prices for one product id span $11.02 in the US, 13,74 € in Germany, ¥1,856 in Japan, £12.71 in the UK, ₩14,460 in Korea, ₹1,355.54 in India, R$79,03 in Brazil and ₺677,35 in Turkey. Three countries we tested could not be served and are not offered: Russia, China and Indonesia.
Against an unfiltered 14,940 results: rating band four gives 8,909, brand NOW 756, brand CGN 319, cheapest price band 248, immune-support topic 2,604, vegan 4,820, iTested 273, in-stock-only 14,468. On a category the same holds — 785 down to 346, 36 and 768. Two filters iHerb's own interface advertises are not exposed here: one is accepted and changes nothing at all, the other errors on every value. Exposing a filter that silently does nothing is worse than not having it.
Unsorted, a vitamin c search returns 14,807 products. With any explicit sort other than featured or relevance, the same search returns 10,559. This is the source's behaviour, not a paging artefact, and the response flags it so it shows up in your data rather than only here.
Across 48 products in 8 categories: product id, SKU, name, brand, price, currency, list price, stock state, rating, rating count, pack size, weight, dimensions, description, suggested use, images, category, breadcrumbs, expiry date and price-per-unit all arrive on 48 of 48. Ingredients 44 of 48, warnings 43 of 48. supplement_facts is 34 of 48 pooled, which is a misleading number on its own: it is 6 of 6 on vitamin C, probiotics, whey protein and fish oil, 5 of 6 on green tea, 3 of 6 on pet health, 2 of 6 on coffee and 0 of 6 on shampoo — a shampoo has no nutrition panel.
No account is involved. Each page carries ten reviews with text, title, star rating, date, language, verified-purchase flag, helpful votes and attached photo count, plus the average, the total and the per-star split — 6,580 ratings on product 468, split 5,314 / 871 / 305 / 52 / 38 from five stars down to one, across 653 pages. iHerb's own written summary of the reviews comes back alongside. Reviewer display names are off by default and opt-in; handles and avatars are never returned.
Six product ids taken from a search and resolved through detail came back with the same id, the same type, the same SKU and the same price to the cent, six times out of six. Where a product is discounted you get the price, the list price and a discount percentage we compute from those two, kept separate from iHerb's own discount figure so that if the source's number ever disagrees with its own prices you can see both instead of having to trust one.
What people build with iHerb
The jobs this data is most often used for.
endpoints
credits per call
Price a product across borders before you launch there: give price_by_country one product id and a dozen markets and get back the price, currency, availability and local display string for each, so you can see what iHerb charges in a market before you set your own price against it.
Watch a competitor's supplement range in one country: run a category or brand-filtered search on that storefront and store price_amount with its currency, the rating and the rating count, then re-run it on a schedule to follow price moves and review growth.
Build a supplement comparison or ingredient search: pull supplement_facts as rows plus the ingredient text across a category and compare dosage per serving between brands, using price_per_unit and pack size to get a real cost per serving rather than a cost per bottle.
Check where a product is actually sold: price_by_country tells you which storefronts list an item and which do not, and each record carries the restricted-countries list and a banned flag, which is the difference between a product you can source and one you cannot.
What iHerb data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 280 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/iherb/v1/price_by_country \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"product_id":1135,"countries":["US","JP"]}'import requests
r = requests.post(
"https://api.reefapi.com/iherb/v1/price_by_country",
headers={"x-api-key": REEF_KEY},
json={
"product_id": 1135,
"countries": [
"US",
"JP"
]
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up iHerb.
Get a free key →How do I get the price in a specific country?▾
Pass country on any call — search, category, detail, batch_detail or reviews all take it, and it defaults to US. Thirty storefronts are supported: US, CA, MX, BR, GB, DE, FR, IT, ES, NL, PL, SE, TR, UA, IL, AE, SA, ZA, IN, JP, KR, HK, TW, SG, MY, TH, VN, PH, AU and NZ. Every response repeats the country and the ISO currency it was priced in, so a stored row can never lose track of which storefront it came from. If a storefront cannot be reached for a request, the call fails with a clear error instead of quietly answering from a different country — a price in the wrong currency is worse than no price.
Can I compare one product across several countries in one call?▾
That is what price_by_country does. Give it a product id and up to twelve country codes and it returns one row per storefront with the price, the ISO currency, the local display price, the stock state and whether the product is listed there at all. Products are not on every storefront — when one is missing, that row says so rather than being dropped, so you can see where a product is simply not sold. No currency conversion is applied anywhere in this API: each figure is the number iHerb itself prints in that market, because an FX rate we invented would be the least reliable number on the page.
Are the reviews real reviews, or just the rating?▾
Real reviews, and no account is involved in reading them. Each page returns ten with the review text, the title, the star rating, the date, the language, the verified-purchase flag, the helpful-vote counts and how many photographs are attached. Alongside them you get the average, the total, and the full per-star breakdown — for product 468 that is 6,580 ratings split 5,314 five-star, 871 four, 305 three, 52 two and 38 one — plus iHerb's own written summary of what customers said. Product 468 runs to 653 pages of reviews. Reviewer display names are withheld by default and returned only if you explicitly ask for them; handles and avatars are never returned.
Do the filters actually narrow the results, or are they accepted and ignored?▾
Every filter this API exposes narrows the result, and we publish the proof. Against an unfiltered 14,940 results for vitamin c: the four-star band returns 8,909, the NOW Foods brand 756, California Gold Nutrition 319, the cheapest price band 248, the immune-support health topic 2,604, the vegan attribute 4,820 and the iTested programme 273. In-stock-only takes 14,940 to 14,468. Two filters that iHerb itself advertises are deliberately not exposed here: one is accepted and changes nothing, and the other returns an error for every value. Rather than pass those through and let you believe they worked, we left them out.
Why is the rating filter called rating_band and not min_rating?▾
Because it is a band and not a minimum, and the honest name saves you a wrong result. Asking for band 3 returns products rated roughly 2.8 to 3.7 — it excludes the four- and five-star products, rather than including everything above three. Measured on one storefront: band 5 returns 5,818 products rated about 4.8 and up, band 4 returns 8,909 rated roughly 3.8 to 4.7, band 3 returns 36, band 2 returns 6 and band 1 returns 2. The filters action prints the live count sitting behind each band so you can see the shape before you query.
Does sorting just reorder the results?▾
No, and this one surprised us enough to put it in the response. Unsorted, vitamin c returns 14,807 results; sorted by price, by rating, by newest or by any other explicit sort, the same query returns 10,559. Sorting changes which products are in the set by about 29 percent, it does not merely change their order. The search response carries a sorted_population_differs flag so this is visible in the data rather than only in the documentation. Featured and relevance are the two that leave the total alone.
How do I find the brand codes and attribute ids the filters want?▾
Call the filters action with a keyword or a category slug. It returns iHerb's own vocabulary for that query with a live product count beside every option: 1,056 brands, 1,349 category ids, plus health topics, price bands, programmes and the attribute groups that cover diet and certification, product form, age range and skin or hair concern. That is 28 filter groups and 2,725 options on a single query. The codes are opaque — NOW Foods is NOW, 100% PURE is URE — so reading them from this call is the only reliable way to get them right.
How do I get product ids in the first place?▾
Three ways, and none of them needs you to know an id in advance. Search by keyword; browse a category, with all 1,483 category slugs available from the categories action; or, if you already have an iHerb URL, the id is the last path segment. Search also resolves a SKU or part number directly, so a query that exactly matches a product comes back flagged as an exact match. A search row and a detail record agree: we checked six ids from search through to detail and got the same id, the same type, the same SKU and the same price to the cent on all six.
What is the iHerb API?▾
iHerb API is a ReefAPI endpoint group for supplements and natural health, priced in 30 countries. It returns live JSON through POST requests under /iherb/v1.
Is the iHerb API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. iHerb calls use the same shared credit balance as every other ReefAPI engine.
Do I need an iHerb login or account?▾
No login to iHerb is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the iHerb data?▾
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the iHerb API use?▾
iHerb actions currently cost 1-3 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call iHerb from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call iherb actions with the same key, credit pool and JSON envelope used by normal REST requests.
116 E-commerce & Marketplaces APIs on the same key
One key, one credit pool, one response envelope. If you are pulling iHerb, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 279 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-09-23.