API and webhooks
Connect your register, your online store or any system of your own to Trivu Loyalty. Available on the Business plan and on Agency Scale clients.
Authentication
Create keys in Settings → API and webhooks (owners and admins only). Send the key in every request:
Authorization: Bearer tlk_xxxxxxxxxxxxxxxxxxxxxxxx- A key is shown once when you create it. If you lose it, revoke it and create another.
- Read-only keys list members and programs; read-and-write keys can also create members and add or redeem balance.
- Up to 5 active keys per business. A revoked key stops working at once.
- About 200 requests a minute per key; beyond that you get 429 RATE_LIMITED.
Base URL: https://loyalty.trivuapp.com/api/v1. Errors look like {"error":"CODE"} with the matching HTTP status.
Endpoints
GET | /members | List members (search, limit, cursor) |
GET | /members/{id} | One member with cards and balances |
POST | /members | Create a member (write key) |
POST | /transactions | Earn or spend balance (write key) |
POST | /redemptions | Redeem a reward (write key) |
GET | /programs | Active programs and their rewards |
Adding balance
curl https://loyalty.trivuapp.com/api/v1/transactions \
-H "Authorization: Bearer tlk_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"passId": "cmv...",
"unit": "POINTS",
"kind": "EARN",
"amount": 40,
"spendCents": 1250,
"reason": "Compra en caja",
"idempotencyKey": "venta-10482"
}'idempotencyKey (8 to 150 characters) is required: repeating the same request with the same key never adds twice, it returns the original movement. Use a stable id from your sale. The answer includes the resulting balance; 409 INSUFFICIENT_BALANCE if the balance is not enough.
Webhooks
A webhook is a public https address of your system that Trivu calls when something happens. Up to 5 per business; private or internal addresses are not accepted.
member.created | A member card is created (dashboard, sign-up page or API) |
transaction.created | Any points, stamps or cashback movement, including birthday and automation bonuses. Gift cards do not emit events yet |
reward.redeemed | A reward is redeemed (also emits transaction.created) |
Events carry ids and the movement, not personal data: use GET /members/{id} to look the person up.
{
"id": "cmv...",
"type": "transaction.created",
"createdAt": "2026-11-02T15:04:05.000Z",
"data": {
"entryId": "cmv...",
"passId": "cmv...",
"customerId": "cmv...",
"unit": "POINTS",
"kind": "EARN",
"amount": 40,
"reason": "Compra en caja",
"branchId": null,
"createdAt": "2026-11-02T15:04:05.000Z"
}
}Verify the signature
Each delivery has the headers Trivu-Event, Trivu-Delivery (same as the event id: use it to ignore duplicates) and Trivu-Signature, in the form t=<seconds>,v1=<hex>. v1 is the HMAC-SHA256 of "<t>.<exact body received>" with the webhook's secret (whsec_…, shown once). Reject events with a wrong signature or an old t.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(secret, header, rawBody) {
const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return v1.length === expected.length &&
timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}Delivery and retries
- Answer 2xx within 8 seconds. Redirects are not followed.
- Failures are retried after 1 minute, 5 minutes, 30 minutes and 2 hours: 5 attempts in total.
- After 10 failed deliveries in a row the webhook switches itself off; turn it on again from the dashboard.
- The "Send test" button sends a ping event to check your receiver and your signature code.