Create a voucher code

POST
/voucher-codes

Creates a voucher code, together with the variants it targets and the date_ranges it spans, in one transaction — a rejected target leaves no voucher code behind. Send only the discount fields belonging to the discount_type you choose.

Header Parameters

Idempotency-Key?string

Client-generated key for idempotent writes; the server deduplicates retries within a 24-hour window.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

discount_type*string
Value in"percentage"
code*string

The code a customer enters at checkout. Letters, digits, and hyphens only. Unique among the company's voucher codes; deleting one frees its code for reuse.

Match^[A-Za-z0-9-]+$
discount_percentage*integer

Share taken off the price, 1–100. Required when discount_type is percentage.

Range1 <= value <= 100
discount_amount?integer

Fixed amount taken off the price, in minor units of the company's currency. Required when discount_type is monetary.

Range0 <= value
bogof_purchase?integer

Number of items a customer must buy to earn the free ones. Required with bogof_free when discount_type is bogof.

Range1 <= value
bogof_free?integer

Number of items given free once bogof_purchase items are bought. Required with bogof_purchase when discount_type is bogof.

Range1 <= value
redemption_limit?integer | null

Maximum number of items the voucher can be redeemed against in total. Null means unlimited, and is the default.

Range1 <= value
minimum_quantity?integer

Number of items a booking must contain before the voucher applies. Defaults to 1.

Range1 <= value
expires_on?string | null

Last day the voucher can be redeemed, inclusive. Wall-clock ISO 8601 YYYY-MM-DD with no timezone offset; anything else, a full timestamp included, is rejected with 422. Null means it never expires, and is the default.

Formatdate
applies_automatically?boolean

When true, the discount applies without the customer entering the code. Defaults to false. Cannot be true alongside apply_to_all_products — that combination is rejected with 422.

apply_to_all_products?boolean

When true, the voucher covers every product and cannot carry variants. Defaults to false. Turning it on discards the variants the voucher already targets, and turning it off again does not restore them.

variants?array<string>

Prefixed IDs of the products the voucher can be redeemed against — experience variants (expv_), accommodation variants (accv_), extras (ext_), or packages (pkg_). What you send is the complete set: it replaces whatever the voucher targeted before, and an empty array clears it. An ID naming anything else, or a resource in another company, is reported as unknown with 422.

date_ranges?array<>

The travel-date windows the voucher applies to. What you send is the complete set: it replaces whatever the voucher spanned before, and an empty array clears it, leaving the voucher valid for any travel date.

discount_type*string
Value in"monetary"
code*string

The code a customer enters at checkout. Letters, digits, and hyphens only. Unique among the company's voucher codes; deleting one frees its code for reuse.

Match^[A-Za-z0-9-]+$
discount_percentage?integer

Share taken off the price, 1–100. Required when discount_type is percentage.

Range1 <= value <= 100
discount_amount*integer

Fixed amount taken off the price, in minor units of the company's currency. Required when discount_type is monetary.

Range0 <= value
bogof_purchase?integer

Number of items a customer must buy to earn the free ones. Required with bogof_free when discount_type is bogof.

Range1 <= value
bogof_free?integer

Number of items given free once bogof_purchase items are bought. Required with bogof_purchase when discount_type is bogof.

Range1 <= value
redemption_limit?integer | null

Maximum number of items the voucher can be redeemed against in total. Null means unlimited, and is the default.

Range1 <= value
minimum_quantity?integer

Number of items a booking must contain before the voucher applies. Defaults to 1.

Range1 <= value
expires_on?string | null

Last day the voucher can be redeemed, inclusive. Wall-clock ISO 8601 YYYY-MM-DD with no timezone offset; anything else, a full timestamp included, is rejected with 422. Null means it never expires, and is the default.

Formatdate
applies_automatically?boolean

When true, the discount applies without the customer entering the code. Defaults to false. Cannot be true alongside apply_to_all_products — that combination is rejected with 422.

apply_to_all_products?boolean

When true, the voucher covers every product and cannot carry variants. Defaults to false. Turning it on discards the variants the voucher already targets, and turning it off again does not restore them.

variants?array<string>

Prefixed IDs of the products the voucher can be redeemed against — experience variants (expv_), accommodation variants (accv_), extras (ext_), or packages (pkg_). What you send is the complete set: it replaces whatever the voucher targeted before, and an empty array clears it. An ID naming anything else, or a resource in another company, is reported as unknown with 422.

date_ranges?array<>

The travel-date windows the voucher applies to. What you send is the complete set: it replaces whatever the voucher spanned before, and an empty array clears it, leaving the voucher valid for any travel date.

discount_type*string
Value in"bogof"
code*string

The code a customer enters at checkout. Letters, digits, and hyphens only. Unique among the company's voucher codes; deleting one frees its code for reuse.

Match^[A-Za-z0-9-]+$
discount_percentage?integer

Share taken off the price, 1–100. Required when discount_type is percentage.

Range1 <= value <= 100
discount_amount?integer

Fixed amount taken off the price, in minor units of the company's currency. Required when discount_type is monetary.

Range0 <= value
bogof_purchase*integer

Number of items a customer must buy to earn the free ones. Required with bogof_free when discount_type is bogof.

Range1 <= value
bogof_free*integer

Number of items given free once bogof_purchase items are bought. Required with bogof_purchase when discount_type is bogof.

Range1 <= value
redemption_limit?integer | null

Maximum number of items the voucher can be redeemed against in total. Null means unlimited, and is the default.

Range1 <= value
minimum_quantity?integer

Number of items a booking must contain before the voucher applies. Defaults to 1.

Range1 <= value
expires_on?string | null

Last day the voucher can be redeemed, inclusive. Wall-clock ISO 8601 YYYY-MM-DD with no timezone offset; anything else, a full timestamp included, is rejected with 422. Null means it never expires, and is the default.

Formatdate
applies_automatically?boolean

When true, the discount applies without the customer entering the code. Defaults to false. Cannot be true alongside apply_to_all_products — that combination is rejected with 422.

apply_to_all_products?boolean

When true, the voucher covers every product and cannot carry variants. Defaults to false. Turning it on discards the variants the voucher already targets, and turning it off again does not restore them.

variants?array<string>

Prefixed IDs of the products the voucher can be redeemed against — experience variants (expv_), accommodation variants (accv_), extras (ext_), or packages (pkg_). What you send is the complete set: it replaces whatever the voucher targeted before, and an empty array clears it. An ID naming anything else, or a resource in another company, is reported as unknown with 422.

date_ranges?array<>

The travel-date windows the voucher applies to. What you send is the complete set: it replaces whatever the voucher spanned before, and an empty array clears it, leaving the voucher valid for any travel date.

Response Body

application/json

application/json

application/json

curl -X POST "https://example.com/voucher-codes" \  -H "Easol-API-Version: 2026-11-01" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "vc_aBcDeFgHiJ",
  "object": "voucher_code",
  "code": "SUMMER25",
  "discount_type": "percentage",
  "discount_percentage": 25,
  "discount_amount": {
    "amount": 0,
    "currency": "string"
  },
  "bogof_purchase": 2,
  "bogof_free": 1,
  "redemption_limit": 100,
  "redemptions": 12,
  "minimum_quantity": 1,
  "expires_on": "2026-12-31",
  "applies_automatically": true,
  "apply_to_all_products": true,
  "status": "valid",
  "variants": {
    "object": "list",
    "url": "string",
    "has_more": false,
    "next_cursor": "string",
    "data": [
      {
        "id": "expv_aBcDeFgHiJ",
        "object": "experience_variant",
        "name": "Double room",
        "tagline": "Sea view, breakfast included"
      }
    ]
  },
  "date_ranges": {
    "object": "list",
    "url": "string",
    "has_more": false,
    "next_cursor": "string",
    "data": [
      {
        "start_on": "2026-09-01",
        "end_on": "2026-09-30"
      }
    ]
  }
}
{
  "error": {
    "code": "string",
    "message": "string"
  }
}
{
  "error": {
    "code": "string",
    "message": "string"
  }
}