Reference Data API
Access categories, subcategories, countries, and currencies for product filtering and localization
Reference Data API
The Reference Data API provides essential lookup data for categories, subcategories, countries, and currencies. This data is used for product filtering, localization, and building user interfaces.
Categories API
List Categories
Get all active categories with pagination.
GET /api/v1/categories
Authorization: Bearer {token}Query Parameters:
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
Example Response:
[
{
"id": 1,
"name": "Gift Cards"
},
{
"id": 2,
"name": "Mobile Top-up"
},
{
"id": 3,
"name": "Digital Services"
}
]PHP Example:
// Get all categories for navigation menu
try {
$categories = $api->getCategories(1, 50);
echo "<select name='category_id'>\n";
echo "<option value=''>All Categories</option>\n";
foreach ($categories as $category) {
echo "<option value='{$category['id']}'>";
echo htmlspecialchars($category['name']);
echo "</option>\n";
}
echo "</select>\n";
// Or create a simple array for JSON API
$categoryList = [];
foreach ($categories as $category) {
$categoryList[] = [
'id' => $category['id'],
'name' => $category['name'],
'slug' => strtolower(str_replace(' ', '-', $category['name']))
];
}
echo json_encode($categoryList, JSON_PRETTY_PRINT);
} catch (Exception $e) {
echo "Error fetching categories: " . $e->getMessage() . "\n";
}Get Category by ID
Retrieve a specific category by its unique identifier.
GET /api/v1/categories/{id}
Authorization: Bearer {token}Example Response:
{
"id": 1,
"name": "Gift Cards"
}PHP Example:
// Get specific category
try {
$category = $api->getCategoryById(1);
echo "Category: {$category['name']} (ID: {$category['id']})\n";
// Use category for product filtering
$products = $api->getProducts(['category_id' => $category['id']]);
echo "Found " . count($products) . " products in this category\n";
} catch (Exception $e) {
if (strpos($e->getMessage(), '404') !== false) {
echo "Category not found or inactive\n";
} else {
echo "Error: " . $e->getMessage() . "\n";
}
}Subcategories API
List Subcategories
Get all active subcategories with pagination.
GET /api/v1/subcategories
Authorization: Bearer {token}Query Parameters:
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
Example Response:
[
{
"id": 101,
"name": "Retail Gift Cards"
},
{
"id": 102,
"name": "Entertainment Gift Cards"
},
{
"id": 201,
"name": "Prepaid Mobile Credit"
}
]PHP Example:
// Get subcategories for advanced filtering
try {
$subcategories = $api->getSubcategories(1, 100);
// Group subcategories by parent category (if you have category relationships)
$groupedSubcategories = [];
foreach ($subcategories as $subcategory) {
// Extract category from subcategory name (simplified approach)
if (strpos($subcategory['name'], 'Gift Cards') !== false) {
$groupedSubcategories['Gift Cards'][] = $subcategory;
} elseif (strpos($subcategory['name'], 'Mobile') !== false) {
$groupedSubcategories['Mobile Top-up'][] = $subcategory;
} else {
$groupedSubcategories['Other'][] = $subcategory;
}
}
// Create hierarchical filter structure
echo "<div class='filter-section'>\n";
foreach ($groupedSubcategories as $categoryName => $subs) {
echo "<h4>{$categoryName}</h4>\n";
echo "<div class='subcategory-filters'>\n";
foreach ($subs as $subcategory) {
echo "<label>\n";
echo "<input type='checkbox' name='subcategory[]' value='{$subcategory['id']}' />";
echo htmlspecialchars($subcategory['name']);
echo "</label>\n";
}
echo "</div>\n";
}
echo "</div>\n";
} catch (Exception $e) {
echo "Error fetching subcategories: " . $e->getMessage() . "\n";
}Get Subcategory by ID
Retrieve a specific subcategory by its unique identifier.
GET /api/v1/subcategories/{id}
Authorization: Bearer {token}Example Response:
{
"id": 101,
"name": "Retail Gift Cards"
}// Get subcategory details for product filtering
try {
$subcategoryId = 101;
$subcategory = $api->getSubcategoryById($subcategoryId);
// Use subcategory data for specific product filtering
$products = $api->getProducts([
'subcategory_id' => $subcategory['id'],
'per_page' => 20
]);
echo "<h2>Products in: " . htmlspecialchars($subcategory['name']) . "</h2>\n";
echo "<div class='product-grid'>\n";
foreach ($products as $product) {
echo "<div class='product-card'>\n";
echo " <h3>" . htmlspecialchars($product['name']) . "</h3>\n";
echo " <p>Category: " . htmlspecialchars($subcategory['name']) . "</p>\n";
echo "</div>\n";
}
echo "</div>\n";
} catch (Exception $e) {
echo "Error fetching subcategory: " . $e->getMessage() . "\n";
}Countries API
List Countries
Get all countries with pagination and filtering options.
GET /api/v1/countries
Authorization: Bearer {token}Query Parameters:
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
Example Response:
[
{
"id": 1,
"name": "United States",
"alpha2": "US",
"alpha3": "USA",
"official_name": "United States of America",
"numeric_code": "840",
"dialing_prefix": "+1"
},
{
"id": 2,
"name": "United Kingdom",
"alpha2": "GB",
"alpha3": "GBR",
"official_name": "United Kingdom of Great Britain and Northern Ireland",
"numeric_code": "826",
"dialing_prefix": "+44"
}
]Get Country by ID
Retrieve a specific country by its unique identifier.
GET /api/v1/countries/{id}
Authorization: Bearer {token}Example Response:
{
"id": 1,
"name": "United States",
"alpha2": "US",
"alpha3": "USA",
"official_name": "United States of America",
"numeric_code": "840",
"dialing_prefix": "+1"
}Currencies API
List Currencies
Get all currencies with pagination support.
GET /api/v1/currencies
Authorization: Bearer {token}Query Parameters:
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
Example Response:
[
{
"id": 1,
"country_id": 1,
"name": "US Dollar",
"currency": "USD",
"symbol": "$",
"currency_code": "USD",
"precision": 2
},
{
"id": 2,
"country_id": 2,
"name": "Pound Sterling",
"currency": "GBP",
"symbol": "£",
"currency_code": "GBP",
"precision": 2
}
]Get Currency by ID
Retrieve a specific currency by its unique identifier.
GET /api/v1/currencies/{id}
Authorization: Bearer {token}Example Response:
{
"id": 1,
"country_id": 1,
"name": "US Dollar",
"currency": "USD",
"symbol": "$",
"currency_code": "USD",
"precision": 2
}Code Example
Here's a basic PHP implementation for the Reference Data API:
<?php
class ReferenceDataAPI {
private $token;
private $baseUrl = '{{host}}';
public function __construct($token) {
$this->token = $token;
}
public function getCategories($page = 1) {
return $this->makeRequest('/api/v1/categories', ['page' => $page]);
}
public function getCategoryById($id) {
return $this->makeRequest("/api/v1/categories/{$id}");
}
public function getSubcategories($page = 1) {
return $this->makeRequest('/api/v1/subcategories', ['page' => $page]);
}
public function getSubcategoryById($id) {
return $this->makeRequest("/api/v1/subcategories/{$id}");
}
public function getCountries($page = 1) {
return $this->makeRequest('/api/v1/countries', ['page' => $page]);
}
public function getCountryById($id) {
return $this->makeRequest("/api/v1/countries/{$id}");
}
public function getCurrencies($page = 1) {
return $this->makeRequest('/api/v1/currencies', ['page' => $page]);
}
public function getCurrencyById($id) {
return $this->makeRequest("/api/v1/currencies/{$id}");
}
private function makeRequest($endpoint, $params = []) {
$url = $this->baseUrl . $endpoint;
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $this->token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API request failed with status {$httpCode}");
}
return json_decode($response, true);
}
}
// Usage
$api = new ReferenceDataAPI('your_token_here');
try {
$categories = $api->getCategories();
$countries = $api->getCountries();
$currencies = $api->getCurrencies();
echo "Found " . count($categories) . " categories\n";
echo "Found " . count($countries) . " countries\n";
echo "Found " . count($currencies) . " currencies\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>Response Fields
Category Fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique category identifier |
name | string | Display name of the category |
Subcategory Fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique subcategory identifier |
name | string | Display name of the subcategory |
Country Fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique country identifier |
name | string | Common country name |
alpha2 | string | ISO 3166-1 alpha-2 country code |
alpha3 | string | ISO 3166-1 alpha-3 country code |
official_name | string | Official country name |
numeric_code | string | ISO 3166-1 numeric country code |
dialing_prefix | string | International dialing prefix |
Currency Fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique currency identifier |
country_id | integer | Associated country ID |
name | string | Full currency name |
currency | string | Currency abbreviation |
symbol | string | Currency symbol |
currency_code | string | ISO currency code |
precision | integer | Decimal precision for amounts |
Common Use Cases
Building Product Filters
Use categories and subcategories to create hierarchical product filters:
-
Fetch all categories for top-level navigation
GET /api/v1/categories?per_page=100 -
Load subcategories for detailed filtering
GET /api/v1/subcategories?per_page=100 -
Use category/subcategory IDs in product search queries
GET /api/v1/products?category_id=1&subcategory_id=101
Example Implementation:
// Build category filter dropdown
$categories = $api->getCategories(1, 100);
foreach ($categories as $category) {
echo "<option value='{$category['id']}'>{$category['name']}</option>";
}
// Filter products by category
$giftCardProducts = $api->getProducts(['category_id' => 1]);Localization and Currency Display
Combine country and currency data for proper localization:
-
Get user's country from their profile or IP geolocation
$userCountryCode = 'US'; // From user profile or IP detection $countries = $api->getCountries(); $userCountry = array_filter($countries, function($c) use ($userCountryCode) { return $c['alpha2'] === $userCountryCode; })[0]; -
Fetch associated currency information
$currencies = $api->getCurrencies(); $userCurrency = array_filter($currencies, function($c) use ($userCountry) { return $c['country_id'] === $userCountry['id']; })[0]; -
Use currency precision and symbols for proper price formatting
function formatPrice($amount, $currency) { $formatted = number_format($amount, $currency['precision']); return $currency['symbol'] . $formatted; } // Usage: $12.50, €15.00, £10.99 echo formatPrice(12.50, $userCurrency);
Product Availability by Region
Reference data helps determine product availability:
Example: Check if products are available in user's country
function isProductAvailableInCountry($productCountryIds, $userCountryId) {
return in_array($userCountryId, $productCountryIds);
}
// Get user's country
$userCountry = $api->getCountryById($userCountryId);
// Check product availability
$product = $api->getProductById(1001);
if (isProductAvailableInCountry($product['supported_countries'], $userCountry['id'])) {
echo "✓ Available in {$userCountry['name']}";
} else {
echo "✗ Not available in {$userCountry['name']}";
}Real-World Integration Examples
1. Multi-Currency Checkout Flow
class CheckoutProcessor {
private $api;
public function processCheckout($userId, $productId, $amount) {
// Get user's country and currency
$user = $this->getUserById($userId);
$country = $this->api->getCountryById($user['country_id']);
$currency = $this->api->getCurrencyById($user['preferred_currency']);
// Format price with proper currency
$formattedPrice = $this->formatPrice($amount, $currency);
// Display checkout summary
return [
'product_id' => $productId,
'amount' => $amount,
'formatted_price' => $formattedPrice,
'currency_code' => $currency['currency_code'],
'country' => $country['name']
];
}
}2. Dynamic Category Navigation
class CategoryNavigator {
private $api;
public function buildCategoryMenu() {
$categories = $this->api->getCategories(1, 50);
$subcategories = $this->api->getSubcategories(1, 200);
$menu = [];
foreach ($categories as $category) {
$menu[$category['id']] = [
'name' => $category['name'],
'subcategories' => array_filter($subcategories, function($sub) use ($category) {
return strpos($sub['name'], $category['name']) !== false;
})
];
}
return $menu;
}
}3. Currency Converter Widget
class CurrencyConverter {
private $api;
public function convertPrice($amount, $fromCurrencyId, $toCurrencyId) {
$fromCurrency = $this->api->getCurrencyById($fromCurrencyId);
$toCurrency = $this->api->getCurrencyById($toCurrencyId);
// In a real implementation, you'd fetch exchange rates
$exchangeRate = $this->getExchangeRate($fromCurrency['currency_code'], $toCurrency['currency_code']);
$convertedAmount = $amount * $exchangeRate;
return [
'original' => $this->formatPrice($amount, $fromCurrency),
'converted' => $this->formatPrice($convertedAmount, $toCurrency),
'rate' => $exchangeRate
];
}
}
## Error Handling
All reference data endpoints return consistent error responses:
**Common Error Codes:**
- `400 Bad Request`: Invalid parameters or ID format
- `401 Unauthorized`: Missing or invalid authentication token
- `404 Not Found`: Resource not found or inactive
- `500 Internal Server Error`: Server-side processing error
**Error Response Format:**
```json
{
"error": {
"code": "NOT_FOUND",
"message": "Category not found",
"details": {}
}
}Best Practices
Caching Strategy
Reference data changes infrequently, making it ideal for caching:
- Cache categories and subcategories for 24 hours
- Cache countries indefinitely (they rarely change)
- Cache currencies for 1 hour (exchange rates may affect display)
Pagination
Always handle pagination for large datasets:
- Use reasonable
per_pagevalues (25-100) - Check
X-Total-Pagesheader for complete data - Implement client-side pagination for better user experience
Data Validation
Validate reference data IDs before making API calls:
- Ensure IDs are positive integers
- Handle cases where referenced data might be inactive
- Provide fallback options for missing reference data