Product detail with independently degrading blocks
Returns everything about one product in independent blocks: a metrics summary compared with the previous period, GA4 funnel, entry cohort, products bought together (pairs in associations and sets of 3 to 5 in boughtTogether), monthly retention, purchase frequency, what was bought next, coupons and acquisition channels.
- Each block has its own
stateandreason: if a source fails or has no data, only that block is affected and the response is still200. 404means the product does not exist in that store;400means a parameter is invalid.- Not every block uses
dateFrom/dateTo: each block'speriodAppliedandwindowsay which period was measured.
ClientIdAuthClientSecretAuthx-client-id<token>Client ID
x-client-secret<token>Client secret
productId*stringParent product id, in the shape its platform publishes: a VTEX identifier (1234567) or a Shopify GID (gid://shopify/Product/10417518674198), which carries slashes and must be percent-encoded in the path. The value is the same productId the listing returned, forwarded opaquely. A product absent from the catalog but present in sales or in the entry cohort is still addressable.
^[A-Za-z0-9._~+@:/-]{1,256}$length <= 256organizationId*stringuuidintegrationId*stringStore identifier: the sourceIntegrationId returned by GET /v1/products/integrations. Do not use the VTEX App Key.
uuiddateFrom?stringDetail period (YYYY-MM-DD; default: the last 30 days up to today). Followed by the summary, funnel, purchase frequency, coupons and channels blocks. Retention uses the months the period touches; cohort, bought together and bought after use their own windows, reported in periodApplied and window.
datedateTo?stringDetail period (YYYY-MM-DD; default: the last 30 days up to today). Followed by the summary, funnel, purchase frequency, coupons and channels blocks. Retention uses the months the period touches; cohort, bought together and bought after use their own windows, reported in periodApplied and window.
datecohortView?stringRetention view of the cohort block: by customers (logo) or by net revenue (revenue). Both are always computed; the parameter only records the chosen view.
"logo""logo""revenue"groupBy?stringGroups the cohort's entry months by month, quarter or semester. The axis of months after entry stays monthly.
"month""month""quarter""semester"cohortWindowMonths?integerHow many entry months the cohort grid shows, counting back from the product's most recent entry month. Does not follow dateFrom/dateTo.
63612combinationSize?integerSize of the product combination analyzed. 2 (pairs) is answered by the associations block, which carries confidence, lift, margin and customers; in that case boughtTogether returns state: not_applicable. From 3 to 5, boughtTogether answers, and associations keeps showing pairs.
22345minOrders?integerMinimum orders in common for a pair (associations) or set (boughtTogether) to be listed. If combinations exist but none reaches the minimum, the block answers thresholded — different from no_base, when there is no combination at all. For sets of 3 to 5 the source also has its own minimum, which cannot be lowered: asking for less returns the reason below_source_support_floor.
1 <= value <= 10005boughtAfterWindow?integer"Bought within N days": the most days between the order with this product and the next order for it to count in boughtAfter. Not a period filter.
30306090180boughtAfterMinCustomers?integerMinimum distinct customers for a next product to be listed in boughtAfter.
1 <= value <= 10005Product detail. Always 200 when the product exists for the organization and store, whatever the state of each block: read each block from its own state. Each block's data can take up to 5 minutes to reflect updates; a block with state: 'error' is not reused, so a new call tries to fetch it again. If every source fails, every block reports error and the response is still 200 — do not monitor availability by HTTP status alone.
application/json- response
Detail composed of independent blocks. There is no response-level success flag: read each block from its own state.
identity*Product identity, taken from the catalog — or from sales and the entry cohort, for a product that left the catalog but was sold. It has a state of its own: an unknown product returns 404, but if the catalog cannot be read, the other blocks still answer and every catalog field is null.
period*Resolved reporting period of the summary block.
asOf*|Oldest update timestamp among the blocks that returned data (null when none did): the page is only as fresh as its least fresh number. Each block has its own asOf, which is the one to show next to its numbers.
date-timesummary*funnel*cohort*Entry-cohort grid of the product. Does not follow dateFrom/dateTo: it shows the product's last cohortWindowMonths entry months, so a short period does not hide mature cohorts. window reports the entry months actually measured.
associations*boughtTogether*Sets of 3 to 5 products bought together with this one. Pairs (size 2) are answered by the associations block, which carries pair-specific metrics; with combinationSize: 2, this block returns state: not_applicable.
This block has no window: it uses the same 12-month window as associations, so associations.window applies here too.
retention*Monthly retention of the product.
The source works with whole calendar months, so the block answers for the months the requested period touches — periodApplied is {basis: "requested", granularity: "month"}. window reports the months that actually returned data.
purchaseFrequency*Distribution of how many times each identified customer bought this product over the requested days — not a monthly average and not the source own window.
Read at order grain on purpose. The monthly series in retention cannot answer this: a customer who bought in July and again in August belongs to the 2 bucket of a period covering both, and summing the monthly rows would count them twice under 1.
Anonymous orders carry no identity to count, so they are outside every bucket and outside the denominator. They are published beside it instead of being dropped, and identityCoverage is what says whether an empty distribution is a product nobody bought or a store checking out anonymously.
boughtAfter*What customers bought in the order that followed their order with this product.
Ignores dateFrom/dateTo: it uses customers' orders over the last 12 months, the same window as the basket blocks. periodApplied reports that basis. Like boughtTogether, it has no window.
coupons*Coupons of the product: paid orders that used a coupon and contained the product, over the requested period (periodApplied is requested/day).
What the discount is not. discountScope: order means the discount figures belong to the whole ORDER: an order can carry a coupon, a promotion and a shipping discount at once, and VTEX does not split the total among them. So discountRate and averageDiscountPerOrder describe the orders that used a coupon — never the discount the coupon caused — and must not be shown as the product's discount.
discountRate is weighted by value (sum of discounts ÷ sum of order gross values), not an average of percentages.
Item-level coverage. itemLevelTagCoverage is the share of coupon orders whose items carry promotion details. It is low for older orders, because those details have only been collected recently; that is why it is reported as coverage, never as a discount.
acquisitionChannels*Acquisition channels of the product: which channels brought the orders that contained it, separating paid from organic media, over the requested period (periodApplied is requested/day).
The channel is the order's last-click channel, under the same attribution definition used across V4MOS.AI. An order may have no identified channel: it is then not counted as Orgânico (organic) but reported in channelCoverage.
This version has no campaign breakdown and no media spend.
curl -X GET "https://example.com/v1/products/string?organizationId=497f6eca-6276-4993-bfeb-53cbbbba6f08&integrationId=497f6eca-6276-4993-bfeb-53cbbbba6f08"{ "identity": { "state": "ready", "reason": null, "integrationId": "3f8a5c62-1d47-4e6b-9a10-5b2c7d8e9f01", "productId": "12345", "productName": "Tênis Runner Pro", "categoryId": "12", "categoryName": "Tênis", "categoryPath": [ { "id": "1", "name": "Esportes" }, { "id": "12", "name": "Tênis" } ], "status": "active", "skuCount": 4, "inventoryState": "monitored", "inventoryFreshness": "fresh", "inventoryUpdatedAt": "2026-08-18T06:12:00.000Z", "firstSaleDate": "2025-11-03", "lastSaleDate": "2026-08-17", "asOf": "2026-08-18T06:12:00.000Z", "imageUrl": null, "sourceImageUrl": null, "imageStatus": "no_source" }, "period": { "from": "2026-07-01", "to": "2026-07-31" }, "asOf": "2026-08-18T05:40:00.000Z", "summary": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "periodApplied": { "basis": "requested", "granularity": "day" }, "data": { "grossSales": 184320.5, "netSales": 171004.2, "grossUnits": 612, "netUnits": 568, "averageTicket": 344.77, "marginAverage": 0.38, "marginTotal": 64981.6, "newCustomers": 402, "recurringCustomers": 94, "ltv180": 512.4, "repurchaseRate180": 0.21, "ltvToDate": 288.6, "repurchaseRateToDate": 0.14, "cohortElapsedDaysAverage": 96.4, "availableStock": 1240, "velocity30d": 18.9, "daysOfStock": 65.6, "returnRate": 0.072 }, "coverage": { "grossValue": 1, "cost": 1, "inventory": 1, "matureCohort": 1 }, "ndReasons": { "averageTicket": null, "margin": null, "averageMargin": null, "daysOfStock": null, "ltv180": null, "repurchaseRate180": null, "returnRate": null }, "previous": { "state": "ready", "reason": null, "window": { "from": "2026-05-31", "to": "2026-06-30" }, "availableWindow": { "from": "2025-11-03", "to": "2026-08-17" }, "data": { "grossSales": 147456.4, "netSales": 136803.36, "grossUnits": 490, "netUnits": 454, "averageTicket": 275.82, "marginAverage": 0.3, "marginTotal": 51985.28, "newCustomers": 322, "recurringCustomers": 75, "ltv180": 409.92, "repurchaseRate180": 0.17, "returnRate": 0.06 }, "coverage": { "grossValue": 1, "cost": 1, "inventory": null, "matureCohort": 1 }, "ndReasons": { "averageTicket": null, "margin": null, "averageMargin": null, "daysOfStock": null, "ltv180": null, "repurchaseRate180": null, "returnRate": null } }, "variation": { "grossSales": 25, "netSales": 25, "grossUnits": 24.9, "netUnits": 25.11, "averageTicket": 25, "marginAverage": 26.67, "marginTotal": 25, "newCustomers": 24.84, "recurringCustomers": 25.33, "ltv180": 25, "repurchaseRate180": 23.53, "returnRate": 20, "availableStock": null, "daysOfStock": null }, "returnMeasurement": { "basis": "floor", "reason": "late_returns_not_rescanned", "underestimated": [ "returnRate" ], "overestimated": [ "netSales", "netUnits", "averageTicket", "marginTotal", "marginAverage" ], "observedReturnRows": 341 } }, "funnel": { "state": "ready", "reason": null, "asOf": "2026-08-18T05:40:00.000Z", "periodApplied": { "basis": "requested", "granularity": "day" }, "window": { "from": "2026-07-01", "to": "2026-07-31" }, "steps": [ { "stageIndex": 1, "stageKey": "exposure", "stageSource": "MEDIA", "volume": null, "volumeUnit": null, "previousVolume": null, "stepRate": null, "abandonments": null, "sequenceClosed": null, "stageReason": "not_attributable_to_product" }, { "stageIndex": 2, "stageKey": "attention", "stageSource": "GA4", "volume": 18000, "volumeUnit": "items", "previousVolume": null, "stepRate": null, "abandonments": null, "sequenceClosed": false, "stageReason": "no_comparable_previous_stage" }, { "stageIndex": 3, "stageKey": "interest", "stageSource": "GA4", "volume": 2700, "volumeUnit": "items", "previousVolume": 18000, "stepRate": 0.15, "abandonments": 15300, "sequenceClosed": false, "stageReason": "aggregated_sequence_only" }, { "stageIndex": 4, "stageKey": "qualification", "stageSource": "GA4", "volume": 1080, "volumeUnit": "items", "previousVolume": 2700, "stepRate": 0.4, "abandonments": 1620, "sequenceClosed": false, "stageReason": "aggregated_sequence_only" }, { "stageIndex": 5, "stageKey": "commitment", "stageSource": "VTEX", "volume": 540, "volumeUnit": "orders", "previousVolume": 1080, "stepRate": null, "abandonments": null, "sequenceClosed": false, "stageReason": "cross_source" }, { "stageIndex": 6, "stageKey": "decision", "stageSource": "VTEX", "volume": 486, "volumeUnit": "orders", "previousVolume": 540, "stepRate": 0.9, "abandonments": 54, "sequenceClosed": true, "stageReason": null }, { "stageIndex": 7, "stageKey": "retention", "stageSource": "VTEX", "volume": 66, "volumeUnit": "customers", "previousVolume": 486, "stepRate": null, "abandonments": null, "sequenceClosed": true, "stageReason": null } ], "largestDrop": { "fromStep": "attention", "toStep": "interest", "lostUsers": 15300, "dropRate": 0.85 }, "mappingCoverage": { "ga4PropertyId": "properties/312445901", "propertyCount": 1, "coverageState": "production", "purchases": 0.973, "views": 0.951, "revenue": 0.968, "purchaseDenominator": 4821, "viewDenominator": 91240, "revenueDenominator": 1204551.3, "totalMappedItems": 812, "totalUnmappedItems": 22, "totalConflictingItems": 0, "totalProductMappedItems": 4, "resolutionRule": "SKU_ID" }, "categoryBenchmark": null }, "cohort": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "periodApplied": { "basis": "source_window", "granularity": "month" }, "view": "logo", "groupBy": "month", "overlappingRows": true, "window": { "from": "2026-03-01", "to": "2026-07-01" }, "activityThrough": "2026-08-01", "data": [ { "cohort": "2026-03-01", "cohortMonths": 1, "ageMonths": 6, "entryCustomers": 218, "netRevenue": 92911.9, "marginTotal": 35306.52, "marginAverage": 161.95651376146787, "marginNdReason": null, "cells": [ { "monthOffset": 0, "entryCustomers": 218, "activeCustomers": 218, "netRevenue": 68940.2, "retentionRate": 1, "revenueRetentionRate": 1, "marginTotal": 26197.28, "marginNdReason": null, "mature": true }, { "monthOffset": 1, "entryCustomers": 218, "activeCustomers": 34, "netRevenue": 10870.5, "retentionRate": 0.155963, "revenueRetentionRate": 0.157682, "marginTotal": 4130.79, "marginNdReason": null, "mature": true }, { "monthOffset": 2, "entryCustomers": 218, "activeCustomers": 19, "netRevenue": 6240.8, "retentionRate": 0.087156, "revenueRetentionRate": 0.090518, "marginTotal": 2371.5, "marginNdReason": null, "mature": true }, { "monthOffset": 4, "entryCustomers": 218, "activeCustomers": 11, "netRevenue": 3720.3, "retentionRate": 0.050459, "revenueRetentionRate": 0.053963, "marginTotal": 1413.71, "marginNdReason": null, "mature": true }, { "monthOffset": 5, "entryCustomers": 218, "activeCustomers": 9, "netRevenue": 3140.1, "retentionRate": 0.041284, "revenueRetentionRate": 0.045547, "marginTotal": 1193.24, "marginNdReason": null, "mature": true } ] }, { "cohort": "2026-05-01", "cohortMonths": 1, "ageMonths": 4, "entryCustomers": 310, "netRevenue": 111650.5, "marginTotal": 42427.19, "marginAverage": 136.86190322580646, "marginNdReason": null, "cells": [ { "monthOffset": 0, "entryCustomers": 310, "activeCustomers": 310, "netRevenue": 96420.1, "retentionRate": 1, "revenueRetentionRate": 1, "marginTotal": 36639.64, "marginNdReason": null, "mature": true }, { "monthOffset": 1, "entryCustomers": 310, "activeCustomers": 47, "netRevenue": 15230.4, "retentionRate": 0.151613, "revenueRetentionRate": 0.157959, "marginTotal": 5787.55, "marginNdReason": null, "mature": true } ] }, { "cohort": "2026-07-01", "cohortMonths": 1, "ageMonths": 2, "entryCustomers": 287, "netRevenue": 102701, "marginTotal": 39026.38, "marginAverage": 135.9804181184669, "marginNdReason": null, "cells": [ { "monthOffset": 0, "entryCustomers": 287, "activeCustomers": 287, "netRevenue": 89120.7, "retentionRate": 1, "revenueRetentionRate": 1, "marginTotal": 33865.87, "marginNdReason": null, "mature": true }, { "monthOffset": 1, "entryCustomers": 287, "activeCustomers": 41, "netRevenue": 13580.3, "retentionRate": null, "revenueRetentionRate": null, "marginTotal": 5160.51, "marginNdReason": null, "mature": false } ] } ] }, "associations": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "periodApplied": { "basis": "source_window", "granularity": "month" }, "combinationSize": 2, "minOrders": 5, "limit": 50, "window": { "from": "2025-09-01", "to": "2026-08-01" }, "pairsTotal": 37, "data": [ { "productId": "20918", "productName": "Meia Esportiva Cano Alto", "ordersTogether": 88, "ordersWithProduct": 496, "ordersWithAssociated": 741, "ordersTotal": 41230, "confidence": 0.177419, "lift": 9.871, "associatedNetRevenue": 5210.9, "basketNetRevenue": 10420.8, "averageTicket": 118.42, "marginTotal": 3910.35, "marginNdReason": null, "newCustomers": 31, "recurringCustomers": 46, "months": 11, "imageUrl": null, "sourceImageUrl": null, "imageStatus": "no_source" } ] }, "boughtTogether": { "state": "not_applicable", "reason": "size_served_by_associations", "asOf": null, "periodApplied": { "basis": "source_window", "granularity": "month" }, "combinationSize": 2, "minOrders": 5, "limit": 50, "supportFloor": null, "maxBasketSize": null, "ordersExcluded": null, "combinationsTotal": 0, "data": [] }, "retention": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "periodApplied": { "basis": "requested", "granularity": "month" }, "window": { "from": "2026-07-01", "to": "2026-07-01" }, "data": [ { "month": "2026-07-01", "buyers": 496, "repeatBuyers": 94, "newBuyers": 402, "repeatBuyerRate": 0.189516, "orders": 610, "identifiedOrders": 588, "anonymousOrders": 22, "purchaseFrequency": 1.185484, "avgDaysBetweenPurchases": 23.4, "repeatIntervals": 78, "netRevenue": 171004.2, "grossUnits": 612, "matureMonth": true } ] }, "purchaseFrequency": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "periodApplied": { "basis": "requested", "granularity": "day" }, "identifiedCustomers": 496, "identifiedOrders": 588, "anonymousOrders": 22, "identityCoverage": 0.963934, "repurchaseRate": 0.133065, "averagePurchaseFrequency": 1.185484, "previous": { "state": "ready", "reason": null, "window": { "from": "2026-05-31", "to": "2026-06-30" }, "identifiedCustomers": 452, "repurchaseRate": 0.111111, "averagePurchaseFrequency": 1.132743 }, "variation": { "repurchaseRate": 19.76, "averagePurchaseFrequency": 4.66 }, "data": [ { "bucket": "1", "customers": 430, "orders": 430, "share": 0.866935 }, { "bucket": "2", "customers": 48, "orders": 96, "share": 0.096774 }, { "bucket": "3", "customers": 12, "orders": 36, "share": 0.024194 }, { "bucket": "4+", "customers": 6, "orders": 26, "share": 0.012097 } ] }, "boughtAfter": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "periodApplied": { "basis": "source_window", "granularity": "month" }, "limit": 50, "data": [ { "productId": "20918", "productName": "Meia Esportiva Cano Alto", "isSameProduct": false, "customers": 128, "transitions": 141, "customersWithNextOrder": 310, "ordersWithNextOrder": 402, "customerShare": 0.412903, "avgDaysToNext": 34.2, "minDaysToNext": 2, "maxDaysToNext": 209, "nextBasketNetRevenue": 54531.75, "averageTicket": 386.75, "marginTotal": 16359.53, "marginNdReason": null, "newCustomers": 31, "recurringCustomers": 97, "imageUrl": null, "sourceImageUrl": null, "imageStatus": "no_source" }, { "productId": "12345", "productName": "Tênis Runner Pro", "isSameProduct": true, "customers": 46, "transitions": 51, "customersWithNextOrder": 310, "ordersWithNextOrder": 402, "customerShare": 0.148387, "avgDaysToNext": 96.8, "minDaysToNext": 21, "maxDaysToNext": 288, "nextBasketNetRevenue": 26132.4, "averageTicket": 512.4, "marginTotal": null, "marginNdReason": "incomplete_cost", "newCustomers": 8, "recurringCustomers": 38, "imageUrl": null, "sourceImageUrl": null, "imageStatus": "no_source" } ] }, "coupons": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "discountScope": "order", "periodApplied": { "basis": "requested", "granularity": "day" }, "ordersWithProduct": 400, "ordersWithCoupon": 120, "couponOrderShare": 0.3, "couponDiscountValue": 5820, "couponGrossValue": 194000, "discountRate": 0.03, "averageDiscountPerOrder": 48.5, "previous": { "state": "ready", "reason": null, "window": { "from": "2026-05-31", "to": "2026-06-30" }, "ordersWithProduct": 360, "ordersWithCoupon": 96, "couponOrderShare": 0.266667, "averageDiscountPerOrder": 42, "discountRate": 0.025 }, "variation": { "couponOrderShare": 12.5, "averageDiscountPerOrder": 15.48, "discountRate": 20 }, "itemLevelTagCoverage": 0.25, "itemLevelTagCoverageStatus": "measured", "limit": 50, "data": [ { "couponCode": "PROMO-INVERNO-15", "orders": 120, "netRevenue": 41000, "averageTicket": 341.67, "marginTotal": 12000, "marginNdReason": null, "newCustomers": 30, "recurringCustomers": 85, "orderDiscountValue": 4616 }, { "couponCode": "FRETEGRATIS", "orders": 44, "netRevenue": 15900, "averageTicket": 361.36, "marginTotal": null, "marginNdReason": "incomplete_cost", "newCustomers": 9, "recurringCustomers": 34, "orderDiscountValue": 1204 } ] }, "acquisitionChannels": { "state": "ready", "reason": null, "asOf": "2026-08-18T06:12:00.000Z", "cacState": "no_source", "ltvScope": "organization_lifetime", "periodApplied": { "basis": "requested", "granularity": "day" }, "ordersWithProduct": 400, "ordersWithChannel": 400, "channelCoverage": 1, "ordersMissingChannelFact": 0, "paidOrderShare": 0.625, "organicOrderShare": 0.375, "customers": 380, "newCustomers": 120, "recurringCustomers": 270, "data": [ { "channel": "Meta Ads", "mediaType": "paid", "orders": 250, "netRevenue": 82000, "customers": 240, "newCustomers": 90, "recurringCustomers": 160, "averageLtv": 512.5, "ltvCoverage": 0.75, "marginTotal": 24000, "marginNdReason": null, "spend": null, "cac": null, "ltvCac": null }, { "channel": "Orgânico", "mediaType": "organic", "orders": 150, "netRevenue": 48000, "customers": 145, "newCustomers": 30, "recurringCustomers": 118, "averageLtv": 702.4, "ltvCoverage": 0.965517, "marginTotal": null, "marginNdReason": "incomplete_cost", "spend": null, "cac": null, "ltvCac": null } ] }}