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

  1. Create a program (in the dashboard or over the API).
  2. Enrol customers with PUT /members/:externalId; show them their referral link.
  3. When someone signs up with ?ref=CODE, send POST /referrals.
  4. Send POST /events for what customers do. Points are awarded, referrals convert on the qualifying event, tiers update.
  5. 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

MethodPathScopeWhat it does
GET/programsprograms:readYour programs.
POST/programsprograms:writeCreate one: { name, config }.
GET/programs/:idprograms:readA program, its config and headline numbers.
PATCH/programs/:idprograms:writeChange name, config or status (active | paused | archived).
PUT/programs/:id/members/:externalIdprograms:writeEnrol a customer (idempotent). Returns their referral code and link.
GET/programs/:id/members/:externalIdprograms:readBalance, lifetime points, tier, referral code and link, conversions.
GET/programs/:id/members/:externalId/ledgerprograms:readEvery point in and out, newest first.
POST/programs/:id/referralsprograms:writeA new customer signed up with a code: { externalId, code }.
POST/programs/:id/eventsprograms:writeSomething a customer did: { externalId, event, amountNgn? } + Idempotency-Key.
POST/programs/:id/redemptionsprograms:writeSpend points: { externalId, points, rewardCode } + Idempotency-Key.
GET/programs/:id/redemptionsprograms:readLatest redemptions, to reconcile what you delivered.
POST/programs/:id/redemptions/:redemptionIdprograms:write{ decision: fulfilled | cancelled, reference? }. Cancelling returns the points.
GET/programs/:id/leaderboardprograms:readTop 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 qualifyingEvent within attributionDays of 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 your landingUrl?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.