Skip to main content
POST
Validate (use) a coupon

Authorizations

X-API-Key
string
header
required

Per-company partner API key (zupy_pk_…). Validated by Zupy against the company integration key hash (Story 14.x); send it on every request as the X-API-Key header. Scoped read-write to the owning company's data.

Headers

X-OTP-Session
string

OTP session token returned by POST /auth/verify-otp/. REQUIRED when the company's integration OTP policy enables it (require_otp_for_redemption for redeem, require_otp_for_coupon_usage for validate). Omitting it returns 403 with code "otp-required".

Path Parameters

coupon_id
string
required

Accepts EITHER the RewardRedemption KSUID (e.g. 16a33f27fbbc1801d63d56d2027) OR the customer-facing coupon_code (e.g. CZ-914F15F3 or CP-LEGACY01). Lookup by code is case-insensitive — both CZ-914F15F3 and cz-914f15f3 resolve to the same coupon. The response always echoes the canonical upper-case form.

id
string
required

Unique identifier for this customer.

Response

Coupon validation result with current status, remaining usages, and a settled-state snapshot of the customer's balances. Story W.x: response now mirrors RewardRedeemResponse — partners get customer_id + new_balance + new_z_balance without a follow-up GET.

customer_id
string
required

Customer KSUID (matches the {id} in the URL path).

coupon_code
string
required
status
enum<string>
required
Available options:
validated
remaining_usages
integer
required
total_usages_allowed
integer
required
validated_at
string<date-time>
required
new_balance
integer
required

Customer's points balance after validation. Validate itself debits 0 pts (points were spent at redemption time); this is the current balance so partners don't need an extra GET /customers/{id}/points/ to confirm settled state.

new_z_balance
string<decimal>
required

Customer's current Z$ balance after validation, as a stringified Decimal with 6 places (matches the format used everywhere else in the API).