Skip to main content

Claim Coupon Endpoint

Assigns an available coupon code to the signed-in user. After a successful claim the code moves to the user's wallet and its status becomes issued.

  • Endpoint: /api/v1/campaigns/coupons/claim
  • Method: POST
  • Authentication: Partner token and a signed-in user (Sanctum bearer token).

Headers

HeaderValueRequiredDescription
Partner-Access-TokenBase64 StringYesYour encrypted AES-256 time-sensitive token.
AuthorizationBearer <token>YesSanctum token of the signed-in user.
Content-Typeapplication/jsonYes
Acceptapplication/jsonYes
X-Currencye.g. THBOptionalCurrency for all money fields. Defaults to THB.

Payload Parameters

ParameterTypeRequiredDescription
coupon_codeStringYesThe code to claim, taken from a campaign or coupon-codes response.

Sample Payload

{
"coupon_code": "SONGKRAN10"
}

Sample Response

{
"result": 1,
"message": "Coupon claimed successfully.",
"data": {
"coupon": {
"id": 9821,
"code": "SONGKRAN10",
"status": "issued",
"issued_at": "2026-04-02T09:00:00.000000Z",
"coupon_expiry": "2026-05-31T23:59:59.000000Z",
"claim_expiry": "2026-04-04T09:00:00.000000Z",
"campaign": {
"id": 41,
"name": "Songkran Hotel Sale",
"slug": "songkran-hotel-sale",
"status": "running",
"promotion_type": "coupon",
"start_at": "2026-04-01T00:00:00.000000Z",
"end_at": "2026-04-30T23:59:59.000000Z",
"coupon_expiry": "2026-05-31T23:59:59.000000Z",
"description": "Save on hotel stays across Thailand.",
"term_and_conditions": "<p>One coupon per booking.</p>",
"images": [],
"applicable_for": "Valid for <strong>Hotel</strong> in <strong>Thailand</strong>"
}
}
}
}

Response Fields

FieldTypeDescription
idIntegerCoupon code row ID. Pass it to the Delete Claimed Coupon endpoint to release the claim.
statusStringissued — the raw status. The listing endpoints show this as claimed.
issued_atDateTimeWhen the claim happened, UTC.
claim_expiryDateTime | nullDeadline to use the code, computed from issued_at plus the campaign's claim duration.

Validation Rules Applied

The claim is executed inside a database transaction with a row lock, so two users cannot take the same code. It fails when any of the following is true:

ConditionMessage
The code does not existCoupon code not found.
The code belongs to a different partner's poolYou are not allowed to claim this coupon.
The code is already taken or on holdCoupon is already issued or invalid.
The code's own expiry has passedThe coupon has expired.
The campaign is not runningCampaign is not running.
The campaign is a voucher campaignVouchers cannot be claimed through this endpoint.
Today is before start_atThe campaign has not started yet.
Today is after end_atThe campaign has ended.
The campaign-level coupon expiry has passedThe campaign-level coupon expiry date has passed.
The user already holds the maximum for this couponYou have reached the maximum number of coupons you can claim.
The campaign is switched offCampaign is not active.
Your partner is not linked to the campaignThe requested partner is not associated with this campaign.

Sample Failure Response

{
"result": 0,
"message": "Coupon is already issued or invalid."
}

Notes

  • Failures return HTTP 200 with result: 0. Always branch on result, not on the status code.
  • The per-user limit is counted per coupon, not per campaign. A campaign with several discount settings lets the user claim one code from each.
  • Only issued and redeemed codes count against that limit; expired or voided codes do not block the user.