Spur Popups

Historical Submissions API

Pull historical popup submissions (newsletter, spin wheel, scratch card) so providers can backfill flows when automation is configured after a popup has already collected leads.

1. Endpoint and authentication

Generate a Provider API key from Webhook Settings in the app. The key is shop-scoped and shown once on creation.

GET /api/provider/submissions
Authorization: Bearer sppk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2. Query parameters

limit: default 100, max 500.

cursor: opaque base64 cursor from previous response.

since: optional ISO timestamp lower bound.

until: optional ISO timestamp upper bound.

popup_id: optional filter for one popup.

popup_type: optional filter (newsletter, spin_wheel, scratch_card).

3. Response and cursor model

Records are ordered by timestamp, then popup_type, then source ID. Use submission_uid for dedupe.

{
  "data": [
    {
      "submission_uid": "spin_wheel:cmabc123",
      "event": "popup_completed",
      "timestamp": "2026-02-27T14:49:20.998Z",
      "popup_type": "spin_wheel",
      "popup_id": "cmm5088da00rwmr3knwe5crfu",
      "popup_name": "Golden Wheel - Feb 27",
      "customer": {
        "email": "lead@example.com",
        "phone": "+919871739342",
        "name": "Rohan",
        "isIdentified": true
      },
      "prize": {
        "label": "$5 OFF",
        "type": "amount",
        "value": 5,
        "discount_code": "SPINLSVXVD",
        "discount_code_id": "gid://shopify/DiscountCodeNode/1840482713909"
      },
      "source_url": null,
      "device_type": "desktop",
      "consent": {
        "marketing": null,
        "email": null,
        "sms": null,
        "whatsapp": null
      },
      "shop": {
        "domain": "your-shop.myshopify.com"
      }
    }
  ],
  "page_info": {
    "has_more": true,
    "next_cursor": "eyJ0cyI6IjIwMjYtMDIt..."
  },
  "meta": {
    "shop": "your-shop.myshopify.com",
    "generated_at": "2026-02-27T15:00:00.000Z"
  }
}

Newsletter records are enriched from nearest signup/consent rows (within ±5 minutes) to provide discount and consent context when available.

4. Backfill and incremental sync

Backfill: start with no cursor, keep requesting pages until has_more = false. Upsert by submission_uid.

Incremental: persist next_cursor, poll every 1-5 minutes, and continue from that cursor.

Retries: on 429/5xx, retry with exponential backoff. Cursor makes replay safe.

Compliance: send on channel only when explicit consent is true; treat null consent as unknown.

5. Provider playbooks

Spur: backfill popup_completed rows, trigger flow entry for each deduped submission, then switch to cursor polling for near real-time sync.

Klaviyo: upsert profile by email/phone, attach popup attributes and prize fields, and trigger list/flow joins from imported submissions.

HubSpot: upsert contacts and append submission event metadata for workflows and lifecycle automation.

Downtime replay: if webhook delivery is paused, recover missed events by replaying this API from last successful cursor.

Related guides