First points in five calls.
REST, gRPC or the .NET SDK, against the same engine. This walks through REST with curl; the documentation covers the rest.
01
Create an application
Sign up, create a Test application and copy its client ID and secret. The secret is shown once, so put it straight into your secret manager. Test applications have their own customers and never touch Live data.
02
Get a token
Exchange the credentials for an access token with the OAuth 2.0 client credentials grant. The token is scoped to that one application.
Request a tokencurl -X POST "$IDENTITY_URL/connect/token" \ -d grant_type=client_credentials \ -d client_id="$CLIENT_ID" \ -d client_secret="$CLIENT_SECRET" \ -d scope=loyalty.api
03
Award points
Send the customer's id in your system, the rule to apply and the order amount. Caps, cooldowns and tiers apply on their own. Reuse the idempotency key on a retry and the award is never made twice.
Award points for an ordercurl -X POST "$LOYALTY_API/api/v1/Engine/Earning" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "externalCustomerId": "CUST-20417", "ruleCode": "PURCHASE", "amount": 52.40, "idempotencyKey": "order-40912" }'04
Read the member
Balance, tier and progress for any customer, by your own id. The catalogue endpoint returns the rewards they can afford right now.
Read a member, then their cataloguecurl "$LOYALTY_API/api/v1/Accounts/CUST-20417" \ -H "Authorization: Bearer $TOKEN" curl "$LOYALTY_API/api/v1/Accounts/CUST-20417/Catalog" \ -H "Authorization: Bearer $TOKEN"
05
Listen for events
Subscribe a URL to an event. Every delivery carries an X-Loyalty-Signature header: an HMAC-SHA256 of the raw body, keyed with the subscription's secret. Verify it before trusting the payload.
Subscribe, then verify a delivery (Node.js)curl -X POST "$LOYALTY_API/api/v1/Webhooks" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "eventType": "level.changed", "url": "https://your-app.example/hooks/loyalty" }' // In your webhook handler, using the raw request body: import { createHmac, timingSafeEqual } from "node:crypto"; const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex"); const received = request.headers["x-loyalty-signature"] ?? ""; const valid = received.length === expected.length && timingSafeEqual(Buffer.from(received), Buffer.from(expected));