Discounts
Discount codes are manually-entered codes that customers apply at checkout for a percentage or fixed-amount discount. Unlike promotions (which apply automatically), discount codes require the customer to enter a code during checkout.
Discount codes support scheduling (starts_at/ends_at), global and per-customer usage limits, minimum cart requirements (subtotal or quantity), customer group eligibility, and compatibility controls with automatic promotions.
Codes must contain only letters and numbers (A-Z, 0-9) and are automatically uppercased by the API. For example, submitting summer20 stores and matches as SUMMER20.
Base URL: https://api.hydrajs.dev
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/v1/discounts |
Secret | List discount codes |
POST |
/v1/discounts |
Secret | Create a discount code |
GET |
/v1/discounts/{id} |
Secret | Get a discount code |
PATCH |
/v1/discounts/{id} |
Secret | Update a discount code |
DELETE |
/v1/discounts/{id} |
Secret | Delete a discount code |
ℹApplying discounts at checkout
To apply or remove a discount code during checkout, use the checkout endpoints:
POST /v1/checkout/{id}/discount— apply a discount codeDELETE /v1/checkout/{id}/discount— remove the applied discount code
These endpoints accept publishable keys and are documented in the Checkout API.
List discount codes
GET /v1/discounts
Returns a paginated list of discount codes.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 25 |
Results per page (1-250) |
cursor |
string | - | Pagination cursor from a previous response |
sort |
string | created_at |
Sort field: created_at, updated_at, code |
order |
string | desc |
Sort direction: asc, desc |
status |
string | - | Filter by status: active, disabled |
search |
string | - | Filter by code or title (case-insensitive substring match) |
fields |
string | - | Comma-separated fields to return |
Request
curl https://api.hydrajs.dev/v1/discounts?status=active&limit=10 \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
"data": [
{
"id": "disc_abc123def456ghij",
"code": "SUMMER20",
"title": "Summer Sale 20%",
"type": "percentage",
"value": 20,
"status": "active",
"min_subtotal": 5000,
"min_quantity": null,
"max_uses": 1000,
"max_uses_per_customer": 1,
"used": 42,
"exclusive": true,
"combinable_with_promotions": true,
"customer_group_ids": null,
"starts_at": "2026-06-01T00:00:00Z",
"ends_at": "2026-08-31T23:59:59Z",
"created_at": "2026-05-15T09:30:00Z",
"updated_at": "2026-05-15T09:30:00Z"
}
],
"pagination": {
"cursor": "eyJ0IjoiMjAyNi...",
"has_more": false,
"total": 1
}
}
ℹPagination
All list endpoints use cursor-based pagination. Pass the cursor value from the response to fetch
the next page.
Create a discount code
POST /v1/discounts
Creates a new discount code. The code value is trimmed and uppercased before storage.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Discount code (1-50 chars, letters and numbers only) |
title |
string | Yes | Human-readable title (1-255 chars) |
type |
string | Yes | Discount type: percentage, fixed_amount |
value |
integer | Yes | Discount value (1-100 for percentage, cents for fixed) |
status |
string | No | active (default) or disabled |
min_subtotal |
integer | null | No | Minimum cart subtotal in cents (null = no minimum) |
min_quantity |
integer | null | No | Minimum total item quantity (null = no minimum) |
max_uses |
integer | null | No | Maximum total uses across all customers (null = unlimited) |
max_uses_per_customer |
integer | null | No | Maximum uses per customer email (null = unlimited) |
exclusive |
boolean | No | Whether this code is exclusive (default: true) |
combinable_with_promotions |
boolean | No | Whether this code can be used alongside automatic promotions (default: true) |
customer_group_ids |
string[] | null | No | Restrict to members of these customer groups (null = all customers) |
starts_at |
string | Yes | ISO 8601 start datetime |
ends_at |
string | null | No | ISO 8601 end datetime (null = no end, must be after starts_at) |
Request
curl -X POST https://api.hydrajs.dev/v1/discounts \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "SUMMER20",
"title": "Summer Sale 20%",
"type": "percentage",
"value": 20,
"min_subtotal": 5000,
"max_uses": 1000,
"max_uses_per_customer": 1,
"starts_at": "2026-06-01T00:00:00Z",
"ends_at": "2026-08-31T23:59:59Z"
}'
Response 201
{
"data": {
"id": "disc_abc123def456ghij",
"code": "SUMMER20",
"title": "Summer Sale 20%",
"type": "percentage",
"value": 20,
"status": "active",
"min_subtotal": 5000,
"min_quantity": null,
"max_uses": 1000,
"max_uses_per_customer": 1,
"used": 0,
"exclusive": true,
"combinable_with_promotions": true,
"customer_group_ids": null,
"starts_at": "2026-06-01T00:00:00Z",
"ends_at": "2026-08-31T23:59:59Z",
"created_at": "2026-05-15T12:00:00Z",
"updated_at": "2026-05-15T12:00:00Z"
}
}
⚠Percentage limits
When type is percentage, value must be between 1 and 100. Values outside this range return a
400 validation error.
ℹCode format
Codes may only contain letters and numbers (A-Z, 0-9). Hyphens, underscores, spaces, and
special characters are not allowed. The API automatically uppercases and trims the code.
Get a discount code
GET /v1/discounts/{id}
Returns a single discount code by ID, including the current usage count.
Request
curl https://api.hydrajs.dev/v1/discounts/disc_abc123def456ghij \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
"data": {
"id": "disc_abc123def456ghij",
"code": "SUMMER20",
"title": "Summer Sale 20%",
"type": "percentage",
"value": 20,
"status": "active",
"min_subtotal": 5000,
"min_quantity": null,
"max_uses": 1000,
"max_uses_per_customer": 1,
"used": 42,
"exclusive": true,
"combinable_with_promotions": true,
"customer_group_ids": null,
"starts_at": "2026-06-01T00:00:00Z",
"ends_at": "2026-08-31T23:59:59Z",
"created_at": "2026-05-15T09:30:00Z",
"updated_at": "2026-05-15T09:30:00Z"
}
}
Update a discount code
PATCH /v1/discounts/{id}
Updates a discount code. All fields are optional – send only what changed.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | No | Human-readable title (1-255 chars) |
type |
string | No | percentage or fixed_amount |
value |
integer | No | Discount value |
status |
string | No | active or disabled |
min_subtotal |
integer | null | No | Minimum cart subtotal in cents |
min_quantity |
integer | null | No | Minimum total item quantity |
max_uses |
integer | null | No | Maximum total uses |
max_uses_per_customer |
integer | null | No | Maximum uses per customer email |
exclusive |
boolean | No | Whether this code is exclusive |
combinable_with_promotions |
boolean | No | Whether this code works with promotions |
customer_group_ids |
string[] | null | No | Restrict to customer groups (null = all) |
starts_at |
string | No | ISO 8601 start datetime |
ends_at |
string | null | No | ISO 8601 end datetime (null to clear) |
Request
curl -X PATCH https://api.hydrajs.dev/v1/discounts/disc_abc123def456ghij \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"value": 25, "status": "disabled"}'
Response 200
{
"data": {
"id": "disc_abc123def456ghij",
"code": "SUMMER20",
"title": "Summer Sale 20%",
"type": "percentage",
"value": 25,
"status": "disabled",
"min_subtotal": 5000,
"min_quantity": null,
"max_uses": 1000,
"max_uses_per_customer": 1,
"used": 42,
"exclusive": true,
"combinable_with_promotions": true,
"customer_group_ids": null,
"starts_at": "2026-06-01T00:00:00Z",
"ends_at": "2026-08-31T23:59:59Z",
"created_at": "2026-05-15T09:30:00Z",
"updated_at": "2026-08-17T14:00:00Z"
}
}
⚠Code is immutable
The code field cannot be changed after creation. Attempting to include code in an update
request returns a 400 error. To change a discount code, delete the existing one and create a new
discount with the desired code.
Delete a discount code
DELETE /v1/discounts/{id}
Soft-deletes a discount code. The code string is freed for reuse. Audit trail is preserved in orders and usage records.
Request
curl -X DELETE https://api.hydrajs.dev/v1/discounts/disc_abc123def456ghij \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 204
Empty body.
The discount object
| Field | Type | Description |
|---|---|---|
id |
string | Unique ID (prefix: disc_) |
code |
string | The discount code (uppercased, letters and numbers only) |
title |
string | Human-readable title |
type |
string | Discount type: percentage or fixed_amount |
value |
integer | Discount value (percentage 1-100, or cents for fixed) |
status |
string | active or disabled |
min_subtotal |
integer | null | Minimum cart subtotal in cents, or null for no minimum |
min_quantity |
integer | null | Minimum total item quantity, or null for no minimum |
max_uses |
integer | null | Maximum total uses across all customers, or null for unlimited |
max_uses_per_customer |
integer | null | Maximum uses per customer email, or null for unlimited |
used |
integer | Number of times this code has been used |
exclusive |
boolean | Whether this code is exclusive |
combinable_with_promotions |
boolean | Whether this code can be used alongside automatic promotions |
customer_group_ids |
string[] | null | Customer group IDs eligible for this discount, or null for all customers |
starts_at |
string | ISO 8601 start datetime |
ends_at |
string | null | ISO 8601 end datetime, or null for no end |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |