Rewards

Tangible rewards — coupons, gift cards, discount vouchers, and free items — are issued automatically when a campaign fires. Use these endpoints to list, retrieve, and manage rewards for your members. Subscribe to the reward.issued webhook to be notified when a code is ready.

Fulfilment flow

Campaign fires → reward row created (PENDING_FULFILMENT)
→ fulfilment worker generates code → state → ISSUED
reward.issued webhook fires

Reward States

PENDING_FULFILMENT

Reward row created; fulfilment worker has not yet generated the code. Usually resolves within seconds.

ISSUED

Code generated and ready for the member to use. The reward.issued webhook fires on this transition.

EXPIRED

Reward passed its expiry date or was manually expired via the API.

FAILED

Fulfilment worker exhausted all retries. Inspect the reward record for the error detail.

Reward Types

The value envelope shape varies by rewardType:

rewardTypeDescriptionvalue fields
COUPON_VOUCHERA voucher code redeemable in-store or online. Code is generated by the fulfilment worker.
providerdescriptioncode (populated after fulfilment)
GIFT_CARDA monetary gift card loaded with a fixed value. Amount is in cents.
amount (cents)currencycode (populated after fulfilment)
DISCOUNT_VOUCHERA percentage or fixed-amount discount voucher. Printed with a unique code.
discountType (PERCENTAGE | FIXED)valuedescriptioncode
FREE_ITEMA complimentary item redeemable by the member. Can be scoped to specific SKUs.
descriptionskus (optional SKU list)code

Endpoints

GET
/tenants/{tenantId}/members/{memberId}/rewards

List all rewards for a member. Filter by state: ISSUED · PENDING_FULFILMENT · EXPIRED · FAILED.

GET
/tenants/{tenantId}/rewards

List all rewards across the tenant. Supports memberId, state, and rewardType filters.

GET
/tenants/{tenantId}/rewards/{rewardId}

Retrieve a single reward by ID, including current state, value envelope, and timestamps.

POST
/tenants/{tenantId}/rewards/{rewardId}/redeem

Mark a reward as redeemed at the point of use. Idempotent — safe to call twice.

POST
/tenants/{tenantId}/rewards/{rewardId}/expire

Manually expire a reward before its natural expiry date.

List member rewards

cURL
curl "https://loyalty-engine-production-e5cb.up.railway.app/v1/tenants/$TENANT_ID/members/$MEMBER_ID/rewards" \
  -H "X-API-Key: sk_test_YOUR_KEY"

Reward object

DISCOUNT_VOUCHER
{
  "id":         "rwd_01HX...",
  "memberId":   "9f4c2e8a-...",
  "campaignId": "5a7b3c9d-...",
  "state":      "ISSUED",
  "rewardType": "DISCOUNT_VOUCHER",
  "value": {
    "discountType": "PERCENTAGE",
    "value":        15,
    "description":  "Happy Birthday — 15% off your next purchase",
    "code":         "BDAY-A3X9-K2P1"
  },
  "issuedAt":   "2026-01-15T10:30:00.000Z",
  "expiresAt":  "2026-02-15T23:59:59.000Z",
  "redeemedAt": null
}

Redeem a reward

cURL
curl -X POST "https://loyalty-engine-production-e5cb.up.railway.app/v1/tenants/$TENANT_ID/rewards/$REWARD_ID/redeem" \
  -H "X-API-Key: sk_test_YOUR_KEY"

# Response:
# {
#   "id":         "rwd_01HX...",
#   "state":      "REDEEMED",
#   "redeemedAt": "2026-01-15T14:22:00.000Z"
# }

Poll GET /members/:memberId/rewards after calling evaluate() or processEvent() to retrieve issued codes. Or subscribe to reward.issued for a push notification when codes are ready.

Rewards — API Reference