Create and manage discount vouchers
/admin/api/vouchers
List vouchers with optional filtering and pagination.
/admin/api/vouchers
Create a new voucher. Returns 409 Conflict if the code is already taken.
/admin/api/vouchers/{id}
Get a single voucher by ID.
/admin/api/vouchers/{id}
Update a voucher. Returns 409 Conflict if the new code collides with another voucher.
/admin/api/vouchers/{id}
Delete a voucher.
/admin/api/vouchers
List vouchers with optional filtering and pagination.
| Name | Type | Required | Description |
|---|---|---|---|
| active | boolean | optional | Filter by active/inactive status |
| search | string | optional | Search by code prefix |
| limit | integer | optional | Maximum rows to return (default: 50) |
| offset | integer | optional | Offset for pagination (default: 0) |
{
"vouchers": [
{
"id": 1,
"code": "SUMMER20",
"discount_type": "percentage",
"discount_value": "20.00",
"usage_limit": 100,
"usage_count": 12,
"per_customer_limit": 1,
"minimum_order_value": "50.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-08-31T23:59:59Z",
"customer_id": null,
"active": true,
"category_ids": [],
"created_at": "2025-05-15T10:00:00Z",
"updated_at": "2025-05-15T10:00:00Z"
},
{
"id": 2,
"code": "FLAT10",
"discount_type": "fixed_amount",
"discount_value": "10.00",
"usage_limit": null,
"usage_count": 5,
"per_customer_limit": null,
"minimum_order_value": null,
"starts_at": null,
"ends_at": null,
"customer_id": null,
"active": true,
"category_ids": [
1,
3
],
"created_at": "2025-05-10T08:00:00Z",
"updated_at": "2025-05-10T08:00:00Z"
}
],
"total": 2
}
curl "https://yourshop.zeroshop.io/admin/api/vouchers?active=true&limit=20&offset=0" \
-H "Authorization: Bearer zspat_..."
import requests
resp = requests.get(
"https://yourshop.zeroshop.io/admin/api/vouchers",
params={"active": "true", "limit": 20, "offset": 0},
headers={"Authorization": "Bearer zspat_..."}
)
vouchers = resp.json()
const params = new URLSearchParams({ active: true, limit: 20, offset: 0 });
const resp = await fetch(
`https://yourshop.zeroshop.io/admin/api/vouchers?${params}`,
{ headers: { "Authorization": "Bearer zspat_..." } }
);
const data = await resp.json();
require "net/http"
require "json"
uri = URI("https://yourshop.zeroshop.io/admin/api/vouchers?active=true&limit=20&offset=0")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer zspat_..."
resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(resp.body)
/admin/api/vouchers
Create a new voucher. Returns 409 Conflict if the code is already taken.
{
"code": "SUMMER20",
"discount_type": "percentage",
"discount_value": "20.00",
"usage_limit": 100,
"per_customer_limit": 1,
"minimum_order_value": "50.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-08-31T23:59:59Z",
"customer_id": null,
"active": true,
"category_ids": []
}
{
"id": 1,
"code": "SUMMER20",
"discount_type": "percentage",
"discount_value": "20.00",
"usage_limit": 100,
"usage_count": 0,
"per_customer_limit": 1,
"minimum_order_value": "50.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-08-31T23:59:59Z",
"customer_id": null,
"active": true,
"category_ids": [],
"created_at": "2025-05-15T10:00:00Z",
"updated_at": "2025-05-15T10:00:00Z"
}
curl -X POST "https://yourshop.zeroshop.io/admin/api/vouchers" \
-H "Authorization: Bearer zspat_..." \
-H "Content-Type: application/json" \
-d '{
"code": "SUMMER20",
"discount_type": "percentage",
"discount_value": "20.00",
"usage_limit": 100,
"per_customer_limit": 1,
"minimum_order_value": "50.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-08-31T23:59:59Z",
"active": true
}'
import requests
resp = requests.post(
"https://yourshop.zeroshop.io/admin/api/vouchers",
headers={"Authorization": "Bearer zspat_..."},
json={
"code": "SUMMER20",
"discount_type": "percentage",
"discount_value": "20.00",
"usage_limit": 100,
"per_customer_limit": 1,
"minimum_order_value": "50.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-08-31T23:59:59Z",
"active": True
}
)
voucher = resp.json()
const resp = await fetch("https://yourshop.zeroshop.io/admin/api/vouchers", {
method: "POST",
headers: {
"Authorization": "Bearer zspat_...",
"Content-Type": "application/json"
},
body: JSON.stringify({
code: "SUMMER20",
discount_type: "percentage",
discount_value: "20.00",
usage_limit: 100,
per_customer_limit: 1,
minimum_order_value: "50.00",
starts_at: "2025-06-01T00:00:00Z",
ends_at: "2025-08-31T23:59:59Z",
active: true
})
});
const voucher = await resp.json();
require "net/http"
require "json"
uri = URI("https://yourshop.zeroshop.io/admin/api/vouchers")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer zspat_..."
req["Content-Type"] = "application/json"
req.body = {
code: "SUMMER20",
discount_type: "percentage",
discount_value: "20.00",
usage_limit: 100,
per_customer_limit: 1,
minimum_order_value: "50.00",
starts_at: "2025-06-01T00:00:00Z",
ends_at: "2025-08-31T23:59:59Z",
active: true
}.to_json
resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
voucher = JSON.parse(resp.body)
/admin/api/vouchers/{id}
Get a single voucher by ID.
{
"id": 1,
"code": "SUMMER20",
"discount_type": "percentage",
"discount_value": "20.00",
"usage_limit": 100,
"usage_count": 12,
"per_customer_limit": 1,
"minimum_order_value": "50.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-08-31T23:59:59Z",
"customer_id": null,
"active": true,
"category_ids": [],
"created_at": "2025-05-15T10:00:00Z",
"updated_at": "2025-05-15T10:00:00Z"
}
curl "https://yourshop.zeroshop.io/admin/api/vouchers/1" \
-H "Authorization: Bearer zspat_..."
import requests
resp = requests.get(
"https://yourshop.zeroshop.io/admin/api/vouchers/1",
headers={"Authorization": "Bearer zspat_..."}
)
voucher = resp.json()
const resp = await fetch("https://yourshop.zeroshop.io/admin/api/vouchers/1", {
headers: { "Authorization": "Bearer zspat_..." }
});
const voucher = await resp.json();
require "net/http"
require "json"
uri = URI("https://yourshop.zeroshop.io/admin/api/vouchers/1")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer zspat_..."
resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
voucher = JSON.parse(resp.body)
/admin/api/vouchers/{id}
Update a voucher. Returns 409 Conflict if the new code collides with another voucher.
{
"code": "SUMMER25",
"discount_type": "percentage",
"discount_value": "25.00",
"usage_limit": 200,
"per_customer_limit": 2,
"minimum_order_value": "30.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-09-30T23:59:59Z",
"customer_id": null,
"active": true,
"category_ids": [
1,
3
]
}
{
"id": 1,
"code": "SUMMER25",
"discount_type": "percentage",
"discount_value": "25.00",
"usage_limit": 200,
"usage_count": 12,
"per_customer_limit": 2,
"minimum_order_value": "30.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-09-30T23:59:59Z",
"customer_id": null,
"active": true,
"category_ids": [
1,
3
],
"created_at": "2025-05-15T10:00:00Z",
"updated_at": "2025-11-20T14:30:00Z"
}
curl -X PUT "https://yourshop.zeroshop.io/admin/api/vouchers/1" \
-H "Authorization: Bearer zspat_..." \
-H "Content-Type: application/json" \
-d '{
"code": "SUMMER25",
"discount_type": "percentage",
"discount_value": "25.00",
"usage_limit": 200,
"per_customer_limit": 2,
"minimum_order_value": "30.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-09-30T23:59:59Z",
"active": true,
"category_ids": [1, 3]
}'
import requests
resp = requests.put(
"https://yourshop.zeroshop.io/admin/api/vouchers/1",
headers={"Authorization": "Bearer zspat_..."},
json={
"code": "SUMMER25",
"discount_type": "percentage",
"discount_value": "25.00",
"usage_limit": 200,
"per_customer_limit": 2,
"minimum_order_value": "30.00",
"starts_at": "2025-06-01T00:00:00Z",
"ends_at": "2025-09-30T23:59:59Z",
"active": True,
"category_ids": [1, 3]
}
)
voucher = resp.json()
const resp = await fetch("https://yourshop.zeroshop.io/admin/api/vouchers/1", {
method: "PUT",
headers: {
"Authorization": "Bearer zspat_...",
"Content-Type": "application/json"
},
body: JSON.stringify({
code: "SUMMER25",
discount_type: "percentage",
discount_value: "25.00",
usage_limit: 200,
per_customer_limit: 2,
minimum_order_value: "30.00",
starts_at: "2025-06-01T00:00:00Z",
ends_at: "2025-09-30T23:59:59Z",
active: true,
category_ids: [1, 3]
})
});
const voucher = await resp.json();
require "net/http"
require "json"
uri = URI("https://yourshop.zeroshop.io/admin/api/vouchers/1")
req = Net::HTTP::Put.new(uri)
req["Authorization"] = "Bearer zspat_..."
req["Content-Type"] = "application/json"
req.body = {
code: "SUMMER25",
discount_type: "percentage",
discount_value: "25.00",
usage_limit: 200,
per_customer_limit: 2,
minimum_order_value: "30.00",
starts_at: "2025-06-01T00:00:00Z",
ends_at: "2025-09-30T23:59:59Z",
active: true,
category_ids: [1, 3]
}.to_json
resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
voucher = JSON.parse(resp.body)
/admin/api/vouchers/{id}
Delete a voucher.
curl -X DELETE "https://yourshop.zeroshop.io/admin/api/vouchers/1" \
-H "Authorization: Bearer zspat_..."
import requests
resp = requests.delete(
"https://yourshop.zeroshop.io/admin/api/vouchers/1",
headers={"Authorization": "Bearer zspat_..."}
)
assert resp.status_code == 204
const resp = await fetch("https://yourshop.zeroshop.io/admin/api/vouchers/1", {
method: "DELETE",
headers: { "Authorization": "Bearer zspat_..." }
});
require "net/http"
uri = URI("https://yourshop.zeroshop.io/admin/api/vouchers/1")
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer zspat_..."
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
We value your privacy
We use cookies for essential site functionality and, with your consent, analytics to understand how our platform is used. No personal data is shared with third parties. See our Privacy Policy for details.