Products API
List, search, and retrieve detailed product information from the product catalog
Products API
The Products API provides access to the product catalog with comprehensive search, filtering, and detailed product information retrieval capabilities.
Overview
The Products API consists of three main endpoints:
- List Products - Search and filter the product catalog with pagination
- Get Product Details - Retrieve comprehensive information for a specific product
- Check Availability - Verify if a product is available for purchase at specific quantity/denomination
All product endpoints require authentication and return data in a consistent JSON format.
List Products
Get a paginated list of products with advanced search and filtering options.
Endpoint
GET /api/v1/productsAuthentication: Bearer token required
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (min: 1) |
limit | number | 50 | Items per page (min: 1, max: 10,000) |
category | string | - | Filter by category name (e.g., "Gift Cards") |
country_id | string | - | Filter by country ID |
currency_id | string | - | Filter by currency ID |
sort | object | {"field":"id","direction":"DESC"} | Sort configuration |
Sort Object Format
{
"field": "id",
"direction": "ASC" // or "DESC"
}Response
Success Response (200 OK)
Headers:
X-Page: 1
X-Per-Page: 50
X-Total-Count: 1247
X-Total-Pages: 25
X-Page-Size: 50
X-Has-More: trueResponse Body:
[
{
"id": 1001,
"name": "Amazon Gift Card - USD",
"category": "Gift Cards",
"sub_category": "E-commerce",
"country_code": "USA",
"currency_code": "USD",
"image_url": "https://cdn.octopus.com/products/amazon-gc.jpg",
"delivery_mode": "Digital",
"delivery_time": "Instant",
"validity": "No expiry",
"available_denominations": [
{
"min_value": 10.00,
"max_value": 500.00,
"discount": 2.5
}
]
},
{
"id": 2001,
"name": "Google Play Gift Card - USD",
"category": "Gift Cards",
"sub_category": "Digital Entertainment",
"country_code": "USA",
"currency_code": "USD",
"image_url": "https://cdn.octopus.com/products/google-play.jpg",
"delivery_mode": "Digital",
"delivery_time": "Instant",
"validity": "No expiry",
"available_denominations": [
{
"min_value": 5.00,
"max_value": 100.00,
"discount": 1.8
}
]
}
]Product Object Fields
| Field | Type | Description |
|---|---|---|
id | number | Unique product identifier |
name | string | Product display name |
category | string | Primary category (e.g., "Gift Cards", "Mobile Top-up") |
sub_category | string | Subcategory classification |
country_code | string | ISO 3166-1 Alpha-3 country code (e.g., "USA", "GBR") |
currency_code | string | ISO 4217 currency code (e.g., "USD", "GBP") |
image_url | string | Product image URL |
delivery_mode | string | Delivery method (e.g., "Digital", "Physical") |
delivery_time | string | Expected delivery time |
validity | string | Product validity period |
terms | string | Terms and conditions (optional) |
details | string | Product description (optional) |
how_to_use | string | Usage instructions (optional) |
available_denominations | array | Available purchase amounts with discounts |
Examples
# Get all products (default pagination)
curl -X GET "{{host}}/api/v1/products" \
-H "Authorization: Bearer your_access_token"
# Filter by category with custom pagination
curl -X GET "{{host}}/api/v1/products?category=Gift%20Cards&page=1&limit=20" \
-H "Authorization: Bearer your_access_token"
# Sort by name in ascending order
curl -X GET "{{host}}/api/v1/products?sort=%7B%22field%22%3A%22name%22%2C%22direction%22%3A%22ASC%22%7D" \
-H "Authorization: Bearer your_access_token"<?php
// Get all products with default pagination
$products = $api->makeAuthenticatedRequest('{{host}}/api/v1/products');
foreach ($products as $product) {
echo "Product: " . $product['name'] . " - " . $product['category'] . "\n";
}
// Filter by category with custom pagination
$params = http_build_query([
'category' => 'Gift Cards',
'page' => 1,
'limit' => 20
]);
$giftCards = $api->makeAuthenticatedRequest(
"{{host}}/api/v1/products?{$params}"
);
// Sort products by name in ascending order
$sortConfig = json_encode([
'field' => 'name',
'direction' => 'ASC'
]);
$sortedProducts = $api->makeAuthenticatedRequest(
'{{host}}/api/v1/products?sort=' . urlencode($sortConfig)
);
// Build product catalog for display
echo "<div class='product-grid'>\n";
foreach ($sortedProducts as $product) {
echo "<div class='product-card'>\n";
echo " <img src='" . htmlspecialchars($product['image_url']) . "'>\n";
echo " <h3>" . htmlspecialchars($product['name']) . "</h3>\n";
echo " <p>Category: " . htmlspecialchars($product['category']) . "</p>\n";
echo " <p>Delivery: " . htmlspecialchars($product['delivery_time']) . "</p>\n";
echo "</div>\n";
}
echo "</div>\n";
?>Get Product Details
Retrieve comprehensive information for a specific product, including detailed product information.
Endpoint
GET /api/v1/products/{id}Authentication: Bearer token required
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | number | Yes | Product ID (must be > 0) |
Response
Success Response (200 OK)
{
"id": 1001,
"name": "Amazon Gift Card - USD",
"category": "Gift Cards",
"sub_category": "E-commerce",
"country_code": "USA",
"currency_code": "USD",
"image_url": "https://cdn.octopus.com/products/amazon-gc.jpg",
"delivery_mode": "Digital",
"delivery_time": "Instant",
"validity": "No expiry",
"terms": "Redeemable on Amazon.com. Cannot be resold or transferred for cash. Gift card will not be replaced if lost, stolen, or used without permission.",
"details": "Digital gift card for Amazon.com purchases. Valid for millions of items across all categories. Perfect for personal use or as a gift.",
"how_to_use": "1. Add items to your Amazon cart\n2. Proceed to checkout\n3. Enter gift card code in the payment section\n4. Complete your purchase",
"available_denominations": [
{
"min_value": 10.00,
"max_value": 500.00,
"discount": 2.5
}
]
}Examples
curl -X GET "{{host}}/api/v1/products/1001" \
-H "Authorization: Bearer your_access_token"<?php
// Get detailed product information
try {
$productId = 1001;
$product = $api->makeAuthenticatedRequest(
"{{host}}/api/v1/products/{$productId}"
);
// Display product details
echo "<div class='product-details'>\n";
echo " <h1>" . htmlspecialchars($product['name']) . "</h1>\n";
echo " <img src='" . htmlspecialchars($product['image_url']) . "' alt='Product Image'>\n";
echo " <p><strong>Category:</strong> " . htmlspecialchars($product['category']) . "</p>\n";
echo " <p><strong>Delivery:</strong> " . htmlspecialchars($product['delivery_time']) . " (" . htmlspecialchars($product['delivery_mode']) . ")</p>\n";
echo " <p><strong>Validity:</strong> " . htmlspecialchars($product['validity']) . "</p>\n";
if (!empty($product['details'])) {
echo " <div class='description'>\n";
echo " <h3>Description</h3>\n";
echo " <p>" . htmlspecialchars($product['details']) . "</p>\n";
echo " </div>\n";
}
if (!empty($product['how_to_use'])) {
echo " <div class='instructions'>\n";
echo " <h3>How to Use</h3>\n";
echo " <pre>" . htmlspecialchars($product['how_to_use']) . "</pre>\n";
echo " </div>\n";
}
// Display available denominations
if (!empty($product['available_denominations'])) {
echo " <div class='denominations'>\n";
echo " <h3>Available Amounts</h3>\n";
foreach ($product['available_denominations'] as $denom) {
$discount = $denom['discount'] ?? 0;
echo " <p>Min: $" . number_format($denom['min_value'], 2) . " - ";
echo "Max: $" . number_format($denom['max_value'], 2);
if ($discount > 0) {
echo " (" . $discount . "% discount)";
}
echo "</p>\n";
}
echo " </div>\n";
}
echo "</div>\n";
} catch (Exception $e) {
echo "Error loading product: " . $e->getMessage() . "\n";
}
?>Check Product Availability
Check if a product is available for purchase at a specific denomination and quantity without calculating full charges.
Endpoint
POST /api/v1/products/{id}/availabilityAuthentication: Bearer token required
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | number | Yes | Product ID (must be > 0) |
Request Body
{
"denomination": 100.00,
"quantity": 2
}| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
denomination | number | Yes | Min: 0.01, Max: 1,000,000,000 | Purchase amount per unit |
quantity | number | Yes | Min: 1 | Number of units to check |
Response
Success Response (200 OK)
{
"is_available": true
}Response Fields
| Field | Type | Description |
|---|---|---|
is_available | boolean | Whether the product is available for the requested denomination and quantity |
Use Cases
- Pre-purchase Validation - Check availability before showing pricing options
- Real-time Inventory - Display current stock status to users
- Performance Optimization - Lighter check than full charge calculation
- User Experience - Show availability indicators in product listings
Examples
# Check if product is available
curl -X POST "{{host}}/api/v1/products/1001/availability" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"denomination": 100.00,
"quantity": 2
}'
# Check large quantity availability
curl -X POST "{{host}}/api/v1/products/1001/availability" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"denomination": 50.00,
"quantity": 100
}'<?php
// Check product availability before showing purchase options
function checkProductAvailability($api, $productId, $denomination, $quantity = 1) {
try {
$requestData = [
'denomination' => $denomination,
'quantity' => $quantity
];
$result = $api->makeAuthenticatedRequest(
"{{host}}/api/v1/products/{$productId}/availability",
'POST',
$requestData
);
return $result['is_available'] ?? false;
} catch (Exception $e) {
error_log("Availability check failed: " . $e->getMessage());
return false;
}
}
// Example usage: Check availability for different scenarios
$productId = 1001;
// Standard purchase check
if (checkProductAvailability($api, $productId, 100.00, 2)) {
echo "<button class='btn-primary'>Buy 2 x $100 Gift Cards</button>\n";
} else {
echo "<button class='btn-disabled' disabled>Currently Unavailable</button>\n";
}
// Bulk purchase check
if (checkProductAvailability($api, $productId, 50.00, 100)) {
echo "<p class='stock-status available'>ā Bulk orders available</p>\n";
} else {
echo "<p class='stock-status unavailable'>Warning: Bulk orders currently unavailable</p>\n";
}
// Build availability matrix for different denominations
$denominations = [25, 50, 100, 250, 500];
echo "<div class='availability-matrix'>\n";
echo " <h3>Availability Status</h3>\n";
echo " <table>\n";
echo " <thead><tr><th>Amount</th><th>Status</th></tr></thead>\n";
echo " <tbody>\n";
foreach ($denominations as $amount) {
$available = checkProductAvailability($api, $productId, $amount, 1);
$status = $available ? 'ā Available' : 'ā Unavailable';
$class = $available ? 'available' : 'unavailable';
echo " <tr>\n";
echo " <td>$" . number_format($amount) . "</td>\n";
echo " <td class='{$class}'>{$status}</td>\n";
echo " </tr>\n";
}
echo " </tbody>\n";
echo " </table>\n";
echo "</div>\n";
?>Error Handling
Common Error Responses
400 Bad Request
{
"error": {
"name": "BadRequestError",
"code": "BAD_REQUEST",
"message": "Invalid product ID"
}
}404 Not Found
{
"error": {
"name": "NotFoundError",
"code": "NOT_FOUND",
"message": "Product not found"
}
}401 Unauthorized
{
"error": {
"name": "UnauthorizedError",
"code": "UNAUTHORIZED",
"message": "Invalid or expired access token"
}
}500 Internal Server Error
{
"error": {
"name": "InternalServerError",
"code": "INTERNAL_SERVER_ERROR",
"message": "Failed to retrieve product"
}
}Next Steps
- Learn how to Calculate Charges for selected products
- Explore Categories for product organization
- Check Countries for regional availability