API reference
Query Sweepstake by ID
Get the settings for one sweepstake by its ID. Build a dedicated display using its title, dates, entry rules, product overrides, and scheduled bonuses.
Use querySweepstake(id) when your display is about one specific sweepstake. Pass its numeric ID or GID-like string to retrieve its title, dates, entry rules, product settings, and scheduled bonuses. This is useful for a dedicated sweepstake page, a promotion banner, or a custom settings display.
Complete implementation
Replace YOUR_SHOP_ID with your shop’s numeric ID. In a Shopify Liquid template, the numeric shop ID is available as {{ shop.id }}. Define the helper before calling it.
const platformId = 'gid://shopify/Shop/YOUR_SHOP_ID';
function sanitizeId(value) {
return String(value).replace(/\D/g, '');
}
async function querySweepstake(sweepstakeNumberOrGid) {
const targetId = sanitizeId(sweepstakeNumberOrGid);
const query = `
query QueryOrganization($organizationId: Int, $platform: String, $platformId: String) {
organization(id: $organizationId, platform: $platform, platformId: $platformId) {
id
plan
sweepstakes {
endDate
id
isActive
organizationId
title
entryTotal
startDate
timeZone
membershipManagement
numberOfWinners
description
productsAllowedByDefault
bonusEntriesDefault
uniqueWinner
calculateWithDiscount
scheduleBonusEnabled
scheduledBonusStart
scheduledBonusEnd
scheduledBonusValue
scheduledBonusActive
products {
productId
productAllowed
productBonusEntries
productMultiplier
orderMultiplierAllowed
orderMultiplier
}
entryManagement
}
}
}
`;
const variables = {
organizationId: null,
platform: "Shopify",
platformId: platformId,
};
try {
const response = await fetch("https://backend.cleansweeps.app/graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query, variables }),
});
const result = await response.json();
const { data, errors } = result;
if (errors) {
console.error("GraphQL errors:", errors);
return null;
}
const sweepstakes = data?.organization?.sweepstakes || [];
const match = sweepstakes.find((s) => sanitizeId(s.id) === targetId);
if (!match) {
console.warn(`[querySweepstake] No sweepstake found for id=${targetId}`);
console.log(
"[querySweepstake] Available sweepstake ids:",
sweepstakes.map((s) => sanitizeId(s.id))
);
return null;
}
// Parse entryManagement safely (optional)
let entryManagementParsed = null;
try {
entryManagementParsed = match.entryManagement ? JSON.parse(match.entryManagement) : null;
} catch (e) {
console.warn("[querySweepstake] entryManagement JSON parse failed:", e);
}
const fullSettings = {
...match,
entryManagementParsed,
};
console.log(`[querySweepstake] Sweepstake ${targetId} settings:`, fullSettings);
return fullSettings;
} catch (error) {
console.error("[querySweepstake] Error:", error);
return null;
}
}
// Example call
querySweepstake(123);How to Use It (Copy-Paste Examples)
Example 1 — Basic Debug Call (Logs to Console)
document.addEventListener("DOMContentLoaded", function () {
querySweepstake("1");
});Example 2 — Await the Settings and Inspect Fields
document.addEventListener("DOMContentLoaded", async function () {
const settings = await querySweepstake(1);
if (!settings) return;
console.log("title:", settings.title);
console.log("isActive:", settings.isActive);
console.log("timeZone:", settings.timeZone);
});Example 3 — Pass a GID-like Input
document.addEventListener("DOMContentLoaded", async function () {
await querySweepstake("gid://shopify/Sweepstake/1");
});Return Value
querySweepstake() returns:
- Sweepstake settings object if found
- null if:
- GraphQL returns errors
- No sweepstake matches the provided ID
- A network error occurs
On success, it adds one helpful field:
- entryManagementParsed (object | null) — parsed version of entryManagement (which is returned as a JSON string)
Field Reference (What Each Field Does)
Expand field reference (what each field does)
| Field | Type | Details |
|---|---|---|
id | Int/String | Unique sweepstake identifier used to target a sweepstake. |
organizationId | Int | The organization that owns this sweepstake. |
title | String | Sweepstake name displayed in UI/admin and often shown in widgets. |
description | String | Sweepstake description text (marketing/notes). |
startDate / endDate | String: epoch ms | Start/end timestamps (milliseconds since epoch). Used for time-based activation and display logic. |
timeZone | String, e.g. "America/Phoenix" | The timezone context used by your backend/admin when calculating active windows (including scheduled bonus windows). |
isActive | Boolean | Server-calculated “currently active” state for the sweepstake. Your storefront often uses active sweepstakes as defaults. |
entryTotal | Int | Aggregate count of entries created so far (informational/debug). |
Entry Calculation Controls
entryManagement (JSON string) entryManagement returns as a string containing JSON. Your storefront parses it to compute base entries. Common keys inside entryManagement (based on your widget logic): dollarSpent (Number) Denominator used in base entry math (entries per X dollars). entryPer (String/Number) Base entries awarded per dollarSpent unit (before scheduled bonus override). roundUp (Boolean) Controls rounding:
- true → Math.ceil
- false → Math.floor
bonusSpending[] (Array) Tier configuration used by your cart widget to compute Bonus Spending entries. Each tier may include:
- spendingLimitEnabled (Boolean)
- spendingLimitDollar (String/Number)
- bonusEntries (String/Number)
entryManagementParsed (client-added) This is not returned by GraphQL. querySweepstake() adds it by doing:
- JSON.parse(match.entryManagement)
If parsing fails, it becomes null (and logs a warning).
Discount Handling
calculateWithDiscount (Boolean) Controls whether entries are computed from discounted totals or original totals. In your cart widget, this changes:
- Per-line calculation uses either item.line_price (discounted) or item.original_line_price (original)
- Bonus spending subtotal uses either cart.items_subtotal_price (discounted) or cart.original_total_price (original)
Scheduled Bonus (Entry Per Override)
scheduleBonusEnabled (Boolean) Whether scheduled bonus configuration is enabled for the sweepstake. scheduledBonusStart / scheduledBonusEnd (String: epoch ms) Scheduled bonus active window boundaries. scheduledBonusValue (Int) The override value used as entryPer when scheduled bonus is active. scheduledBonusActive (Boolean) Server-calculated “scheduled bonus is active right now” flag. In your widget logic, you compute:
- effectiveEntryPer = scheduledBonusActive ? scheduledBonusValue : entryPer
So scheduled bonus can temporarily increase entries per dollar during promo windows.
Defaults (When Product Has No Override)
productsAllowedByDefault (Boolean) If a product does not have an explicit override in products[], this determines whether it is eligible by default. bonusEntriesDefault (Int) If a product has no override, this is the default bonus entries applied (usually per quantity).
Winner Controls (Informational / Admin-Oriented)
These are returned for visibility/debug, even if your cart widget doesn’t use them. numberOfWinners (Int) How many winners will be selected. uniqueWinner (Boolean) If true, a single person cannot win multiple times (winner uniqueness enforced).
Membership Rules (Tag-Based Bonus / Multiplier)
membershipManagement (String: JSON) JSON string containing membership rules. Your widget parses it and applies:
- Membership bonus entries (added to total)
- Membership multiplier (may affect order multiplier)
Typical rule shape:
- tag (String) — customer tag to match
- bonusEntries (Number) — adds membership entries
- multiplier (Number) — candidate multiplier
Your cart widget:
- matches rules against logged-in customer tags
- accumulates membershipBonusEntries
- uses the highest membershipMultiplier
Product Overrides (products[])
The sweepstake returns an array of product rule overrides. Your widget builds a map by productId and applies these per cart item. products[].productId (String: Shopify Product GID) Example: gid://shopify/Product/9063734772014 products[].productAllowed (Boolean) If false, that product yields 0 entries (even if defaults allow). products[].productBonusEntries (Int) Extra flat bonus entries for this product (your code applies per quantity). products[].productMultiplier (Number) Multiplier applied to the computed “base entries” for this product line. products[].orderMultiplierAllowed (Boolean) If true, this product can contribute an order-level multiplier. products[].orderMultiplier (Number) Order-level multiplier candidate. Your widget uses the max across items and membership multiplier.
Notes / Best Practices
This function is best used for debugging
- It fetches all sweepstakes for the org and filters client-side.
- Useful for inspecting configuration during development.
- For production runtime entry calculations, your smaller “by product IDs” query is more efficient, but querySweepstake() is the best “inspect everything now” tool.
Field parsing should be defensive
- entryManagement and membershipManagement are JSON strings; parsing should always be in a try/catch to avoid storefront breakage.

