curl --request GET \
--url https://api.syntalic.com/v1/marketing/retailer-assortmentimport requests
url = "https://api.syntalic.com/v1/marketing/retailer-assortment"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.syntalic.com/v1/marketing/retailer-assortment', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.syntalic.com/v1/marketing/retailer-assortment",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.syntalic.com/v1/marketing/retailer-assortment"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.syntalic.com/v1/marketing/retailer-assortment")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.syntalic.com/v1/marketing/retailer-assortment")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"brand": "<string>",
"category": "<string>",
"country": "<string>",
"currency": "<string>",
"retailers": [
{
"seller": "<string>",
"product_count": 123,
"avg_price_usd": 123,
"median_price_usd": 123
}
],
"coverage": {
"products": 42,
"sufficient": true,
"note": "<string>",
"unpublished_note": "<string>",
"sku_note": "<string>",
"rank_note": "<string>"
},
"freshness": {
"observedThrough": "2023-11-07T05:31:56Z",
"staleHours": 6.5
},
"quality": {},
"resolved": {
"input": "<string>",
"category_path": "<string>",
"department": "<string>",
"match_source": "<string>",
"match_confidence": 123,
"alternates": [
{}
]
},
"meta": {
"served_from": "<string>",
"freshness_seconds": 123,
"schema_version": "<string>",
"computed_at": "2023-11-07T05:31:56Z",
"price_observed_at_min": "2023-11-07T05:31:56Z",
"price_observed_at_max": "2023-11-07T05:31:56Z"
}
}{
"type": "<string>",
"title": "Bad Request",
"status": 400,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Payment Required",
"status": 402,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Not Found",
"status": 404,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Too Many Requests",
"status": 429,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Internal Server Error",
"status": 500,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}Find which retail chains carry a brand or category
Which retail CHAINS carry a brand or a category, ranked by how many distinct priced products each lists, with that chain’s average and median price. Answers ‘who stocks this brand’, ‘where can I find it’, and ‘which retailers carry the most of this category’. Grouped on the retailer chain, never on the scrape lane - a lane like ‘shopify’ spans hundreds of storefronts, so grouping by it would answer ‘which retailer’ with ‘shopify’. At least one of brand or category is required. Price statistics exclude rows the pipeline flagged as incoherent while the COUNTS keep them: a chain that genuinely carries the brand should not disappear because one of its prices is wrong. DISTINCT from share-of-shelf, which answers which BRANDS hold a category’s shelf.
curl --request GET \
--url https://api.syntalic.com/v1/marketing/retailer-assortmentimport requests
url = "https://api.syntalic.com/v1/marketing/retailer-assortment"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.syntalic.com/v1/marketing/retailer-assortment', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.syntalic.com/v1/marketing/retailer-assortment",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.syntalic.com/v1/marketing/retailer-assortment"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.syntalic.com/v1/marketing/retailer-assortment")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.syntalic.com/v1/marketing/retailer-assortment")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"brand": "<string>",
"category": "<string>",
"country": "<string>",
"currency": "<string>",
"retailers": [
{
"seller": "<string>",
"product_count": 123,
"avg_price_usd": 123,
"median_price_usd": 123
}
],
"coverage": {
"products": 42,
"sufficient": true,
"note": "<string>",
"unpublished_note": "<string>",
"sku_note": "<string>",
"rank_note": "<string>"
},
"freshness": {
"observedThrough": "2023-11-07T05:31:56Z",
"staleHours": 6.5
},
"quality": {},
"resolved": {
"input": "<string>",
"category_path": "<string>",
"department": "<string>",
"match_source": "<string>",
"match_confidence": 123,
"alternates": [
{}
]
},
"meta": {
"served_from": "<string>",
"freshness_seconds": 123,
"schema_version": "<string>",
"computed_at": "2023-11-07T05:31:56Z",
"price_observed_at_min": "2023-11-07T05:31:56Z",
"price_observed_at_max": "2023-11-07T05:31:56Z"
}
}{
"type": "<string>",
"title": "Bad Request",
"status": 400,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Payment Required",
"status": 402,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Not Found",
"status": 404,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Too Many Requests",
"status": 429,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}{
"type": "<string>",
"title": "Internal Server Error",
"status": 500,
"detail": "<string>",
"instance": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
}
}Query Parameters
Brand name (e.g., Sony, Samsung, Nike)
1Product category. Accepts a human-readable name (e.g. 'electronics', 'beauty') or a taxonomy slug path (e.g. 'electronics/headphones'); matched against the catalog's category tree (exact node, subtree, or path substring). Also accepts a GS1 GPC code (exactly 8 digits, e.g. '10001159') to filter by PRODUCT TYPE instead of by shelf placement — the same product type is shelved under different categories by different retailers, so a category filter answers from a fraction of the data while a GPC code spans them. Coarser codes (class/family/segment) match every brick beneath them. Resolve a phrase to a code with /v1/reference/classify?q=... ; when a code is used, resolved.match_source is 'gpc'.
1Country (us or ca)
us, ca Response
Retailer assortment
Show child attributes
Show child attributes
How much data backed this answer. sufficient is false when the slice is too thin to read as a market statement; the count is always reported so you can judge for yourself, and note explains an empty or thin result rather than leaving you to infer it.
Show child attributes
Show child attributes
How current the underlying observations are. observedThrough is the newest observation behind this answer; staleHours is its age. Both null when nothing was observed.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes

