Online Store Intelligence API

Turn a store domain into a profile, with every field's source named

Online Store Intelligence API returns live Online Store Intelligence data as clean JSON for online store intelligence The primary endpoint, store_lookup, returns platform data including name, confidence, ecommerce confirmed, supported and partial.

no credit card1,000 free credits · instant API key · pay by card or crypto
Missing a Online Store Intelligence endpoint, or need a source we don't have yet?Contact us real people · same-day reply.
O
/enrich-store/v1

3 active endpoints, on 2, 8 and 20 credit tiers.

  • POST/enrich-store/v1/store_lookup
  • POST/enrich-store/v1/platform_detect
  • POST/enrich-store/v1/batch

What Online Store Intelligence endpoints does ReefAPI ship?

3 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.

3 endpoints

store_lookup

8 cr

store domain → platform verdict + store metadata + tech-stack + catalog sample (price/discoun…

required
store
optional
mode, max_items, include_marketplace

platform_detect

2 cr

store domain → ecommerce platform verdict (shopify|woocommerce|magento|bigcommerce|prestashop…

required
store
optional

batch

20 cr

look up to 5 stores in one call (basic mode, cache-first, per-store ok/error).

required
stores
optional

Every parameter, every allowed value →

Online Store Intelligence API

3 of 3 endpoints, ready to run

View docs ↗

One domain, five sections, and a provenance block that tells you which of them actually matched: the platform verdict with its evidence and confidence, the tech and CDN stack, the store's declared name, country and currency, a priced catalogue sample with sale and stock flags, and a reputation score matched by domain.

8 credits1 required · 2 optional
POST/enrich-store/v1/store_lookup
ok4930 ms · 5 records · sample
{
  "ok": true,
  "meta": {
    "api": "enrich-store",
    "endpoint": "store_lookup",
    "mode": "basic",
    "latency_ms": 4930.3,
    "record_count": 5,
    "cache_hit": false,
    "completeness_pct": 100
  },
  "data": {
    "provenance": {
      "platform": {
        "status": "matched",
        "engine": "shopify+domain-intel"
      },
      "tech": {
        "status": "matched",
        "engine": "domain-intel"
      },
      "catalog": {
        "status": "matched",
        "engine": "shopify"
      },
      "reputation": {
        "status": "matched",
        "engine": "trustpilot"
      },
      "presence": {
        "status": "matched",
        "engine": "shopify+google-search"
      }
    },
    "platform": {
      "name": "shopify",
      "confidence": 0.98,
      "ecommerce_confirmed": true,
      "evidence": "shopify_public_json_live",
      "technologies": [
        "Cloudflare",
        "Google Tag Manager",
        "Shopify"
      ],
      "supported": true,
      "partial": false
    },
    "store_info": {
      "name": "Allbirds",
      "domain": "www.allbirds.com",
      "myshopify_domain": "weareallbirds.myshopify.com",
      "currency": "USD",
      "description": "The world’s most comfortable shoes, made with natural materials like merino wool, eucalyptus tree fiber, and sugar cane, Allbirds has created the comfiest shoes on the planet.",
      "country": "US",
      "province": "California",
      "city": "Beverly Hills",
      "store_url": "https://www.allbirds.com"
    },
    "tech": {
      "technologies": [
        "Cloudflare",
        "Google Tag Manager",
        "Shopify"
      ],
      "cdn": [
        "Cloudflare"
      ],
      "server": "cloudflare",
      "http_status": 200
    },
    "catalog": {
      "catalog_sample": {
        "size": 50,
        "products": [
          {
            "title": "Men's Strider Explore - Natural Black (Dark Grey Sole)",
            "vendor": "Allbirds",
            "type": "Shoes",
            "url": "https://allbirds.com/products/mens-strider-explore",
            "price_min": 130,
            "price_max": 130,
            "on_sale": false,
            "max_discount_percent": 0,
            "available": false,
            "total_variants": 13,
            "image": "https://cdn.shopify.com/s/files/1/1104/4168/files/A11768_25Q4_Strider-Explore-Natural-Black-Dark-Grey-Sole_PDP_LEFT.png?v=1759336475"
          },
          {
            "title": "Women's Dasher NZ - Blizzard/Deep Navy (Blizzard Sole)",
            "vendor": "Allbirds",
            "type": "Shoes",
            "url": "https://allbirds.com/products/womens-dasher-nz-blizzard-deep-navy",
            "price_min": 140,
            "price_max": 140,
            "on_sale": false,
            "max_discount_percent": 0,
            "available": true,
            "total_variants": 13,
            "image": "https://cdn.shopify.com/s/files/1/1104/4168/files/A12464_26Q1_Dasher-NZ-Blizzard-Deep-Navy-Blizzard_PDP_LEFT_e38509e9-51da-49a3-a794-53de6797a109.png?v=1768948779"
          },
          {
            "title": "Men's Dasher NZ - Anthracite (Dark Anthracite Sole)",
            "vendor": "Allbirds",
            "type": "Shoes",
            "url": "https://allbirds.com/products/mens-dasher-nz-anthracite",
            "price_min": 140,
            "price_max": 140,
            "on_sale": false,
            "max_discount_percent": 0,
            "available": true,
            "total_variants": 13,
            "image": "https://cdn.shopify.com/s/files/1/1104/4168/files/A12416_26Q1_Dasher-NZ-Anthracite-Dark-Anthr_PDP_LEFT.png?v=1768948005"
          }
        ],
        "price_range": {
          "min": 12,
          "max": 160,
          "median": 105,
          "avg": 96.52,
          "currency": "USD"
        },
        "discount_ratio": 0,
        "avg_discount_percent": null,
        "in_stock_ratio": 0.14,
        "stock_signals": {
          "on_sale": 0,
          "in_stock": 7,
          "sampled": 50
        },
        "top_vendors": [
          {
            "name": "Allbirds",
            "count": 50
          }
        ],
        "top_product_types": [
          {
            "name": "Shoes",
            "count": 36
          },
          {
            "name": "Socks",
            "count": 9
          },
          {
            "name": "Apparel",
            "count": 5
          }
        ]
      },
      "catalog_estimate": {
        "total_products_estimate": null,
        "estimate_source": "partial_sample_more_available",
        "collections_count": 250,
        "note": "estimate from store metadata/collections — NOT a full harvest; use the shopify engine with max_items for a complete product pull"
      },
      "sampled": 50,
      "has_more": true
    },
    "reputation": {
      "trustpilot": {
        "found": true,
        "business_unit_id": "5ba28e8dafa8530001888470",
        "domain": "allbirds.com",
        "name": "Allbirds",
        "trust_score": 3.4,
        "stars": 3.5,
        "reviews_count": 2675,
        "categories": [
          "Shoe Store",
          "Clothing Store"
        ],
        "match_type": "domain"
      }
    },
    "presence": {
      "store_url": "https://allbirds.com",
      "policies_convention": {
        "privacy": "https://allbirds.com/policies/privacy-policy",
        "terms": "https://allbirds.com/policies/terms-of-service",
        "refund": "https://allbirds.com/policies/refund-policy",
        "shipping": "https://allbirds.com/policies/shipping-policy"
      },
      "social_links": {},
      "serp": [],
      "note": "policy URLs are Shopify storefront conventions (not verified live); social links are brand-keyed SERP hits"
    }
  }
}
Real response, fetched from the live endpoint with the parameters on the left — trimmed to the first few rows, with seller names left out. Press Try it for the untrimmed response.

How the Online Store Intelligence API works

Online Store Intelligence is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.

01
Authenticate
x-api-key header

No OAuth app, no request signing, no per-site account. One key covers all 184 engines.

02
Call
POST /enrich-store/v1/…

Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.

03
Pay
2 or 8 or 20 credits per call

Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.

04
Read
{ ok, data, meta, error }

One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.

Qualify a list of stores without opening any of them

The question a partnerships or agency pipeline asks is 'is this a real store, on a platform I can integrate with, big enough to bother with'. That is three fields, and they are all in one response.

01batch
POST/enrich-store/v1/batch
{"stores": ["a.com", "b.com", "c.com", "d.com", "e.com"]}

Five at a time, each with a platform verdict, a confidence and a reputation match. The cheap first pass over a long list.

02store_lookup
POST/enrich-store/v1/store_lookup
{"store": "<the ones that came back supported>", "mode": "catalog", "max_items": 200}

Walks the catalogue for the survivors: price ranges, sale flags, discount percentages, variant counts and availability on every product.

03platform_detect
POST/enrich-store/v1/platform_detect
{"store": "<a store whose verdict was partial>"}

The cheap re-probe. A partial verdict is a failed probe, not a negative answer, and it is worth one retry before you drop the lead.

A qualified shortlist with a platform, a catalogue size, a price band and a reputation score against each — and, crucially, a provenance record saying which of those you should actually trust.

request
curl -X POST https://api.reefapi.com/enrich-store/v1/store_lookup \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"store":"allbirds.com"}'
response envelope
{
  "ok": true,
  "data": { … },
  "meta": {
    "api": "enrich-store",
    "endpoint": "store_lookup",
    "mode": "live",
    "latency_ms": …,
    "record_count": …
  },
  "error": null
}

Platform verdicts, and what each one unlocks

Two fields decide how much of the response you get: platform.name and platform.supported. Detection is broad, catalog harvesting is not, and the response says so rather than handing back an empty catalog. Values below are measured against allbirds.com, gymshark.com, barefootbuttons.com, amazon.com and a domain that does not exist — which store_lookup now answers with NOT_FOUND rather than with an empty success.

FieldMeasured valueWhat to know
platform.nameshopify / woocommerce / unknownthe enum also lists magento, bigcommerce, prestashop and custom_or_unknown; we verified the first three live
platform.confidence + evidence0.98 with "shopify_public_json_live"; 0.9 with "technographic:woocommerce"; 0.0 with "tech_detect_unavailable"0.98 means the store's own public JSON answered; 0.9 means a technology fingerprint only
platform.supported / partialshopify true and false; woocommerce false and truesupported false means detection worked and catalog harvesting will not run
catalog.availablefalse, with reason "catalog depth is Shopify-only; this store is 'woocommerce'"on a non-Shopify store the catalog block is a one-line refusal, not an empty product array
catalog_sample.size vs products[]size 50 returned 25 products; size 120 returned 25 productsthe distribution stats cover the whole sample, the returned array is capped at 25 rows
catalog_estimate.estimate_source"partial_sample_more_available" in basic; "full_storefront_walk" in catalog modetotal_products_estimate stays null until a full walk finishes; allbirds.com resolved to 120 products
catalog_estimate.collections_count250 on both Shopify stores measuredthe identical figure on two unrelated stores reads as a ceiling, not a count
reputation.trustpilottrust_score 3.4 with stars 3.5; trust_score 0.0 with reviews_count 0trust_score is the fine-grained figure and stars the rounded display; found:true does not mean reviewed
presence.policies_conventionfour /policies/... URLs, but only for a Shopify storefront that was actually reachedconstructed from Shopify's URL convention and not fetched; the response note says "not verified live"
store_info.domain"us.checkout.gymshark.com" for input gymshark.comthis is the domain the Shopify store declares about itself, not the host you asked about

mode is the credit dial. basic samples the storefront's first page, catalog walks pages until max_items (1 to 1000, default 250), and rich adds Trustpilot rating_distribution, is_claimed and sample_reviews plus a Google Maps attempt. In our measurements rich populated neither presence.serp nor presence.social_links on either store; both stayed empty. For a full product export the response itself points you at the shopify engine instead.

How you tell a real answer from a failed probe

Measured against the live gateway on real stores and one invented domain, and re-measured after the not-found path was rewritten. The first two rows are the ones that keep this engine from lying to you.

Read `provenance` before you read anything else

Every response opens with a per-section status: matched, error, blocked, or unsupported, each naming the engine that produced it. That is how you distinguish 'this store has no Trustpilot presence' from 'the reputation probe failed'. Nothing else in the response makes that distinction, and the two mean opposite things to a scoring pipeline.

A domain with no storefront behind it is a not-found, not an empty success

An invented domain answers ok:false with NOT_FOUND and retryable false, saying the site did not answer and that no platform, catalogue or reputation record matched it. It used to answer 200 with a confidence of zero and — worse — a set of guessed policy URLs for a shop that does not exist; both are gone. Inside batch the same domain still comes back as its own row rather than failing the call, with confidence 0, presence marked not_found and an empty policy block carrying a written note that the storefront was never reached.

The reputation match is keyed on the domain, not on the name

On four real stores the reputation match came back typed as a domain match every time, with the matched domain echoed so you can check it. The invented domain returned found:false rather than a same-named stranger's review score. Name-keyed matching is how a review lookup lands on the wrong company, and this one does not do it.

The platform verdict is evidenced, and it declines to guess

A confirmed Shopify store returns 0.98 with evidence naming the store's own public catalogue endpoint as the proof. A custom-built store returns custom_or_unknown at 0.4 with a note saying no recognised platform was found, plus the technographic stack it did find — a web server, a JavaScript library, a CDN. Those are two different answers and the confidence tells them apart.

Catalogue depth is Shopify-only, and it says so instead of returning nothing

A store whose platform is not supported returns catalog.available false with a written reason — the depth is Shopify-only and there is no generic-storefront promise — rather than an empty product array that reads like an empty shop. A shop with a live catalogue returns products with a minimum and maximum price, an on-sale flag, a maximum discount percentage, a variant count and an availability flag on each.

Mode is a real depth control — but `size` is what was sampled, not what you get back

Basic mode sampled fifty products and returned twenty-five rows. Catalog mode with a hundred-item budget sampled a hundred and returned twenty-five rows, in about five seconds. The size and sampled figures describe the walk the price and discount statistics were computed over; the products array itself is capped at twenty-five either way. Read size for the statistics and has_more for whether you saw the shop — and use the dedicated storefront engine when you want the actual catalogue.

The currency is the store's own declaration

store_info carries the shop's declared currency, country, province and city as the storefront itself publishes them — not a guess from the top-level domain and not a conversion. On a brand running separate national storefronts this is how you find out which one you actually resolved to, because the returned domain is the storefront's, not the one you typed.

batch fails per store, never as a whole

A list including one domain that does not exist returned a result row for every domain, each carrying its own verdict and its own provenance, with the dead one scored at confidence 0 rather than dropped. There is no partial-failure mode where one bad domain costs you the rest, which is what makes it usable over a list you did not clean first — and it is the reason batch keeps a row where store_lookup answers NOT_FOUND.

What people build with Online Store Intelligence

The jobs this data is most often used for.

3

endpoints

2/8/20

credits per call

01

Pricing teams use Online Store Intelligence to get store domain → platform verdict + store metadata + tech-stack + catalog sample (price/discoun….

02

Marketplace operators use Online Store Intelligence to get store domain → ecommerce platform verdict (shopify|woocommerce|magento|bigcommerce|prestashop….

03

Catalog enrichment teams use Online Store Intelligence to look up to 5 stores in one call (basic mode, cache-first, per-store ok/error).

What Online Store Intelligence data costs

The cheapest call here is 2 credits, so $15/mo (Pro) buys 5,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 →
$0.67–$1.50 / 1,000 credits
  • 1,000 free credits on signup, no card
  • One key, all 184 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
curl -X POST https://api.reefapi.com/enrich-store/v1/store_lookup \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"store":"allbirds.com"}'
python
import requests

r = requests.post(
    "https://api.reefapi.com/enrich-store/v1/store_lookup",
    headers={"x-api-key": REEF_KEY},
    json={
  "store": "allbirds.com"
},
)
print(r.json()["data"])
FAQ

Have a question? We got answers.

The questions people actually ask before wiring up Online Store Intelligence.

Get a free key →
catalog_sample.size says 50 but products[] has 25 rows. Which is right?

Both. size and sampled report how many products were fetched and fed into the aggregates; products[] is truncated to 25. We confirmed it twice: a basic lookup reported size 50 with 25 rows and stock_signals {in_stock: 7, sampled: 50} while only 6 of the 25 returned rows were in stock, and a catalog-mode call with max_items 120 reported size 120 and still returned 25 rows. Read price_range, discount_ratio, in_stock_ratio and top_product_types as the answer over the full sample, and treat products[] as a preview.

Why did amazon.com come back as platform "unknown"?

Because this engine identifies the software a merchant runs their own storefront on, and a marketplace is not running one. A measured amazon.com lookup returned platform.name "unknown", confidence 0.0, ecommerce_confirmed false and evidence "tech_detect_unavailable", with the tech block still reporting server "CloudFront" and http_status 202. A confidence of 0.0 is the honest answer for any site whose platform could not be fingerprinted. For marketplace listings, call the marketplace engines directly.

What actually changes between a supported and a partial platform?

The catalog. Shopify came back supported true and partial false, and the catalog block carried a 50-product sample with a price range, discount ratio, stock ratio and vendor and product-type breakdowns. A measured WooCommerce store came back supported false and partial true, and its catalog block was {available: false, reason: "catalog depth is Shopify-only; this store is 'woocommerce' - platform detected, catalog not harvested (no generic-ecommerce promise)"}. Platform, tech stack, reputation and presence all still resolved on that store.

Trustpilot says found:true but trust_score is 0.0. Is the store rated zero?

No. A measured WooCommerce store returned trustpilot found true with a real business_unit_id and two categories, and trust_score 0.0, stars 0.0, reviews_count 0, which is a claimed profile with nothing on it. Always read reviews_count before reading the score. Zero reviews and a genuinely terrible rating produce the same numbers here, and only reviews_count separates them.

Why are trust_score and stars different numbers?

trust_score is Trustpilot's own weighted figure and stars is the rounded half-star it displays. Both Shopify stores we measured returned trust_score 3.4 with stars 3.5. Use trust_score when you are ranking or thresholding, and stars when you are showing a badge that has to match what a visitor sees on Trustpilot.

I asked about gymshark.com and store_info.domain says us.checkout.gymshark.com. Why?

Because store_info is what the Shopify store publishes about itself, and this brand's US store declares its checkout host. The same response returned myshopify_domain "gymsharkusa.myshopify.com", name "Gymshark US", country US, province Colorado and city Denver, while presence.store_url returned "https://gymshark.com". One response therefore carries two different store_url values. Key your own records on the domain you asked for, and read store_info.domain and myshopify_domain as facts about the store account rather than about the website you typed.

Can I trust the policy URLs?

Only on Shopify, and even there they are constructed rather than fetched. presence.policies_convention returns the same four paths under /policies/ (privacy-policy, terms-of-service, refund-policy, shipping-policy) and the response note states they are storefront conventions, not verified live. They used to be emitted for any domain at all, including stores on other platforms and domains that do not exist; they now appear only when a storefront was genuinely reached, and otherwise the block comes back empty with a note saying why. Re-measured: a Shopify store returns four, a custom-built store returns none, an invented domain returns none. Fetch them yourself before publishing them as links.

What does a domain that does not exist return?

A not-found, and it says which kind. store_lookup on a domain we made up returns ok:false with error.code NOT_FOUND and retryable false, saying the site did not answer and that no platform, catalogue or reputation record matched it — it used to answer 200 with a confidence of zero, which read like a real verdict. A string that is not a domain at all is a different refusal: "definitely not a domain" returns INVALID_PARAM in about 13 ms, before anything goes upstream. batch is the exception on purpose: it keeps a row for every domain you sent, scoring the dead one at confidence 0 with presence marked not_found, so one bad entry never costs you the rest of the list. No path returns a different real store.

What is the Online Store Intelligence API?

Online Store Intelligence API is a ReefAPI endpoint group for online store intelligence It returns live JSON through POST requests under /enrich-store/v1.

Is the Online Store Intelligence API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Online Store Intelligence calls use the same shared credit balance as every other ReefAPI engine.

Do I need an Online Store Intelligence login or account?

No login to Online Store Intelligence 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 Online Store Intelligence data?

The page example is captured from a live store_lookup call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Online Store Intelligence API use?

Online Store Intelligence actions currently cost 2-20 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

Can I call Online Store Intelligence from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call enrich-store actions with the same key, credit pool and JSON envelope used by normal REST requests.

35 E-commerce & Marketplaces APIs on the same key

One key, one credit pool, one response envelope. If you are pulling Online Store Intelligence, 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.

0/4000

No account needed · we reply from [email protected]

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 183 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-08-28.