E-Commerce Tools

8 Code Examples Using Canopy REST API for Amazon Data

Eight JavaScript examples showing how to use the Canopy REST API to fetch Amazon product details, pricing, reviews, inventory, search, and price tracking.

8 Code Examples Using Canopy REST API for Amazon Data

8 Code Examples Using Canopy REST API for Amazon Data

The Canopy REST API is a tool for developers to access real-time Amazon product data through simple HTTP requests. This includes product details, pricing, reviews, and inventory status - all delivered in structured JSON format. Here's what you'll learn in this guide:

  • Fetch product details by ASIN, including title, brand, price, and availability.
  • Retrieve real-time pricing for competitive analysis.
  • Track product reviews and ratings to understand customer feedback.
  • Monitor inventory to stay updated on stock levels.
  • Search Amazon products by keyword for research.
  • Track price changes over time for trend analysis.
  • Analyze best sellers and category rankings.
  • Aggregate data for merchandising decisions.

Each example uses JavaScript with the fetch API, making it easy to integrate into your projects. This guide is perfect for building tools like price trackers, e-commerce dashboards, or market analysis systems.

Key Features:

  • Simple GET requests to endpoints like https://rest.canopyapi.co/api/amazon/product.
  • Flexible pricing: 100 free requests/month, then $0.01/request.
  • JSON responses for seamless integration.

Whether you're tracking prices or analyzing reviews, these examples simplify the process of working with Amazon data.

1. Fetch Product Details by ASIN

Once you’ve set up the basic API, you can take it a step further by fetching detailed product data using an ASIN (Amazon Standard Identification Number). The ASIN is like a product's fingerprint on Amazon, allowing you to pull up detailed information such as the title, brand, price, images, and specifications with ease.

The endpoint to use is https://rest.canopyapi.co/api/amazon/product, and it requires two key query parameters:

  • asin: The unique ASIN of the product.
  • domain: Set this to US if you're retrieving data from Amazon.com in the United States.

Here’s a quick JavaScript example to fetch and format product details for the U.S. market:

const fetchProductDetails = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product?asin=${asin}&domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    // Extracting key product details
    const productInfo = {
      title: data.title,
      brand: data.brand,
      price: data.price?.displayAmount || 'N/A',
      rating: data.rating,
      reviewCount: data.reviewCount?.toLocaleString('en-US'),
      availability: data.availability,
      imageUrl: data.mainImage
    };

    console.log('Product Details:', productInfo);
    return productInfo;
  } else {
    console.error(`Request failed with status: ${response.status}`);
    return null;
  }
};

// Example usage with a real ASIN
fetchProductDetails('B0B3JBVDYP');

Key Details to Note:

  • Pricing Format: When the domain parameter is set to US, prices are returned in U.S. currency (e.g., "$52.16"). The displayAmount field handles this directly.
  • Number Formatting: JavaScript’s toLocaleString('en-US') ensures numbers like review counts are formatted correctly, turning 1234 into "1,234" for better readability.

This API gives you access to a staggering 350 million Amazon products, making it a powerful tool for e-commerce platforms, price comparison apps, or merchandising dashboards. And because the JSON response is structured, there’s no need to rely on web scraping or complex parsing.

Bonus: Formatting Dates

If your application needs to display dates in a standard U.S. format (MM/DD/YYYY), here’s a simple utility function:

const formatDate = (dateString) => {
  const date = new Date(dateString);
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const year = date.getFullYear();
  return `${month}/${day}/${year}`;
};

This method works seamlessly in a variety of environments, ensuring you can integrate accurate and clean product data into your application without hassle. Whether you're building a pricing tool or an inventory tracker, this approach simplifies the process and saves you time.

2. Retrieve Real-Time Pricing and Offers

Real-time pricing data plays a critical role in e-commerce, competitive analysis, and merchandising. With the Canopy REST API, you can access pricing information directly from Amazon.com, eliminating the need for manual checks and ensuring reliable, up-to-date data.

When you query a product using its ASIN, the API returns key pricing details. This includes current prices, discounts, offers from various sellers, and any available deal information - all through a single endpoint.

Here’s a practical example in JavaScript that demonstrates how to extract pricing data:

const fetchPricingAndOffers = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product?asin=${asin}&domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    // Extract pricing details
    const pricingInfo = {
      currentPrice: data.price?.displayAmount || 'N/A',
      rawPrice: data.price?.value || 0,
      currency: data.price?.currency || 'USD',
      listPrice: data.listPrice?.displayAmount || null,
      discount: data.discount || null,
      savingsAmount: data.savingsAmount?.displayAmount || null,
      savingsPercent: data.savingsPercent || null,
      dealType: data.dealType || 'Standard',
      availability: data.availability,
      isPrimeEligible: data.isPrime || false
    };

    // Format savings information
    if (pricingInfo.savingsPercent) {
      console.log(`Save ${pricingInfo.savingsPercent}% (${pricingInfo.savingsAmount})`);
    }

    console.log('Pricing Information:', pricingInfo);
    return pricingInfo;
  } else {
    console.error(`Request failed with status: ${response.status}`);
    return null;
  }
};

// Example usage
fetchPricingAndOffers('B0B3JBVDYP');

Understanding the Price Object

The API organizes pricing data in a format tailored for the U.S. market. The displayAmount field shows prices with the dollar sign and proper decimal formatting (e.g., "$52.16"), while the value field provides the raw numeric value (e.g., 52.16) for calculations.

For calculations, always rely on the raw value to ensure accuracy. Use the formatted amount for user interfaces, as it maintains correct U.S. currency conventions with the dollar sign and two decimal places.

Handling Multiple Offer Types

Amazon products often come with offers from multiple sellers, each with its own price and conditions. You can enhance the basic implementation to categorize and display these offers clearly:

const analyzePricingOptions = (productData) => {
  const offers = {
    mainOffer: {
      price: productData.price?.displayAmount,
      seller: productData.soldBy || 'Amazon',
      condition: productData.condition || 'New'
    },
    usedOffers: productData.usedPrice ? {
      startingPrice: productData.usedPrice.displayAmount,
      count: productData.usedOfferCount || 0
    } : null,
    primeAvailable: productData.isPrime || false
  };

  return offers;
};

This function organizes offers into categories, making it easier to display them or set up user alerts. The structured API response simplifies the process, removing the need for complex parsing.

Formatting for Financial Applications

If your project involves dashboards or reports that require consistent formatting for monetary values, you can use a utility function to ensure all prices follow U.S. conventions:

const formatUSD = (amount) => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(amount);
};

// Usage example
const rawPrice = 52.16;
console.log(formatUSD(rawPrice)); // Output: $52.16

The Intl.NumberFormat API automatically handles currency symbols, decimal points, and thousand separators, ensuring your data looks polished, whether it’s $5.99 or $1,234.56.

Automating Price Monitoring

With the Canopy API providing real-time data, you can set up workflows to monitor prices at regular intervals. This is especially useful for automating price comparisons or tracking deals. The Pay As You Go plan - starting at $0.01 per request after the first 100 free requests each month - keeps frequent checks affordable for most use cases.

3. Get Product Reviews and Ratings

Customer reviews and ratings play a crucial role in shaping purchasing decisions and providing insights into product performance. With the Canopy REST API, you can retrieve review data - such as overall ratings, review counts, and star breakdowns - all in one API call. Here's an example of how to extract and format this data using JavaScript:

const fetchProductReviews = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product?asin=${asin}&domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    // Extract review and rating information
    const reviewData = {
      averageRating: data.rating || 0,
      totalReviews: data.reviewCount || 0,
      ratingBreakdown: data.ratingBreakdown || {},
      topReviews: data.reviews?.map(review => ({
        title: review.title,
        body: review.body,
        rating: review.rating,
        author: review.author,
        verifiedPurchase: review.isVerified || false,
        date: formatReviewDate(review.date),
        helpfulVotes: review.helpfulVotes || 0
      })) || []
    };

    console.log('Review Summary:', reviewData);
    return reviewData;
  } else {
    console.error(`Request failed with status: ${response.status}`);
    return null;
  }
};

// Format date to MM/DD/YYYY for U.S. conventions
const formatReviewDate = (dateString) => {
  if (!dateString) return 'N/A';

  const date = new Date(dateString);
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const year = date.getFullYear();

  return `${month}/${day}/${year}`;
};

// Example usage
fetchProductReviews('B0B3JBVDYP');

Working with Rating Distributions

Understanding the breakdown of ratings is essential for evaluating customer feedback. The ratingBreakdown object provides a detailed view of ratings across the five-star scale, helping to identify trends like consistently high ratings or polarized feedback. Visualizing this data can help guide decisions about product offerings:

const analyzeRatingDistribution = (ratingBreakdown) => {
  const stars = [5, 4, 3, 2, 1];
  const distribution = stars.map(star => {
    const count = ratingBreakdown[`${star}Star`] || 0;
    return {
      stars: star,
      count: count,
      percentage: ratingBreakdown.total > 0 
        ? ((count / ratingBreakdown.total) * 100).toFixed(1) 
        : 0
    };
  });

  // Calculate quality score (weighted average)
  const qualityScore = distribution.reduce((score, item) => {
    return score + (item.stars * item.count);
  }, 0) / ratingBreakdown.total;

  return {
    distribution,
    qualityScore: qualityScore.toFixed(2)
  };
};

This function not only calculates the distribution percentages but also generates a weighted quality score, which can be used to compare products or monitor changes over time.

Handling Review Dates

To ensure reviews are displayed in chronological order, sort them by their raw date values before formatting. This keeps the most recent feedback at the top, making it easier to monitor new trends or issues:

const sortReviewsByDate = (reviews) => {
  return reviews.sort((a, b) => {
    return new Date(b.date) - new Date(a.date);
  }).map(review => ({
    ...review,
    formattedDate: formatReviewDate(review.date)
  }));
};

This method ensures the latest reviews are prioritized while maintaining a consistent date format for U.S. audiences.

Filtering Verified Purchase Reviews

Verified purchase reviews are particularly valuable since they come from confirmed buyers. By filtering for these reviews, you can focus on more reliable feedback:

const getVerifiedReviews = (reviews) => {
  return reviews.filter(review => review.isVerified === true);
};

const calculateVerifiedRating = (reviews) => {
  const verifiedReviews = getVerifiedReviews(reviews);

  if (verifiedReviews.length === 0) return 0;

  const totalRating = verifiedReviews.reduce((sum, review) => {
    return sum + review.rating;
  }, 0);

  return (totalRating / verifiedReviews.length).toFixed(2);
};

This technique highlights product quality based on the experiences of verified buyers, reducing the influence of potentially biased or incentivized reviews.

Extracting Sentiment Indicators

Beyond star ratings, the text of reviews can reveal customer sentiment. By performing a basic keyword analysis, you can identify positive and negative trends:

const extractReviewInsights = (reviews) => {
  const positiveKeywords = ['excellent', 'great', 'love', 'perfect', 'amazing'];
  const negativeKeywords = ['poor', 'terrible', 'broken', 'disappointed', 'waste'];

  const insights = {
    positiveCount: 0,
    negativeCount: 0,
    commonPhrases: []
  };

  reviews.forEach(review => {
    const text = (review.title + ' ' + review.body).toLowerCase();

    positiveKeywords.forEach(keyword => {
      if (text.includes(keyword)) insights.positiveCount++;
    });

    negativeKeywords.forEach(keyword => {
      if (text.includes(keyword)) insights.negativeCount++;
    });
  });

  return insights;
};

This simple analysis provides a snapshot of customer sentiment, helping to identify recurring themes in feedback.

Cost Considerations for Review Data

Review data is included with product data requests at no extra cost. Under the Pay As You Go plan, each product request costs $0.01 after the first 100 free requests per month. This makes it a cost-effective way to gather valuable insights.

4. Track Inventory and Availability

Keeping tabs on inventory is essential for understanding how your products are performing. Product availability directly impacts sales, and having a clear picture of stock levels can help you make better decisions. With the Canopy REST API, you can access Amazon product data in real time, including stock estimates. Here's an example in JavaScript to get you started:

const checkProductAvailability = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product?asin=${asin}&domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    // Extract stock data
    const inventoryData = {
      availability: data.availability || 'Unknown',
      stockLevel: data.stockEstimate || null,
      lastUpdated: formatDateTime(new Date())
    };

    console.log('Inventory Status:', inventoryData);
    return inventoryData;
  } else {
    console.error(`Request failed with status: ${response.status}`);
    return null;
  }
};

// Format date and time to U.S. conventions (MM/DD/YYYY, HH:MM AM/PM)
const formatDateTime = (date) => {
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const year = date.getFullYear();

  let hours = date.getHours();
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const ampm = hours >= 12 ? 'PM' : 'AM';
  hours = hours % 12 || 12;

  return `${month}/${day}/${year}, ${hours}:${minutes} ${ampm}`;
};

// Example usage
checkProductAvailability('B0B3JBVDYP');

Understanding Stock Estimates

Stock estimates are a great way to gauge inventory levels, even if they don’t reveal exact quantities. You can categorize these estimates into meaningful insights and determine urgency levels:

const categorizeStockLevel = (stockEstimate) => {
  if (!stockEstimate) return 'Unknown';

  if (stockEstimate > 1000) {
    return 'High Stock';
  } else if (stockEstimate > 100) {
    return 'Moderate Stock';
  } else if (stockEstimate > 10) {
    return 'Low Stock';
  } else if (stockEstimate > 0) {
    return 'Very Low Stock';
  } else {
    return 'Out of Stock';
  }
};

const assessInventoryHealth = (inventoryData) => {
  const stockCategory = categorizeStockLevel(inventoryData.stockLevel);
  const urgencyScore = inventoryData.stockLevel 
    ? Math.max(0, 100 - inventoryData.stockLevel) 
    : 100;

  return {
    category: stockCategory,
    urgencyScore: urgencyScore.toFixed(0),
    recommendation: urgencyScore > 80 
      ? 'Consider alternative suppliers or products' 
      : urgencyScore > 50 
        ? 'Monitor closely for restocking' 
        : 'Healthy inventory levels'
  };
};

This method helps you focus on products that need immediate attention, ensuring you can adjust your strategy effectively.

Tracking Multiple Products

If you need to monitor several products at once, batch processing can save you time. Here's how you can check availability for multiple ASINs and present the results in a clear format:

const batchCheckInventory = async (asins) => {
  const results = [];

  for (const asin of asins) {
    const inventoryData = await checkProductAvailability(asin);

    if (inventoryData) {
      results.push({
        asin: asin,
        status: inventoryData.stockLevel && inventoryData.stockLevel > 0 ? 'In Stock' : 'Out of Stock',
        stockLevel: inventoryData.stockLevel 
          ? inventoryData.stockLevel.toLocaleString('en-US') 
          : 'N/A',
        availability: inventoryData.availability,
        timestamp: inventoryData.lastUpdated
      });
    }

    // Delay to respect API rate limits
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  return results;
};

// Format and display the inventory report
const displayInventoryReport = (results) => {
  console.log('\n=== Inventory Report ===\n');

  results.forEach((item, index) => {
    console.log(`${index + 1}. ASIN: ${item.asin}`);
    console.log(`   Status: ${item.status}`);
    console.log(`   Stock Level: ${item.stockLevel}`);
    console.log(`   Availability: ${item.availability}`);
    console.log(`   Last Updated: ${item.timestamp}\n`);
  });
};

// Example usage with multiple products
const productList = ['B0B3JBVDYP', 'B08N5WRWNW', 'B09G9FPHY6'];
batchCheckInventory(productList).then(displayInventoryReport);

Setting Up Alerts for Availability

Proactive stock management becomes much easier with an automated alert system. Here's a simple way to set up notifications that trigger when stock levels change:

const createAvailabilityMonitor = (asin, checkInterval = 300000) => {
  let previousStock = null;

  const monitor = setInterval(async () => {
    const inventoryData = await checkProductAvailability(asin);

    if (!inventoryData) return;

    const currentStock = inventoryData.stockLevel;

    if (previousStock !== null && currentStock !== previousStock) {
      const change = currentStock - previousStock;
      const changeFormatted = change.toLocaleString('en-US', { 
        signDisplay: 'always' 
      });

      console.log(`\n🔔 Stock Alert for ${asin}`);
      console.log(`   Previous: ${previousStock !== null ? previousStock.toLocaleString('en-US') : 'N/A'}`);
      console.log(`   Current: ${currentStock !== null ? currentStock.toLocaleString('en-US') : 'N/A'}`);
      console.log(`   Change: ${changeFormatted} units`);
      console.log(`   Time: ${formatDateTime(new Date())}\n`);

      if (currentStock === 0) {
        console.log('⚠️ CRITICAL: Product is now out of stock!');
      } else if (currentStock < 10) {
        console.log('⚠️ WARNING: Stock level critically low!');
      }
    }

    previousStock = currentStock;
  }, checkInterval);

  return monitor;
};

// Start monitoring (checks every 5 minutes)
// const monitor = createAvailabilityMonitor('B0B3JBVDYP', 300000);

// To stop monitoring, use clearInterval(monitor);

5. Search Products by Keyword

The Canopy REST API makes it simple to search for Amazon products by keyword, returning detailed product data in a structured JSON format. Here's how you can use it with a straightforward JavaScript example:

const searchProducts = async (keyword, page = 1) => {
  const url = `https://rest.canopyapi.co/api/amazon/search?keyword=${encodeURIComponent(keyword)}&domain=US&page=${page}`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    // Extract and format search results
    const products = data.results.map(product => ({
      asin: product.asin,
      title: product.title,
      price: formatPrice(product.price),
      rating: product.rating ? product.rating.toFixed(1) : 'N/A',
      reviewCount: product.reviewCount 
        ? product.reviewCount.toLocaleString('en-US') 
        : '0',
      imageUrl: product.imageUrl,
      isPrime: product.isPrime || false
    }));

    return {
      keyword: keyword,
      totalResults: data.totalResults.toLocaleString('en-US'),
      page: page,
      products: products
    };
  } else {
    console.error(`Search failed with status: ${response.status}`);
    return null;
  }
};

// Format prices to U.S. currency
const formatPrice = (price) => {
  if (!price) return 'N/A';

  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(price);
};

// Example usage
searchProducts('wireless headphones', 1).then(results => {
  if (results) {
    console.log(`Found ${results.totalResults} results for "${results.keyword}"`);
    results.products.forEach((product, index) => {
      console.log(`\n${index + 1}. ${product.title}`);
      console.log(`   ASIN: ${product.asin}`);
      console.log(`   Price: ${product.price}`);
      console.log(`   Rating: ${product.rating} (${product.reviewCount} reviews)`);
      console.log(`   Prime: ${product.isPrime ? 'Yes' : 'No'}`);
    });
  }
});

Filtering and Sorting Results

Once you've retrieved raw search data, you can refine it by applying filters and sorting to meet specific needs. Here's how to customize results:

const filterSearchResults = (products, filters = {}) => {
  return products.filter(product => {
    // Price range filter (in dollars)
    if (filters.minPrice && parseFloat(product.price.replace(/[$,]/g, '')) < filters.minPrice) {
      return false;
    }
    if (filters.maxPrice && parseFloat(product.price.replace(/[$,]/g, '')) > filters.maxPrice) {
      return false;
    }

    // Minimum rating filter
    if (filters.minRating && parseFloat(product.rating) < filters.minRating) {
      return false;
    }

    // Prime eligibility filter
    if (filters.primeOnly && !product.isPrime) {
      return false;
    }

    // Minimum review count filter
    if (filters.minReviews) {
      const reviewCount = parseInt(product.reviewCount.replace(/,/g, ''));
      if (reviewCount < filters.minReviews) {
        return false;
      }
    }

    return true;
  });
};

// Sort products by different criteria
const sortProducts = (products, sortBy = 'relevance') => {
  const sorted = [...products];

  switch (sortBy) {
    case 'price-low':
      return sorted.sort((a, b) => {
        const priceA = parseFloat(a.price.replace(/[$,]/g, ''));
        const priceB = parseFloat(b.price.replace(/[$,]/g, ''));
        return priceA - priceB;
      });

    case 'price-high':
      return sorted.sort((a, b) => {
        const priceA = parseFloat(a.price.replace(/[$,]/g, ''));
        const priceB = parseFloat(b.price.replace(/[$,]/g, ''));
        return priceB - priceA;
      });

    case 'rating':
      return sorted.sort((a, b) => parseFloat(b.rating) - parseFloat(a.rating));

    case 'reviews':
      return sorted.sort((a, b) => {
        const reviewsA = parseInt(a.reviewCount.replace(/,/g, ''));
        const reviewsB = parseInt(b.reviewCount.replace(/,/g, ''));
        return reviewsB - reviewsA;
      });

    default:
      return sorted;
  }
};

// Example: Premium Wireless Headphones
const findPremiumHeadphones = async () => {
  const results = await searchProducts('wireless headphones', 1);

  if (!results) return;

  const filtered = filterSearchResults(results.products, {
    minPrice: 50,
    maxPrice: 300,
    minRating: 4.0,
    minReviews: 100,
    primeOnly: true
  });

  const sorted = sortProducts(filtered, 'rating');

  console.log(`\nFound ${sorted.length} premium options:\n`);
  sorted.slice(0, 5).forEach((product, index) => {
    console.log(`${index + 1}. ${product.title}`);
    console.log(`   ${product.price} | ${product.rating}★ | ${product.reviewCount} reviews\n`);
  });
};

Building a Multi-Page Search Tool

For larger queries, you can extend your search across multiple pages to gather more comprehensive product data:

const searchMultiplePages = async (keyword, maxPages = 3) => {
  const allProducts = [];
  const searchMetadata = {
    keyword: keyword,
    pagesSearched: 0,
    totalProducts: 0,
    searchDate: new Date().toLocaleDateString('en-US')
  };

  for (let page = 1; page <= maxPages; page++) {
    console.log(`Searching page ${page}...`);

    const results = await searchProducts(keyword, page);

    if (!results || results.products.length === 0) {
      console.log(`No more results after page ${page - 1}`);
      break;
    }

    allProducts.push(...results.products);
    searchMetadata.pagesSearched = page;
    searchMetadata.totalProducts = allProducts.length;

    // Respect API rate limits
    if (page < maxPages) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }

  return {
    metadata: searchMetadata,
    products: allProducts
  };
};

// Analyze search results across multiple pages
const analyzeSearchResults = (searchData) => {
  const products = searchData.products;

  const prices = products
    .map(p => parseFloat(p.price.replace(/[$,]/g, '')))
    .filter(p => !isNaN(p));

  const ratings = products
    .map(p => parseFloat(p.rating))
    .filter(r => !isNaN(r));

  const primeCount = products.filter(p => p.isPrime).length;

  const analysis = {
    totalProducts: products.length,
    priceRange: {
      lowest: Math.min(...prices).toLocaleString('en-US', { 
        style: 'currency', 
        currency: 'USD' 
      }),
      highest: Math.max(...prices).toLocaleString('en-US', { 
        style: 'currency', 
        currency: 'USD' 
      })

6. Monitor Price Changes Over Time

Tracking price trends can help you make smarter purchasing decisions, optimize sales strategies, or adjust pricing effectively. By leveraging real-time data from the Canopy REST API, you can create a custom system to monitor and analyze Amazon price fluctuations over time.

Here’s how you can fetch current pricing and keep a historical record:

const trackProductPrice = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product/${asin}?domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    const priceSnapshot = {
      asin: asin,
      timestamp: new Date().toLocaleString('en-US', {
        month: '2-digit',
        day: '2-digit',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
        hour12: true
      }),
      timestampISO: new Date().toISOString(),
      price: data.price || null,
      listPrice: data.listPrice || null,
      discount: data.discount || 0,
      availability: data.availability || 'Unknown',
      currency: 'USD'
    };

    return priceSnapshot;
  } else {
    console.error(`Price data request failed with status: ${response.status}`);
    return null;
  }
};

// Store price history
let priceHistory = [];

const addPriceSnapshot = async (asin) => {
  const snapshot = await trackProductPrice(asin);

  if (snapshot && snapshot.price) {
    priceHistory.push(snapshot);

    const savings = snapshot.listPrice && snapshot.listPrice > snapshot.price 
      ? snapshot.listPrice - snapshot.price 
      : 0;

    console.log(`Price recorded for ${asin}: ${snapshot.timestamp} | ${formatCurrency(snapshot.price)}${savings > 0 ? ` | Save ${formatCurrency(savings)} (${snapshot.discount}%)` : ''}`);
  }

  return snapshot;
};

// Format currency in U.S. format
const formatCurrency = (amount) => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2
  }).format(amount);
};

// Example: Track a product by ASIN
const asin = 'B08N5WRWNW';
addPriceSnapshot(asin);

Once you’ve gathered enough price data, you can dig into the numbers to uncover patterns. This analysis can help you spot opportunities or identify the best times to buy or sell:

const analyzePriceHistory = (asin) => {
  const productHistory = priceHistory.filter(snapshot => snapshot.asin === asin);

  if (productHistory.length < 2) {
    console.log('Not enough data for analysis. Need at least 2 price points.');
    return null;
  }

  // Sort by timestamp
  productHistory.sort((a, b) => new Date(a.timestampISO) - new Date(b.timestampISO));

  const prices = productHistory.map(s => s.price);
  const currentPrice = prices[prices.length - 1];
  const previousPrice = prices[prices.length - 2];
  const lowestPrice = Math.min(...prices);
  const highestPrice = Math.max(...prices);
  const averagePrice = prices.reduce((a, b) => a + b, 0) / prices.length;

  // Calculate price change
  const priceChange = currentPrice - previousPrice;
  const priceChangePercent = ((priceChange / previousPrice) * 100).toFixed(2);

  // Calculate volatility
  const priceChanges = [];
  for (let i = 1; i < prices.length; i++) {
    priceChanges.push(Math.abs(prices[i] - prices[i - 1]));
  }
  const averageChange = priceChanges.reduce((a, b) => a + b, 0) / priceChanges.length;

  const analysis = {
    asin: asin,
    dataPoints: productHistory.length,
    timeRange: {
      start: productHistory[0].timestamp,
      end: productHistory[productHistory.length - 1].timestamp
    },
    currentPrice: formatCurrency(currentPrice),
    previousPrice: formatCurrency(previousPrice),
    priceChange: formatCurrency(Math.abs(priceChange)),
    priceChangeDirection: priceChange > 0 ? 'up' : priceChange < 0 ? 'down' : 'unchanged',
    priceChangePercent: `${Math.abs(parseFloat(priceChangePercent))}%`,
    lowestPrice: formatCurrency(lowestPrice),
    highestPrice: formatCurrency(highestPrice),
    averagePrice: formatCurrency(averagePrice),
    volatility: averageChange > 5 ? 'High' : averageChange > 2 ? 'Moderate' : 'Low',
    recommendation: currentPrice <= lowestPrice * 1.05 ? 'Good time to buy' : 
                    currentPrice >= highestPrice * 0.95 ? 'Price is near peak' : 
                    'Monitor for better deals'
  };

  return analysis;
};

const displayPriceAnalysis = (asin) => {
  const analysis = analyzePriceHistory(asin);
  if (!analysis) return;

  console.log(`\n=== Price Analysis for ${analysis.asin} ===`);
  console.log(`Data Points: ${analysis.dataPoints}`);
  console.log(`Period: ${analysis.timeRange.start} to ${analysis.timeRange.end}\n`);
  console.log(`Current Price: ${analysis.currentPrice}`);
  console.log(`Previous Price: ${analysis.previousPrice}`);
  console.log(`Change: ${analysis.priceChange} ${analysis.priceChangeDirection} (${analysis.priceChangePercent})\n`);
  console.log(`Lowest Recorded: ${analysis.lowestPrice}`);
  console.log(`Highest Recorded: ${analysis.highestPrice}`);
  console.log(`Average Price: ${analysis.averagePrice}`);
  console.log(`Price Volatility: ${analysis.volatility}\n`);
  console.log(`💡 ${analysis.recommendation}`);
};

// Example: Display analysis for the tracked product
displayPriceAnalysis(asin);

Building a Price Alert System

Take your monitoring to the next level by setting up automated alerts. These alerts can notify you when prices hit specific thresholds, helping you act quickly:

const createPriceAlert = (asin, targetPrice, alertType = 'below') => {
  return {
    asin,
    targetPrice,
    alertType, // 'below' or 'above'
    createdAt: new Date().toLocaleString('en-US'),
    isActive: true
  };
};

const checkPriceAlerts = async (alerts) => {
  const triggeredAlerts = [];

  for (const alert of alerts.filter(a => a.isActive)) {
    const snapshot = await trackProductPrice(alert.asin);
    if (!snapshot || !snapshot.price) continue;

    let triggered = false;
    let message = '';

    switch (alert.alertType) {
      case 'below':
        if (snapshot.price <= alert.targetPrice) {
          triggered = true;
          message = `Price dropped to ${formatCurrency(snapshot.price)} (target: ${formatCurrency(alert.targetPrice)})`;
        }
        break;
      case 'above':
        if (snapshot.price >= alert.targetPrice) {
          triggered = true;
          message = `Price increased to ${formatCurrency(snapshot.price)} (target: ${formatCurrency(alert.targetPrice)})`;
        }
        break;
    }

7. Build a Best Seller or Category Overview

Spotting top-selling products can sharpen your market analysis, improve your listings, and help you create dashboards packed with actionable insights. The Canopy REST API makes it simple to pull best seller rankings and category data, so you can track which products are performing well. The structured data provided by the API integrates seamlessly into your analytical tools, helping you dig deeper into your competitive landscape.

Here’s an example of how to fetch product data, including best seller rankings:

const getBestSellerData = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product/${asin}?domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    return {
      asin: data.asin || asin,
      title: data.title || 'N/A',
      brand: data.brand || 'Unknown',
      price: data.price || null,
      rating: data.rating || null,
      reviewCount: data.reviewCount || 0,
      bestSellerRank: data.bestSellerRank || null,
      categories: data.categories || [],
      availability: data.availability || 'Unknown',
      imageUrl: data.imageUrl || null
    };
  } else {
    console.error(`Request failed with status: ${response.status}`);
    return null;
  }
};

// Using previously defined formatCurrency and formatNumber functions

// Example: Fetch data for a single best seller
const asin = 'B08N5WRWNW';
const productData = await getBestSellerData(asin);

if (productData) {
  console.log(`Product: ${productData.title}`);
  console.log(`Brand: ${productData.brand}`);
  console.log(`Price: ${formatCurrency(productData.price)}`);
  console.log(`Rating: ${productData.rating}/5.0 (${formatNumber(productData.reviewCount)} reviews)`);

  if (productData.bestSellerRank) {
    console.log(`Best Seller Rank: #${formatNumber(productData.bestSellerRank)}`);
  }
}

Creating a Category Overview Dashboard

Using real-time product data, you can create a dashboard that synthesizes best seller and category metrics for a more strategic perspective. When analyzing multiple products in a category, it’s essential to organize and compare ranking data effectively:

const buildCategoryOverview = async (asins) => {
  const products = [];

  for (const asin of asins) {
    const productData = await getBestSellerData(asin);
    if (productData) {
      products.push(productData);
    }
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  // Sort products by ascending best seller rank
  products.sort((a, b) => {
    const rankA = a.bestSellerRank || Infinity;
    const rankB = b.bestSellerRank || Infinity;
    return rankA - rankB;
  });

  return products;
};

const displayCategoryOverview = (products, categoryName) => {
  console.log(`\n=== ${categoryName} - Best Sellers Overview ===\n`);

  products.forEach((product, index) => {
    const position = index + 1;
    const rank = product.bestSellerRank ? `#${formatNumber(product.bestSellerRank)}` : 'Unranked';
    const price = formatCurrency(product.price);
    const rating = product.rating ? `${product.rating}/5.0` : 'N/A';
    const reviews = formatNumber(product.reviewCount);

    console.log(`${position}. ${product.title}`);
    console.log(`   Brand: ${product.brand} | ASIN: ${product.asin}`);
    console.log(`   Rank: ${rank} | Price: ${price}`);
    console.log(`   Rating: ${rating} (${reviews} reviews)`);
    console.log(`   Availability: ${product.availability}\n`);
  });

  // Calculate category statistics
  const availablePrices = products.filter(p => p.price).map(p => p.price);
  const avgPrice = availablePrices.length > 0 
    ? availablePrices.reduce((a, b) => a + b, 0) / availablePrices.length 
    : 0;

  const availableRatings = products.filter(p => p.rating).map(p => p.rating);
  const avgRating = availableRatings.length > 0
    ? availableRatings.reduce((a, b) => a + b, 0) / availableRatings.length
    : 0;

  console.log(`--- Category Statistics ---`);
  console.log(`Total Products Analyzed: ${products.length}`);
  console.log(`Average Price: ${formatCurrency(avgPrice)}`);
  console.log(`Average Rating: ${avgRating.toFixed(2)}/5.0`);
  console.log(`Price Range: ${formatCurrency(Math.min(...availablePrices))} - ${formatCurrency(Math.max(...availablePrices))}`);
};

// Example: Analyze a category of electronics
const electronicsAsins = [
  'B08N5WRWNW',
  'B0B7CPSN8C',
  'B09G9FPHY6',
  'B0BDJ7FWDZ',
  'B08L5VFJ2L'
];

const categoryProducts = await buildCategoryOverview(electronicsAsins);
displayCategoryOverview(categoryProducts, 'Electronics');

Identifying Market Opportunities

Once you have a clear overview of a category, you can identify competitive advantages. By analyzing best seller data, you can uncover gaps and opportunities for differentiation. The function below evaluates a product’s position based on reviews, ratings, pricing, and ranking:

const analyzeMarketPosition = (products) => {
  const insights = [];

  products.forEach(product => {
    const analysis = {
      asin: product.asin,
      title: product.title,
      opportunities: []
    };

    // Check for high demand with strong ratings
    if (product.reviewCount > 1000 && product.rating >= 4.0) {
      analysis.opportunities.push('High demand product with strong ratings');
    }

    // Identify premium pricing opportunities
    const productsWithPrice = products.filter(p => p.price);
    const avgPrice = productsWithPrice.length > 0 
      ? productsWithPrice.reduce((sum, p) => sum + p.price, 0) / productsWithPrice.length 
      : 0;

    if (product.price && avgPrice > 0 && product.price < avgPrice * 0.7) {
      analysis.opportunities.push(`Priced ${((1 - product.price / avgPrice) * 100).toFixed(0)}% below category average`);
    }

    // Mark products ranked in the top 100
    if (product.bestSellerRank && product.bestSellerRank <= 100) {
      analysis.opportunities.push(`Top 100 best seller (Rank #${formatNumber(product.bestSellerRank)})`);
    }

    // Identify popular products with room for improvement
    if (product.rating && product.rating < 4.0 && product.reviewCount > 500) {
      analysis.opportunities.push('Popular but lower-rated - potential for differentiation');
    }

    if (analysis.opportunities.length > 0) {
      insights.push(analysis);
    }
  });

  return insights;
};

const displayMarketInsights = (insights) => {
  console.log(`\n=== Market Opportunities ===\n`);
  insights.forEach((insight, index) => {
    console.log(`${index + 1}. ${insight.title} (ASIN: ${insight.asin})`);
    console.log(`   Opportunities:`);

8. Aggregate Data for Merchandising Decisions

To make smart merchandising decisions, you need to bring together data like product details, pricing trends, reviews, inventory status, and best seller rankings. The Canopy REST API makes this easier by combining all these points into a single dataset. This allows you to spot trends, fine-tune product assortments, adjust pricing, and make informed product decisions.

Trying to track this data manually just isn’t practical. By automating the process with the API, you can generate clear, actionable reports. The key is to structure your data collection around the metrics that align with your business goals.

The aggregation methods explained here build on earlier examples, such as tracking pricing, reviews, and inventory, giving merchandisers a well-rounded view.

Building a Comprehensive Product Intelligence System

Start by creating a function that pulls together multiple data points for each product. This method gathers pricing, reviews, availability, and ranking information into one unified dataset:

const aggregateProductData = async (asin) => {
  const url = `https://rest.canopyapi.co/api/amazon/product/${asin}?domain=US`;

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'API-KEY': '<YOUR_API_KEY>',
      'Content-Type': 'application/json'
    }
  });

  if (response.status === 200) {
    const data = await response.json();

    // Calculating additional metrics
    const pricePerReview = data.price && data.reviewCount > 0 
      ? data.price / data.reviewCount 
      : null;

    const ratingQuality = data.rating && data.reviewCount 
      ? (data.rating / 5.0) * Math.log10(data.reviewCount + 1) 
      : 0;

    return {
      asin: data.asin || asin,
      title: data.title || 'N/A',
      brand: data.brand || 'Unknown',
      price: data.price || null,
      rating: data.rating || null,
      reviewCount: data.reviewCount || 0,
      bestSellerRank: data.bestSellerRank || null,
      categories: data.categories || [],
      availability: data.availability || 'Unknown',
      inStock: data.availability && data.availability.toLowerCase().includes('in stock'),
      imageUrl: data.imageUrl || null,
      // Additional calculated metrics
      pricePerReview: pricePerReview,
      ratingQuality: ratingQuality,
      timestamp: new Date().toISOString()
    };
  } else {
    console.error(`Failed to fetch data for ASIN ${asin}: ${response.status}`);
    return null;
  }
};

// Uses previously defined formatCurrency and formatNumber functions

Creating a Merchandising Dashboard

Once you’ve aggregated the data, you can create a dashboard that consolidates these metrics into actionable insights for merchandising:

const generateMerchandisingReport = async (asins) => {
  const products = [];

  console.log(`Aggregating data for ${asins.length} products...\n`);

  for (const asin of asins) {
    const productData = await aggregateProductData(asin);
    if (productData) {
      products.push(productData);
    }
    // Adding a delay to respect API rate limits
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  // Calculating overall metrics for the portfolio
  const inStockProducts = products.filter(p => p.inStock);
  const productsWithPrice = products.filter(p => p.price);
  const productsWithRatings = products.filter(p => p.rating);

  const totalInventoryValue = productsWithPrice.reduce((sum, p) => sum + p.price, 0);
  const avgPrice = productsWithPrice.length > 0 
    ? totalInventoryValue / productsWithPrice.length 
    : 0;

  const avgRating = productsWithRatings.length > 0
    ? productsWithRatings.reduce((sum, p) => sum + p.rating, 0) / productsWithRatings.length
    : 0;

  const totalReviews = products.reduce((sum, p) => sum + p.reviewCount, 0);

  // Identifying top performers and other categories
  const topRated = [...products]
    .filter(p => p.rating && p.reviewCount >= 10)
    .sort((a, b) => b.ratingQuality - a.ratingQuality)
    .slice(0, 5);

  const topSellers = [...products]
    .filter(p => p.bestSellerRank)
    .sort((a, b) => a.bestSellerRank - b.bestSellerRank)
    .slice(0, 5);

  const lowPerformers = [...products]
    .filter(p => p.rating && p.rating < 3.5 && p.reviewCount >= 20)
    .sort((a, b) => a.rating - b.rating);

  const outOfStock = products.filter(p => !p.inStock);

  return {
    summary: {
      totalProducts: products.length,
      inStockCount: inStockProducts.length,
      inStockRate: (inStockProducts.length / products.length * 100).toFixed(1),
      avgPrice: avgPrice,
      totalInventoryValue: totalInventoryValue,
      avgRating: avgRating,
      totalReviews: totalReviews
    },
    topRated: topRated,
    topSellers: topSellers,
    lowPerformers: lowPerformers,
    outOfStock: outOfStock,
    allProducts: products
  };
};

To display the results, you can use the following function to print the merchandising report in your console:

const displayMerchandisingReport = (report) => {
  console.log(`\n========================================`);
  console.log(`    MERCHANDISING INTELLIGENCE REPORT`);
  console.log(`    Generated: ${new Date().toLocaleString('en-US')}`);
  console.log(`========================================\n`);

  // Portfolio Summary
  console.log(`--- Portfolio Summary ---`);
  console.log(`Total Products Analyzed: ${report.summary.totalProducts}`);
  console.log(`In Stock: ${report.summary.inStockCount} (${report.summary.inStockRate}%)`);
  console.log(`Average Price: ${formatCurrency(report.summary.avgPrice)}`);
  console.log(`Total Inventory Value: ${formatCurrency(report.summary.totalInventoryValue)}`);
  console.log(`Average Rating: ${report.summary.avgRating.toFixed(2)}/5.0`);
  console.log(`Total Customer Reviews: ${formatNumber(report.summary.totalReviews)}\n`);

  // Top Rated Products
  if (report.topRated.length > 0) {
    console.log(`--- Top Rated Products (Quality Score) ---`);
    report.topRated.forEach((product, index) => {
      console.log(`${index + 1}. ${product.title}`);
      console.log(`   ASIN: ${product.asin} | Brand: ${product.brand}`);
      console.log(`   Rating: ${product.rating}/5.0 (${formatNumber(product.reviewCount)} reviews)`);
      console.log(`   Price: ${formatCurrency(product.price)} | Quality Score: ${product.ratingQuality.toFixed(2)}\n`);
    });
  }

  // Best Sellers
  if (report.topSellers.length > 0) {
    console.log(`--- Best Selling Products ---`);
    report.topSellers.forEach((product, index) => {
      console.log(`${index + 1}. ${product.title}`);
      console.log(`   ASIN: ${product.asin} | Best Seller Rank: ${product.bestSellerRank}`);
      console.log(`   Price: ${formatCurrency(product.price)} | Rating: ${product.rating}/5.0\n`);
    });
  }

  // Low Performing Products
  if (report.lowPerformers.length > 0) {
    console.log(`--- Low Performing Products ---`);
    report.lowPerformers.forEach((product, index) => {
      console.log(`

Comparison Table

The table below organizes key product metrics side-by-side, making it easier for merchandising teams to evaluate performance at a glance. This format is particularly helpful when pulling data from an API and presenting it in a clear, concise format.

ASIN Product Title Brand Price (USD) Rating Reviews BSR In Stock Last Updated
B08N5WRWNW Echo Dot (4th Gen) Amazon $49.99 4.7 284,532 12 Yes 12/04/2025
B09B8V1LZ3 Fire TV Stick 4K Max Amazon $54.99 4.6 156,891 8 Yes 12/04/2025
B0BSHF7WHW Ring Video Doorbell Ring $99.99 4.5 89,234 45 Yes 12/04/2025
B07XJ8C8F5 Kindle Paperwhite Amazon $139.99 4.6 127,456 23 No 12/04/2025
B08J5F3G18 Blink Mini Camera Blink $34.99 4.3 201,678 67 Yes 12/04/2025

Generating the Table with JavaScript

To create a comparison table programmatically, you can use JavaScript to organize and display product data. For example, the function below sorts products by their Best Seller Rank (BSR) and formats them into a readable table.

const generateComparisonTable = (products) => {
  // Sort products by Best Seller Rank
  const sortedProducts = [...products]
    .filter(p => p.bestSellerRank)
    .sort((a, b) => a.bestSellerRank - b.bestSellerRank);

  console.log(`\n--- Product Comparison Table ---\n`);

  // Table header
  console.log(
    `${'ASIN'.padEnd(12)} | ${'Title'.padEnd(35)} | ${'Brand'.padEnd(15)} | ${'Price'.padEnd(10)} | ${'Rating'.padEnd(8)} | ${'Reviews'.padEnd(10)} | ${'BSR'.padEnd(6)} | ${'In Stock'.padEnd(10)} | ${'Updated'.padEnd(12)}`
  );
  console.log(
    `${'-'.repeat(12)} | ${'-'.repeat(35)} | ${'-'.repeat(15)} | ${'-'.repeat(10)} | ${'-'.repeat(8)} | ${'-'.repeat(10)} | ${'-'.repeat(6)} | ${'-'.repeat(10)} | ${'-'.repeat(12)}`
  );

  // Table rows
  sortedProducts.forEach(product => {
    const title = product.title.length > 35 
      ? product.title.substring(0, 32) + '...' 
      : product.title.padEnd(35);
    const brand = product.brand ? product.brand.padEnd(15) : 'N/A'.padEnd(15);
    const price = product.price 
      ? formatCurrency(product.price).padEnd(10) 
      : 'N/A'.padEnd(10);
    const rating = product.rating 
      ? `${product.rating}/5.0`.padEnd(8) 
      : 'N/A'.padEnd(8);
    const reviews = product.reviewCount 
      ? formatNumber(product.reviewCount).padEnd(10) 
      : '0'.padEnd(10);
    const bsr = product.bestSellerRank 
      ? String(product.bestSellerRank).padEnd(6) 
      : 'N/A'.padEnd(6);
    const stock = (product.inStock ? 'Yes' : 'No').padEnd(10);
    const updated = new Date(product.timestamp).toLocaleDateString('en-US').padEnd(12);

    console.log(`${product.asin.padEnd(12)} | ${title} | ${brand} | ${price} | ${rating} | ${reviews} | ${bsr} | ${stock} | ${updated}`);
  });

  console.log('\n');
};

Exporting Data to CSV

To make the data accessible in spreadsheets, you can export it as a CSV file. Here's a function that converts the product data into CSV format:

const exportToCSV = (products, filename = 'product_comparison.csv') => {
  const headers = [
    'ASIN',
    'Title',
    'Brand',
    'Price (USD)',
    'Rating',
    'Review Count',
    'Best Seller Rank',
    'In Stock',
    'Last Updated'
  ];

  const rows = products.map(product => [
    product.asin,
    `"${product.title.replace(/"/g, '""')}"`, // Escape quotes in titles
    product.brand,
    product.price || '',
    product.rating || '',
    product.reviewCount || 0,
    product.bestSellerRank || '',
    product.inStock ? 'Yes' : 'No',
    new Date(product.timestamp).toLocaleDateString('en-US')
  ]);

  const csvContent = [
    headers.join(','),
    ...rows.map(row => row.join(','))
  ].join('\n');

  // In a Node.js environment
  const fs = require('fs');
  fs.writeFileSync(filename, csvContent, 'utf8');
  console.log(`CSV exported successfully to ${filename}`);

  return csvContent;
};

Rendering as HTML

For web dashboards, you can render the comparison table as an HTML element. Here's a function to generate HTML for the table:

const generateHTMLTable = (products) => {
  const tableRows = products.map(product => `
    <tr>
      <td>${product.asin}</td>
      <td>${product.title}</td>
      <td>${product.brand}</td>
      <td class="price">${product.price ? formatCurrency(product.price) : 'N/A'}</td>
      <td class="rating">${product.rating ? `${product.rating}/5.0` : 'N/A'}</td>
      <td class="reviews">${formatNumber(product.reviewCount)}</td>
      <td class="bsr">${product.bestSellerRank || 'N/A'}</td>
      <td class="stock ${product.inStock ? 'in-stock' : 'out-of-stock'}">
        ${product.inStock ? 'Yes' : 'No'}
      </td>
      <td class="date">${new Date(product.timestamp).toLocaleDateString('en-US')}</td>
    </tr>
  `).join('');

  return `
    <table class="product-comparison">
      <thead>
        <tr>
          <th>ASIN</th>
          <th>Product Title</th>
          <th>Brand</th>
          <th>Price (USD)</th>
          <th>Rating</th>
          <th>Reviews</th>
          <th>BSR</th>
          <th>In Stock</th>
          <th>Last Updated</th>
        </tr>
      </thead>
      <tbody>
        ${tableRows}
      </tbody>
    </table>
  `;
};

Using CSS, you can visually enhance the table, such as highlighting out-of-stock items in red or emphasizing best-sellers. These tools allow you to present data in various formats, catering to different needs and audiences.

Conclusion

The Canopy REST API offers a simple and effective way to access Amazon product data. In this article, you walked through eight practical code examples that tackle common challenges developers face when working with e-commerce data. These examples highlight how different integrations can come together to create a scalable and reliable solution.

Starting with basic data retrieval, you progressed to more advanced use cases like monitoring market trends and building detailed dashboards. These examples showcase the API's flexibility, making it a valuable tool for applications ranging from pricing strategies and inventory planning to product research and decision-making.

Each JavaScript example provided is ready for immediate use, whether you're developing a price comparison tool, a product research dashboard, or an inventory management system. The REST endpoint at https://rest.canopyapi.co/ simplifies data retrieval, helping you streamline your workflow.

You can begin experimenting with the API using the Hobby plan, which includes 100 free requests per month. If your application grows, the Pay As You Go plan offers scalability at just $0.01 per request beyond the free tier, with other scaling options available as needed.

The earlier examples also demonstrated how to transform raw API responses into actionable formats. Whether you're working with console tables for quick insights, CSV files for spreadsheets, or HTML tables for web dashboards, these formatting utilities work seamlessly with any of the API endpoints covered. This flexibility ensures you can adapt the integrations to suit your specific business requirements.

Take these examples as a starting point and begin integrating Amazon data into your projects today. For more details on request parameters, response formats, and error handling, refer to the API documentation to build dependable and efficient integrations.

FAQs

How can I use the Canopy REST API to track Amazon product prices and inventory on my e-commerce platform?

To get started with integrating the Canopy REST API into your e-commerce platform, begin by creating a Canopy API account and generating an API key. This key is essential for authenticating your requests, so make sure to include it in the headers of every API call.

Next, determine which REST endpoints you’ll need to access Amazon product data, such as pricing and inventory information. Once you’ve identified the right endpoints, you can send requests to the API to pull real-time product details.

By doing this, you’ll be able to track price changes, monitor inventory levels, and streamline your e-commerce operations effectively.

How can I effectively manage API request limits when using the Canopy REST API for large-scale Amazon data retrieval?

To handle API request limits efficiently when working with the Canopy REST API for large-scale data retrieval, try these practical approaches:

  • Batch requests: Whenever possible, group multiple data needs into a single API call to reduce the overall number of requests.
  • Implement rate limiting: Keep an eye on your API usage and build in logic to slow down or pause requests to avoid hitting the limit.
  • Utilize caching: Save frequently used data locally to cut down on repeated API calls for the same information.

These methods can help you manage API usage effectively, avoid hitting request caps, and maintain smooth integration of Amazon data into your applications.

How does the Canopy REST API ensure accurate and up-to-date Amazon product data in real time?

The Canopy REST API offers developers a dependable way to access Amazon product data, delivering essential details like pricing, inventory levels, and customer reviews with a focus on accuracy and timeliness. While real-time data updates depend on the API's specific implementation, Canopy generally refreshes product information at regular intervals to keep up with changes on Amazon's platform.

This makes the API a solid choice for building tools that rely on up-to-date data, such as e-commerce dashboards or inventory tracking systems. When designing your workflows, it's crucial to account for the API's rate limits and update schedules to ensure your application runs smoothly and maintains accurate information.

Tags:

APIsDeveloper ToolsE-Commerce