Products API
All endpoints are under /api/v1/{platform}/, where platform is shopify, bigcommerce or woocommerce. Authenticate with an API key or a dashboard session — see Authentication.
List products
GET /api/v1/shopify/products?limit=50&offset=0&storeId=...
Authorization: Bearer sk_live_...
limit defaults to 20 (max 5000). storeId scopes the list to one store.
Response:
{
"products": [
{
"id": "...",
"title": "...",
"vendor": "...",
"price": 29.99,
"currency": "EUR",
"identity": "...",
"enrichment_status": "enriched",
"manually_edited": false,
"last_enriched_at": "2026-04-14T...",
"url": "/api/v1/shopify/products/...",
"llm_url": "/api/v1/shopify/products/....llm"
}
],
"total": 281,
"pagination": { "limit": 50, "offset": 0, "count": 50, "total": 281, "has_more": true }
}
On BigCommerce, each row also carries jsonld_url and meta_url.
Get one product (full semantic payload)
GET /api/v1/shopify/products/:id
Returns the full SemanticProduct with core_identity, reasoning, synthetic_properties, technical_details, metadata. Send Accept: text/markdown to get the Markdown version instead.
LLM-optimized variant
GET /api/v1/shopify/products/:id.llm
Returns a condensed JSON tuned for LLM consumption — identity, reasoning, quality_scores, pricing, market_context, plus a pre-computed summary_for_ai string.
JSON-LD
GET /api/v1/shopify/products/:id.jsonld
Returns application/ld+json: the schema.org @graph for the product, the same graph Clione publishes on the storefront. The X-Schema-Nodes response header lists the @type of every node in it.
Markdown (text/markdown)
GET /api/v1/shopify/products/:id.md
Returns text/markdown; charset=utf-8 with a structured Markdown document: title, core identity, product details, quality scores, buying guide, market context, search keywords and images.
SEO meta signals
GET /api/v1/shopify/products/:id.meta
Returns meta_title, meta_description in three lengths (seo ≤160 chars, extended ≤300, full unlimited), canonical, keywords, og (Open Graph and Twitter Card fields) and a links object pointing to the other formats (jsonld, llm, md, self). The canonical URL is also sent as a Link header.
Signal endpoints for every entity type
Every entity type exposes the same four signal formats at the same suffixes. Only the base path changes, and the fields inside each format differ per entity type.
Base paths
| Platform | Entity | Base path |
|---|---|---|
| Shopify | Products | /api/v1/shopify/products |
| Shopify | Collections | /api/v1/shopify/collections |
| Shopify | Pages | /api/v1/shopify/pages |
| BigCommerce | Products | /api/v1/bigcommerce/products |
| BigCommerce | Categories | /api/v1/bigcommerce/categories |
| BigCommerce | Pages | /api/v1/bigcommerce/pages |
| WooCommerce | Products | /api/v1/woocommerce/products |
| WooCommerce | Categories | /api/v1/woocommerce/categories |
| WooCommerce | Pages | /api/v1/woocommerce/pages |
Signal formats
| Suffix | Content-Type | Description |
|---|---|---|
/:id.jsonld | application/ld+json | Schema.org JSON-LD @graph for the entity. |
/:id.llm | application/json | LLM-optimized representation: identity, context, keywords, enrichment data. |
/:id.md | text/markdown; charset=utf-8 | Structured Markdown for LLM crawlers. |
/:id.meta | application/json | Meta title, description, keywords, Open Graph, plus links to the other formats. |
:id is the entity's Clione id, as returned by the list endpoints.
Examples
# Collection JSON-LD (Shopify)
GET /api/v1/shopify/collections/:id.jsonld
# Category Markdown (BigCommerce)
GET /api/v1/bigcommerce/categories/:id.md
# Page meta signals
GET /api/v1/shopify/pages/:id.meta
GET /api/v1/woocommerce/pages/:id.meta
.meta response shape (categories, collections, pages)
{
"collection_id": "...",
"meta_title": "Summer 2026 | Store Name",
"meta_description": "AI-enriched description...",
"keywords": ["summer", "collection", "2026"],
"og": {
"og_title": "...",
"og_description": "...",
"og_type": "website",
"og_image": { "url": "...", "alt": "..." },
"og_url": "...",
"og_site_name": "...",
"twitter_card": "...",
"twitter_title": "...",
"twitter_description": "...",
"twitter_image": "..."
},
"links": {
"jsonld": "/api/v1/shopify/collections/<id>.jsonld",
"llm": "/api/v1/shopify/collections/<id>.llm",
"md": "/api/v1/shopify/collections/<id>.md",
"self": "/api/v1/shopify/collections/<id>"
}
}
The id key follows the entity type: category_id, collection_id or page_id.
Re-enrich a single product
POST /api/v1/shopify/enrich/:id
Authorization: Bearer <JWT>
Content-Type: application/json
{
"hints": {
"target_audience": "...",
"material_composition": "..."
}
}
Hints are optional; they're the same fields the Enrichment Wizard collects. If the enrichment takes longer than the request deadline, the API answers 202 with a jobId; poll GET /api/v1/shopify/enrich/jobs/:jobId for the result.
Bulk re-enrich
POST /api/v1/shopify/enrich/all?pending=true&storeId=<storeId>
pending=true only re-enriches products flagged as pending; failed=true only those whose last enrichment failed. Without either, it re-enriches every product in the store — the dashboard asks for one confirmation showing the credit cost before doing this.
Versions + rollback
GET /api/v1/shopify/enrich/:id/versions → list past versions
POST /api/v1/shopify/enrich/:id/rollback?version=N → restore version N
The rollback itself creates a new version snapshot, so it's reversible.
Update a product's enrichment manually
PATCH /api/v1/shopify/products/:id # also on /bigcommerce/ and /woocommerce/
{
"core_identity": "...",
"reasoning": { ... },
"synthetic_properties": {
"durability_score": 8,
"competitors_owner_provided": [
{ "brand": "Nike", "model": "Air Max 90", "ref_price": "€120", "notes": "direct competitor" }
]
}
}
Whitelisted top-level fields: core_identity, reasoning, synthetic_properties, seo_overrides. Flags the product with:
metadata.manually_edited = true— future re-enrichments show an overwrite two-step confirm in the dashboardmetadata.competitors_source = 'owner'— only whensynthetic_properties.competitors_owner_providedis a non-empty array, so re-enrichment won't regenerate the competitors list.
Update category / collection metadata
PATCH /api/v1/shopify/collections/:id # Shopify → "collections"
PATCH /api/v1/bigcommerce/categories/:id # BigCommerce → "categories"
Whitelisted fields:
{
"name": "...",
"description": "...",
"slug": "...",
"imageUrl": "https://...",
"metaTitle": "...",
"metaDescription": "...",
"seo_overrides": { ... },
"buyerIntents": [ ... ]
}
Tenant-scoped — the request's tenant must own the entity or the endpoint returns 404. Empty string values are coerced to null. The response is { "data": <updated row> }.
Verify storefront — per-product diff
GET /api/v1/shopify/diff/:id?store_url=https://yourstore.com
Fetches your live storefront and compares every signal Clione propagated (for example meta_description, meta_title, jsonld, faq_jsonld, og_tags, canonical, meta_keywords) against what the HTML contains right now.
Per-signal statuses: identical | different | missing_in_storefront | never_propagated | propagation_failed | parse_error | unverifiable (the storefront could not be fetched).
The response includes a summary (match_rate excludes never_propagated), a per-signal diff and, for JSON-LD, a structural breakdown of added/removed/changed keys.
Verify storefront — batch
GET /api/v1/shopify/diff?store_url=https://yourstore.com&product_ids=id1,id2,id3
Same contract as /diff/:id, across several products. Aggregates totals and returns per-product results under results[]. One slow product won't fail the batch — failures come back as { entity_id, error, summary: null }.