Skip to main content

Applicable Coupons Endpoint

Given a cart, returns the coupons the user already claimed that can actually be used on it — each one priced with the exact discount it would give, best saving first. This is what you render in the "choose a coupon" drawer at checkout.

  • Endpoint: /api/v1/campaigns/coupons/applicable
  • Method: POST

Headers

HeaderValueRequiredDescription
Partner-Access-TokenBase64 StringYesYour encrypted AES-256 time-sensitive token.
Content-Typeapplication/jsonYes
Acceptapplication/jsonYes
X-Currencye.g. THBOptionalCurrency of grand_total and of every amount returned. Defaults to THB.

Payload Parameters

ParameterTypeRequiredDescription
user_idIntegerYesID of the user whose claimed coupons should be checked.
product_typeStringYesProduct code, e.g. pd11. See the table below.
grand_totalNumberYesCart total in the requested currency. Minimum 0.
product_idInteger | StringOptionalThe specific product being booked. Required for coupons limited to certain products or destinations.

Product Types

CodeProductSend as product_id
allEvery product
pd4More ExperiencesMore Experiences product ID
pd6Airport TransferTransfer airport ID
pd7Airport VIP AssistanceAirport package ID
pd8TourTour ID
pd9Fliggy Airline Ticket
pd11TourMind HotelHotel ID or hotel code

Sample Payload

{
"user_id": 3312,
"product_type": "pd11",
"grand_total": 4500,
"product_id": 749588
}

Sample Response

{
"result": 1,
"message": "success",
"data": {
"currency": "THB",
"coupons": [
{
"id": 9821,
"code": "SONGKRAN10",
"currency": "THB",
"discount_amount": 450,
"status": "claimed",
"discount_type": "percentage",
"discount_value": 10,
"min_purchase_amount": 1000,
"max_discount_amount": 500,
"coupon_expiry": "2026-05-31T23:59:59.000000Z",
"claim_expiry": "2026-04-04T09:00:00.000000Z",
"reward": "TourMind Hotel",
"reward_destinations": [
{
"id": 12,
"name": "Thailand"
}
],
"reward_variations": [],
"rules": [
"Save up to THB 500",
"Min. spend THB 1000"
],
"applicable_for": "Valid for <strong>Hotel</strong> in <strong>Thailand</strong>",
"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
currencyStringCurrency of discount_amount and every other amount.
couponsArrayUsable coupons, sorted by discount_amount descending. Empty when none fit.
coupons[].discount_amountNumberExact saving this coupon gives on the submitted grand_total.

How the List Is Built

Every coupon the user holds with status issued is run through the full eligibility check — timeline, minimum spend, per-user limit, product type, destination, product restrictions, and partner association. Coupons that fail any rule are silently dropped rather than returned with an error, so an empty coupons array simply means nothing fits this cart.

Notes

  • The destination is resolved automatically from product_type + product_id, so you never send a destination ID yourself.
  • grand_total is converted to THB internally before the rules run, then the resulting discount is converted back to your requested currency.
  • This endpoint reads only. It never claims, reserves, or redeems anything.
  • Validation failures (missing user_id, negative grand_total, …) return HTTP 422 with Laravel's standard validation body.