Reporting custom loyalty events
Report an event with POST /loyalty-events. It takes your secret API key like every other
admin endpoint, so call it from your server and never from storefront JavaScript.
A 202 means the event was recorded, not that anything was awarded. Rules run on a queue,
so a slow rule never holds up your checkout. loyaltyProgramIds names the programs with a
rule listening for the name; whether the customer earns is up to that rule's conditions and
caps.
Conditions, punch cards and limits
On the rule, the trigger is { "type": "customEvent", "eventName": "review.written" }, plus
any of these:
conditions, keyed by property name, such as{ "wordCount": { "$gte": 20 }, "channel": "store" }. A bare value means equality; the operators are$eq,$ne,$in,$gt,$gte,$lt,$lteand$exists. Every condition has to hold, at most 10. Types are strict, so5does not match"5"andtruedoes not match1. Send each property with one type. A missing property passes$ne.every: fire on the customer's Nth, 2Nth, 3Nth matching event. Members' progress is in the widget API asmember.ruleProgress.limit:{ "period": "day" | "week" | "month", "count": 2 }caps how often the rule pays one customer per calendar period, in the organization's time zone.variableAmountanddefaultValue: scale the reward by the event'svalue, so a 50-point rule pays 150 for avalueof 3. An event with novalueusesdefaultValue, or 1. Only points, fixed-amount coupons and gift cards can scale.
Retries, unknown customers and paused programs
- Retries. Sending the same
idempotencyKeyagain for the same customer returns the original event with"duplicate": trueand awards nothing again. Keys are per customer, so two of your systems reusing one record id don't collide. Leave the key out and every call counts. - Unknown customers. An email Meisei has never seen is a
404that names the address, so a typo doesn't create a customer. Send"createCustomer": truewhen your system is where customers sign up. - Paused programs earn nothing, so they're listed in
pausedLoyaltyProgramIdsrather than queued. This isn't an error.
Listing events
GET /loyalty-events returns events newest first. Filter on name, properties.<name>,
customer.id, customer.email or occurredAt, search by customer, and add
include=customer for the customer's details. GET /loyalty-events/{id} returns one.
Rate limits and webhooks
POST /loyalty-events allows a burst of 120 calls per organization, refilling at two a
second, on top of the organization-wide limit. Back off and retry on a
429. For backfilling balances or history, use the
member import or the
history import instead, because an event sent here earns under
today's rules.
What an event earns arrives as loyaltyTransaction.created and loyaltyReward.issued
webhooks. Full schemas are in the API reference:
Loyalty events and Loyalty rules.
What a merchant sets up, and the rules they write, are in Custom loyalty events.