Searching Products

Find products by name, country, or category.

The Bitrefill API offers multiple ways to find products in the catalog.

Search Endpoint

Search products by keyword:

const response = await fetch(`${BASE_URL}/products/search?q=amazon`, { headers });
const { data: products } = await response.json();

products.forEach(p => console.log(`${p.id}: ${p.name} (${p.country})`));
// amazon-us: Amazon.com (US)
// amazon-uk: Amazon.co.uk (GB)

Query Parameters

ParameterDescription
qSearch query (required, 1-100 chars)
startPagination offset
limitResults per page (max 50)
include_test_productsInclude test products

Listing with Filters

// All US products
const response = await fetch(`${BASE_URL}/products?country=US`, { headers });

// Gift cards only
const response = await fetch(`${BASE_URL}/products?type=gift_card`, { headers });

// US gift cards
const response = await fetch(`${BASE_URL}/products?country=US&type=gift_card`, { headers });

Pagination

async function getAllProducts() {
  const products = [];
  let url = `${BASE_URL}/products?limit=50`;
  
  while (url) {
    const response = await fetch(url, { headers });
    const data = await response.json();
    products.push(...data.data);
    url = data.meta._next;
  }
  
  return products;
}

Test Products

To include test products in results, add include_test_products=true. See Core Concepts for the list of available test products.

Caching Products

For production integrations, cache the product list locally:

class ProductCache {
  constructor() {
    this.products = new Map();
    this.lastRefresh = 0;
    this.refreshInterval = 60 * 60 * 1000; // 1 hour
  }
  
  async getProduct(productId) {
    await this.ensureFresh();
    return this.products.get(productId);
  }
  
  async searchProducts(query) {
    await this.ensureFresh();
    const lowerQuery = query.toLowerCase();
    return Array.from(this.products.values())
      .filter(p => p.name.toLowerCase().includes(lowerQuery));
  }
  
  async ensureFresh() {
    if (Date.now() - this.lastRefresh > this.refreshInterval) {
      await this.refresh();
    }
  }
  
  async refresh() {
    const allProducts = await this.fetchAllProducts();
    this.products.clear();
    allProducts.forEach(p => this.products.set(p.id, p));
    this.lastRefresh = Date.now();
  }
}

Refresh Recommendations

Use CaseRefresh Interval
DevelopmentOn-demand
Low volumeDaily
Medium volumeHourly
High volumeEvery 15-30 minutes

Product Quota

There's a quota limit on product endpoints:

  • 1000 requests per hour for /products and /products/search

Headers show remaining quota:

X-product-quota-remaining: 850
X-product-quota-next-window: 1800

Caching helps stay within limits.

eSIM Products

eSIM products have their own endpoints:

// List eSIM products
const response = await fetch(`${BASE_URL}/products/esims`, { headers });

// Get specific eSIM product
const response = await fetch(`${BASE_URL}/products/esims/bitrefill-esim-europe`, { headers });