Skip to main content

Issue Coupon

Create a coupon from a template. The platform generates the code and returns it once.

Endpoint

POST /v1/coupons

Headers

HeaderTypeDescriptionRequired
X-Client-IdStringYour client ID✅ Yes
X-Client-SecretStringYour client secret✅ Yes
Content-TypeStringapplication/json✅ Yes

Request Body

FieldTypeDescriptionRequired
couponTemplateIdString (UUID)The template to issue from✅ Yes

Discount behaviour, applicability, usage limits and expiry all come from the template — see Setup Flow.

Example Request

curl --location 'https://stage-platform-exlr8-incentives.exlr8now.com/v1/coupons' \
--header 'X-Client-Id: YOUR_CLIENT_ID' \
--header 'X-Client-Secret: YOUR_CLIENT_SECRET' \
--header 'Content-Type: application/json' \
--data '{
"couponTemplateId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9"
}'

Response

Successful Response — 201 Created

{
"success": true,
"data": {
"couponId": "7c8d9e0f-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
"code": "SAVE20-K4M9XQ"
}
}

Response Fields

FieldTypeDescription
couponIdStringInternal identifier — store it for lookups
codeStringThe code the customer presents to redeem

:::caution Returned exactly once Only a hash of code is stored. It cannot be retrieved again by any endpoint. Deliver it to the customer and persist what you need before acknowledging this response. :::

Unique and shared codes

The template's codeType changes what issuance means.

UNIQUE — every call produces a distinct code. Issue one per customer. This is the usual choice for targeted offers, and typically pairs with a usage limit of one.

SHARED — every customer uses the same code, as with a public promo code. The template is issued once, and you distribute the returned code however you like. Calling this endpoint again for a shared template returns the existing coupon rather than creating another; the response shape is unchanged, so no special handling is needed.

A shared coupon is still redeemed once per customer, each redemption with its own idempotency key.

Behaviour

The campaign must be active. Issuance is refused with PROGRAM_INACTIVE when the campaign is DRAFT, PAUSED, EXPIRED or ARCHIVED. Campaigns expire automatically at their endAt, so this can begin failing without any change on your side.

Only the count cap applies here. Issuing a coupon reserves one unit of the template's issuance count, atomically with the insert, so over-issuance is impossible. Exceeding it returns TEMPLATE_LIMIT_EXCEEDED.

The value budgets — the template's and the campaign's — are not touched at issuance, because a coupon has no cost until someone redeems it. They are charged at redemption instead, which is why a coupon can issue cleanly and still fail to redeem later.

Expiry is set now. FROM_ISSUANCE computes expiry from this moment plus the template's validity period; FIXED_DATE gives every coupon the same date.

Issuance is not idempotent. No idempotency key is taken, so two calls create two coupons for a UNIQUE template. On a timeout, check List Coupons before retrying.

Error Responses

Error codeHTTPCause
BAD_REQUEST400Missing or malformed couponTemplateId, or an unknown field
TEMPLATE_NOT_FOUND404No such template within your merchant
PROGRAM_NOT_FOUND404The template points at a campaign that no longer exists
PROGRAM_INACTIVE422The campaign is not ACTIVE
TEMPLATE_LIMIT_EXCEEDED422The template's issuance count cap is reached
INTERNAL_SERVER_ERROR500Platform fault
{
"success": false,
"errCode": "TEMPLATE_LIMIT_EXCEEDED",
"message": "Template limit exceeded: coupon template issuance count limit reached"
}