# Welcome to the Jungle Office Locations and Addresses (`gubidonius/wttj-offices`) Actor

Every office of every company on Welcome to the Jungle, one row per site with street address, postcode, city, country and map coordinates. The street and the coordinates are only on the per-company profile, and the search index ships coordinates in a separate array that is not always aligned.

- **URL**: https://apify.com/gubidonius/wttj-offices.md
- **Developed by:** [Gregory Bolshakov](https://apify.com/gubidonius) (community)
- **Categories:** Lead generation, Business, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Welcome to the Jungle Office Locations and Addresses

Every office of every company on Welcome to the Jungle, one row per site. Street address,
postcode, city, district, country and map coordinates, with the company's sector, size and
open advert count on the same row. No key and no login.

### The problem this solves

The street address and the coordinates are not in the site's search index. The index has an
offices list, and it holds the city and the district and no street at all. It also ships
coordinates in a second array, `_geoloc`, that sits beside the office list rather than inside
it, and the two are not always in the same order. For GreenFlex the profile returns the same
ten offices in a different order from the index. Pairing them by position puts the wrong city
on the wrong point, and the map looks fine.

So every address and every coordinate here comes from the per-company profile endpoint, where
the latitude and longitude sit on the office itself and cannot be mispaired.

### What one row is

One office of one company. A company with 15 offices gives 15 rows, numbered `officeIndex`
out of `officeCountForCompany`, so you can see when the row budget cut a company short. 95 of
the 120 rows in our test run belong to a company with more than one office.

A country filter picks companies that have an office in that country and then returns the
offices that are there. It has to do both. Picking the company alone and keeping all of its
offices gave us 120 rows for GB of which 96 were somewhere else, and every one was charged.
Set `allOfficesOfMatchingCompanies` if you do want the whole footprint of every company with a
British office. `companyOfficeCountryCodes` is on every row either way, so a London office
still shows that the company also sits in Paris.

### One company is indexed several times

Swan appears four times in the search index, once for its own page and once each for wttj\_fr,
francefintech and hub-bpifrance. Four different record ids, the same company, the same five
offices. Across the whole directory there are 17,189 records and 12,423 real companies,
measured 9 September 2026.

This Actor matches on the company reference, which is stable when a company renames itself,
so you get each office once and pay for it once. Deduplicating on the record id instead
returned the same office twice on 23 of 120 rows in our banking test.

### What a run admits

Every row carries `companySearchTotalReported`, the count the site's own search gave for your
filter. That number counts companies and the rows are offices, so read it next to
`officeCountForCompany` rather than against the row count. `RUN_SUMMARY` in the key-value
store holds every cell with what it reported, what it returned and why it stopped, plus
`complete`, `limitedBy`, `companiesRead` and `duplicateCompaniesSuppressed`.

### Billing

Two events: a start fee charged only once offices are returned, and a per-office fee charged
after each office is written. An office removed by the headquarters filter or the coordinates
filter is never charged. A run that matches nothing costs nothing.

# Actor input Schema

## `query` (type: `string`):

Words to look for in company names and descriptions. This is a search and not a filter: it is typo tolerant and ranks by relevance, so it returns more companies than the matching sector filter would. Leave empty to walk the whole directory.

## `sectors` (type: `array`):

Sectors as the site writes them in English, for example Software, SaaS, Consulting, Biotechnology. There are 100 of them, measured 9 September 2026, and every value is checked against the live list before the search runs, so a misspelling is reported with the real spelling rather than silently returning nothing. A company is filed under several sectors at once.

## `sizes` (type: `array`):

The five bands the site uses, written out in full and exactly as it writes them: "< 15 employees", "Between 15 and 50 employees", "Between 50 and 250 employees", "Between 250 and 2,000 employees", "> 2,000 employees". 2,106 companies carry no band at all and are excluded when you set this.

## `countries` (type: `array`):

Two-letter ISO codes, for example FR, ES, DE, GB, US. This picks companies that have an office in those countries and then returns only the offices that are there. Turn on "All offices of matching companies" to get their other offices as well.

## `labels` (type: `array`):

Certification slugs the company declares, for example bcorp, great-place-to-work, qualiopi, mission-company, ecovadis-gold. The commonest is bcorp on 373 companies, measured 9 September 2026.

## `hiringOnly` (type: `boolean`):

Keep only companies advertising at least one job right now. 4,301 of the 17,189 companies do, measured 9 September 2026.

## `minEmployees` (type: `integer`):

Keep only companies declaring at least this many employees. Companies that declare no headcount are excluded when you set this.

## `headquartersOnly` (type: `boolean`):

Return one row per company instead of one per office, keeping only the office the company flags as its headquarters. 292 of 342 offices sampled on 9 September 2026 carried that flag. A company that flags none returns no row under this setting rather than its first office, because nothing here guesses which address is the head office.

## `withCoordinatesOnly` (type: `boolean`):

Keep only offices carrying a latitude and a longitude, for mapping. 340 of 342 offices sampled on 9 September 2026 had both.

## `allOfficesOfMatchingCompanies` (type: `boolean`):

Off by default. When you filter by country you get only the offices in those countries. Turn this on to get every office of every company that matched, including the ones elsewhere. On a test search for GB, 96 of 120 offices were outside GB.

## `language` (type: `string`):

The language for sector names and size bands, which the site holds in five languages at once. A company that has no text in your language falls back to English and then to whatever it does have, rather than returning an empty column.

## `maxResults` (type: `integer`):

The most OFFICE ROWS to return, and what you are charged for. One company gives 1.16 offices on average, so 100 offices is about 86 companies. The budget is shared across the whole run, so the total never exceeds it.

## Actor input object example

```json
{
  "query": "",
  "sectors": [
    "FinTech / InsurTech"
  ],
  "sizes": [],
  "countries": [],
  "labels": [],
  "hiringOnly": false,
  "headquartersOnly": false,
  "withCoordinatesOnly": false,
  "allOfficesOfMatchingCompanies": false,
  "language": "en",
  "maxResults": 100
}
```

# Actor output Schema

## `results` (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 = {
    "query": "",
    "sectors": [
        "FinTech / InsurTech"
    ],
    "sizes": [],
    "countries": [],
    "labels": [],
    "hiringOnly": false,
    "headquartersOnly": false,
    "withCoordinatesOnly": false,
    "allOfficesOfMatchingCompanies": false,
    "language": "en",
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("gubidonius/wttj-offices").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 = {
    "query": "",
    "sectors": ["FinTech / InsurTech"],
    "sizes": [],
    "countries": [],
    "labels": [],
    "hiringOnly": False,
    "headquartersOnly": False,
    "withCoordinatesOnly": False,
    "allOfficesOfMatchingCompanies": False,
    "language": "en",
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("gubidonius/wttj-offices").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 '{
  "query": "",
  "sectors": [
    "FinTech / InsurTech"
  ],
  "sizes": [],
  "countries": [],
  "labels": [],
  "hiringOnly": false,
  "headquartersOnly": false,
  "withCoordinatesOnly": false,
  "allOfficesOfMatchingCompanies": false,
  "language": "en",
  "maxResults": 100
}' |
apify call gubidonius/wttj-offices --silent --output-dataset

```

## MCP server setup

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

```

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/sgpTehRG5E95E3fh7/builds/AiY1nYf1tJFIFK9ep/openapi.json
