# Soopage Indonesia Business Directory Scraper (`crawlerbros/soopage-indonesia-business-directory-scraper`) Actor

Scrape id.soopage.com - Indonesia's business directory of 419,000+ companies. Browse by province/city, walk the nationwide index, or fetch companies directly by URL. Get contact details, address, category, email, website, and more.

- **URL**: https://apify.com/crawlerbros/soopage-indonesia-business-directory-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Soopage Indonesia Business Directory Scraper

Scrape **id.soopage.com** — a directory of 419,000+ companies across Indonesia. Browse by province or city, walk the nationwide index, or fetch specific companies directly by URL. Get name, category, phone, fax, email, website, full address, contact person, and more. HTTP-only, no login, no cookies required.

### What this actor does

- **Three modes:** browse by province/city, browse the nationwide index, or fetch companies by URL
- **34 provinces/cities/areas** covered, from Jakarta (160k+ companies) down to Gorontalo
- **Category keyword filter** to narrow results to a business type
- **Full contact enrichment** — every company is enriched from its own detail page: phone, fax, de-obfuscated email, website, address, postal code, contact person, and more
- **Derived Google Maps link** for every company with an address
- **Empty fields are omitted**

### Output per company

- `companyName`
- `companyId` — short id parsed from the source URL
- `category` — business category/type, when listed
- `phone`, `fax`
- `email` — decoded from Cloudflare's obfuscated mail-protection markup when present
- `website` — normalized to a full `https://` URL
- `streetAddress`, `city`, `country`, `postalCode`
- `contactPerson`, `contactPosition`
- `aboutUs` — free-text company description, when provided
- `description`
- `googleMapsUrl` — derived from the address (only present when an address exists)
- `relatedCompanies` — nearby companies from Soopage's own "Other Companies" sidebar, each `{name, url}`, when listed
- `searchArea` — the province/city queried (byCity mode only)
- `sourceUrl` — canonical company page URL
- `recordType: "company"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `byCity` | `byCity` / `browseAll` / `byUrl` |
| `city` | string (select) | `Jakarta` | Province/city to browse (mode=byCity) |
| `categoryKeyword` | string | – | Keep only companies whose category contains this text (mode=byCity, browseAll) |
| `companyUrls` | array | – | Company page URLs or filenames to fetch directly (mode=byUrl) |
| `maxItems` | int | `10` | Hard cap on emitted records (1–2000) |
| `proxyConfiguration` | object | off | Optional Apify proxy — not required for normal use |

#### Example: browse Jakarta companies

```json
{
  "mode": "byCity",
  "city": "Jakarta",
  "maxItems": 20
}
```

#### Example: browse Bali, filtered to a category

```json
{
  "mode": "byCity",
  "city": "Bali",
  "categoryKeyword": "hotel",
  "maxItems": 20
}
```

#### Example: walk the nationwide index

```json
{
  "mode": "browseAll",
  "maxItems": 200
}
```

#### Example: fetch specific companies by URL

```json
{
  "mode": "byUrl",
  "companyUrls": [
    "https://id.soopage.com/company/FUSION-NET_2V8.html",
    "AGRO-CHOMSA-PT_5K1"
  ]
}
```

### Use cases

- **B2B lead generation** — build contact lists of Indonesian companies by province or category
- **Market research** — survey business density and category mix by province/city
- **Sales prospecting** — pull phone, email, and website for outbound outreach
- **Data enrichment** — cross-reference company names against your own CRM
- **Directory migration** — bulk-export listings for a specific region

### Limitations

- **No keyword/text search.** Soopage's `/search.php` page renders only a client-side Google Custom Search widget with no server-rendered results, so a free-text keyword search mode is not possible against this source. Use `byCity` + `categoryKeyword`, or `browseAll` + `categoryKeyword`, instead.
- **No upstream category-browse index.** Soopage does not publish a category listing page. `categoryKeyword` is a post-fetch filter applied to whatever category text each individual company page happens to show — it cannot enumerate "all companies in category X" upstream.
- **`byCity` returns up to ~20 companies per run.** Soopage's own edge/WAF blocks every province/city listing page beyond page 1 (`/city/{area}-page2.html` and higher all return a hard 403 challenge — confirmed persistent, not a rate limit, and not specific to this actor's traffic). Page 1 (up to 20 companies) is the reliable, fetchable slice of a city listing. For larger pulls, run `mode=browseAll` (which is not affected by this block and can walk far deeper into the nationwide index), optionally combined with `categoryKeyword`, or supply specific `companyUrls` via `mode=byUrl`.
- **`browseAll` has no authoritative total-page count.** Unlike province/city pages (which show "Page X Of Y"), the nationwide index does not expose a total. `browseAll` stops once two consecutive pages return no listings, or once `maxItems` is reached — whichever comes first.

### FAQ

**What is id.soopage.com?** A business directory site listing companies across Indonesia by province/city, with per-company contact and address details.

**Is this affiliated with Soopage?** No — this is an independent, third-party actor that reads Soopage's public web pages.

**Why do some companies have no email, fax, or website?** Those fields are optional on the source page and are simply omitted if the company listing doesn't include them.

**How is the email address recovered?** Soopage uses Cloudflare's email-obfuscation feature on some listings; the actor decodes it automatically. Where a plain email is shown instead, that is used directly.

**Why is `category` sometimes based on "Type"?** Soopage shows either a "Category" or a "Type" field on a company's page (rarely both). The actor prefers "Category" and falls back to "Type" when "Category" isn't present.

**Can I get every company in a province?** Not via `byCity` alone — Soopage blocks city-listing pages beyond page 1, so `byCity` reliably returns up to ~20 companies per province/city per run (see Limitations). To pull larger volumes, use `mode=browseAll`, which walks Soopage's nationwide index without that restriction, optionally combined with `categoryKeyword` to narrow the results.

**How fresh is the data?** As fresh as the source pages — the actor reads live HTML on every run and does not cache.

**Is the `website` field always live?** It's the company's self-reported website exactly as published on their Soopage listing, some of which date back many years — a handful of listed domains may have since lapsed or changed hands. `sourceUrl` (the Soopage listing itself) and `googleMapsUrl` are actor-generated and always resolve.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

## `city` (type: `string`):

Area, province, or city to browse.

## `categoryKeyword` (type: `string`):

Only keep companies whose category text contains this keyword (case-insensitive). Applies after each company's detail page is fetched. (mode=byCity, browseAll)

## `companyUrls` (type: `array`):

Full soopage company page URLs, e.g. `https://id.soopage.com/company/FUSION-NET_2V8.html`, or just the filename part `FUSION-NET_2V8`.

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

Hard cap on emitted records. Note: mode=byCity reliably returns at most ~20 companies (Soopage blocks city-listing pages beyond page 1) — use mode=browseAll for larger pulls.

## `proxyConfiguration` (type: `object`):

Optional proxy settings. Leave empty to use no proxy — Soopage is publicly accessible without one. If you see blocking from your own IP range you can enable the free Apify AUTO datacenter proxy group.

## Actor input object example

```json
{
  "mode": "byCity",
  "city": "Jakarta",
  "companyUrls": [],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `companies` (type: `string`):

Dataset containing all scraped Soopage companies.

# 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 = {
    "mode": "byCity",
    "city": "Jakarta",
    "companyUrls": [],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/soopage-indonesia-business-directory-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 = {
    "mode": "byCity",
    "city": "Jakarta",
    "companyUrls": [],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/soopage-indonesia-business-directory-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "mode": "byCity",
  "city": "Jakarta",
  "companyUrls": [],
  "maxItems": 10
}' |
apify call crawlerbros/soopage-indonesia-business-directory-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/soopage-indonesia-business-directory-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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