Browse rewards, redeem coupons, list customer coupons, and validate (use) coupons via the Zupy API
Coupons are the core reward delivery mechanism in Zupy. When a customer redeems a reward, a coupon is created with a unique code (CZ-XXXXXXXX). The partner can then list, display, and validate (use) that coupon at the point of sale.
Prerequisites: Your API key (zupy_pk_*) and familiarity with the Authentication page. If your integration requires OTP for redemption or coupon usage, see the OTP Flow guide first.
Query the reward catalog to see what rewards are available for a customer. The customer_id parameter enriches each reward with the customer’s redemption status.
Copy
GET /api/v2/rewards/?customer_id={id}
Key query parameters:
Parameter
Type
Description
customer_id
string
Customer KSUID — enriches response with already_redeemed flag
redeemable
boolean
If true, only returns rewards the customer can currently afford
Response fields:
Field
Type
Description
id
string
Reward KSUID (use in redeem URL)
name
string
Reward display name
points_required
integer
Points needed to redeem
is_available
boolean
Whether the reward is currently active
already_redeemed
boolean
Whether this customer already redeemed this reward
validity_days
integer
Days the coupon remains valid after redemption
Copy
curl -X GET "https://api.zupy.com/api/v2/rewards/?customer_id=2awTHloSJX7kGGprFerOOsvABcd" \ -H "X-API-Key: zupy_pk_your_api_key_here"
Retrieve all coupons for a customer, optionally filtered by status.
Copy
GET /api/v2/rewards/coupons/?customer_id={id}
Key query parameters:
Parameter
Type
Description
customer_id
string
Required. Customer KSUID
status
string
Filter by status: active, used, expired, cancelled
Response fields:
Field
Type
Description
id
string
Coupon KSUID (use in validate URL)
coupon_code
string
Unique coupon code (CZ-XXXXXXXX)
status
string
active, used, expired, or cancelled
remaining_usages
integer
How many times the coupon can still be used
total_usages_allowed
integer
Total uses allowed (1 for single-use coupons)
valid_until
string
ISO 8601 expiration date
reward_name
string
Name of the redeemed reward
Copy
# All coupons for a customercurl -X GET "https://api.zupy.com/api/v2/rewards/coupons/?customer_id=2awTHloSJX7kGGprFerOOsvABcd" \ -H "X-API-Key: zupy_pk_your_api_key_here"# Only active couponscurl -X GET "https://api.zupy.com/api/v2/rewards/coupons/?customer_id=2awTHloSJX7kGGprFerOOsvABcd&status=active" \ -H "X-API-Key: zupy_pk_your_api_key_here"
Validate a coupon to mark it as used. This is an atomic operation — concurrent validate calls are race-safe (uses database-level locking).
Copy
POST /api/v2/customers/{id}/coupons/{coupon_id}/validate/
Send an empty POST body (no JSON needed).Response fields:
Field
Type
Description
coupon_code
string
The validated coupon code
status
string
"validated" — confirms the coupon was successfully used
remaining_usages
integer
Remaining uses after validation
total_usages_allowed
integer
Total uses allowed for this coupon
validated_at
string
ISO 8601 timestamp of validation
This is an atomic operation. The backend uses select_for_update() to prevent race conditions. If two concurrent validate calls hit the same coupon, only one will succeed — the other returns 409 Conflict.
Copy
curl -X POST "https://api.zupy.com/api/v2/customers/2awTHloSJX7kGGprFerOOsvABcd/coupons/2cxSLnqYLZ0nJJsuIhuSSvyFGij/validate/" \ -H "X-API-Key: zupy_pk_your_api_key_here"