Catalogue and stock feed
Goal: keep your copy of the RaviFurnitures catalogue (products, variants, prices) and stock up to date.
Permission: decide what you need first.
- Published products, prices and in-stock flags only: no key at all.
productsandproductare public, andinStockis public. - Stock counts, warehouses,
lowStockor unpublished products: one key withMANAGE_PRODUCTSonly. That permission can also change prices, delete products and adjust stock through unpublished operations, so guard the key.
Webhook events: PRODUCT_UPDATED and STOCK_LOW. Read what each one covers below before relying on it.
Queries: products, product, warehouses, lowStock.
Recommended sync pattern
Section titled “Recommended sync pattern”1. Sweep the catalogue on a schedule
Section titled “1. Sweep the catalogue on a schedule”Webhooks don’t cover every catalogue change, so a regular full sweep is the backbone of this integration. Page through products and upsert by slug:
query CatalogueSweep($after: String) { products(first: 50, after: $after) { edges { node { slug name status hsnCode gstRate mrp { paise } price { paise } variants { sku name mrp { paise } price { paise } inStock stocks { warehouseName available } } } } pageInfo { hasNextPage endCursor } }}This page costs 1,500 under the cost rules. Compare that with the maxCost a cost error reports, and adjust first if you add fields. Drop stocks if you have no key.
- A product missing from a complete sweep has been deleted or, in a sweep without a key, unpublished. Neither sends an event, and deletion is permanent.
- With
MANAGE_PRODUCTSthe sweep includes draft products. Checkstatusand list onlyPUBLISHEDones if that is what you sell. - Cursors mark positions, so a product added during the sweep can make one item appear twice. Upserting by
slughandles that.
2. Refresh a product on PRODUCT_UPDATED
Section titled “2. Refresh a product on PRODUCT_UPDATED”Fetch the product by the slug in the event and upsert it:
query ProductBySlug($slug: String!) { product(slug: $slug) { slug name status mrp { paise } price { paise } variants { sku name mrp { paise } price { paise } inStock } }}PRODUCT_UPDATED is sent every time staff save the product’s own details: name, description, brand, category, tax codes, product-level price and MRP, dimensions and similar fields. It is sent even when nothing changed. That edit can’t change the slug, so the slug is a safe key.
It is not sent when a product is created, published, unpublished or deleted, or for edits to variants (including a variant’s own price), media or stock. Your scheduled sweep picks those up.
3. Read stock
Section titled “3. Read stock”inStock(public) istruewhen warehouses that sell online hold unreserved stock.stocks(needsMANAGE_PRODUCTS) lists every warehouse holding the variant, including retailers’ floors and goods in transit, which are not for sale online.availableisquantityminusquantityReserved.- To tell warehouses apart, read
warehousesonce and matchstocks.warehouseNametoWarehouse.name. Warehouse names are unique.
query Warehouses { warehouses { name slug kind active sellableOnline city state }}Stock changes send no event, apart from the daily STOCK_LOW summary. Re-read stock as often as you need, within the cost limit.
4. Treat STOCK_LOW as an alert, not a feed
Section titled “4. Treat STOCK_LOW as an alert, not a feed”STOCK_LOW comes from a scan that runs once a day, at 07:00 IST by default (staff can change the schedule). It is sent only when something is low, and lists at most 50 rows, lowest stock first. Each row has a SKU, product name, available quantity and threshold, but no warehouse name. Only warehouses that sell online are scanned.
The lowStock query returns the full list of low rows, with warehouse name, quantities and threshold but no SKU, so it can’t be matched to products on its own.
Things to know
Section titled “Things to know”- A key that has been revoked doesn’t make
productsfail. It quietly drops drafts and returns emptystocks. Includewarehousesin each run so a bad key fails loudly (see Authentication). - Prices are whole paise in
paise.priceis the GST-inclusive selling price;mrpis the printed maximum retail price. onSale,salePriceanddiscountPercentreflect sales running now and change without any event.
See Webhook events for every field in each event.