Coupons and promotion codes
Discount codes in Áskell are made up of two objects that work together:
A coupon (
coupon) defines the discount itself: a fixed amount (amount_offandcurrency) or a percentage (percent_off), how long it applies (duration:forever,onceorrepeatingwithduration_in_months) and limits such asmax_redemptionsandredeem_by.A promotion code (
promotion_code) is the code the customer enters (code), and it points to a coupon. You can create many codes for the same coupon, restrict a code to a single customer, and set an expiry date (expires_at) and a minimum amount inrestrictions.
Both objects can be created, fetched, updated and deleted through the V2 API. All calls require a secret API key. Legacy token authentication is not supported on these endpoints:
Authorization: Api-Key your-secret-api-key
Full documentation of fields and responses is in our Swagger documentation under V2 Coupons at /api/swagger/v2/.
Coupons
Endpoint |
Description |
|---|---|
|
Lists coupons. Filters: |
|
Creates a coupon. |
|
Retrieves a single coupon. |
|
Partially updates a coupon. |
|
Deletes a coupon (soft delete). |
Example of creating a 20% coupon that applies for three months:
{
"name": "Sumartilboð",
"percent_off": "20",
"duration": "repeating",
"duration_in_months": 3,
"max_redemptions": 100,
"redeem_by": "2026-12-31T23:59:59Z"
}
Rules:
Exactly one of
amount_off(together withcurrency) orpercent_offmust be set. To switch from one to the other withPATCH, send the old field asnullin the same call.duration_in_monthsis required whendurationisrepeatingand must not be set otherwise.redeem_bymust be in the future unless the coupon has already expired; an expired coupon can still be updated and deleted, but a valid coupon cannot be made to expire by setting a date in the past.Unknown fields in
POSTandPATCHare rejected with400.metadataandrestrictionscan be sent asnullto clear them.idandtimes_redeemedcannot be changed.idcan be supplied on creation (letters, digits, underscores, hyphens and periods, at most 128 characters); otherwise it is generated automatically.currencymust be a valid three-letter ISO 4217 code.max_redemptionsandduration_in_monthsmust be 1 or higher.A coupon that has been redeemed (
times_redeemed> 0) cannot be deleted. Useredeem_byormax_redemptionsto close it.
Promotion codes
Endpoint |
Description |
|---|---|
|
Lists promotion codes. Filters: |
|
Creates a promotion code. |
|
Retrieves a single promotion code. |
|
Partially updates a promotion code. |
|
Deletes a promotion code (soft delete). |
Example of creating a code that a single customer can redeem only once:
{
"coupon": "coup_5f3a1c2b9d8e4f6a7b8c9d0e",
"code": "VELKOMIN",
"customer_reference": "customer-123",
"max_redemptions": 1,
"expires_at": "2026-12-31T23:59:59Z",
"restrictions": {
"minimum_amount": "1000",
"minimum_amount_currency": "ISK"
}
}
Rules:
couponmust be a coupon on the same account.codeis 4-50 characters (letters, digits, hyphens and underscores) and is always stored in uppercase. If it is omitted, a code is generated automatically. The code must be unique among the account’s active codes; inactive (active: false) and deleted codes free the code up for reuse.The customer is given with
customer(ID) orcustomer_reference, not both.nullremoves the customer binding.restrictionssupports only a minimum amount:minimum_amount(greater than 0) andminimum_amount_currency(ISO 4217 code) must be sent together. An empty{}removes the restriction.A promotion code that has been redeemed cannot be deleted. Set
activetofalseinstead.
Applying codes to subscriptions is documented with the subscription endpoints: see POST /api/v2/subscription-contracts/{contractId}/apply-code/ for V2 contracts and POST /api/subscriptions/{subscription_id}/apply-code/ for legacy subscriptions.