SweepsyRequest access
On this page

API reference

Sweepsy API v1

Create entries, confirm a participant, and verify webhooks with a key that stays on your server.

AUTHSignedBearer + HMAC
ENTRIES300per minute, per IP
INPUTJSONraw body is signed
OUTPUTJSONentry id and tickets
WINDOW5 mintimestamp skew

Sweepsy connects store events to campaigns, entries, tickets, and the verified draw. Send entries from your server after the order is final. Use a stable order id so a retry does not create a second entry.

The public key identifies the brand. The secret proves the request. Keep the secret on the server that signs the body.

  • Authorization: Bearer, the public key
  • X-Sweepy-Timestamp, unix seconds
  • X-Sweepy-Signature, hex HMAC-SHA256 of timestamp, a dot, then the raw body
  • Reject and retry when the timestamp is older than five minutes

Authentication

Send the public key as a Bearer token, plus the timestamp and signature headers. The signed string is the timestamp, a single dot, and the exact raw JSON body. Rotate a key from API keys if it becomes public.

Manage API keys

Quickstart

  1. Create or copy an API key.
  2. Connect a development store.
  3. Send a signed test entry from your server.
  4. Check the result on Entries.

Endpoints

POSTEntries /api/v1/entriesPOSTTrack /api/v1/trackPOSTEvents /api/v1/eventsGETWidget /api/v1/widget/{publicKey}POSTLookup /api/v1/lookupPOSTFree entry /api/v1/amoePOSTPublic prize /api/v1/public-prize/enterPOSTWebhooks /api/webhooks/…POSTMCP /api/mcp

Track is the browser call from a thank-you page. It is not the trusted path. Brands that need a hard guarantee use the signed entries route. Widget configuration and events carry no participant data. Lookup returns that person’s counts only, and does not reveal a winner before the draw is published.

Entries

Create an entry only after the related order is final. Required fields are orderId and email. campaign is optional and selects the live campaign by slug. Optional fields are firstName, lastName, phone, country, region, customerId, amount, netAmount, currency, marketingOptIn, and items.

netAmount is product revenue after discounts, excluding tax and shipping. Omit it and the order is recorded but left out of billing. A gift-card line item sets giftCard so that amount does not earn tickets.

A successful response includes ok, created, entryId, tickets, ticketRange, totalTickets, and campaign. A duplicate order id returns 409.

Rate limits

Limits are requests per IP for the window below. They are not a priced tier. A limited request returns 429 with error rate_limited.

Entries300per 60 seconds
Events120per 60 seconds
Widget120per 60 seconds
Lookup10per 10 minutes
RouteRequestsWindowScope
POST /api/v1/entries30060 secondsPer IP
POST /api/v1/events12060 secondsPer IP
GET /api/v1/widget/{publicKey}12060 secondsPer IP
POST /api/v1/lookup1010 minutesPer IP
POST /api/v1/track2060 secondsPer IP
POST /api/v1/amoe51 hourPer IP
POST /api/v1/public-prize/enter51 hourPer IP
POST /api/mcp60060 secondsPer IP
POST /api/oauth/token6060 secondsPer IP
POST /api/oauth/revoke6060 secondsPer IP
POST /api/oauth/register201 hourPer IP

Campaigns

A campaign defines its dates, markets, prize, entry rules, and draw schedule. Use the campaign slug in server requests.

Winners and draw

Sweepsy runs the verified draw from valid entries. Read winner status in the workspace. Do not infer a winner before the draw completes.

Audience

Audience data belongs to the connected brand. Use consented customer fields only. Do not send payment data.

Webhooks and signatures

Shopify, Stripe, and WooCommerce each have a webhook path under /api/webhooks. Use the endpoint shown on Webhooks. Verify every signature. Return success only after your server stores the event.

View webhook endpoints

Shopify connection

Connect Shopify from Store connection. Connected stores open the embedded Shopify app from the workspace.

Errors

rate_limited429
missing_api_key, missing_signature, stale_timestamp, invalid_api_key, bad_signature401
invalid_json400
invalid_payload422
no_live_campaign404
Rejected or duplicate entry409

Retry temporary server errors with backoff. Fix authentication and validation errors before retrying. Delivery logs are not available in this workspace yet.

Features

Signed requestsSupported
Stable order idSupported
WebhooksSupported
Free entrySupported
Participant lookupCounts only
Browser trackNot the trusted path

Agents

Use the Sweepsy MCP guide to connect Codex, Claude, Cursor, or another MCP client. Grant only the access required for the task.

Available tools cover brand identity, campaigns, entry rules, prize tiers, entry simulation, analytics, widgets, draws, and winners.

Workflow prompts help an agent plan a sweepstake, build a custom pop-up, report on a campaign, and check launch readiness.

Reference resources describe ticket rules, storefront widget requirements, territory rules, and product limits.

Examples

cURL

TIMESTAMP=$(date +%s)
BODY='{"campaign":"your-campaign","orderId":"ORDER-1234","email":"buyer@example.com"}'
SIGNATURE=$(printf '%s.%s' "$TIMESTAMP" "$BODY" | openssl dgst -sha256 -hmac "$SWEEPSY_API_SECRET" | awk '{print $2}')
curl -X POST https://trysweepsy.com/api/v1/entries \
  -H "Authorization: Bearer $SWEEPSY_PUBLIC_KEY" \
  -H "X-Sweepy-Timestamp: $TIMESTAMP" \
  -H "X-Sweepy-Signature: $SIGNATURE" \
  -H "Content-Type: application/json" \
  -d "$BODY"

TypeScript

import { createHmac } from "node:crypto";

const body = JSON.stringify({
  campaign: "your-campaign",
  orderId: "ORDER-1234",
  email: "buyer@example.com",
});
const timestamp = Math.floor(Date.now() / 1000).toString();
// Your server's own settings. Never ship the secret key to a browser.
const { SWEEPSY_API_SECRET, SWEEPSY_PUBLIC_KEY } = process.env;
const signature = createHmac("sha256", SWEEPSY_API_SECRET ?? "")
  .update(timestamp + "." + body)
  .digest("hex");

const response = await fetch("https://trysweepsy.com/api/v1/entries", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + SWEEPSY_PUBLIC_KEY,
    "X-Sweepy-Timestamp": timestamp,
    "X-Sweepy-Signature": signature,
    "Content-Type": "application/json",
  },
  body,
});

if (!response.ok) throw new Error("Sweepsy entry request failed");