Event Reference
All payloads follow the standard envelope. The data field is documented for each event below.
stamp.earned
Fired when a customer earns stamps from a purchase.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"event": "stamp.earned",
"occurred_at": "2026-04-19T14:30:00Z",
"organization": "kahveci-mehmet",
"data": {
"customer_code": 482193,
"customer_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"stamps_added": 2,
"stamp_balance": 7,
"max_stamps": 10,
"source": "webhook",
"transaction_id": "7c9e6679-7bd5-4b1a-9e10-5a9b3e4d6f2c",
"amount": 85.50
}
}| Field | Type | Description |
|---|---|---|
customer_code | int | 6-digit customer identifier |
customer_id | UUID | Customer's internal ID |
stamps_added | int | Number of stamps added in this transaction |
stamp_balance | int | Customer's total stamp balance after this event |
max_stamps | int | Stamps required to fill the card (earn a reward) |
source | string | Transaction source: "webhook" (POS API), "manual" (merchant app) |
transaction_id | UUID | Internal transaction ID |
amount | float | Purchase amount (present when a monetary amount was passed; omitted otherwise) |
stamp.redeemed
Fired when a customer's stamp card fills and a reward coupon is issued. This fires during an earn call — not when the customer redeems a coupon at the counter.
stamp.redeemed fires in the same earn transaction that completes the stamp card. It means a coupon was created and is ready to use. See coupon.redeemed for when the customer actually uses the coupon.
{
"id": "...",
"event": "stamp.redeemed",
"occurred_at": "2026-04-19T15:00:00Z",
"organization": "kahveci-mehmet",
"data": {
"customer_code": 482193,
"customer_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"stamps_added": 1,
"coupon_id": "e3b0c442-98fc-1c14-9afb-f4c8996fb924",
"coupon_name": "Free Coffee",
"transaction_id": "7c9e6679-7bd5-4b1a-9e10-5a9b3e4d6f2c"
}
}| Field | Type | Description |
|---|---|---|
customer_code | int | 6-digit customer identifier |
customer_id | UUID | Customer's internal ID |
stamps_added | int | Stamps added in the earn call that triggered the card fill |
coupon_id | UUID | The newly issued reward coupon |
coupon_name | string | Reward coupon name as configured by the merchant |
transaction_id | UUID | Internal transaction ID of the earn call |
points.earned
Fired when a customer earns loyalty points.
{
"id": "...",
"event": "points.earned",
"occurred_at": "2026-04-19T14:30:00Z",
"organization": "my-store",
"data": {
"customer_code": 391047,
"customer_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"points_added": 125,
"point_balance": 870,
"source": "webhook",
"transaction_id": "9a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"amount": 85.50
}
}| Field | Type | Description |
|---|---|---|
customer_code | int | 6-digit customer identifier |
customer_id | UUID | Customer's internal ID |
points_added | int | Points earned in this transaction |
point_balance | int | Total point balance after this event |
source | string | Transaction source: "webhook" (POS API), "manual" (merchant app) |
transaction_id | UUID | Internal transaction ID |
amount | float | Purchase amount (present when a monetary amount was passed; omitted otherwise) |
points.spent
Fired when a customer spends loyalty points.
{
"id": "...",
"event": "points.spent",
"occurred_at": "2026-04-19T16:00:00Z",
"organization": "my-store",
"data": {
"customer_code": 391047,
"customer_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"points_spent": 500,
"points_earned": 0,
"point_balance": 370,
"remaining_amount": 34.50,
"amount": 85.50,
"transaction_id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}
}| Field | Type | Description |
|---|---|---|
customer_code | int | 6-digit customer identifier |
customer_id | UUID | Customer's internal ID |
points_spent | int | Points deducted in this transaction |
points_earned | int | Points awarded in the same transaction (usually 0 on a pure redemption) |
point_balance | int | Remaining point balance after this event |
remaining_amount | float | Purchase amount not covered by the redeemed points |
amount | float | Total transaction amount |
transaction_id | UUID | Internal transaction ID |
coupon.redeemed
Fired when a customer's coupon is scanned and marked as used — i.e. the customer presents the reward coupon at the counter and the merchant scans it.
Don't confuse this with stamp.redeemed. stamp.redeemed fires when the stamp card fills and a coupon is created. coupon.redeemed fires when that coupon is later used at the counter.
{
"id": "...",
"event": "coupon.redeemed",
"occurred_at": "2026-04-19T17:00:00Z",
"organization": "kahveci-mehmet",
"data": {
"customer_code": 482193,
"customer_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"coupon_id": "c3d4e5f6-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
"coupon_name": "Free Coffee",
"redeemed_at": "2026-04-19T17:00:00Z"
}
}| Field | Type | Description |
|---|---|---|
customer_code | int | 6-digit customer identifier |
customer_id | UUID | Customer's internal ID |
coupon_id | UUID | Coupon's internal ID |
coupon_name | string | Coupon name as configured by the merchant |
redeemed_at | ISO 8601 | Timestamp when the coupon was used |
customer.enrolled
Fired when a new customer joins the loyalty program. This fires only when a customer is created for the first time (is_new: true) — it does not fire when an existing customer is looked up via the enroll endpoint.
{
"id": "...",
"event": "customer.enrolled",
"occurred_at": "2026-04-19T10:00:00Z",
"organization": "kahveci-mehmet",
"data": {
"customer_code": 482193,
"customer_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"masked_email": "j***@gmail.com",
"enrolled_at": "2026-04-19T10:00:00Z"
}
}| Field | Type | Description |
|---|---|---|
customer_code | int | 6-digit customer identifier |
customer_id | UUID | Customer's internal ID |
masked_email | string | Masked email address (j***@gmail.com) — full email is never exposed |
enrolled_at | ISO 8601 | Registration timestamp |
Privacy: The full customer email is never included in webhook payloads. Only the masked form is sent.