</> Developers

One API for the whole program.

Everything the dashboard does, your code can do. Bearer-key auth, idempotent writes, signed webhooks. No SDK required — it's plain JSON over HTTPS.

Authentication

Create API keys in Dashboard → Settings (owner keys have full access; staff keys are scanner-only). Send the key as a bearer token:

curl https://api.rewardfinity.com/v1/members \
  -H "authorization: Bearer lp_sk_…" \
  -H "content-type: application/json" \
  -d '{"email":"customer@example.com","name":"Priya"}'

Endpoints

POST
/v1/merchants
Sign up a merchant → returns the API key (shown once). Rate-limited.
POST
/v1/members
Enroll a member (idempotent by email). Optional referralCode.
GET
/v1/members/:id
Member with balance, lifetime points, tier and stamps.
POST
/v1/events/purchase
Record a purchase → points/stamps/referrals. Idempotent by (source, externalId). Offers & tier multipliers apply automatically.
POST
/v1/events/refund
Refund → clawback at the purchase-time earn rate. Idempotent.
POST
/v1/rewards
Create a reward (discount / store_credit / giftcard).
POST
/v1/redemptions
Redeem for a member — race-safe balance check, idempotencyKey supported.
POST
/v1/campaigns
Create a QR reward campaign (budget + per-person caps).
POST
/v1/campaigns/:id/codes
Generate single-use claim codes (≤1000).
PATCH
/v1/campaigns/:id
Kill switch — pause/resume/end.
GET
/v1/campaigns/:id
Campaign stats: codes, claims, spend vs budget.
POST
/v1/promos
Create promo codes; POST /v1/promos/redeem to apply.
POST
/v1/wheels/:id/spin
Spin-to-win (atomic daily caps).
POST
/v1/import
CSV member import — idempotent per importId, balances preserved.
GET
/v1/insights
Rule-based program suggestions.
GET
/v1/automations
Configured lifecycle automations: birthday, winback, welcome, anniversary, and expiry.

Public (no auth): GET /p/:slug member page · POST /p/:slug/join self-enroll · POST /p/:slug/redeem member self-redemption · GET /c/:code claim page. Money is integer cents; points are integers; the ledger is append-only.

Webhooks

Set a webhook URL in Dashboard → Automations. Rewardfinity POSTs batched events — member.joined, points.earned, stamp.added, reward.redeemed, campaign.claimed, plus automation firings — signed with your secret:

// verify: hex(HMAC-SHA256(rawBody, secret)) === headers['x-torna-signature']
{ "type": "torna.outbox", "events": [
  { "id": "out_…", "kind": "points.earned",
    "payload": { "email": "…", "pointsEarned": 25, "balance": 125 },
    "createdAt": 1783380000000 } ] }

Automation kinds are lifecycle triggers (birthday, winback, welcome, anniversary, and expiry). Firings keep web push and signed webhook events, and queue each consented email, SMS, or WhatsApp leg through the first-party dispatcher. Provider submission occurs only when the corresponding operator-enabled provider path is configured. Failed webhook deliveries stay pending and retry on the next daily tick; provider callbacks distinguish acceptance from delivery for direct channels.

POS connections

Square connects natively (Dashboard → Integrations: paste your own access token; Rewardfinity registers its webhook and matches payments to members by email). Shopify uses signed store order and refund webhooks; Shopify POS remains an order-ingestion boundary until a POS extension is separately shipped and verified. Other POS systems (Clover, Lightspeed, Loyverse, Zettle…) drive the signed inbound endpoint POST /webhooks/in/:merchantId — directly or through Zapier/Make. Do not read the Shopify, Square, or generic webhook paths as one shared POS integration.