Starship Rewards API

Products API

List, search, and retrieve detailed product information from the Starship Rewards catalog

Products API

The Products API provides access to the Starship Rewards 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/products

Authentication: Bearer token required

Query Parameters

ParameterTypeDefaultDescription
pagenumber1Page number (min: 1)
limitnumber50Items per page (min: 1, max: 10,000)
categorystring-Filter by category name (e.g., "Gift Cards")
sortobject{"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: true

Response Body:

[
  {
    "id": 1001,
    "name": "Amazon Gift Card - USD",
    "category": "Gift Cards",
    "sub_category": "E-commerce",
    "country_id": 1,
    "currency_id": 1,
    "image_url": "https://cdn.starship.com/products/amazon-gc.jpg",
    "delivery_mode": "Digital",
    "delivery_type": "Email",
    "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_id": 1,
    "currency_id": 1,
    "image_url": "https://cdn.starship.com/products/google-play.jpg",
    "delivery_mode": "Digital",
    "delivery_type": "Code",
    "delivery_time": "Instant",
    "validity": "No expiry",
    "available_denominations": [
      {
        "min_value": 5.00,
        "max_value": 100.00,
        "discount": 1.8
      }
    ]
  }
]

Product Object Fields

FieldTypeDescription
idnumberUnique product identifier
namestringProduct display name
categorystringPrimary category (e.g., "Gift Cards", "Mobile Top-up")
sub_categorystringSubcategory classification
country_idnumberSupported country ID
currency_idnumberProduct currency ID
image_urlstringProduct image URL
delivery_modestringDelivery method (e.g., "Digital", "Physical")
delivery_typestringDelivery type (e.g., "Email", "Code", "SMS")
delivery_timestringExpected delivery time
validitystringProduct validity period
termsstringTerms and conditions (optional)
detailsstringProduct description (optional)
how_to_usestringUsage instructions (optional)
available_denominationsarrayAvailable 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

ParameterTypeRequiredDescription
idnumberYesProduct ID (must be > 0)

Query Parameters

ParameterTypeDefaultDescription

Response

Success Response (200 OK)

{
  "id": 1001,
  "name": "Amazon Gift Card - USD",
  "category": "Gift Cards",
  "sub_category": "E-commerce",
  "country_id": 1,
  "currency_id": 1,
  "image_url": "https://cdn.starship.com/products/amazon-gc.jpg",
  "delivery_mode": "Digital",
  "delivery_type": "Email",
  "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

# Get basic product details
curl -X GET "{{host}}/api/v1/products/1001" \
  -H "Authorization: Bearer your_access_token"

# Get product with full details
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']) . " via " . htmlspecialchars($product['delivery_type']) . "</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}/availability

Authentication: Bearer token required

Path Parameters

ParameterTypeRequiredDescription
idnumberYesProduct ID (must be > 0)

Request Body

{
  "denomination": 100.00,
  "quantity": 2
}
FieldTypeRequiredValidationDescription
denominationnumberYesMin: 0.01, Max: 1,000,000,000Purchase amount per unit
quantitynumberYesMin: 1Number of units to check

Response

Success Response (200 OK)

{
  "is_available": true
}

Response Fields

FieldTypeDescription
is_availablebooleanWhether the product is available for the requested denomination and quantity

Use Cases

  1. Pre-purchase Validation - Check availability before showing pricing options
  2. Real-time Inventory - Display current stock status to users
  3. Performance Optimization - Lighter check than full charge calculation
  4. 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": "bad_request",
  "message": "Invalid product ID"
}

404 Not Found

{
  "error": "not_found",
  "message": "Product not found"
}

401 Unauthorized

{
  "error": "unauthorized",
  "message": "Invalid or expired access token"
}

Error Handling Best Practices

  1. Always validate product IDs before making requests
  2. Handle 404 responses gracefully as products may become unavailable
  3. Implement retry logic with exponential backoff for 5xx errors
  4. Cache product data to reduce API calls and improve performance
  5. Check pagination headers when processing large datasets

Rate Limits

  • Product Listing: 100 requests per minute
  • Product Details: 200 requests per minute
  • Burst Limit: 20 requests per 10 seconds

Rate limit information is included in response headers:

  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: Unix timestamp when limit resets

Next Steps