# takealot API scraper — South Africa's largest online marketplace (takealot.com): search and category browse, the full product record with both buy-box offers and every other seller, customer reviews, running deals and search suggestions, in rand. No account, no browser.

> Search takealot.com by keyword: product id (PLID), title, brand, image, the price (or the price range for variant products), takealot's list price kept apart, rating with review count and star distribution, stock status with the Cape Town / Johannesburg / Durban warehouses and the delivery estimate. Filter by brand, price, rating, in-stock, warehouse and condition; sort by relevance, price, rating or newest; page with a cursor.
> ReefAPI engine `takealot` · 8 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/takealot/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /takealot/v1/search — 1 credit
Search takealot.com by keyword: product id (PLID), title, brand, image, the price (or the price range for variant products), takealot's list price kept apart, rating with review count and star distribution, stock status with the Cape Town / Johannesburg / Durban warehouses and the delivery estimate. Filter by brand, price, rating, in-stock, warehouse and condition; sort by relevance, price, rating or newest; page with a cursor.

**Parameters:**
- `query` (string, required) — What to look for on takealot.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `cursor` (string, optional) — Next page. Pass the `next_cursor` of the previous response; omit for page 1. takealot pages by cursor only (36 products per page).
- `sort` (enum, optional, default "relevance") — Order of results. Only takealot's own orderings are accepted. [one of: relevance, price_asc, price_desc, rating, newest]
- `brand` (string, optional) — Brand name exactly as takealot lists it (every row returns `brand`; `facets` lists the brands on a query).
- `price_min` (number, optional) — Lowest price in rand.
- `price_max` (number, optional) — Highest price in rand.
- `min_rating` (integer, optional) — Only products rated at least this many stars (1-4, takealot's own buckets).
- `in_stock` (boolean, optional, default false) — true: only products takealot shows as in stock (not 'ships in N days').
- `warehouse` (enum, optional) — Only products in stock at this takealot warehouse (takealot's own filter). [one of: cpt, jhb, dbn]
- `condition` (enum, optional) — Product condition as takealot classifies it. [one of: new, refurbished]
- `include_facets` (boolean, optional, default false) — true: also return takealot's filter panel (brands, price bands, warehouses, conditions, attributes with counts) and related searches.
- `include_fallback_results` (boolean, optional, default false) — takealot sometimes answers a keyword with no real match with a few unrelated products. Default: those are dropped (results empty, fallback_results_dropped counts them). true: returned apart in fallback_results.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** results[]{plid, product_id, tsin, offer_sku, title, subtitle, brand, authors[], url, image, image_count, price (lowest price on the row), price_max (only when the row is a variant price range), price_is_range, currency (ZAR), list_price (takealot's 'List price' — only when above the price; a reference, not a was-price), list_price_discount_percent, saving_text, saving_badge, promotion_id, rating, review_count, rating_scale (5), rating_distribution{5..1}, in_stock, availability (in_stock|ships_in_days|out_of_stock|preorder|other), stock_status, is_leadtime, is_imported, warehouses[] (CPT/JHB/DBN), delivery_estimate, delivery_type, is_preorder, variant_selection_required, has_more_colours, free_delivery_with_takealotmore}, count, total_results (capped by takealot at 5000), total_is_approximate, total_results_capped, next_cursor, has_more, sort_applied, filters_applied, facets[]{name, filter_name, entries[]{label, value, count}} (include_facets), related_searches[] (include_facets), keyword_matches_on_page, fallback_results_dropped, fallback_total, fallback_results[], currency, country, query

**Example request body:**
```json
{
  "query": "air fryer"
}
```

### POST /takealot/v1/category/products — 1 credit
Browse one takealot department or category (slug path or category URL) with the same product rows, filters, sorts and cursor paging as `search`.

**Parameters:**
- `category` (string, required) — takealot category path or URL, e.g. 'cellular-gps' (a department), 'cellular-gps/cellphones-26249' or https://www.takealot.com/home-kitchen/air-fryers-25752. Product breadcrumbs return these slugs.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `cursor` (string, optional) — Next page. Pass the `next_cursor` of the previous response; omit for page 1. takealot pages by cursor only (36 products per page).
- `sort` (enum, optional, default "relevance") — Order of results. Only takealot's own orderings are accepted. [one of: relevance, price_asc, price_desc, rating, newest]
- `brand` (string, optional) — Brand name exactly as takealot lists it (every row returns `brand`; `facets` lists the brands on a query).
- `price_min` (number, optional) — Lowest price in rand.
- `price_max` (number, optional) — Highest price in rand.
- `min_rating` (integer, optional) — Only products rated at least this many stars (1-4, takealot's own buckets).
- `in_stock` (boolean, optional, default false) — true: only products takealot shows as in stock (not 'ships in N days').
- `warehouse` (enum, optional) — Only products in stock at this takealot warehouse (takealot's own filter). [one of: cpt, jhb, dbn]
- `condition` (enum, optional) — Product condition as takealot classifies it. [one of: new, refurbished]
- `include_facets` (boolean, optional, default false) — true: also return takealot's filter panel (brands, price bands, warehouses, conditions, attributes with counts) and related searches.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** results[]{plid, product_id, tsin, offer_sku, title, subtitle, brand, authors[], url, image, image_count, price (lowest price on the row), price_max (only when the row is a variant price range), price_is_range, currency (ZAR), list_price (takealot's 'List price' — only when above the price; a reference, not a was-price), list_price_discount_percent, saving_text, saving_badge, promotion_id, rating, review_count, rating_scale (5), rating_distribution{5..1}, in_stock, availability (in_stock|ships_in_days|out_of_stock|preorder|other), stock_status, is_leadtime, is_imported, warehouses[] (CPT/JHB/DBN), delivery_estimate, delivery_type, is_preorder, variant_selection_required, has_more_colours, free_delivery_with_takealotmore}, count, total_results (capped by takealot at 5000), total_is_approximate, total_results_capped, next_cursor, has_more, sort_applied, filters_applied, facets[]{name, filter_name, entries[]{label, value, count}} (include_facets), related_searches[] (include_facets), keyword_matches_on_page, fallback_results_dropped, fallback_total, fallback_results[], currency, country, department_slug, category_slug

### POST /takealot/v1/product/detail — 1 credit
The full takealot product record by PLID or URL: title, subtitle, brand, description, highlights, gallery, barcode (when published and valid), model, warranty, the preselected buy-box price with takealot's list price kept apart, the cheapest and dearest offer, reward points, availability with warehouses and delivery estimate, the seller (takealot or a marketplace seller with its rating), both buy-box offers and every other offer, rating with star distribution, breadcrumbs and category paths, the specification table, colour and size variants (pick one with `colour` / `size`) and running promotions.

**Parameters:**
- `product_id` (string, required) — takealot product id: 'PLID93227833', '93227833' or a product URL.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `colour` (string, optional) — Pick a colour variant (exactly as in `variants[].options[].value`).
- `size` (string, optional) — Pick a size variant (exactly as in `variants[].options[].value`).
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** product{plid, product_id, tsin, offer_sku, title, subtitle, brand, authors[], url, description, highlights[], images[], gtin (null unless published with a valid check digit), mpn, model, warranty, price (the preselected buy-box offer; for a product that needs a variant choice, takealot's 'from' price with price_is_from true), price_is_from, currency, list_price (takealot's reference 'List price', only when above price), list_price_discount_percent, price_min, price_max (cheapest / dearest offer on the page), reward_prices[]{program (eBucks|Discovery Miles), points} (the same price in points, not a discount), availability (in_stock|ships_in_days|out_of_stock|preorder|select_variant), in_stock, stock_status, warehouses[], delivery_estimate, is_preorder, variant_selection_required, sold_by_takealot, seller{seller_id, seller_type (takealot|marketplace), seller_name, seller_rating, seller_rating_count, seller_rating_scale, seller_vat_registered}, buybox_is_cheapest, offer_count, offers[] (as in product/offers), rating, review_count, rating_scale, rating_distribution{5..1}, breadcrumbs[]{id, name, slug, type}, category_paths[][], category, specifications[]{name, value}, variants[]{type (colour|size), title, options[]{value, available, selected, image}}, promotions[]{promotion_id, name, group_id}, country}

**Example request body:**
```json
{
  "product_id": "PLID93227833"
}
```

### POST /takealot/v1/product/offers — 1 credit
Every offer on one takealot product, cheapest first: both buy-box offers (the preselected 'Fastest Delivery' one and the 'Best Price' one) plus every other seller, each with price, condition, seller id, type (takealot or marketplace), name and rating where takealot publishes them, stock status, warehouses and delivery estimate.

**Parameters:**
- `product_id` (string, required) — takealot product id: 'PLID93227833', '93227833' or a product URL.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `colour` (string, optional) — Pick a colour variant (exactly as in `variants[].options[].value`).
- `size` (string, optional) — Pick a size variant (exactly as in `variants[].options[].value`).
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** product{plid, product_id, title, brand, url, currency, price (preselected buy-box offer), price_min, price_max, buybox_is_cheapest, offer_count, availability, variant_selection_required} + offers[]{position, offer_sku, source (buybox|other_offers), buybox_preference (fastest|lowest_priced), buybox_label, preselected, condition, price, currency, list_price, list_price_discount_percent, seller_id, seller_type, seller_name (null where takealot does not publish it), seller_rating, seller_rating_count, seller_rating_scale, seller_vat_registered, in_stock, availability, stock_status, is_leadtime, is_imported, warehouses[], delivery_estimate, delivery_type, add_to_cart_available, free_shipping, reward_prices[]} + count

**Example request body:**
```json
{
  "product_id": "PLID93227833"
}
```

### POST /takealot/v1/product/reviews — 1 credit
Customer reviews of one takealot product, 10 per page: star rating, title, text, date, the reviewer's display name, helpful votes, how long after purchase it was written and the variant bought. Sort by most helpful or newest; filter by star rating.

**Parameters:**
- `product_id` (string, required) — takealot product id: 'PLID93227833', '93227833' or a product URL.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `page` (integer, optional, default 1) — Review page, 1-based (10 reviews per page).
- `sort` (enum, optional, default "most_helpful") — Review order. [one of: most_helpful, newest]
- `rating` (integer, optional) — Only reviews with exactly this many stars.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** reviews[]{review_id, rating, title, body, date (YYYY-MM-DD), author, helpful_votes, time_after_purchase, variant[], tsin}, count, total_reviews, total_pages, page, has_more, sort_applied, product_id, plid

**Example request body:**
```json
{
  "product_id": "PLID93227833"
}
```

### POST /takealot/v1/deals — 1 credit
Every promotion running on takealot right now: promotion id, name, start and end, and a link. Use `deals/products` with a promotion id for the discounted products.

**Parameters:**
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** deals[]{promotion_id, name, short_name, group_id, active, starts_at, ends_at, qualifying_quantity, url}, count, country

### POST /takealot/v1/deals/products — 1 credit
The products in one takealot promotion, with the same rows, filters, sorts and cursor paging as `search`.

**Parameters:**
- `promotion_id` (string, required) — A takealot promotion id — `deals` returns every running one.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `cursor` (string, optional) — Next page. Pass the `next_cursor` of the previous response; omit for page 1. takealot pages by cursor only (36 products per page).
- `sort` (enum, optional, default "relevance") — Order of results. Only takealot's own orderings are accepted. [one of: relevance, price_asc, price_desc, rating, newest]
- `brand` (string, optional) — Brand name exactly as takealot lists it (every row returns `brand`; `facets` lists the brands on a query).
- `price_min` (number, optional) — Lowest price in rand.
- `price_max` (number, optional) — Highest price in rand.
- `min_rating` (integer, optional) — Only products rated at least this many stars (1-4, takealot's own buckets).
- `in_stock` (boolean, optional, default false) — true: only products takealot shows as in stock (not 'ships in N days').
- `warehouse` (enum, optional) — Only products in stock at this takealot warehouse (takealot's own filter). [one of: cpt, jhb, dbn]
- `condition` (enum, optional) — Product condition as takealot classifies it. [one of: new, refurbished]
- `include_facets` (boolean, optional, default false) — true: also return takealot's filter panel (brands, price bands, warehouses, conditions, attributes with counts) and related searches.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** results[]{plid, product_id, tsin, offer_sku, title, subtitle, brand, authors[], url, image, image_count, price (lowest price on the row), price_max (only when the row is a variant price range), price_is_range, currency (ZAR), list_price (takealot's 'List price' — only when above the price; a reference, not a was-price), list_price_discount_percent, saving_text, saving_badge, promotion_id, rating, review_count, rating_scale (5), rating_distribution{5..1}, in_stock, availability (in_stock|ships_in_days|out_of_stock|preorder|other), stock_status, is_leadtime, is_imported, warehouses[] (CPT/JHB/DBN), delivery_estimate, delivery_type, is_preorder, variant_selection_required, has_more_colours, free_delivery_with_takealotmore}, count, total_results (capped by takealot at 5000), total_is_approximate, total_results_capped, next_cursor, has_more, sort_applied, filters_applied, facets[]{name, filter_name, entries[]{label, value, count}} (include_facets), related_searches[] (include_facets), keyword_matches_on_page, fallback_results_dropped, fallback_total, fallback_results[], currency, country, promotion_id

### POST /takealot/v1/search/suggest — 1 credit
takealot's search-box suggestions for what a shopper has typed so far.

**Parameters:**
- `query` (string, required) — What the shopper has typed so far.
- `country` (enum, optional, default "za") — takealot sells in South Africa only; prices are in rand (ZAR). [one of: za]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** suggestions[]{term, departments[], categories[]}, count, query, country

**Example request body:**
```json
{
  "query": "air fryer"
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=takealot
- Human docs page: https://reefapi.com/docs/takealot
- Overview page: https://reefapi.com/takealot-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
