retailerapi / docs

Node.js examples

TypeScript and JavaScript examples. Use the official SDK or call the REST API directly.

Install the SDK

npm i @retailerapi/sdk

Basic lookup with the SDK

import { createClient } from '@retailerapi/sdk';

const client = createClient({ apiKey: process.env.RETAILERAPI_KEY });

const product = await client.products.lookup({
  identifier: '19667262713',
});

console.log(product.title, product.current_price);

Cross-retailer lookup

const product = await client.products.lookup({
  identifier: '19667262713',
  include_cross_retailer: true,
});

const cheapest = (product.cross_retailer || [])
  .filter(c => c.status === 'ok' && typeof c.price === 'number')
  .reduce((min, c) => (c.price < min.price ? c : min), { price: Infinity });

console.log('Cheapest:', cheapest.retailer, cheapest.price);

Price history

const history = await client.products.priceHistory({
  identifier: '19667262713',
  timeframe: '90d',
  retailer: 'walmart',
});

const lowest = Math.min(...history.observations.map(o => o.price));
console.log(`Lowest in 90d: $${lowest}`);

Direct REST (no SDK)

const r = await fetch(
  'https://api.retailerapi.com/v1/products/19667262713',
  { headers: { Authorization: `Bearer ${process.env.RETAILERAPI_KEY}` } }
);
if (!r.ok) throw new Error(`${r.status}: ${await r.text()}`);
const product = await r.json();

Retry on 429

async function callWithRetry(url, opts = {}, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const r = await fetch(url, opts);
    if (r.ok) return r;
    if (r.status === 429) {
      const retryAfter = Number(r.headers.get('Retry-After') ?? '5');
      await new Promise(res => setTimeout(res, retryAfter * 1000));
      continue;
    }
    if (r.status >= 500 && attempt < maxRetries) {
      await new Promise(res => setTimeout(res, 2 ** attempt * 500));
      continue;
    }
    throw new Error(`${r.status}: ${await r.text()}`);
  }
}

Bulk lookup with concurrency

async function bulkLookup(upcs, concurrency = 5) {
  const results = [];
  for (let i = 0; i < upcs.length; i += concurrency) {
    const batch = upcs.slice(i, i + concurrency);
    const responses = await Promise.all(
      batch.map(upc => client.products.lookup({ identifier: upc }))
    );
    results.push(...responses);
  }
  return results;
}

const products = await bulkLookup([
  '19667262713', '194629116676', '728028502244',
]);

TypeScript types

The SDK exports types for every endpoint. Auto-completion works in any LSP-aware editor:

import type { Product, CrossRetailerCell } from '@retailerapi/sdk';

function isInStock(p: Product): boolean {
  return typeof p.current_price === 'number' && p.offers_count > 0;
}