Proposed API - Rokt Team
Giveaway Details API
Shared Sweeps API · Partner Integration · Proposal — for review & approval
https://api.sharedsweepsapp.com
Authentication (shared)
Same as Store Entries API, please refer to store entries API documentation
| Header | Required | Description |
|---|---|---|
X-Timestamp |
required | Unix time in seconds when the request was signed. |
X-Signature |
required |
Lowercase hex
HMAC-SHA256(secret, "<X-Timestamp>.<rawBody>").
|
X-Shopify-Shop-Domain |
optional* |
Shop domain, e.g. store.myshopify.com. *Required unless
sent as a shop query parameter.
|
The signed payload is `${timestamp}.${rawBody}`. For
read (GET) requests there is no body, so the signed payload
is simply `${timestamp}.` (timestamp + dot + empty string). The
timestamp must be within ±5 minutes of server time, and the
signature is checked against every active secret (zero-downtime rotation).
Any failure returns 401 without
revealing which check failed.
slug, which is unique per shop.
The dedicated bucket that store-entries writes to has the slug
api-entries.
How giveaways exist for an API-only shop
If your shop does not install the Shared Sweeps app, the only giveaway that exists is the one we create for you automatically:
-
The first
POST /store-entriescall for a shop find-or-creates a giveaway with slugapi-entries(title "API Entries",isActive: false). This same row is then reused permanently for all subsequent entries. - Because it isn't a real, scheduled giveaway, its dates are empty and its entry rules are defaults — it exists only as a stable container to attach entries to.
So for a pure-API integration, the read endpoint returns a single
api-entries giveaway. Shops that also run the
app will have their own app-created giveaways (with their own slugs, dates,
and rules) returned alongside it. The summer-2026 example below
illustrates such an app-created giveaway.
API 1 — Read giveaway details Requested now
Returns the giveaway configuration for a shop.
api-entries — identical across all shops; only the
shop differs. So you don't need to look a slug up: just call the
per-shop endpoint with slug = api-entries. The list endpoint
exists mainly for shops that also run the app and therefore
have additional, app-created giveaways with their own slugs.
/giveaways/api-entries
Fetch the giveaway for a shop (primary).
Because the slug is the known constant api-entries, the only
variable you supply is the shop. Returns a single
giveaway object.
GET /giveaways/api-entries?shop=store.myshopify.com
| Path / query | Required | Description |
|---|---|---|
slug |
required |
Path segment. For API-managed giveaways this is always
api-entries.
|
shop |
optional* |
Shop domain. *Or send via the
X-Shopify-Shop-Domain header.
|
/giveaways
List all giveaways for a shop (only if the app is also installed).
Returns every giveaway for the shop, each with its slug. For
pure-API shops it simply returns the single api-entries
giveaway.
GET /giveaways?shop=store.myshopify.com&active=true
| Query param | Required | Description |
|---|---|---|
shop |
optional* |
Shop domain. *Or send via the
X-Shopify-Shop-Domain header.
|
active |
optional |
true returns only currently-active giveaways. Default
false (all).
|
Response — 200 OK
The primary endpoint (1a) returns a single
giveaway object:
{
"success": true,
"giveaway": {
"slug": "api-entries",
"title": "API Entries",
"description": null,
"isActive": false,
"startDate": null,
"endDate": null,
"timezone": "",
"entryRules": {
"entriesOnPurchase": 1,
"subscriptionMultiplier": 5
}
}
}
The list endpoint (1b) returns the same objects wrapped in a
giveaways array — for a shop that also runs the app this is
where app-created giveaways (with their own slugs, dates, and rules) appear:
{
"success": true,
"giveaways": [
{
"slug": "api-entries",
"title": "API Entries",
"isActive": false,
"startDate": null,
"endDate": null,
"entryRules": { "entriesOnPurchase": 1, "subscriptionMultiplier": 5 }
},
{
"slug": "summer-2026",
"title": "Summer Giveaway",
"isActive": true,
"startDate": "2026-06-01T00:00:00.000Z",
"endDate": "2026-08-31T23:59:59.000Z",
"entryRules": { "entriesOnPurchase": 1, "subscriptionMultiplier": 5 }
}
]
}| Field | Type | Description |
|---|---|---|
slug |
string | Stable per-shop identifier for the giveaway. |
title |
string | Display name. |
description |
string | null | Optional description. |
isActive |
boolean | Whether the giveaway is currently active. |
startDate / endDate
|
string | null | ISO-8601 timestamps (UTC). |
timezone |
string | IANA timezone the giveaway's dates are evaluated in. |
entryRules.entriesOnPurchase |
number | Base entry multiplier applied to eligible one-time purchases. |
entryRules.subscriptionMultiplier |
number | Entry multiplier applied to subscription (selling-plan) line items. |
| Status | Body | Cause |
|---|---|---|
| 400 | { "error": "Missing shop" } |
No shop query param or header. |
| 401 | { "error": "Unauthorized" } |
Bad/missing signature or stale timestamp. |
| 404 | { "error": "Giveaway not found" } |
No giveaway with that slug for the shop. |
| 500 | { "error": "Internal server error" } |
Unexpected failure (reported to our Sentry). |
API 2 — Update giveaway details Future
Updates a subset of mutable fields on an existing giveaway.
Uses PATCH semantics — send only the fields you want to change.
For your API-managed giveaway the slug is always api-entries.
/giveaways/api-entries
PATCH /giveaways/api-entries
Content-Type: application/json
X-Timestamp: 1749945600
X-Signature: <hmac>
X-Shopify-Shop-Domain: store.myshopify.com
{
"title": "Summer Giveaway (Extended)",
"description": "Now running through September",
"isActive": true,
"startDate": "2026-06-01T00:00:00.000Z",
"endDate": "2026-09-30T23:59:59.000Z",
"entryRules": {
"entriesOnPurchase": 2,
"subscriptionMultiplier": 10
}
}| Field | Type | Notes |
|---|---|---|
title |
string | Display name. |
description |
string | Optional description. |
isActive |
boolean | Activate / deactivate the giveaway. |
startDate |
string | ISO-8601. |
endDate |
string | ISO-8601; must be after startDate. |
entryRules.entriesOnPurchase |
number | Entry multiplier for one-time purchases. Positive integer. |
entryRules.subscriptionMultiplier |
number | Entry multiplier for subscription line items. Positive integer. |
entryRules is itself optional, and within it each field is
optional — send only the multiplier(s) you want to change.
entryRules affects how entries are calculated for
future orders only — entries already recorded are not
retroactively recalculated. We recommend updating multipliers before a
giveaway goes live rather than mid-run.
{
"success": true,
"giveaway": { /* same shape as the read response */ }
}- Create vs. update only? This covers updating an existing giveaway. Do you also need to create new giveaways via API?
- Audit. All updates would be recorded in our internal change log with your partner identity for traceability.
Summary — what we're asking you to approve
| # | Endpoint | Method | Purpose | Timeline |
|---|---|---|---|---|
| 1 |
/giveaways + /giveaways/{slug}
|
GET | Read giveaway details | 29 June 2026 |
| 2 | /giveaways/{slug} |
PATCH | Update giveaway details | Future |