Skip to main content
Products are the core of your Chariow store. This guide covers how to retrieve and work with products through the Public API.

Product Types

Chariow supports several product types:
TypeDescription
downloadableDigital files that customers can download after purchase
courseOnline courses with structured chapters and lessons
licenseSoftware licenses with activation and validation management
serviceDigital services, consultations, or custom work
bundleA collection of multiple products sold together at a discounted price

Product Categories

Products are organised into the following categories:
CategoryValue
Creative Artscreative_arts
Technologytechnology
Business and Financebusiness_and_finance
Personal Developmentpersonal_development
Education and Learningeducation_and_learning
Entertainmententertainment
Health and Wellnesshealth_and_wellness
Literature and Publishingliterature_and_publishing
Media and Communicationmedia_and_communication
Miscellaneousmiscellaneous

Product States

Products can be in different states:
  • Draft - Not visible to customers, still being edited
  • Published - Available for purchase on your store
  • Archived - No longer available but kept for records
The Public API only returns published products. Draft and archived products are not accessible via the API.

Listing Products

Retrieve all published products for your store with optional filtering:
curl -X GET "https://api.chariow.com/v1/products?per_page=20&type=course" \
  -H "Authorization: Bearer sk_live_your_api_key"

Query Parameters

ParameterTypeDescription
per_pageintegerNumber of products per page (default: 10, max: 100)
cursorstringPagination cursor from previous response
searchstringSearch by product name or slug
categorystringFilter by category (e.g., technology, education_and_learning)
typestringFilter by type (e.g., course, license, bundle)

Pagination

The API uses cursor-based pagination for efficient data retrieval:
let allProducts = [];
let cursor = null;

do {
  const url = cursor
    ? `https://api.chariow.com/v1/products?cursor=${cursor}`
    : 'https://api.chariow.com/v1/products';

  const response = await fetch(url, {
    headers: { 'Authorization': 'Bearer sk_live_your_api_key' }
  });

  const result = await response.json();
  allProducts.push(...result.data);
  cursor = result.pagination.next_cursor;
} while (cursor);

console.log(`Retrieved ${allProducts.length} products`);

Example Response

{
  "data": [
    {
      "id": "prd_abc123",
      "name": "Complete Web Development Course",
      "slug": "web-development-course",
      "type": "course",
      "category": {
        "value": "education_and_learning",
        "label": "Education and Learning"
      },
      "status": "published",
      "is_free": false,
      "pictures": {
        "thumbnail": "https://cdn.chariow.com/products/thumb.jpg",
        "cover": "https://cdn.chariow.com/products/cover.jpg"
      },
      "pricing": {
        "type": "one_time",
        "current_price": {
          "amount": 99.00,
          "currency": "USD",
          "formatted": "$99.00"
        },
        "price": {
          "amount": 99.00,
          "currency": "USD",
          "formatted": "$99.00"
        }
      }
    }
  ],
  "pagination": {
    "next_cursor": "eyJpZCI6NTB9",
    "prev_cursor": null,
    "has_more": true
  }
}

Getting a Single Product

Retrieve detailed information about a specific product by its public ID or slug:
curl -X GET "https://api.chariow.com/v1/products/prd_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key"

Product Details

The single product endpoint returns comprehensive information including:
  • Pricing: Current price, base price, sale price (if applicable), and discount percentage
  • Images: Thumbnail and cover images
  • Ratings: Average rating and number of reviews
  • Sales: Sales count (if not hidden)
  • Quantity: Stock information (if product has limited quantity)
  • Bundle: Savings information for bundle products
  • Custom Fields: Additional product fields (when loaded)
  • SEO: SEO metadata (when loaded)

Pricing Types

Products can have different pricing models:
A fixed price that customers pay once to access the product. This is the most common pricing type.
{
  "pricing": {
    "type": "one_time",
    "current_price": {
      "amount": 49.00,
      "currency": "USD",
      "formatted": "$49.00"
    },
    "price": {
      "amount": 49.00,
      "currency": "USD",
      "formatted": "$49.00"
    },
    "sale_price": null,
    "price_off": null
  }
}
Customers choose how much to pay, with an optional minimum and suggested price. Useful for donations, tip-ware, or customer-driven pricing.
{
  "pricing": {
    "type": "what_you_want",
    "min_price": {
      "amount": 5.00,
      "currency": "USD",
      "formatted": "$5.00"
    },
    "suggested_price": {
      "amount": 25.00,
      "currency": "USD",
      "formatted": "$25.00"
    }
  }
}
Products available at no cost, often used for lead generation, freebies, or sample content.
{
  "pricing": {
    "type": "free",
    "current_price": {
      "amount": 0,
      "currency": "USD",
      "formatted": "$0.00"
    }
  },
  "is_free": true
}
Products can have temporary sale prices with an expiration date. The current_price reflects the active price.
{
  "pricing": {
    "type": "one_time",
    "current_price": {
      "amount": 99.00,
      "currency": "USD",
      "formatted": "$99.00"
    },
    "price": {
      "amount": 149.00,
      "currency": "USD",
      "formatted": "$149.00"
    },
    "sale_price": {
      "amount": 99.00,
      "currency": "USD",
      "formatted": "$99.00"
    },
    "price_off": "34%"
  },
  "on_sale_until": "2025-02-28T23:59:59Z"
}

Product Bundles

Bundles combine multiple products at a discounted price. When retrieving a bundle product, you’ll receive information about the total bundle value and savings:
{
  "id": "prd_bundle123",
  "name": "Complete Developer Bundle",
  "slug": "developer-bundle",
  "type": "bundle",
  "pricing": {
    "type": "one_time",
    "current_price": {
      "amount": 199.00,
      "currency": "USD",
      "formatted": "$199.00"
    }
  },
  "bundle": {
    "value": {
      "amount": 297.00,
      "currency": "USD",
      "formatted": "$297.00"
    },
    "savings": {
      "amount": {
        "amount": 98.00,
        "currency": "USD",
        "formatted": "$98.00"
      },
      "percentage": "33%"
    }
  }
}
The bundle.value shows the total value if all products were purchased separately, whilst the pricing.current_price shows the discounted bundle price. The bundle.savings shows how much customers save by purchasing the bundle.

Working with Product Data

Filtering Products

You can combine multiple filters to refine your product queries:
// Get all free courses
const response = await fetch(
  'https://api.chariow.com/v1/products?type=course&category=education_and_learning',
  {
    headers: { 'Authorization': 'Bearer sk_live_your_api_key' }
  }
);

// Search for products
const searchResponse = await fetch(
  'https://api.chariow.com/v1/products?search=web+development',
  {
    headers: { 'Authorization': 'Bearer sk_live_your_api_key' }
  }
);

Understanding Ratings

Products include rating information with the average score and total count:
{
  "rating": {
    "average": 4.8,
    "count": 245
  }
}
  • average: Rating from 0 to 5
  • count: Total number of ratings received

Stock Quantity

For products with limited stock, the quantity field provides detailed information:
{
  "quantity": {
    "value": 100,
    "remaining": {
      "value": 35,
      "percent": "35%"
    },
    "sold": {
      "value": 65,
      "percent": "65%"
    },
    "total": 100
  }
}
Products without limited stock will have quantity: null.

Price Formatting

All price objects include three fields for flexible display:
  • amount: Decimal number (e.g., 99.00)
  • currency: ISO currency code (e.g., USD, EUR, GBP)
  • formatted: Ready-to-display string (e.g., $99.00, £99.00, €99.00)
// Using the formatted price
const product = response.data;
console.log(`Buy now for ${product.pricing.current_price.formatted}`);

// Working with the numeric amount
if (product.pricing.current_price.amount < 50) {
  console.log('Affordable option!');
}

Common Use Cases

Building a Product Catalogue

async function buildProductCatalogue(category) {
  const products = [];
  let cursor = null;

  do {
    const params = new URLSearchParams({
      per_page: 50,
      category: category,
      ...(cursor && { cursor })
    });

    const response = await fetch(
      `https://api.chariow.com/v1/products?${params}`,
      {
        headers: { 'Authorization': 'Bearer sk_live_your_api_key' }
      }
    );

    const result = await response.json();
    products.push(...result.data);
    cursor = result.pagination.next_cursor;
  } while (cursor);

  return products;
}

// Get all technology products
const techProducts = await buildProductCatalogue('technology');

Displaying Sale Products

async function getSaleProducts() {
  const response = await fetch('https://api.chariow.com/v1/products?per_page=100', {
    headers: { 'Authorization': 'Bearer sk_live_your_api_key' }
  });

  const result = await response.json();

  // Filter products currently on sale
  return result.data.filter(product =>
    product.pricing.sale_price !== null &&
    product.on_sale_until &&
    new Date(product.on_sale_until) > new Date()
  );
}
async function getPopularProducts(minRating = 4.5, minReviews = 50) {
  const response = await fetch('https://api.chariow.com/v1/products?per_page=100', {
    headers: { 'Authorization': 'Bearer sk_live_your_api_key' }
  });

  const result = await response.json();

  return result.data
    .filter(p => p.rating.average >= minRating && p.rating.count >= minReviews)
    .sort((a, b) => b.rating.average - a.rating.average);
}

Best Practices

Always use cursor-based pagination instead of fetching all products at once. This ensures efficient data retrieval and prevents timeouts.
Product data doesn’t change frequently. Consider caching products locally and refreshing periodically to reduce API calls.
Not all products have thumbnail or cover images. Always check for null values before displaying images.
Use the formatted field from price objects for display purposes. This ensures proper currency formatting and symbols.
When displaying sale prices, verify that on_sale_until is in the future to avoid showing expired sales.

Next Steps