List vouchers
curl --request GET \
--url https://api.example.com/api/v1/developer/vouchersimport requests
url = "https://api.example.com/api/v1/developer/vouchers"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/developer/vouchers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/developer/vouchers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/developer/vouchers"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/developer/vouchers")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/developer/vouchers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyVouchers
List vouchers
List vouchers in your tenant with filtering, sorting, and pagination.
GET
/
api
/
v1
/
developer
/
vouchers
List vouchers
curl --request GET \
--url https://api.example.com/api/v1/developer/vouchersimport requests
url = "https://api.example.com/api/v1/developer/vouchers"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/developer/vouchers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/developer/vouchers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/developer/vouchers"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/developer/vouchers")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/developer/vouchers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyRequired scope:
Page shape (deprecated):
When
If a voucher has no linked customer,
vouchers:read
Rate limit: 300 requests/minute
Pagination
This endpoint supports both cursor pagination (recommended) and page pagination (deprecated). The cursor shape wins if both are sent on the same request. In cursor mode, results are orderedcreated_at DESC, id DESC, and the
sort_by / sort_order params are ignored.
Query parameters
Cursor shape (recommended)
| Parameter | Type | Default | Notes |
|---|---|---|---|
cursor | string | – | Opaque cursor from a previous response’s next_cursor |
limit | integer | 50 | 1–100 |
Page shape (deprecated)
The page shape is kept for back-compat. Use cursor pagination for new
integrations – see Pagination.
| Parameter | Type | Default | Notes |
|---|---|---|---|
page | integer | 1 | 1-indexed page (min 1) |
per_page | integer | 50 | 1–100 |
Filters & sorting (both shapes)
| Parameter | Type | Default | Notes |
|---|---|---|---|
status | string | – | One of pending, completed, redeemed, expired, voided, refunded |
search | string | – | An email-shaped query searches recipient_email only. Any other query searches voucher code (prefix match) and recipient_name together – but not email. The two branches are exclusive. In cursor mode the in-process name fallback is skipped (SQL match only). |
sort_by | string | created_at | Page mode only. One of code, amount, balance, status, created_at. Ignored in cursor mode. |
sort_order | string | desc | Page mode only. asc or desc. Ignored in cursor mode. |
include | string | – | Set to customer to embed the linked customer record on each row |
Response
Cursor shape:{
"vouchers": [
{
"id": "8d82f0d2-7f94-4a3b-8b55-1e2e3a4f5b6c",
"code": "VG-EXAMPLE1",
"amount": "100.00",
"balance": "75.00",
"status": "completed",
"recipient_name": "Sam Recipient",
"recipient_email": "sam@example.com",
"expiry_date": "2029-04-26T00:00:00Z",
"created_at": "2026-04-26T01:23:45Z",
"updated_at": "2026-04-26T01:23:45Z",
"location_id": null
}
],
"next_cursor": "cur_v1_eyJ2IjoxLCJ0Ijoi…uH8.QwR2…"
}
{
"vouchers": [/* …items… */],
"total": 247,
"page": 1,
"per_page": 50
}
include=customer is supplied, each voucher additionally carries a
customer field:
{
"id": "...",
"code": "VG-EXAMPLE1",
"...": "...",
"customer": {
"id": "c0ffee00-...-...",
"email": "buyer@example.com",
"first_name": "Alex",
"last_name": "Buyer"
}
}
customer is null.
Errors
400– Invalidstatusvalue, or invalid/forged/cross-tenantcursor.422–includeis set to anything other thancustomer.
Examples
curl \
-H "X-API-Key: vg_live_EXAMPLEdoNotUseThis123456" \
"https://api.vouchergrid.com/api/v1/developer/vouchers?status=completed&per_page=25"
const params = new URLSearchParams({
status: "completed",
per_page: "25",
sort_by: "created_at",
sort_order: "desc",
});
const res = await fetch(
`https://api.vouchergrid.com/api/v1/developer/vouchers?${params}`,
{ headers: { "X-API-Key": process.env.VOUCHERGRID_API_KEY! } },
);
const data = await res.json();