Products API
List products or retrieve a single product by ID
GET /api/v1/products
Browse the product catalog. Returns a paginated list of products available to your client account, filtered by country, currency, category, or search term.
Request
curl "{{host}}/api/v1/products?country_id=1&category=Gaming&page=1&limit=25" \
-H "Authorization: Bearer <token>"package main
import (
"encoding/json"
"fmt"
"net/http"
)
type Denomination struct {
MinValue *float64 `json:"min_value"`
MaxValue *float64 `json:"max_value"`
Discount *float64 `json:"discount"`
}
type Product struct {
ID int `json:"id"`
Name string `json:"name"`
Category string `json:"category"`
SubCategory *string `json:"sub_category"`
CountryCode string `json:"country_code"`
CurrencyCode string `json:"currency_code"`
ImageURL *string `json:"image_url"`
DeliveryMode *string `json:"delivery_mode"`
DeliveryTime *string `json:"delivery_time"`
Validity *string `json:"validity"`
AvailableDenominations []Denomination `json:"available_denominations"`
}
func main() {
req, _ := http.NewRequest("GET", "{{host}}/api/v1/products?country_id=1&limit=25", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Total:", resp.Header.Get("X-Total-Count"))
var products []Product
json.NewDecoder(resp.Body).Decode(&products)
for _, p := range products {
fmt.Printf("%s (%s) — %s\n", p.Name, p.CurrencyCode, p.Category)
}
}Query Parameters
| Key | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-based) |
limit | integer | 10 | Items per page (1–500) |
category | string | — | Filter by category name (exact match) |
country_id | integer | — | Filter by country ID |
currency_id | integer | — | Filter by currency ID |
search | string | — | Search by product name (case-insensitive) |
sort_by | string | name | Sort field: name, category |
sort_dir | string | asc | Sort direction: asc or desc |
Response
[
{
"id": 123,
"name": "Steam Wallet Card",
"category": "Gaming",
"sub_category": "PC Gaming",
"country_code": "USA",
"currency_code": "USD",
"image_url": "https://cdn.example.com/steam.png",
"delivery_mode": "Code with PIN",
"delivery_time": "Instant",
"validity": "12 months",
"available_denominations": [
{
"min_value": 50.00,
"max_value": 50.00,
"discount": 3.5
},
{
"min_value": 100.00,
"max_value": 100.00,
"discount": 3.5
}
]
}
]Response Headers
| Header | Description |
|---|---|
X-Page | Current page number |
X-Per-Page | Items per page |
X-Total-Count | Total matching products |
X-Total-Pages | Total pages |
X-Page-Size | Items in current page |
X-Has-More | true if more pages exist |
Response Fields
| Key | Type | Description |
|---|---|---|
id | integer | Unique product identifier |
name | string | Product name (e.g. "Steam Wallet Card") |
category | string | Primary category (e.g. "Gaming", "Gift Cards") |
sub_category | string or null | Secondary category (e.g. "PC Gaming") |
country_code | string | ISO 3166-1 alpha-3 country code (e.g. USA) |
currency_code | string | ISO 4217 currency code (e.g. USD) |
image_url | string or null | Product image URL |
delivery_mode | string or null | Code with PIN or URL |
delivery_time | string or null | Instant or Delayed |
validity | string or null | Voucher validity period (e.g. "12 months") |
available_denominations | array | List of available denominations with pricing |
available_denominations[].min_value | number | Minimum face value |
available_denominations[].max_value | number | Maximum face value (equals min_value for fixed denominations) |
available_denominations[].discount | number | Discount percentage off face value |
Errors
400 Bad Request — Invalid query parameters.
{
"error": {
"name": "BadRequestError",
"code": "BAD_REQUEST",
"message": "Invalid query parameters"
}
}403 Forbidden — Request IP not in whitelist.
{
"error": {
"name": "ForbiddenError",
"code": "FORBIDDEN",
"message": "IP address not authorized"
}
}400 Bad Request — Vouchers feature not enabled for your client.
{
"error": {
"name": "BadRequestError",
"code": "INVALID_FEATURE",
"message": "The requested feature is not enabled for this client"
}
}500 Internal Server Error — Database query failed.
{
"error": {
"name": "InternalServerError",
"code": "INTERNAL_SERVER_ERROR",
"message": "Failed to retrieve products"
}
}GET /api/v1/products/:id
Returns full details for a single product, including all available denominations and their discounts.
Request
curl "{{host}}/api/v1/products/123" \
-H "Authorization: Bearer <token>"req, _ := http.NewRequest("GET", "{{host}}/api/v1/products/123", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var product Product
json.NewDecoder(resp.Body).Decode(&product)
fmt.Printf("%s — %s %s\n", product.Name, product.CurrencyCode, product.DeliveryTime)
for _, d := range product.AvailableDenominations {
fmt.Printf(" $%.2f–$%.2f (%.1f%% off)\n", *d.MinValue, *d.MaxValue, *d.Discount)
}Request Parameters
| Key | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Product ID (path parameter). Must be greater than 0. |
Response
{
"id": 123,
"name": "Steam Wallet Card",
"category": "Gaming",
"sub_category": "PC Gaming",
"country_code": "USA",
"currency_code": "USD",
"image_url": "https://cdn.example.com/steam.png",
"terms": "Non-refundable. Redeemable on Steam only.",
"details": "Add funds to your Steam wallet for games, DLC, and in-game items.",
"how_to_use": "Open Steam client → Account Details → Add Funds → Redeem code",
"delivery_mode": "Code with PIN",
"delivery_time": "Instant",
"validity": "12 months",
"available_denominations": [
{
"min_value": 10.00,
"max_value": 10.00,
"discount": 3.0
},
{
"min_value": 50.00,
"max_value": 50.00,
"discount": 3.5
},
{
"min_value": 100.00,
"max_value": 100.00,
"discount": 3.5
}
]
}Response Fields
All fields from the list endpoint, plus:
| Key | Type | Description |
|---|---|---|
terms | string or null | Redemption terms and conditions |
details | string or null | Product description |
how_to_use | string or null | Step-by-step redemption instructions |
Errors
400 Bad Request — ID is not a valid integer.
{
"error": {
"name": "BadRequestError",
"code": "BAD_REQUEST",
"message": "Invalid product ID"
}
}404 Not Found — Product does not exist or is blacklisted for your client.
{
"error": {
"name": "NotFoundError",
"code": "NOT_FOUND",
"message": "Product not found"
}
}403 Forbidden — Request IP not in whitelist.
{
"error": {
"name": "ForbiddenError",
"code": "FORBIDDEN",
"message": "IP address not authorized"
}
}