Programs API
Run a referral program, a loyalty program, or both, for your own customers — without building the ledger, the codes, the fraud rules or the tiers yourself. Your customers never need a Flixerpay account: you identify them by your own ids.
How it works
- Create a program (in the dashboard or over the API).
- Enrol customers with
PUT /members/:externalId; show them their referral link. - When someone signs up with
?ref=CODE, sendPOST /referrals. - Send
POST /eventsfor what customers do. Points are awarded, referrals convert on the qualifying event, tiers update. - Customers spend points with
POST /redemptions. You deliver the reward, then mark it fulfilled.
Points, not money. A balance is what you owe your customer in your own rewards. Flixerpay keeps the ledger and tells you by webhook when to deliver; it never holds or sends money for a program.
Authentication
Every request: Authorization: Bearer flxk_…. Create a key on Developers with the programs:read and/or programs:write scopes. Keys are per workspace; a program is only reachable with a key from the workspace that owns it. Available on the Brand Growth and Brand Scale plans. 60 requests a minute per key.
Base URL: https://app.flixerpay.com/api/v1. JSON in, JSON out; responses are { data } or { error, detail? }.
Endpoints
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /programs | programs:read | Your programs. |
| POST | /programs | programs:write | Create one: { name, config }. |
| GET | /programs/:id | programs:read | A program, its config and headline numbers. |
| PATCH | /programs/:id | programs:write | Change name, config or status (active | paused | archived). |
| PUT | /programs/:id/members/:externalId | programs:write | Enrol a customer (idempotent). Returns their referral code and link. |
| GET | /programs/:id/members/:externalId | programs:read | Balance, lifetime points, tier, referral code and link, conversions. |
| GET | /programs/:id/members/:externalId/ledger | programs:read | Every point in and out, newest first. |
| POST | /programs/:id/referrals | programs:write | A new customer signed up with a code: { externalId, code }. |
| POST | /programs/:id/events | programs:write | Something a customer did: { externalId, event, amountNgn? } + Idempotency-Key. |
| POST | /programs/:id/redemptions | programs:write | Spend points: { externalId, points, rewardCode } + Idempotency-Key. |
| GET | /programs/:id/redemptions | programs:read | Latest redemptions, to reconcile what you delivered. |
| POST | /programs/:id/redemptions/:redemptionId | programs:write | { decision: fulfilled | cancelled, reference? }. Cancelling returns the points. |
| GET | /programs/:id/leaderboard | programs:read | Top customers by lifetime points. |
Program config
{
"kind": "both", // "referral" | "loyalty" | "both"
"landingUrl": "https://yourapp.ng/signup", // referral links send people here with ?ref=CODE
"referrerPoints": 500, // to the customer who referred
"refereePoints": 200, // to the new customer
"qualifyingEvent": "first_purchase",// the event that converts a referral
"attributionDays": 30, // …if it happens within this many days of sign-up
"maxReferralsPerMember": 50, // null = no limit
"pointsPer100Ngn": 1, // spend-based earning on events that carry amountNgn
"rules": [ // points for specific events
{ "event": "data_purchase", "points": 10, "maxPerMember": null },
{ "event": "app_review", "points": 100, "maxPerMember": 1 }
],
"tiers": [{ "name": "Silver", "minPoints": 1000 }, { "name": "Gold", "minPoints": 5000 }],
"pointsExpireDays": 365 // null = points never expire
}Idempotency
Events and redemptions require an Idempotency-Key header (or idempotencyKey in the body) — use your own order or transaction id. Sending the same key again returns the first result with duplicate: true and awards or spends nothing twice. Retries are always safe.
Referral rules
- First referrer wins — a customer can be referred once per program.
- Self-referral is refused.
- The referral converts only on
qualifyingEventwithinattributionDaysof sign-up; both sides are rewarded then, not at sign-up. - After
maxReferralsPerMember, the new customer is still rewarded; the referrer is not. - Referral links are
https://app.flixerpay.com/r/CODE: taps are counted, then the person lands on yourlandingUrl?ref=CODE.
Webhooks
Register an endpoint on Developers. Payloads are signed (X-Flixerpay-Signature, HMAC-SHA256).
program.points.earned— a customer earned points from an event.program.referral.converted— a referral converted; both sides were rewarded.program.tier.changed— a customer moved tier.program.redemption.requested— deliver this reward, then mark it fulfilled.
Example: a bill-payments app
# A customer buys ₦1,500 of data. Earns 10 (rule) + 15 (1 per ₦100) points,
# and if this is their first purchase within 30 days of being referred, the referral converts.
curl -X POST https://app.flixerpay.com/api/v1/programs/PROGRAM_ID/events \
-H "Authorization: Bearer $FLX_KEY" -H "Idempotency-Key: txn_88213" \
-d '{"externalId":"cust_4412","event":"data_purchase","amountNgn":1500}'
# They trade 500 points for ₦500 airtime. You get program.redemption.requested, top them up, then:
curl -X POST https://app.flixerpay.com/api/v1/programs/PROGRAM_ID/redemptions/REDEMPTION_ID \
-H "Authorization: Bearer $FLX_KEY" -d '{"decision":"fulfilled","reference":"airtime_txn_551"}'Errors
400 invalid input (invalid_external_id, invalid_event, idempotency_key_required) · 401 bad key · 403 insufficient_scope or plan_required · 404 program_not_found, member_not_found, unknown_code · 409 self_referral, already_referred, insufficient_points, program_not_active · 422 invalid_program (with detail) · 429 rate limited.