Get store configuration
Get store settings used by the storefront (theme, locale, branding).
query Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
theme^(?=.{1,64}$)[a-z][a…The requesting theme's key (defineTheme({ key })). Its text edits ride along as contentOverrides; without it there are none.
The requesting theme's key (defineTheme({ key })). Its text edits ride along as contentOverrides; without it there are none.
Get store configuration › Responses
Store configuration
successGet a menu
A navigation menu by handle, as a shopper sees it: labels in the requested language (?locale=, else the store's primary), each item's href a path of the store without a language prefix (or the merchant's URL). An item whose destination is deleted or not public is left out with its children. An unknown handle is a 404: the theme then renders its own fallback.
path Parameters
handle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the menu
Lowercase letters, digits and hyphens; how a theme names the menu
query Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
Get a menu › Responses
The menu
successGet a collection
A collection's title and description for its page (/collections/:handle), in the requested language (?locale=, else the store's primary). Its products come from /store/products?collection=. An unknown handle is a 404: the theme answers a real 404 page.
path Parameters
handle^[a-z0-9][a-z0-9-]{0… · requiredLowercase letters, digits and hyphens; how a theme names the collection
Lowercase letters, digits and hyphens; how a theme names the collection
query Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
Get a collection › Responses
The collection
successList store products
Get the public product catalog for the storefront. Only returns products where status=ACTIVE, showInStore=true and visibility=true.
query Parameters
collection^[a-z0-9][a-z0-9-]{0…Only this collection's products (by handle), in the merchant's order. An unknown handle lists nothing.
Only this collection's products (by handle), in the merchant's order. An unknown handle lists nothing.
onSaleWhen true, only products priced below their compare-at price.
When true, only products priced below their compare-at price.
categoryIdFilter by category ID.
Filter by category ID.
sortThe order: newest, price-ascending or price-descending. Absent: a collection's own order, a search's best match first, else newest.
The order: newest, price-ascending or price-descending. Absent: a collection's own order, a search's best match first, else newest.
limitMaximum number of products to return. Server cap: 100.
Maximum number of products to return. Server cap: 100.
offsetProducts to skip, for paging through the whole catalog (e.g. a sitemap).
Products to skip, for paging through the whole catalog (e.g. a sitemap).
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
List store products › Responses
List of products
successcountNumber of items in data
totalNumber of products in the whole listing, across its pages
Search store products
The products a shopper's words find, with the list endpoint's gates, filters, paging and sort; without a sort, products whose name holds every word come first. Its own path, so a server without search answers 404 rather than the whole catalog.
query Parameters
qWhat the shopper typed. Every word must be in the product's name — the catalog's or the requested language's — or its tags; case is ignored for Latin letters.
What the shopper typed. Every word must be in the product's name — the catalog's or the requested language's — or its tags; case is ignored for Latin letters.
collection^[a-z0-9][a-z0-9-]{0…Only this collection's products (by handle), in the merchant's order. An unknown handle lists nothing.
Only this collection's products (by handle), in the merchant's order. An unknown handle lists nothing.
onSaleWhen true, only products priced below their compare-at price.
When true, only products priced below their compare-at price.
categoryIdFilter by category ID.
Filter by category ID.
sortThe order: newest, price-ascending or price-descending. Absent: a collection's own order, a search's best match first, else newest.
The order: newest, price-ascending or price-descending. Absent: a collection's own order, a search's best match first, else newest.
limitMaximum number of products to return. Server cap: 100.
Maximum number of products to return. Server cap: 100.
offsetProducts to skip, for paging through the whole catalog (e.g. a sitemap).
Products to skip, for paging through the whole catalog (e.g. a sitemap).
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
Search store products › Responses
The products found
successcountNumber of items in data
totalNumber of products in the whole listing, across its pages
Get store product
Get a single product by its URL handle. Same visibility filters as the list endpoint. Returns parsed variantOptions, tags, joined category, active variants, all images, and offers — the active Buy X Get Y promotions currently applicable to this product.
path Parameters
handlequery Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
Get store product › Responses
Product details
successGet published landing page
Get a published landing page by its public slug: the ordered image stack, spacing settings, the linked product in its full store-product shape (variants, offers, inventory) in the requested language (?locale=), so the storefront order form works unmodified, and the page's own document for the requesting ?theme=. Store-hidden products (showInStore=false) still render here — the landing page is their sales channel; the catalog list and the product's own page stay hidden. Draft/archived/unknown slugs return 404; with ?preview=1 a draft answers too. Each successful GET increments the page's view counter (non-unique in v1), except a preview.
path Parameters
slugquery Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
theme^(?=.{1,64}$)[a-z][a…The requesting theme's key (defineTheme({ key })): the page's own document for that theme comes with it.
The requesting theme's key (defineTheme({ key })): the page's own document for that theme comes with it.
preview1 for an editor's preview: a draft page answers too, and no visit is counted. Never sent for a shopper's page.
1 for an editor's preview: a draft page answers too, and no visit is counted. Never sent for a shopper's page.
Get published landing page › Responses
Published landing page with its product
successGet a published store page
Get a Terms/Privacy/Refund/Shipping/custom page by its public slug, in the requested language (?locale=, else the store's primary). Falls back to the primary, then to whichever locale exists, only when the requested language has no translation for this page; the actual locale served is in the response's locale field. Draft or unknown slugs return 404 — never a soft 200 with empty content.
path Parameters
slugquery Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
Get a published store page › Responses
The resolved page, already-sanitised HTML — render with set:html, never re-sanitise
successGet the store's saved page document
The store's saved composition for one theme and surface (a page such as home or product, an area such as area:header, or one landing page's lp:<id>), written by Wocart Cloud's editor and read verbatim. data is null when the store has never saved one, or when the saved row is not a document for this surface: the theme then renders its own default. A store that has none is a normal answer, so it is a 200, not a 404.
path Parameters
surface^[a-z0-9][a-z0-9._:-… · requiredquery Parameters
theme^(?=.{1,64}$)[a-z][a…The requesting theme's key (defineTheme({ key })): its document for the surface. Without it, the most recently saved document for the surface, whichever theme wrote it.
The requesting theme's key (defineTheme({ key })): its document for the surface. Without it, the most recently saved document for the surface, whichever theme wrote it.
Get the store's saved page document › Responses
The saved document, or null when there is none
successThis page's own composition (its lp:<id> page document) for the requesting theme, written by Wocart Cloud's editor; null when it has none or no theme is named — the theme then renders its landing default.
Get an order's tracking destination
Which Meta pixel this order belongs to, and which browser event the thank-you page should fire for it.
The thank-you page cannot work this out for itself: it knows the order id and nothing about which landing page the shopper came from, and landing-page attribution is best-effort — an unknown, draft or archived slug leaves the order unattributed. A browser deciding independently would fire at a pixel the Conversions API never mirrors to, and Meta deduplicates per pixel, so that produces two conversions in two ad accounts instead of one.
Returns the decision, not the configuration. event is null when no browser event should fire — either tracking is off, or the merchant's conversion fires further down the funnel (phone confirmation, delivery) from the server only.
Deliberately narrow: nothing about the order itself is returned, and never an access token.
path Parameters
idOrder UUID
Order UUID
Get an order's tracking destination › Responses
The order's tracking destination
successFind where a shopper's order is
The order's number and the phone it was placed with prove it is the shopper's, as for a review; a wrong number and a wrong phone both answer 404 ORDER_NOT_FOUND. Attempts are limited per order and per shopper (ORDER_LOOKUP_RATE_LIMITED, with windowSeconds). The answer is what a shopper may know — the step it is at, its lines and total, and the carrier's tracking number once shipped — never the address, the notes or the merchant's own statuses. A POST, so the phone never sits in a URL or a log.
Find where a shopper's order is › Request Body
orderNumber^ORD-\d{8}-\d+$/i · requiredThe customer-facing order number, as on the thank-you page and the SMS
phoneThe phone the order was placed with, however it is typed
Find where a shopper's order is › Responses
The order's status
successList store categories
Get product categories ordered by position.
query Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
List store categories › Responses
List of categories
successcountNumber of items in data
List communes for a wilaya
Get all communes for a given wilaya. Use the returned id as communeId when submitting an order.
path Parameters
wilayaIdWilaya number (1–58).
Wilaya number (1–58).
List communes for a wilaya › Responses
List of communes for the wilaya
successcountNumber of items in data
Create store order
Submit a customer order from the public storefront. Finds or creates the customer by phone number.
Basket (items): send items to order several products in one go — up to 20 distinct lines, each up to 100 units. Lines with the same product AND variant are merged and their quantities summed. When items is absent the flat productId/quantity fields are used, so existing integrations are unaffected.
Pricing is server-authoritative. pricePerUnit is accepted for UI continuity and never trusted; every line is priced from the catalog row.
All or nothing. If any line cannot be satisfied — insufficient stock, missing SKU — the whole order is refused and nothing is written.
Delivery fee is resolved per basket: a product's own shipping profile overrides the store default, a commune-level override beats the wilaya rule, and a basket spanning two profiles pays the highest applicable rate. Delivery is refused (not silently free) when any product cannot be shipped to the destination.
Offer selection: send offerId to explicitly select the tier the customer chose. It is honoured only if it independently qualifies — reached, and able to give its benefit; otherwise the server picks the highest threshold that qualifies. Trigger quantity counts a product across all its lines, so two variants of one shirt are two shirts.
Buy X Get Y (discountType: "free"): the reward product is appended as a $0 line item. A reward the stock cannot cover makes its offer not qualify: the product falls to its next offer and the order still succeeds. Reward lines never trigger further offers.
Coupon (couponCode): applied after offers, to the paid lines in its scope that no offer applied to; its discount is shared across those lines, so price is net of it, and a free-delivery coupon makes deliveryFee 0. A code that does not apply refuses the whole order with COUPON_NOT_APPLICABLE (reason, with shortBy or startsAt when there is one) — the order is never placed without it. Its uses are counted by the database as the order is inserted, so two orders cannot take the last one.
Free Shipping (discountType: "free_shipping"): the delivery fee is overridden to 0 — reflected in both deliveryFee and total. This applies only when the basket holds a single distinct product; in a multi-product basket free delivery is earned by the store's basket threshold instead, so one cheap promotional item cannot ship an expensive basket for free.
One checkout, one order (checkoutKey): a UUID the shopper's browser stamps on the checkout attempt. Sent again — a double click, a resubmitted form, a retried request — it answers with the order already placed, as it answered the first time, without placing another; for another phone it is refused with CHECKOUT_KEY_IN_USE. Without it, every request places an order.
Multi-unit variant orders: when different variants are selected per unit, send variantSelections — one entry per unit. Identical variants are grouped into a single line and inventory deducts per-variant.
query Parameters
localeThe language the shopper checked out in (BCP 47, e.g. fr): recorded on the order, and the language its customer messages are written in, when the store publishes it; the primary language otherwise. The Content-Language response header names the one recorded.
The language the shopper checked out in (BCP 47, e.g. fr): recorded on the order, and the language its customer messages are written in, when the store publishes it; the primary language otherwise. The Content-Language response header names the one recorded.
Create store order › Request Body
customerNamephone^0[567]\d{8}$ · requiredwilayaIdcommuneIdproductIdproductNamevariantIdvariantLabelquantityofferIdaddressdeliveryTypepricePerUnitnotesemailfbcfbpotpTokenturnstileTokenlandingPageSlugcouponCodecheckoutKeyCreate store order › Responses
Order created
successRe-price and check a basket — the quote of an order
Read-only. Returns what the catalog says about a basket right now, so the cart can show the truth before the shopper commits. Nothing is written and no stock is reserved.
The body names what is being ordered in the order's own fields: a basket (items[]), or one product — productId, productName, quantity, optionally variantId, a variant per unit (variantSelections) and an offer tier (offerId). A product page asks with exactly what its form will post, and the lines are built the same way the order builds them.
Every line comes back with its CURRENT catalog price, the units still available (maxQuantity, null when the product is not stock-tracked), and a blocker when it cannot be ordered as requested:
missing: the product no longer existsunlisted: it is no longer on sale (draft, hidden or removed)out_of_stock: fewer units are available than requested
Blocked lines are excluded from subtotal, from offer evaluation and from the free-delivery calculation, so the basket never promises something checkout would refuse.
freeDelivery is subtotal-based and therefore answerable before the shopper types an address: use remaining for a "spend X more" prompt.
Send destination (wilayaId, optional communeId, deliveryType) and the answer carries delivery: the fee and the total the order would charge there, from the same quote the order itself uses — product shipping profiles, commune overrides, the free-delivery threshold and free-shipping offers included. available: false (fee and total null) means the store does not deliver there, and an order to it is refused with DELIVERY_NOT_AVAILABLE. Without destination, there is no delivery field.
Send couponCode and the answer carries coupon: applied (with the discount taken off the lines, each line's share in its discount, and whether it makes delivery free) or refused with the reason the order would be refused for. Send phone once the shopper has typed it, so a coupon for selected customers, or one use per customer, is judged before the order. Without couponCode, coupon is null.
Product names and variant labels come from the catalog, in the language ?locale= asks for (the store's primary when it does not publish that language), announced in Content-Language. The order itself records the catalog's names in the store's primary language.
query Parameters
localeThe language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
The language to serve merchant text in (BCP 47, e.g. fr). Served when the store publishes it, the primary language otherwise; the Content-Language response header names the one served. Untranslated fields fall back to the primary one by one.
Re-price and check a basket — the quote of an order › Request Body
productIdproductNamevariantIdvariantLabelquantityofferIdpricePerUnitcouponCodephoneRe-price and check a basket — the quote of an order › Responses
Basket priced and checked against the live catalog
successList a product's approved reviews
A product's approved reviews, newest first, with their photos and voice note. Empty when the store turned reviews off.
query Parameters
productIdProduct ID to fetch reviews for.
Product ID to fetch reviews for.
limitoffsetList a product's approved reviews › Responses
One page of approved reviews
successcounttotalApproved reviews of this product
Submit a review
Proves the purchase again, records the review and answers at once. Its photos and voice note are prepared afterwards (resized, location data removed); visibility says whether it is public now or after the store checks it — the store's choice.
One review per product of an order (409 ORDER_ALREADY_REVIEWED). Without phone (storefronts on @wocart/storefront 1.5) a review is text only, still for a delivered order — deprecated.
Submit a review › Request Body
orderNumber^ORD-\d{8}-\d+$/i · requiredThe customer-facing order number, as on the thank-you page and the SMS
productIdratingphoneThe phone the order was placed with. Storefronts on @wocart/storefront 1.5 send none: their reviews are text only, still for a delivered order. Deprecated without it.
titlebodyAt least 10 characters, unless a voice note says it
grantThe upload grant from /store/reviews/eligibility, when files are sent
uploadsUpload IDs from /store/reviews/uploads
Submit a review › Responses
Review received
successFind an order to review
Proves the purchase with the order number and the phone it was placed with, and answers what can be reviewed: the order's products the shopper kept (each once), and — when the store takes photos or a voice note — what may be attached and an upload grant for PUT /store/reviews/uploads (30 minutes).
A wrong number and a wrong phone both answer 404 ORDER_NOT_FOUND. An order not delivered yet answers 422 REVIEW_ORDER_NOT_DELIVERED. Attempts are limited per order number (422 REVIEW_RATE_LIMITED). Turnstile is not asked here: it guards checkout.
Find an order to review › Request Body
orderNumber^ORD-\d{8}-\d+$/i · requiredThe customer-facing order number, as on the thank-you page and the SMS
phoneThe phone the order was placed with, however it is typed
turnstileTokenIgnored: Turnstile guards checkout, not reviews — the order number and phone are the proof, and attempts are limited per order
Find an order to review › Responses
The order can be reviewed
successSend a review photo or voice note
The file itself as the request body, with the grant from /store/reviews/eligibility in the X-Review-Grant header (and, for a voice note, its length as the recorder reported it in X-Media-Duration-Ms — shown only when the file does not say). Send each file as soon as it is picked; submit the review with the returned uploadIds.
Its kind is read from the file's bytes: a photo (JPEG, PNG, WebP, GIF — shrink it in the browser first, 8 MB at most) or a voice note (WebM, Ogg, M4A, MP3 — as long as the store allows).
Send a review photo or voice note › Responses
Received; kept until the review is submitted (a day at most)
success