API reference
Product Entry Display API
Show how many entries a product earns, including its multipliers and bonuses, in your own product badges and cards.
https://backend.cleansweeps.app/graphqlOperation: QuerySweepstakeDetailsByProductId
Request
Send a JSON body with query and variables. Set Content-Type: application/json. Check both the HTTP response and GraphQL errors.
query QuerySweepstakeDetailsByProductId(
$platform: String!
$platformId: String!
$productIds: [String!]
) {
sweepstakeDetailsByProductId(
platform: $platform
platformId: $platformId
productIds: $productIds
) {
id
entryManagement
productsAllowedByDefault
bonusEntriesDefault
# ✅ Scheduled Bonus Fields
scheduledBonusValue
scheduledBonusActive
isActive
products(productIds: $productIds) {
productId
productAllowed
productBonusEntries
productMultiplier
}
}
}Variables
| Field | Type | Details |
|---|---|---|
platform | String! | Required. Use Shopify. |
platformId | String! | Required. Shop GID: gid://shopify/Shop/<SHOP_ID>. |
productIds | [String!] | Product GIDs to look up. Batch products in one query where possible. |
Response (Shape & Meaning)
Expand response (shape & meaning)
Sample Response
{
"data": {
"sweepstakeDetailsByProductId": [
{
"id": "123",
"entryManagement": "{\"dollarSpent\":\"1\",\"entryPer\":\"10\",\"roundUp\":true}",
"productsAllowedByDefault": true,
"bonusEntriesDefault": 0,
"scheduledBonusValue": 20,
"scheduledBonusActive": true,
"isActive": true,
"products": [
{
"productId": "gid://shopify/Product/1122334455",
"productAllowed": true,
"productBonusEntries": 0,
"productMultiplier": "2"
}
]
}
]
}
}Field Notes
Expand field notes
| Field | Type | Details |
|---|---|---|
entryManagement | JSON string | This contains the base entry rules: * dollarSpent (stringified number) |
Spend unit | ex: "1" means “per $1 spent” | * entryPer (stringified number) |
Entries per dollarSpent unit | ex: "10" means “10 entries per $1” | * roundUp (boolean, optional) * true → subtotal uses Math.ceil() * false → subtotal uses Math.floor() * missing → defaults to true |
scheduledBonusActive | boolean | If true, the scheduled bonus period is currently active. |
scheduledBonusValue | number | The entryPer override used when scheduledBonusActive === true. This replaces the base entryPer value for the duration of the scheduled bonus period. This matches how price-fetch.js calculates entriesPer when scheduled bonus is active. |
productsAllowedByDefault | boolean | If true and there is no product-level override, the default rules apply. |
bonusEntriesDefault | number | Default bonus entries applied when using default rules. |
products[] | array | Product-level overrides for the product(s) you requested: * productAllowed (boolean): eligible or not * productMultiplier (stringified number): entry multiplier * productBonusEntries (number): extra bonus entries |
Selection & Matching Rules
The API may return multiple sweepstakes. Use this selection strategy:
- Match a sweepstake whose id equals your requested numeric sweepstakeId (strip non-digits)
- If none match, pick the first isActive === true
- If still none, use the first item in the array
How to Calculate Entries (Rules → Final Display)
Inputs
- Subtotal = product’s current price in dollars (variant-aware)
- entryManagement.dollarSpent, entryManagement.entryPer, entryManagement.roundUp
- scheduledBonusActive, scheduledBonusValue
- Product row (optional): productAllowed, productMultiplier, productBonusEntries
- Defaults: productsAllowedByDefault, bonusEntriesDefault
Step A — Choose rounding function
roundFn = roundUp ? Math.ceil : Math.floor
roundedSubtotal = roundFn(subtotal)Step B — Override entryPer during scheduled bonus (if active)
effectiveEntryPer =
scheduledBonusActive === true && scheduledBonusValue > 0
? scheduledBonusValue
: entryPerStep C — Compute base entries
baseEntries = (effectiveEntryPer / dollarSpent) * roundedSubtotalStep D — Apply product rules Case 1: No product override AND productsAllowedByDefault === true
finalEntries = roundFn(baseEntries) + bonusEntriesDefault
displayMultiplier = effectiveEntryPerCase 2: Product override exists AND productAllowed === true
finalEntries = roundFn(baseEntries * productMultiplier) + productBonusEntries
displayMultiplier = roundFn(effectiveEntryPer * productMultiplier)Case 3: Product override exists AND productAllowed === false Display: Product Not Eligible
Multiplier Display Rule Hide multiplier unless: displayMultiplier > 1
Error Handling
- HTTP non-200 → treat as network error
- GraphQL errors → check errors[] in the payload
- Missing/malformed data → treat as “no data” or “not eligible” depending on your UI
Practical Example (Numbers)
Base rules:
- entryPer = 10
- dollarSpent = 1
- roundUp = true
Scheduled bonus:
- scheduledBonusActive = true
- scheduledBonusValue = 20
→ effectiveEntryPer = 20 Product price:
- $24.10 → roundedSubtotal = 25
- baseEntries = (20 / 1) * 25 = 500
Product multiplier:
- 2
- finalEntries = round(500 * 2) + 0 = 1000
Display: ✅ “1,000 Entries” ✅ multiplier chip: “40X”

