Import Promo Codes
Create many promo codes in one request. This is the same row-level import the in-app import wizard runs, so a code created here behaves identically to one created in the app.
Rows that can't be saved are reported back individually rather than failing the whole request โ useful when migrating a list from another system.
Endpointโ
POST /v1/promo-codes/import
Requires the promotions:write scope.
Request Bodyโ
| Field | Type | Required | Description |
|---|---|---|---|
promo_codes | array | Yes | 1โ500 rows. Each row is an object using the fields below. |
Row fieldsโ
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Letters, numbers, hyphens and underscores. Max 50 chars, auto-uppercased. |
name | string | No | Display name. Defaults to the code when omitted. |
description | string | No | Internal description. |
discount_type | string | Yes | percentage or fixed. Common spellings such as percent, flat and amount are also accepted. |
discount_value | string/number | Yes | The discount. Currency symbols, % and thousands separators are stripped. |
min_booking_amount | string/number | No | Minimum booking total required. |
max_discount_amount | string/number | No | Maximum discount cap. |
valid_from | string | No | Start date. ISO (2026-06-01) or the supplier's own date order. Past dates are accepted. |
valid_until | string | No | Expiration date, same formats. |
max_uses | integer | No | Total usage limit. |
max_uses_per_customer | integer | No | Per-customer usage limit. |
status | string | No | active (default) or inactive. |
Imported codes apply to everything the supplier sells. Use Update Promo Code afterwards to narrow a code to specific products, experiences or store items.
Example Requestโ
curl -X POST "https://app.equipdash.com/api/v1/promo-codes/import" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"promo_codes": [
{
"code": "SUMMER-2026",
"name": "Summer discount",
"discount_type": "percentage",
"discount_value": 20,
"valid_from": "2026-06-01",
"valid_until": "2026-08-31",
"max_uses": 100
},
{
"code": "WELCOME-BACK",
"discount_type": "fixed",
"discount_value": "$15.00"
},
{
"code": "SPRING BREAK",
"discount_type": "percentage",
"discount_value": 10
}
]
}'
Responseโ
{
"data": {
"imported": 2,
"skipped": 1,
"skipped_rows": [
{
"row": 3,
"code": "SPRING BREAK",
"reason": "The code can only contain letters, numbers, hyphens and underscores."
}
]
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-06-01T10:00:00+00:00"
}
}
row is the 1-based position of the row in the promo_codes array you sent.
Skip Reasonsโ
| Reason | Cause |
|---|---|
Already in your promo codes | A code with that exact text already exists. Existing codes are never overwritten. |
The code can only contain letters, numbers, hyphens and underscores. | The code contains spaces or punctuation. |
Discount type "โฆ" not recognized โ use "percentage" or "fixed" | The discount type could not be interpreted. |
A percentage discount cannot be more than 100% | A percentage row has a value above 100. |
Valid from date "โฆ" not recognized โ use a date like 31-12-2026 | The date could not be parsed. |
Valid until is before valid from | The date range is inverted. |
| Validation messages | A required field is missing or a number is out of range. |
Notesโ
- The request is idempotent for codes that already exist โ re-sending the same list only adds what's missing.
- A maximum of 500 rows per request; send larger lists in batches.
- Codes are always created against the supplier the API key belongs to.