# Traveloka Email Scraper (`leads-scraper/traveloka-email-scraper`) Actor

Traveloka Email Scraper SD - Traveloka Email Scraper is a lead generation tool that extracts leads with public contact emails, account names and profile URLs from Traveloka results by keyword, location and email domain - Traveloka email extractor.

- **URL**: https://apify.com/leads-scraper/traveloka-email-scraper.md
- **Developed by:** [Leads Scraper](https://apify.com/leads-scraper) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.49 / 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/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

### Traveloka Email Scraper — public hotel and activity contacts across Southeast Asia

The **Traveloka Email Scraper** builds a deduplicated list of publicly indexed contact emails from
Traveloka hotel and activity listings, together with the property label, snippet and the exact query
that produced each row. It is aimed at hospitality-tech vendors and OTA supply teams working in Asia.

One structural fact shapes the output, so the Traveloka Email Scraper states it up front. Traveloka
indexes hotel and activity listings rather than operator profiles, so rows carry an email without a
property handle.

The measurement is clear about what that means. In live runs, roughly every 10 parsed results
returned about 0 rows with an identity, 0 profile URLs and 10 unique emails — the strongest email
volume among the aggregator-style sources in this family.

The Traveloka Email Scraper never logs in, never opens the Traveloka website and never touches a
Traveloka API. Every field comes from Google's public index: result titles, snippets and the site
label Google prints beside them.

#### Who the Traveloka Email Scraper is for

Property management systems, channel managers and direct-booking vendors selling into Indonesia,
Thailand, Vietnam, Malaysia, Singapore and the Philippines use it to find properties that publish a
reservations address.

OTA supply teams recruiting Southeast Asian inventory, destination marketing organisations mapping
regional stock, hotel and F\&B suppliers, and travel PR teams are the other regular users. Properties
publish booking and partnership addresses deliberately, so approach them as trade contacts.

#### Why a regional live search beats a generic hotel email list

Most bought travel lists skew heavily towards Europe and North America. The Traveloka Email Scraper
runs a fresh Google search against a platform whose inventory is concentrated in Southeast Asia, so
the leads reflect a market that generic databases under-cover.

Re-running the Traveloka Email Scraper each quarter on a country surfaces newly listed properties
and activity operators as they publish contact details. It is a research instrument, not a one-off
purchase.

***

### Key features of the Traveloka Email Scraper

Everything below is code that ships in the Traveloka Email Scraper today, not a roadmap.

| Feature | What it does |
|---|---|
| Google `site:` targeting | Searches `traveloka.com` with your keyword and email domains |
| Query expansion | Base, quoted, `intitle:` and one variant per query modifier; base queries run first |
| Global deduplication | Each email is emitted once across every query and every page |
| Email normalisation | Case-insensitive; handles `name [at] domain [dot] com`, `(at)`, `name @ domain.com`, `domain .com`, zero-width characters and the full-width `＠` |
| Junk filter | Rejects placeholders such as `email@`, `yourname@`, `test@`, `xxx@` and single-character locals |
| Boundary-correct matching | `@gmail.com` does not match inside `@gmail.company` or `@gmail.com.br` |
| Soft-wrap repair | Drops a hit that is only the tail of another email in the same block |
| Structural parsing | Locates the `<h3>` title then the smallest surrounding block, instead of relying on Google CSS class names |
| Whole-page fallback | If Google's markup changes, the run degrades to "emails without account details", not "no emails" |
| Block detection | CAPTCHA, "unusual traffic" and consent pages are detected and retried, not counted as empty |
| Retries | Up to 3 attempts per page, exponential backoff, fresh proxy session per request |
| Requeue | Blocked or failed queries are re-queued once at the end of the run |
| Concurrency | `asyncio` worker pool with a shared stop signal on `maxEmails` |
| Resumable state | Progress is stored in the key-value store, keyed by a hash of the input, and saved on `PERSIST_STATE`, `MIGRATING` and `ABORTING` |
| Run summary | Logs pages fetched, blocked pages, retries and emails per page |

***

### How the Traveloka Email Scraper works

The pipeline is short and fully inspectable. The Traveloka Email Scraper reads your input, builds
Google queries with the `site:` operator, fetches result pages through the Apify **GOOGLE\_SERP**
proxy with `aiohttp`, and parses each result block structurally.

Emails are extracted from the block text with a domain-filtered regular expression, normalised,
deduplicated globally and pushed to the Apify dataset immediately. There is no browser, no
JavaScript rendering, no authentication and no cookies.

A base query looks like this, with your keyword and one of your email domains:

```
site:traveloka.com hotel "@gmail.com" "Bali"
```

#### Query expansion inside the Traveloka Email Scraper

Google caps a single query at roughly 300 results, so pagination depth alone can never fill a large
list. Coverage in the Traveloka Email Scraper comes from query diversity, which is why
`expandQueries` defaults to `true`.

Each keyword × domain pair runs as a base query, a quoted query, an `intitle:` query, and one extra
query per entry in `queryModifiers`. The Traveloka defaults are `email`, `contact`, `bookings`,
`group tours` and `partnerships`.

Base queries always run first, so a short run with a low `maxEmails` finishes on the strongest
phrasings. Because deduplication is global, expansion can only add leads, never repeat them.

#### Southeast Asia targeting with location and countryCode

`location` is a genuine lever here, more so than on Western-centric platforms. The phrase you supply
is quoted and appended to every query, so `"Bali"`, `"Phuket"` or `"Ho Chi Minh City"` narrows the
whole run to one market.

`countryCode` points the search proxy at a two-letter country such as `ID`, `TH`, `VN`, `MY`, `SG`
or `PH`, which changes which localised Traveloka pages Google surfaces. Country-by-country runs are
how the Traveloka Email Scraper produces a clean regional pipeline.

***

### Input fields of the Traveloka Email Scraper

| Field | Type | Default | Meaning |
|---|---|---|---|
| `keywords` | array (required) | `["hotel", "tour operator"]` | Search terms describing the listings you want |
| `location` | string | `""` | Optional location phrase added to every query |
| `customDomains` | array | `["@gmail.com", "@yahoo.com"]` | Only emails on these domains are kept; the `@` is optional |
| `maxEmails` | integer 1–10000 | `20` | Stop after this many unique emails |
| `countryCode` | string | `""` | Two-letter country for the search proxy (US, GB, DE…) |
| `expandQueries` | boolean | `true` | Search each keyword × domain pair in several phrasings |
| `queryModifiers` | array | `["email", "contact", "bookings", "group tours", "partnerships"]` | Extra words combined with each keyword when expansion is on |
| `maxPagesPerQuery` | integer 1–50 | `30` | Page cap per query |
| `maxConcurrency` | integer 1–20 | `5` | Parallel queries |

#### Example input for the Traveloka Email Scraper

```json
{
  "keywords": ["hotel", "tour operator", "villa"],
  "location": "Bali",
  "customDomains": ["@gmail.com", "@yahoo.com", "@hotmail.com"],
  "maxEmails": 250,
  "countryCode": "ID",
  "expandQueries": true,
  "queryModifiers": ["email", "contact", "bookings", "group tours", "partnerships"],
  "maxPagesPerQuery": 30,
  "maxConcurrency": 5
}
```

Free-mail addresses dominate independent accommodation in the region, which is why the defaults
perform well. Adding `@hotmail.com` gives the Traveloka Email Scraper another full set of queries.

***

### Output fields of the Traveloka Email Scraper

Every dataset item the Traveloka Email Scraper pushes carries all fourteen fields below — no
optional keys, no schema drift between runs.

| Field | Meaning |
|---|---|
| `network` | Platform name |
| `keyword` | The keyword that produced the lead |
| `query` | The exact Google query used |
| `title` | Raw result title |
| `accountName` | Account label Google prints (usually the property or activity name) |
| `fullName` | Display name parsed from a profile-style title; empty for listing pages |
| `username` | URL-safe handle when the platform exposes one; otherwise `null` |
| `profileUrl` | Canonical property URL when a handle is known; otherwise empty |
| `url` | Direct platform link when exposed, else the profile URL |
| `description` | Snippet text, cleaned of labels and counters |
| `email` | Lower-cased email address |
| `emailDomain` | The matched domain (e.g. `@gmail.com`) |
| `possiblyTruncated` | `true` when Google's snippet ellipsis touched the email |
| `foundAt` | ISO 8601 UTC timestamp |

When a handle is available, `profileUrl` takes the shape
`https://www.traveloka.com/en-en/hotel/{username}`. Because Traveloka indexes listings rather than
operator profiles, that is uncommon.

#### Example output from the Traveloka Email Scraper

```json
[
  {
    "network": "Traveloka",
    "keyword": "hotel",
    "query": "site:traveloka.com hotel bookings \"@gmail.com\" \"Bali\"",
    "title": "Ubud Garden Hotel, Bali - Traveloka",
    "accountName": "Ubud Garden Hotel",
    "fullName": "",
    "username": null,
    "profileUrl": "",
    "url": "https://www.traveloka.com/en-en/hotel/indonesia/ubud-garden-hotel",
    "description": "Boutique hotel in central Ubud. Bookings: ubudgardenhotel@gmail.com",
    "email": "ubudgardenhotel@gmail.com",
    "emailDomain": "@gmail.com",
    "possiblyTruncated": false,
    "foundAt": "2026-08-31T13:21:47Z"
  },
  {
    "network": "Traveloka",
    "keyword": "tour operator",
    "query": "site:traveloka.com tour operator group tours \"@yahoo.com\" \"Bali\"",
    "title": "Bali day tours and activities - Traveloka",
    "accountName": "Bali day tours and activities",
    "fullName": "",
    "username": null,
    "profileUrl": "",
    "url": "https://www.traveloka.com/en-en/activities/indonesia/city/bali",
    "description": "Group tours by Sunrise Bali Tours: sunrisebalitours@yahoo.com",
    "email": "sunrisebalitours@yahoo.com",
    "emailDomain": "@yahoo.com",
    "possiblyTruncated": true,
    "foundAt": "2026-08-31T13:22:16Z"
  }
]
```

Both rows show the honest pattern here: a usable email and a readable `accountName`, but
`username: null` and an empty `profileUrl`. The Traveloka Email Scraper reports what Google exposed
rather than guessing a handle.

***

### Use cases for the Traveloka Email Scraper

| Use case | How the Traveloka Email Scraper helps |
|---|---|
| PMS and channel manager sales in Asia | Find properties publishing a bookings address |
| Direct-booking tool outreach | Reach hotels and villas already promoting direct enquiries |
| Activity and tour partnerships | Contact operators advertising a partnerships inbox |
| Hotel supplier prospecting | Build a country list for linen, amenity and F\&B vendors |
| OTA supply recruitment | Source Southeast Asian properties not yet on your marketplace |
| Group and MICE sales | Target listings promoting group tours or group bookings |
| Destination marketing | Map regional accommodation and activity stock for a DMO |
| Travel PR and media | Contact properties publishing a press or enquiries address |

#### Worked example: a country-by-country Southeast Asia pipeline

Run the Traveloka Email Scraper once per market — `"Bali"` with `ID`, `"Phuket"` with `TH`,
`"Da Nang"` with `VN` — keeping `keywords` at `["hotel", "villa", "tour operator"]`. Narrow runs
consistently beat one broad regional run.

#### Worked example: activity-operator partnerships

Set `keywords` to `["tour operator", "activity", "day tour"]` and trim `queryModifiers` to
`["partnerships", "group tours", "email"]`. The Traveloka Email Scraper then concentrates on the
pages where operators advertise a trade inbox.

***

### Expected results from the Traveloka Email Scraper

In live measurement, about 10 results parsed by the Traveloka Email Scraper produced roughly
0 identity rows, 0 profile URLs and 10 unique emails. Email yield is the highest of the
listing-indexed sources here, while handle resolution is effectively nil.

Plan your workflow around `email` plus `accountName` as the identifying pair. Yield still varies
with keywords, email domains and location, and no volume is guaranteed.

***

### Limitations of the Traveloka Email Scraper

- **Traveloka indexes hotel and activity listings rather than operator profiles**, so rows carry an
  email without a property handle.
- Only properties whose email is **publicly visible in Google's index** can be found by the
  Traveloka Email Scraper.
- Google caps a single query at roughly 300 results, which is exactly why query expansion exists.
- `possiblyTruncated: true` means Google's snippet ellipsis may have cut the address — verify it.
- `username` and `profileUrl` are populated only when Google's result exposes a handle, which is
  uncommon here. That is a Google limitation, not a bug.
- The Traveloka Email Scraper requires the Apify **GOOGLE\_SERP** proxy and cannot run without Apify
  proxy credentials.
- Free Apify plans are capped at 100 emails per run; paid plans are uncapped.
- Results vary with keywords, domains and location, and no volume is guaranteed.

#### Responsible use and GDPR

Addresses returned by the Traveloka Email Scraper are business contact points that properties and
operators published for bookings and partnerships, so treat them as B2B outreach data. Identify
yourself, explain why you are writing and honour opt-outs immediately.

GDPR applies whenever you contact people in the EU or EEA, and several Southeast Asian markets have
comparable rules of their own. You need a lawful basis — usually legitimate interest — a transparent
privacy notice and a working unsubscribe path.

***

### FAQ about the Traveloka Email Scraper

#### How many results should I expect from the Traveloka Email Scraper?

In measured live runs, roughly every 10 parsed results gave about 0 identity rows, 0 profile URLs
and 10 unique emails. Volume is never guaranteed and shifts with keywords, domains and location.

#### Why is `username` always `null` in my dataset?

Traveloka indexes hotel and activity listings rather than operator profiles, so Google's results
rarely expose a URL-safe handle. The Traveloka Email Scraper leaves the field `null` instead of
inventing one.

#### Does the Traveloka Email Scraper log in or use the Traveloka API?

No. It does not log in, does not open the Traveloka website and does not use any Traveloka API. All
data comes from publicly indexed Google search results.

#### Is the Traveloka Email Scraper only useful for Southeast Asia?

That is where the platform's inventory is concentrated, so `countryCode` values such as `ID`, `TH`,
`VN`, `MY`, `SG` and `PH` give the best returns. It will run against any location phrase you supply.

#### Which email domains should I use?

Start with `@gmail.com` and `@yahoo.com`, then add `@hotmail.com`, `@outlook.com` or a country
domain. Every extra domain multiplies the queries the Traveloka Email Scraper runs.

#### Can I limit the Traveloka Email Scraper to one city or country?

Yes. `location` appends a quoted phrase to every query and `countryCode` sets the proxy's two-letter
country, which together give destination-led prospecting.

#### Do I need a proxy to run the Traveloka Email Scraper?

Yes. It runs through the Apify GOOGLE\_SERP proxy and cannot operate without Apify proxy credentials.

#### What does `possiblyTruncated` mean?

It flags a row where Google's snippet ellipsis touched the email, so the address may be incomplete.
Verify those rows before sending.

#### How do I get more emails out of a run?

Keep `expandQueries` on, add keywords such as `villa`, `resort` or `homestay`, add more email
domains, raise `maxEmails`, and split one regional run into several country runs.

#### Is there a free-plan limit on the Traveloka Email Scraper?

Free Apify plans stop at 100 emails per run. Paid plans are uncapped, subject to Google's own
per-query ceiling.

#### Can I resume an interrupted Traveloka Email Scraper run?

Yes. Progress is stored in the key-value store keyed by a hash of your input and saved on Apify's
`PERSIST_STATE`, `MIGRATING` and `ABORTING` events.

#### Is the Traveloka Email Scraper affiliated with Traveloka?

No. It is an independent tool that reads public Google search results and is not endorsed by or
connected to Traveloka.

***

### Related Actors

Every Actor below runs the same engine against a different Travel, Hospitality & Food platform.
For regional breadth pair this with the \[Wego Email Scraper]\(https://apify.com/leads-
scraper/wego-email-scraper), which covers the Middle East and Asia, and the [Klook Email
Scraper](https://apify.com/neuro-scraper/klook-email-scraper) for Asia-Pacific activities.

For global accommodation coverage add the \[Booking.com Email Scraper]\(https://apify.com/leads-
scraper/booking-com-email-scraper), the \[Airbnb Email Scraper]\(https://apify.com/leads-
scraper/airbnb-email-scraper) and the [Tripadvisor Hotels Email
Scraper](https://apify.com/leads-scraper/tripadvisor-hotels-email-scraper).

| Actor | What it collects |
|---|---|
| [Airbnb Email Scraper](https://apify.com/leads-scraper/airbnb-email-scraper) | Public contact emails from Airbnb |
| [Booking.com Email Scraper](https://apify.com/leads-scraper/booking-com-email-scraper) | Public contact emails from Booking.com |
| [Caviar Email Scraper](https://apify.com/neuro-scraper/caviar-email-scraper) | Public contact emails from Caviar |
| [ChowNow Email Scraper](https://apify.com/neuro-scraper/chownow-email-scraper) | Public contact emails from ChowNow |
| [Contiki Email Scraper](https://apify.com/neuro-scraper/contiki-email-scraper) | Public contact emails from Contiki |
| [Craigslist Email Scraper](https://apify.com/leads-scraper/craigslist-email-scraper) | Public contact emails from Craigslist |
| [Delivery.com Email Scraper](https://apify.com/neuro-scraper/delivery-com-email-scraper) | Public contact emails from Delivery.com |
| [DoorDash Email Scraper](https://apify.com/leads-scraper/doordash-email-scraper) | Public contact emails from DoorDash |
| [EatStreet Email Scraper](https://apify.com/neuro-scraper/eatstreet-email-scraper) | Public contact emails from EatStreet |
| [G Adventures Email Scraper](https://apify.com/neuro-scraper/g-adventures-email-scraper) | Public contact emails from G Adventures |
| [GetYourGuide Email Scraper](https://apify.com/leads-scraper/getyourguide-email-scraper) | Public contact emails from GetYourGuide |
| [Grubhub Email Scraper](https://apify.com/leads-scraper/grubhub-email-scraper) | Public contact emails from Grubhub |
| [Hostelbookers Email Scraper](https://apify.com/leads-scraper/hostelbookers-email-scraper) | Public contact emails from Hostelworld |
| [HotelsCombined Email Scraper](https://apify.com/neuro-scraper/hotelscombined-email-scraper) | Public contact emails from HotelsCombined |
| [Intrepid Travel Email Scraper](https://apify.com/neuro-scraper/intrepid-travel-email-scraper) | Public contact emails from Intrepid Travel |
| [Just Eat Email Scraper](https://apify.com/leads-scraper/just-eat-email-scraper) | Public contact emails from Just Eat |
| [Klook Email Scraper](https://apify.com/neuro-scraper/klook-email-scraper) | Public contact emails from Klook |
| [OpenTable Email Scraper](https://apify.com/neuro-scraper/opentable-email-scraper) | Public contact emails from OpenTable |
| [Resy Email Scraper](https://apify.com/leads-scraper/resy-email-scraper) | Public contact emails from Resy |
| [TheFork Email Scraper](https://apify.com/leads-scraper/thefork-email-scraper) | Public contact emails from TheFork |
| [Toast Restaurant Email Scraper](https://apify.com/leads-scraper/toast-restaurant-email-scraper) | Public contact emails from Toast |
| [TourRadar Email Scraper](https://apify.com/leads-scraper/tourradar-email-scraper) | Public contact emails from TourRadar |
| [Tripadvisor Attractions Email Scraper](https://apify.com/leads-scraper/tripadvisor-attractions-email-scraper) | Public contact emails from Tripadvisor |
| [Tripadvisor Hotels Email Scraper](https://apify.com/leads-scraper/tripadvisor-hotels-email-scraper) | Public contact emails from Tripadvisor |
| [Tripadvisor Restaurants Email Scraper](https://apify.com/leads-scraper/tripadvisor-restaurants-email-scraper) | Public contact emails from Tripadvisor |
| [Uber Eats Email Scraper](https://apify.com/leads-scraper/uber-eats-email-scraper) | Public contact emails from Uber Eats |
| [Viator Email Scraper](https://apify.com/leads-scraper/viator-email-scraper) | Public contact emails from Viator |
| [Wanderlog Email Scraper](https://apify.com/leads-scraper/wanderlog-email-scraper) | Public contact emails from Wanderlog |
| [Wego Email Scraper](https://apify.com/leads-scraper/wego-email-scraper) | Public contact emails from Wego |
| [Zomato Email Scraper](https://apify.com/leads-scraper/zomato-email-scraper) | Public contact emails from Zomato |
| [Airbnb Email and Phone Number Scraper](https://apify.com/leads-scraper/airbnb-email-and-phone-number-scraper) | Emails and phone numbers from Airbnb |
| [Booking.com Email and Phone Number Scraper](https://apify.com/leads-scraper/booking-com-email-and-phone-number-scraper) | Emails and phone numbers from Booking.com |
| [Caviar Email and Phone Number Scraper](https://apify.com/neuro-scraper/caviar-email-and-phone-number-scraper) | Emails and phone numbers from Caviar |
| [ChowNow Email and Phone Number Scraper](https://apify.com/neuro-scraper/chownow-email-and-phone-number-scraper) | Emails and phone numbers from ChowNow |
| [Contiki Email and Phone Number Scraper](https://apify.com/neuro-scraper/contiki-email-and-phone-number-scraper) | Emails and phone numbers from Contiki |
| [Craigslist Email and Phone Number Scraper](https://apify.com/leads-scraper/craigslist-email-and-phone-number-scraper) | Emails and phone numbers from Craigslist |
| [Delivery.com Email and Phone Number Scraper](https://apify.com/neuro-scraper/delivery-com-email-and-phone-number-scraper) | Emails and phone numbers from Delivery.com |
| [DoorDash Email and Phone Number Scraper](https://apify.com/leads-scraper/doordash-email-and-phone-number-scraper) | Emails and phone numbers from DoorDash |
| [EatStreet Email and Phone Number Scraper](https://apify.com/neuro-scraper/eatstreet-email-and-phone-number-scraper) | Emails and phone numbers from EatStreet |
| [G Adventures Email and Phone Number Scraper](https://apify.com/neuro-scraper/g-adventures-email-and-phone-number-scraper) | Emails and phone numbers from G Adventures |
| [Grubhub Email and Phone Number Scraper](https://apify.com/neuro-scraper/grubhub-email-and-phone-number-scraper) | Emails and phone numbers from Grubhub |
| [Hostelworld Email and Phone Number Scraper](https://apify.com/neuro-scraper/hostelbookers-email-and-phone-number-scraper) | Emails and phone numbers from Hostelworld |

### Leave a review

If the Traveloka Email Scraper saved you time, please leave a star rating and a short review on
the Actor page.

Reviews are how other buyers judge whether a tool works, and they tell us which features to
build next.

If something did not work, email <neurodata.apify@gmail.com>
instead - bugs get fixed faster than they get complained about.

### Support

Questions, a bug, or a custom build of the Traveloka Email Scraper? Email
**neurodata.apify@gmail.com** and we will get back to you.

# Actor input Schema

## `keywords` (type: `array`):

Search terms describing the Traveloka accounts you want (niche, job title, industry).

## `location` (type: `string`):

Optional location phrase added to every query (e.g. "New York").

## `customDomains` (type: `array`):

Only emails ending with one of these domains are collected. With or without the leading @. Each domain is searched separately, so more domains means more results but a longer run - remove some for a faster, narrower search, or add your own (e.g. @company.com).

## `maxEmails` (type: `integer`):

Stop once this many unique emails have been collected.

## `countryCode` (type: `string`):

Two-letter country code for the search proxy (e.g. US, GB, DE). Empty for any.

## `expandQueries` (type: `boolean`):

Search each keyword x domain pair with several phrasings. Recommended - Google caps a single query at ~300 results.

## `queryModifiers` (type: `array`):

Extra words combined with each keyword when Expand queries is on. Tuned for Traveloka.

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

Google rarely returns more than ~30 pages for one query.

## `maxConcurrency` (type: `integer`):

How many queries run in parallel.

## Actor input object example

```json
{
  "keywords": [
    "hotel",
    "tour operator"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com"
  ],
  "maxEmails": 20,
  "countryCode": "",
  "expandQueries": true,
  "queryModifiers": [
    "email",
    "contact",
    "bookings",
    "group tours",
    "partnerships"
  ],
  "maxPagesPerQuery": 30,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `results` (type: `string`):

Records produced by Traveloka Email Scraper, stored in the run's default dataset.

# 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 = {
    "keywords": [
        "hotel",
        "tour operator"
    ],
    "location": "",
    "customDomains": [
        "@gmail.com",
        "@yahoo.com"
    ],
    "countryCode": "",
    "queryModifiers": [
        "email",
        "contact",
        "bookings",
        "group tours",
        "partnerships"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leads-scraper/traveloka-email-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 = {
    "keywords": [
        "hotel",
        "tour operator",
    ],
    "location": "",
    "customDomains": [
        "@gmail.com",
        "@yahoo.com",
    ],
    "countryCode": "",
    "queryModifiers": [
        "email",
        "contact",
        "bookings",
        "group tours",
        "partnerships",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("leads-scraper/traveloka-email-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 '{
  "keywords": [
    "hotel",
    "tour operator"
  ],
  "location": "",
  "customDomains": [
    "@gmail.com",
    "@yahoo.com"
  ],
  "countryCode": "",
  "queryModifiers": [
    "email",
    "contact",
    "bookings",
    "group tours",
    "partnerships"
  ]
}' |
apify call leads-scraper/traveloka-email-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leads-scraper/traveloka-email-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/SeBfZk3E3vL2hxSBQ/builds/jwKJpVp8n6AbYsQFJ/openapi.json
