Activity shown in the product preview: Workflow triggered, Task complete, 12 reactions, Credits redeemed.
Build loyalty into your product on plain REST
One OAuth call, standard REST, and predictable JSON errors you can branch on - no SDK to learn, no lock-in, correct under retries.

Members, points, and logins - all over plain REST
Three resource groups, one token, one surface to learn.
One identity, however messy the data
Create members with custom attributes and link multiple accounts or devices into a single loyalty identity - so the same person never splits into two.
CreateProfileWithAttributesPoints that never double-count
Earn, redeem, and reverse with confidence - every redemption is keyed so a retry can never debit twice. Balances, statements, and expiry are one call away.
RedeemPoints · ReversalPointsMember logins, no extra identity store
Verify credentials and run OTP or passwordless sign-in through the same API - one less system for your team to build and run.
GenerateOTP · VerifyOTPThree resource groups, one OAuth token, one REST surface to learn.
Set up auth once, then forget it
Swap your Client ID and Secret for a token the platform caches and reuses until it expires - so auth is something you set up once, not something you maintain.
Your service
holds Client ID + Secret
Program-scoped Client ID and Secret, generated and rotated from the admin portal.
TokenService
issues + caches the JWT
Returns a JWT Bearer token and reuses it until it expires - a new token is only minted once the current one lapses.
Authenticated call
Authorization: Bearer
Attach the cached JWT to every v1 request. On a 401, request a fresh token and retry.
Token request - client_credentials grant
POST /oauth/Auth/Token
{
"grant_type": "client_credentials",
"client_id": "<program_client_id>",
"client_secret": "<program_client_secret>"
}Cache the token and refresh just before the window closes - don't fetch a new one on every request.
Follow the money - and see why it stays correct
Walk a redeem request from token to confirmed debit. Toggle a member with enough points against one who is short, and watch the platform branch deterministically - it never partially debits. Step through every message.
Redeem request
The client posts a redemption: which member, how many points, and the amount. Every call carries the JWT Bearer token.
POST /v1/RedeemPoints
Authorization: Bearer <jwt>
{ "memberId": "m_8124", "points": 1000, "amount": 12.50 }Built so a retry never costs a member a point
Loyalty moves money, so the contract is machine-readable and safe to retry - you branch on codes, not guesswork, and the balance stays correct under failure.
Errors you branch on, not parse
Every response carries IsSucessful, ErrorCode, ExceptionMessage, and ReturnObject alongside the HTTP status. Check one flag, branch on a numeric code - no string matching, no surprises.
200 · 400 · 401 · 404 · 409 · 422 · 500Retries never double-charge a member
RedeemPoints returns a transaction GUID, and reversal is keyed to it and runs exactly once. A second reversal against the same GUID comes back as a duplicate-reversal code, so the redeem-then-reverse path is safe to retry.
RedeemPoints → GUID → ReversalPointsThe same failure, every single time
Application failures carry deterministic codes - insufficient balance on redemption, duplicate reversal on a reused GUID, auth failure on a bad credential check - so your error handling is a switch statement, not a guess.
switch (ErrorCode) { … }Loyalty moves money, so the contract is machine-readable and safe to retry - you branch on codes, not guesswork.
Start with files today, go real-time when you are ready
Earning runs the same whether events arrive over the real-time API or as batch SFTP files - same rule engine, same ledger - so you are never blocked on your side's readiness. Redemption is a balance-checked path from catalog to fulfillment. Toggle between them.
Dual-ingestion - API or SFTP, at parity
Real-time API · Batch SFTPMembers and transactions both flow in over the real-time REST APIs or as batch CPD files over SFTP. Either channel reaches the same platform state, so you can start with batch and move to real-time later without changing earning logic.
Issuer and platform exchange member data, transaction data, and attribute definitions bidirectionally.
The endpoints you'll actually call
v1 publishes 27 documented endpoints across auth, members, sub-relations, transactions, redemption, statements, and member auth - inside a 204-API platform.
Authentication
1One OAuth 2.0 token authenticates every call that follows.
Members & profiles
4Full read/write over the loyalty identity, with custom attributes.
Sub-relations
2Link accounts, devices, or external IDs to one member.
Transactions
2Post earnings and reversals to the points ledger.
Redemption
3Balance-checked redemption with one-time, GUID-keyed reversal.
Statements & history
4Summaries, categorized statements, and the expiry schedule.
Member auth & OTP
3Verify member credentials and run one-time-passcode flows.
The same OAuth Bearer token authenticates every call.·Every response returns the same predictable JSON error envelope.
From credentials to live in three steps
A short path from first token to production - no surprises in between.
Generate credentials
Create a Client ID and Secret scoped to your program. Regenerable, with prior tokens invalidated and rotation tracked from the admin portal.
client_id · client_secretGet a token, call v1
Exchange credentials for a JWT, then call the documented v1 endpoints for members, transactions, redemption, and member auth.
POST /oauth/Auth/TokenPromote to production
Handle the standard error envelope and the one-time reversal path, then switch to live credentials. The contract is identical.
switch to live credentialsA short path from first token to production - the same error envelope and reversal contract in dev and live.