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
| Header | Value | Required | Description |
|---|---|---|---|
Partner-Access-Token | Base64 String | Yes | Your encrypted AES-256 time-sensitive token. |
Authorization | Bearer <token> | Yes | Sanctum token of the signed-in user. |
Content-Type | application/json | Yes | |
Accept | application/json | Yes | |
X-Currency | e.g. THB | Optional | Currency for all money fields. Defaults to THB. |
Payload Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
coupon_code | String | Yes | The 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
| Field | Type | Description |
|---|---|---|
id | Integer | Coupon code row ID. Pass it to the Delete Claimed Coupon endpoint to release the claim. |
status | String | issued — the raw status. The listing endpoints show this as claimed. |
issued_at | DateTime | When the claim happened, UTC. |
claim_expiry | DateTime | null | Deadline 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:
| Condition | Message |
|---|---|
| The code does not exist | Coupon code not found. |
| The code belongs to a different partner's pool | You are not allowed to claim this coupon. |
| The code is already taken or on hold | Coupon is already issued or invalid. |
| The code's own expiry has passed | The coupon has expired. |
The campaign is not running | Campaign is not running. |
| The campaign is a voucher campaign | Vouchers cannot be claimed through this endpoint. |
Today is before start_at | The campaign has not started yet. |
Today is after end_at | The campaign has ended. |
| The campaign-level coupon expiry has passed | The campaign-level coupon expiry date has passed. |
| The user already holds the maximum for this coupon | You have reached the maximum number of coupons you can claim. |
| The campaign is switched off | Campaign is not active. |
| Your partner is not linked to the campaign | The 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 onresult, 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
issuedandredeemedcodes count against that limit; expired or voided codes do not block the user.