# Jumia Scraper \[$0.90/1K💰] | 9 African Markets Data (`ahmed_jasarevic/jumia-scraper`) Actor

Scrape Jumia across Nigeria, Egypt, Kenya, Morocco, Ghana, Uganda, Cote dôIvoire, Tunisia and Algeria - prices, discounts, seller, official store, ratings and customer reviews, in two datasets.

- **URL**: https://apify.com/ahmed_jasarevic/jumia-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Jumia Scraper

Scrape [Jumia](https://www.jumia.com) across **9 African markets** — Nigeria, Egypt, Kenya, Morocco, Ghana, Uganda, Côte d'Ivoire, Tunisia and Algeria — into structured product rows with price, old price, discount, brand, seller, official-store flag, rating and availability, plus a separate customer-reviews dataset.

Built for African e-commerce price monitoring, marketplace seller research, competitive assortment analysis and catalogue ingestion. HTTP-only: no headless browser, no captcha solver, and **robots-compliant by design**.

### What you get

#### Monitor prices across 9 markets at once

`country`, `countryName`, `currency`, `price`, `oldPrice`, `discountPercent` and `priceFormatted` on every row. Currency is per-market (NGN, EGP, KES, MAD, GHS, UGX, XOF, TND, DZ), so you can compare local pricing without FX conversion — and flag currency alongside price when you do aggregate.

#### Separate official stores from marketplace sellers

`isOfficialStore`, `sellerId` and `sellerName` distinguish brand-authorised sellers from third-party resellers, which is the split that matters for price-quality analysis. `brand` lets you compare a brand's own store against its resellers.

#### Get verified-purchase review data

`includeReviews: true` fills the **Reviews** dataset with `rating`, `title`, `text`, `author`, `date` and `isVerifiedPurchase` — and `isVerifiedPurchase` means you can restrict sentiment analysis to confirmed buyers instead of counting drive-by ratings.

#### Ingest clean multi-market catalogue data

`sku` (Jumia's config SKU, the stable product key), `productId`, `productUrl`, `images[]`, `categoryPath[]`, `availability` and `sourceUrl` form a ready-to-load product table.

#### Know exactly how a row was obtained

`sourceType` (`listing` vs `product`) is on every row. Listing rows come from search/category/seller cards; product rows come from full product pages and additionally carry `description` and `specifications`. `sourceUrl` tells you which page produced the row.

### How it works

Jumia's listing pages embed their product payload in the server-rendered HTML, so the Actor fetches pages over plain HTTP with `CheerioCrawler` — no browser is launched. One listing page yields about **40 products**, which is what `maxPagesPerQuery` is calibrated against.

This Actor treats Jumia's `robots.txt` as a real constraint rather than an obstacle to route around, and three inputs exist specifically to keep it compliant:

- **`categoryPaths` is preferred over `searchQueries`.** Jumia's `robots.txt` disallows the `?q=` search URLs but leaves category paths open. `searchQueries` still works, but `categoryPaths` is the compliant choice — the Actor's own source comments say so.
- **`botContact` is baked into the User-Agent.** Jumia's `robots.txt` permits scraping only for a bot that identifies itself with a reachable owner, and blocks fake user agents. Leaving `botContact` empty produces a run that identifies as generic — set it to your URL or e-mail.
- **`maxRequestsPerMinute` is capped at 200.** That is the ceiling in Jumia's `robots.txt`. Requests are issued **serially from one IP address** — this is a deliberate design decision, not a performance oversight.

The result is a slower run than a parallel crawler, and an unambiguously allowed one. If you need throughput, raise `maxRequestsPerMinute` toward (never above) 200, and accept the trade-off explicitly.

### Input

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `markets` | string\[] | `["ng"]` | Market codes: `ng`, `eg`, `ke`, `ma`, `gh`, `ug`, `ci`, `tn`, `dz`. |
| `searchQueries` | string\[] | `[]` | Free-text search terms. **Note:** `?q=` search URLs are disallowed in Jumia's `robots.txt` — prefer `categoryPaths`. |
| `categoryPaths` | string\[] | `[]` | Category paths such as `/phones-tablets/`. **Preferred and robots-compliant.** |
| `botContact` | string | `""` | Your URL or e-mail, baked into the User-Agent so the bot identifies itself with a reachable owner. |
| `maxRequestsPerMinute` | integer | `120` | Requests per minute, ceiling 200 per Jumia's `robots.txt`. |
| `startUrls` | array | `[]` | Plain Jumia URLs, or `{ url }` objects from the request-list editor. |
| `maxItems` | integer | `100` | Hard cap on products in the Products dataset. |
| `maxPagesPerQuery` | integer | `1` | Listing pages per source. 1 page ≈ 40 products. |
| `includeReviews` | boolean | `true` | Collect reviews into the Reviews dataset. |
| `maxReviewsPerProduct` | integer | `20` | Reviews per product (10 per reviews page). |
| `proxy` | object | `{ useApifyProxy: false }` | Standard Apify proxy picker. See the compliance note below before enabling. |

`markets`, `searchQueries`, `categoryPaths` and `startUrls` are additive — use any combination, but supply at least one. `countries` remains available as a legacy alias for `markets`.

### Output

**Products dataset — 25 fields, one row per product:**

`country`, `countryName`, `currency`, `title`, `sku`, `productId`, `productUrl`, `sourceUrl`, `price`, `priceFormatted`, `oldPrice`, `discountPercent`, `brand`, `sellerId`, `sellerName`, `isOfficialStore`, `rating`, `ratingCount`, `availability`, `images`, `categoryPath`, `sourceType`, `description`, `specifications`, `scrapedAt`

**Reviews dataset — 13 fields, one row per customer review:**

`country`, `countryName`, `sku`, `productTitle`, `productUrl`, `rating`, `title`, `text`, `author`, `date`, `isVerifiedPurchase`, `sourceUrl`, `scrapedAt`

Dataset views ship as **Products** (default) and **Reviews**.

Field notes that change how you read the data:

- `price`/`oldPrice` are numbers; `priceFormatted` is the rendered local string. `discountPercent` is `null` when there is no markdown, not `0` — the opposite of the Hepsiburada Actor, so don't reuse that logic here.
- `ratingCount` is the count of **verified ratings**, not total reviews. The Reviews dataset can hold more rows than `ratingCount` suggests.
- `description` and `specifications` are only present on `sourceType: "product"` rows. On `listing` rows they are `null`. To get specs you must fetch product pages.
- `country` is the market code (`ng`), `countryName` is the readable name. Carry both — `country` is the join key.
- `sku` is Jumia's config SKU and the stable key across markets; `productId` is the numeric id from the URL.
- `date` in reviews is Jumia's own `DD-MM-YYYY` format, not ISO. Parse it deliberately.

### Example input

Compliance-first category walk:

```json
{
  "markets": ["ng", "ke", "eg"],
  "categoryPaths": ["/phones-tablets/", "/laptops-computers-accessories/"],
  "botContact": "https://example.com/bot",
  "maxRequestsPerMinute": 120,
  "maxItems": 300,
  "maxPagesPerQuery": 3
}
```

All 9 markets, reviews off, price monitoring only:

```json
{
  "markets": ["ng", "eg", "ke", "ma", "gh", "ug", "ci", "tn", "dz"],
  "categoryPaths": ["/phones-tablets/"],
  "includeReviews": false,
  "maxItems": 500,
  "maxPagesPerQuery": 2
}
```

Seller and assortment research:

```json
{
  "startUrls": ["https://www.jumia.com.ng/product-category/phones-tablets/"],
  "includeReviews": true,
  "maxReviewsPerProduct": 20,
  "maxItems": 150
}
```

### Example output

```json
{
  "country": "ng",
  "countryName": "Nigeria",
  "currency": "NGN",
  "title": "Samsung Galaxy A54 5G (128GB) - Dual SIM",
  "sku": "SI842G7AFDBEA5YEOVB",
  "productId": "428719203",
  "productUrl": "https://www.jumia.com.ng/samsung-galaxy-a54-5g-128gb-dual-sim-428719203.html",
  "sourceUrl": "https://www.jumia.com.ng/phones-tablets/",
  "price": 289000.0,
  "priceFormatted": "₦289,000",
  "oldPrice": 335000.0,
  "discountPercent": 13.73,
  "brand": "Samsung",
  "sellerId": "seller-jumia-ng-1042",
  "sellerName": "Jumia Store NG",
  "isOfficialStore": true,
  "rating": 4.6,
  "ratingCount": 412,
  "availability": "In Stock",
  "images": ["https://storage-jumia.jumia.com/w/280x280/pri/428719203.jpg"],
  "categoryPath": ["Phones & Tablets", "Mobile Phones", "Smart Phones"],
  "sourceType": "listing",
  "description": null,
  "specifications": null,
  "scrapedAt": "2026-10-04T11:48:03.916Z"
}
```

### Integrations & automation

Call it over the Apify API, from Python/JavaScript, the CLI or MCP. Datasets export as JSON, CSV, Excel or XML.

For **price monitoring**, a daily run over the same `categoryPaths` per market gives a stable comparable set — 1 listing page is ~40 products, so `maxItems: 200` and `maxPagesPerQuery: 5` is a comfortable daily cadence. For **assortment analysis**, run weekly with `includeReviews: false` to cut cost roughly in half, then filter on `isOfficialStore` to separate brand pricing from marketplace pricing.

Typical pipeline: run on schedule → upsert on `sku` + `country` → compute price and `discountPercent` deltas → alert on target-price hits → roll up per `brand` and `sellerName`. Because requests are serial by design, run markets as **separate concurrent runs** rather than one wide run if you need to move faster — that is the compliant way to gain parallelism.

### Related Actors

| Actor | Why |
| --- | --- |
| [`scrapers_lat/jumia-products-scraper`](https://apify.com/scrapers_lat/jumia-products-scraper) | The established Jumia Actor in the Store, 160 users, 5.2K runs. The reference point here. |
| [`ahmed_jasarevic/hepsiburada-scraper`](https://apify.com/ahmed_jasarevic/hepsiburada-scraper) | Structurally identical problem in a different market: Turkish marketplace with multi-seller, official-store and delivery fields. |
| [`ahmed_jasarevic/notino-scraper`](https://apify.com/ahmed_jasarevic/notino-scraper) | Retail catalogue extraction with brand, price and discount modelling, for the Italian market. |
| [`ahmed_jasarevic/amazon-bestsellers-scraper`](https://apify.com/ahmed_jasarevic/amazon-bestsellers-scraper) | Same retail-data job at global scale — useful for schema and price-tracking patterns. |
| [`ahmed_jasarevic/ikea-scraper`](https://apify.com/ahmed_jasarevic/ikea-scraper) | Single-retailer product and stock extraction, another comparable reference implementation. |

### FAQ

#### How does the price compare to other Jumia scrapers?

[scrapers_lat's Jumia Actor](https://apify.com/scrapers_lat/jumia-products-scraper) lists from **$6.80/1K products**, while this one is **$0.90/1K** — about 7.5× cheaper. Reviews are also billed at $0.0009 each here. Prices are a snapshot and providers change them; check the live table on each Actor page before committing.

#### Is it really allowed to scrape Jumia?

More so than most. Jumia's `robots.txt` permits scraping only for a bot that **identifies itself with a reachable owner** and blocks fake user agents — so this Actor exposes `botContact` precisely so you can put your own URL or e-mail in the User-Agent, and it runs serially from a single IP at or below the 200 requests/minute ceiling the file specifies. It also warns you that `?q=` search URLs are disallowed while category paths remain open, which is why `categoryPaths` is the recommended input.

To be precise about what that does and does not mean: a compliant User-Agent and rate limit make automated access *tolerated* under Jumia's stated policy. They do not grant permission to resell the data, and they are not a substitute for a commercial agreement. Jumia's Terms of Service still govern your use.

#### Why is `categoryPaths` recommended over `searchQueries`?

Because Jumia's `robots.txt` disallows the `?q=` search URLs but leaves category paths open. `searchQueries` still works if you need it, but `categoryPaths` is the compliant way to get the same product data.

#### Why is it slower than other scrapers — no parallelism?

Deliberate. Requests are issued serially from one IP at `maxRequestsPerMinute` (default 120, ceiling 200) to stay inside Jumia's stated limits. To go faster, split markets across separate concurrent runs rather than parallelising requests inside one run.

#### What is the difference between `ratingCount` and the reviews dataset?

`ratingCount` is Jumia's count of **verified ratings** shown on the listing. The Reviews dataset holds individual written reviews. Because `ratingCount` only counts verified ratings, the Reviews dataset can contain more rows — and more critical reviews — than the headline number suggests.

#### Can I get product descriptions and specs?

Only from product pages. `description` and `specifications` are populated when `sourceType` is `"product"`; on `listing` rows they are `null`. Category and search walks produce listing rows only, so plan a product-page pass if you need specs.

#### What does `isOfficialStore` actually mean?

Whether the seller is Jumia's brand-authorised storefront for that product. It is the cleanest available proxy for first-party pricing versus marketplace reseller pricing — and the single most useful filter for competitive price analysis.

### SEO Keywords

jumia scraper, jumia.com, african ecommerce data, jumia api alternative, nigeria ecommerce data, kenya marketplace data, egypt online shopping data, product price monitoring africa, marketplace seller data, official store pricing, discount tracking africa, jumia product data, customer reviews dataset, catalogue ingestion, competitor price analysis, multi country scraping, west africa ecommerce, north africa ecommerce, verified purchase reviews, assortment analysis, online marketplace research, product availability data

### For AI Agents & LLM Apps

Returns Jumia product listings across 9 African markets as flat dataset rows, one per product, plus optional customer reviews in a second dataset.

**Minimal input** — smallest input that produces a valid run:

```json
{ "categoryPaths": ["/phones-tablets/"], "maxItems": 50 }
```

**Multi-market run** with compliant identification:

```json
{ "markets": ["ng", "ke", "eg"], "categoryPaths": ["/phones-tablets/"], "botContact": "https://example.com/bot", "maxItems": 300, "maxPagesPerQuery": 3 }
```

**Price monitoring** (reviews off to halve cost):

```json
{ "markets": ["ng"], "categoryPaths": ["/laptops-computers-accessories/"], "includeReviews": false, "maxItems": 200, "maxPagesPerQuery": 5 }
```

**Output fields — products (25):** country, countryName, currency, title, sku, productId, productUrl, sourceUrl, price, priceFormatted, oldPrice, discountPercent, brand, sellerId, sellerName, isOfficialStore, rating, ratingCount, availability, images, categoryPath, sourceType, description, specifications, scrapedAt

**Output fields — reviews (13):** country, countryName, sku, productTitle, productUrl, rating, title, text, author, date, isVerifiedPurchase, sourceUrl, scrapedAt

**Behaviours an agent should know**

- **Prefer `categoryPaths` over `searchQueries`.** Jumia's `robots.txt` disallows `?q=` search URLs; category paths are open. Using `searchQueries` works but is the disallowed route.
- `includeReviews` defaults to **true**, so a default run bills review events too. Set it to `false` for price-only work — that roughly halves cost.
- Requests are **serial from a single IP** by design, capped at 200/min (`maxRequestsPerMinute`, default 120). Do not expect parallelism. To go faster, run markets as separate concurrent runs.
- `botContact` is baked into the User-Agent. Leave it empty and you are running as a generic bot, which is exactly what Jumia's `robots.txt` blocks. Set it to a reachable URL or e-mail.
- `discountPercent` is **`null`** when there is no discount (not `0`). Do not copy null-handling from the Hepsiburada Actor, which behaves the opposite way.
- `description` and `specifications` are only populated on `sourceType: "product"` rows. Category/search walks give `sourceType: "listing"` with both `null`.
- `date` in reviews is `DD-MM-YYYY`, not ISO. `ratingCount` counts verified ratings only.
- One listing page ≈ 40 products. Billing: **$0.0009 per product** and **$0.0009 per review** — `maxItems` alone does not bound cost when reviews are on; bound `maxReviewsPerProduct` too.
- `countries` is a legacy alias for `markets`; prefer `markets`.

### Legal & Compliance

This Actor is an independent third-party tool. It is not affiliated with, endorsed by, or sponsored by Jumia, and it is not associated with any seller, brand or official store whose listings appear in its output.

**What it actually accesses:** publicly visible Jumia listing, category and product pages, over plain HTTP, with no login, no authentication bypass, no captcha solving and no private endpoints. No headless browser is launched.

**Robots policy, handled explicitly.** Jumia's `robots.txt` permits scraping only for a bot that identifies itself with a reachable owner and blocks fake user agents; it caps automated request rates and disallows `?q=` search URLs while leaving category paths open. This Actor is built to those terms: `botContact` is embedded in the User-Agent so the bot identifies itself, requests are serialised from a single IP at or below the 200 requests/minute ceiling, and `categoryPaths` is the recommended input precisely because that route is open. **Set `botContact` to a real, reachable URL or e-mail before running at any volume.**

**What that does not mean.** Identifying your bot and staying under the rate limit makes automated access tolerated under Jumia's stated policy. It is not a commercial licence. Jumia's Terms of Service govern your use, and scraping the marketplace to build a competing catalogue, price-comparison service or resold dataset may require a separate agreement with Jumia. Use of `proxy` also deserves a second thought: routing through rotating IPs works around the single-IP design that keeps this Actor within Jumia's limits, so enabling it may put you outside the policy this Actor otherwise respects.

You are solely responsible for compliance with Jumia's Terms of Service, its `robots.txt`, and applicable law including GDPR and Africa's data-protection regimes. The reviews dataset contains consumer `author` names attached to public reviews — treat it as personal data, and do not use it to contact reviewers. Keep volumes modest: `maxItems` (default 100), `maxPagesPerQuery` (default 1) and `maxRequestsPerMinute` (default 120) bound a run without effort.

# Actor input Schema

## `markets` (type: `array`):

Jumia storefronts to scrape. Every search query runs once per selected market. Note: the Tunisia and Algeria storefronts are currently returning HTTP 410/530 from Jumia's side.

## `searchQueries` (type: `array`):

Keywords to search on every selected market, e.g. "samsung galaxy s24". Each query is paginated up to `maxPagesPerQuery` pages (40 products per page). Note: Jumia's robots.txt disallows the site-search URLs (`/*q=`), so `categoryPaths` is the compliant way to walk a catalog.

## `categoryPaths` (type: `array`):

Category pages to walk on every selected market, e.g. "/phones-tablets/" or "/computing/". robots.txt disallows the site-search URLs but leaves category paths open, so this is the recommended input. Paginated up to `maxPagesPerQuery` (40 products per page).

## `botContact` (type: `string`):

Jumia's robots.txt allows scraping only for a bot that "clearly identifies it as a bot" and carries "a owner url or contact", and it states that "bots with fake user-agent will be blocked". This value goes into the User-Agent as `JumiaScraperBot/1.0 (+<value>)`. Leave empty to use this Actor's store URL.

## `maxRequestsPerMinute` (type: `integer`):

Global request rate. robots.txt permits "less than 200 request per minute" for an identified bot; above that Jumia asks you to contact their techops team first. Capped at 190 here.

## `startUrls` (type: `array`):

Direct Jumia URLs: search (https://www.jumia.com.ng/catalog/?q=laptop), category (https://www.jumia.com.ng/phones-tablets/), seller shop (https://www.jumia.com.ng/shop/<slug>/) or product (https://www.jumia.com.ng/<slug>-123456.html) pages. The market is read from the domain, so `markets` only affects search queries.

## `maxItems` (type: `integer`):

Hard cap on products pushed to the PRODUCTS dataset across all requests. Reviews do not count towards this cap.

## `maxPagesPerQuery` (type: `integer`):

How many pages of a search / category / seller listing to walk (1 page = 40 products).

## `includeReviews` (type: `boolean`):

Collect reviews into a separate REVIEWS dataset, one row per review. Adds roughly 1 extra request per 10 reviews per product.

## `maxReviewsPerProduct` (type: `integer`):

Reviews fetched per product from Jumia's reviews page (10 per page). Only used when `includeReviews` is on.

## `proxy` (type: `object`):

Leave empty. robots.txt warns that "bots trying to use too many IPs to increase performance may also be blocked", so a single exit IP is the compliant default and this Actor needs no proxy. Add RESIDENTIAL only if the run is still challenged after `botContact` is set.

## Actor input object example

```json
{
  "markets": [
    "ng",
    "ke"
  ],
  "searchQueries": [],
  "categoryPaths": [
    "/phones-tablets/"
  ],
  "botContact": "",
  "maxRequestsPerMinute": 120,
  "startUrls": [
    {
      "url": "https://www.jumia.com.ng/catalog/?q=iphone+15"
    },
    {
      "url": "https://www.jumia.com.ng/phones-tablets/"
    }
  ],
  "maxItems": 100,
  "maxPagesPerQuery": 1,
  "includeReviews": true,
  "maxReviewsPerProduct": 20,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `products` (type: `string`):

No description

## `reviews` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "markets": [
        "ng",
        "ke"
    ],
    "searchQueries": [],
    "categoryPaths": [
        "/phones-tablets/"
    ],
    "botContact": "",
    "maxRequestsPerMinute": 120,
    "startUrls": [
        {
            "url": "https://www.jumia.com.ng/catalog/?q=iphone+15"
        },
        {
            "url": "https://www.jumia.com.ng/phones-tablets/"
        }
    ],
    "maxItems": 100,
    "maxPagesPerQuery": 1,
    "includeReviews": true,
    "maxReviewsPerProduct": 20,
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/jumia-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "markets": [
        "ng",
        "ke",
    ],
    "searchQueries": [],
    "categoryPaths": ["/phones-tablets/"],
    "botContact": "",
    "maxRequestsPerMinute": 120,
    "startUrls": [
        { "url": "https://www.jumia.com.ng/catalog/?q=iphone+15" },
        { "url": "https://www.jumia.com.ng/phones-tablets/" },
    ],
    "maxItems": 100,
    "maxPagesPerQuery": 1,
    "includeReviews": True,
    "maxReviewsPerProduct": 20,
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/jumia-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "markets": [
    "ng",
    "ke"
  ],
  "searchQueries": [],
  "categoryPaths": [
    "/phones-tablets/"
  ],
  "botContact": "",
  "maxRequestsPerMinute": 120,
  "startUrls": [
    {
      "url": "https://www.jumia.com.ng/catalog/?q=iphone+15"
    },
    {
      "url": "https://www.jumia.com.ng/phones-tablets/"
    }
  ],
  "maxItems": 100,
  "maxPagesPerQuery": 1,
  "includeReviews": true,
  "maxReviewsPerProduct": 20,
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/jumia-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/jumia-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/j2iydA4zhf7Ugoofn/builds/oXxbZju5euAhZybM7/openapi.json
