Skip to content

Estimate the points a product would earn

GET /products/{product_id}/points
Scopeprogram:read
Customer session tokenAccepted with the read scope, for the token’s own customer
Rate limit classread (limits)
Idempotency keyNot used
MCP toolcharm_estimate_product_points

The number the storefront widget shows on a product page, for headless storefronts: earning rules with the shop’s tax handling, product / collection / tag exclusions, active campaigns and, with customer_id, that customer’s tier multiplier and per-customer bonuses. No Shopify lookup happens — send the unit price in the shop currency and, where the program uses them, the product’s collection_ids and tags. An unknown customer_id gives the anonymous estimate. enabled: false carries a reason (program_disabled, no_points_layer, product_excluded, customer_excluded).

NameInTypeDescription
product_idpathstringShopify product GID (percent-encoded) or the numeric product id.
pricequerynumberUnit price in the shop currency.
quantity (optional)queryintegerUnits, 1–99. Defaults to 1.
variant_id (optional)querystringVariant GID or numeric id, for variant-level exclusions.
collection_ids (optional)querystringComma-separated collection GIDs or numeric ids the product belongs to.
tags (optional)querystringComma-separated product tags, for tag-based exclusions.
customer_id (optional)querystringCustomer GID or numeric id; applies their tier multiplier and per-customer bonuses.

Returns ProductEstimate.

FieldTypeDescription
product_idstring
variant_idstring or null(nullable)
quantityinteger
pricenumberThe unit price you sent, in the shop currency.
currencystring or null(nullable)
estimatetrue
enabledbooleanFalse when nothing would be earned; see reason.
reasonstring or null: program_disabled, no_points_layer, product_excluded, customer_excluded(nullable)
pointsintegerTotal the purchase would earn.
base_pointsinteger
bonus_pointsinteger
tier_multipliernumber(optional)
campaign_multipliernumber(optional)
customer_idstring or nullThe customer the estimate was priced for; null for anonymous. (optional, nullable)
{
"product_id": "8123456789",
"variant_id": "44123456789",
"quantity": 1,
"price": 1,
"currency": "EUR",
"estimate": true,
"enabled": true,
"reason": "program_disabled",
"points": 120,
"base_points": 120,
"bonus_points": 120,
"tier_multiplier": 1,
"campaign_multiplier": 1,
"customer_id": "gid://shopify/Customer/7712345"
}
Terminal window
curl -X GET "https://charm.appfleece.app/api/v1/products/<product_id>/points" \
-H "Authorization: Bearer chrm_live_..."

unauthorized · invalid_token · token_expired · insufficient_scope · access_required · not_found · validation_error · rate_limited

Every error body carries code, message, request_id and a doc_url pointing at the matching entry in the error catalog.