# Trabajando.cl Jobs Scraper — Chile Job Listings (`fabrikit/trabajando-cl-jobs-scraper`) Actor

Scrape job listings from Trabajando.cl, Chile's veteran job board: title, company, comuna/region, schedule, contract, salary when published, requirements and dates. Filter by keyword, location, area and jornada. US$0.50 per 1,000 jobs.

- **URL**: https://apify.com/fabrikit/trabajando-cl-jobs-scraper.md
- **Developed by:** [Fabrikit](https://apify.com/fabrikit) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 job results

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

## Trabajando.cl Jobs Scraper — Chile Job Listings

Scrape job postings from **Trabajando.cl**, one of Chile's oldest and largest job boards (part of the Trabajando.com network used by major Chilean employers and universities), into clean, analysis-ready JSON. Filter by **keyword**, **region or comuna**, **job area** and **work schedule (jornada)**, and get back every posting with title, company, location with GPS coordinates, contract type, **salary when the employer publishes it**, experience and education requirements, and ISO dates. This is a **Chile jobs data** and **Chilean job market API** in one Actor: no browser, no login, plain HTTP against the site's own JSON endpoints — fast and cheap.

What you get from a single run:

- **Every core field a labor-market analyst or recruiter needs**: job title, company (or an explicit `confidential` flag when the employer hides its name), comuna and region, schedule type, salary in CLP when published, years of experience required, education level, target careers, number of vacancies, publication and expiry dates.
- **The whole board if you want it**: ~12,000 open postings across all 16 Chilean regions at any given time, 50 per request, with stable numeric IDs for cross-run diffing.
- **Monitoring-ready**: sort by `newest`, schedule the Actor daily, and diff against yesterday's dataset — new postings, expired postings and hiring spikes by region, area or company.

Example output item (real posting):

```json
{
    "id": "6115846",
    "url": "https://www.trabajando.cl/trabajo/6115846-tecnico-en-prevencion-de-riesgos",
    "title": "Técnico en Prevención de Riesgos",
    "company": "Empresa Confidencial",
    "confidential": true,
    "area": "Otra Área",
    "positionType": "Técnico",
    "location": "Santiago, Metropolitana de Santiago",
    "comuna": "Santiago",
    "region": "Metropolitana de Santiago",
    "latitude": -33.4386021,
    "longitude": -70.6483453,
    "jornada": "Jornada Completa",
    "contractType": null,
    "salary": 1050000,
    "salaryCurrency": "CLP",
    "experienceYears": 1,
    "educationLevel": "Técnico profesional superior",
    "vacancies": 1,
    "publishedAt": "2026-08-20T17:07:00",
    "expiresAt": "2026-08-25",
    "featured": true,
    "inclusive": true,
    "description": "Funciones:\n- Asegurar el cumplimiento de la ley N.º 16.744...",
    "requirements": [
        "Estudios Técnico en Prevención de Riesgos.",
        "Al menos 1 año de experiencia, deseable en el Sector Público..."
    ],
    "scrapedAt": "2026-08-21T02:03:23.748Z"
}
```

### How to scrape Trabajando.cl

1. Type a **keyword** (`vendedor`, `ingeniero civil`, `react`) — or leave it empty to list all open jobs.
2. Optionally narrow by **region or comuna** (free text: `Antofagasta`, `Providencia`, `Valparaíso`), **area** (the site's own category names, e.g. `Comercial`, `Informática`, `Seguros`) and **jornada** (full time, part time, remote, hybrid, shifts, internship...).
3. Pick a **sort order** and a **max jobs** cap, and press **Start**. Results land in the dataset and can be exported as JSON, CSV or Excel, or pushed to Sheets, webhooks, Zapier, Make or the Apify API.

#### Example input

```json
{
    "keyword": "ingeniero",
    "location": "Antofagasta",
    "jornada": "full_time",
    "maxItems": 200,
    "sort": "newest",
    "fetchDetails": true
}
```

- **keyword** — free-text search over titles and descriptions. Empty = all jobs.
- **location** — free text matched against the posting's location: a region (`Metropolitana de Santiago`, `Biobío`) or a comuna (`Las Condes`, `Concepción`). Empty = all of Chile.
- **area** — job area exactly as named on Trabajando.cl (`Comercial`, `Informática`, `Seguros`, ...). Empty = all areas.
- **jornada** — `any`, `full_time`, `part_time`, `remote` (Teletrabajo), `hybrid` (Mixta), `field_work` (En terreno), `shifts` (Por Turnos), `internship` (Práctica), `freelance`, `replacement`, `commission`.
- **maxItems** — cap on jobs returned (50 per page; the whole board is ~12,000 postings).
- **sort** — `relevance` (site default, featured first), `newest`, `oldest`.
- **fetchDetails** — visit each posting's own JSON endpoint (default on, 1 extra request per job) to add area, contract type, salary, requirements, education, careers, vacancies, expiry date, external apply link and the full description. Turn off for card-only data at a fraction of the runtime.

### Output fields

| Field | Type | Description |
|---|---|---|
| `id` | string | Trabajando.cl posting ID, stable across runs — use it for diffing |
| `url` | string | Direct link to the posting |
| `title` | string | Job title |
| `company` | string | Employer name, or `Empresa Confidencial` when hidden |
| `confidential` | boolean | `true` when the employer hides its name |
| `companyLogo` | string | null | Company logo URL |
| `area` | string | null | Job area / category (detail pages) |
| `positionType` | string | null | Position level, e.g. `Técnico`, `Profesional`, `Operario` |
| `location` | string | null | Raw `comuna, region` string as published |
| `comuna` / `region` | string | null | Parsed location — Chile's key segmentation units |
| `latitude` / `longitude` | number | null | Map pin of the posting (`null` when the site has no real pin) |
| `jornada` | string | null | Work schedule, e.g. `Jornada Completa`, `Teletrabajo`, `Part Time` |
| `contractType` | string | null | Contract duration when stated (often not published) |
| `salary` | number | null | Salary — **only when the employer chose to publish it** |
| `salaryCurrency` | string | null | `CLP` for published salaries |
| `experienceYears` | number | null | Years of experience required |
| `educationLevel` | string | null | Minimum education, e.g. `Media`, `Técnico profesional superior` |
| `careers` | string\[] | null | Target degrees/careers when the employer lists them |
| `vacancies` | number | null | Number of openings in this posting |
| `publishedAt` | string | null | ISO publication date-time (America/Santiago local time) |
| `publishedAgo` | string | null | Site's relative label, e.g. `Publicada hoy` |
| `expiresAt` | string | null | ISO expiry date of the posting |
| `featured` | boolean | `true` for paid/featured postings |
| `inclusive` | boolean | `true` for postings flagged as inclusive employment |
| `applyUrl` | string | null | External ATS application link when the employer uses one |
| `descriptionSnippet` | string | null | Short description from the search card |
| `description` | string | null | Full plain-text description (detail pages) |
| `requirements` | string\[] | null | Minimum requirements as a structured list (detail pages) |
| `scrapedAt` | string | ISO 8601 timestamp of this run |

A run summary (filters used, pages fetched, per-item detail errors) is stored in the run's key-value store under `SUMMARY`.

### What can you do with Chilean job-listings data?

- **Labor-market analysis**: hiring volume by region, area and schedule type; salary levels from the postings that publish them; demand for specific degrees (`careers`) — mining regions like Antofagasta alone carry 1,400+ open postings.
- **Recruiting intelligence**: which companies are hiring, for what, and how many vacancies — `featured` flags who is paying to promote roles.
- **Job-board aggregation**: feed a niche board (remote-only, one region, one industry) on a schedule; `id` is stable, so dedup across runs is trivial.
- **Sales signals**: a company opening dozens of roles is a growth signal — filter by company and diff daily.
- **Academic and policy research**: education requirements, experience thresholds and inclusive-employment flags across the whole Chilean market, in one flat table.

### Integrations

Every Apify dataset exports to **CSV, Excel, JSON, XML or HTML** with one click, or syncs to **Google Sheets**, and the Actor plugs into **Zapier, Make, webhooks, MCP** and the Apify API:

```python
## Python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("fabrikit/trabajando-cl-jobs-scraper").call(run_input={
    "keyword": "ingeniero",
    "location": "Antofagasta",
    "sort": "newest",
    "maxItems": 200,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], "—", job["company"], "—", job["comuna"])
```

```javascript
// Node.js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('fabrikit/trabajando-cl-jobs-scraper').call({
    keyword: 'vendedor',
    location: 'Providencia',
    maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'jobs');
```

### Performance & limits

- Runs use **plain HTTP JSON requests** — no browser — so a 50-job run with full details finishes in well under a minute, and card-only runs (`fetchDetails: false`) fetch 50 jobs per request.
- The board holds **~12,000 open postings**; pagination is verified deep into the list, so a single run can cover all of it.
- With `fetchDetails` on, detail endpoints are fetched 5 at a time; a failed detail fetch **never drops the job** — you keep the search-card data and the error is noted in `SUMMARY`.
- Items are deduplicated by `id` within a run.

### Tips for best results

- **Monitoring pipelines**: use `sort: "newest"` with a modest `maxItems` and a daily schedule — you only pay for what you fetch.
- **Full-market snapshots**: leave keyword/location empty, set `maxItems` high, and turn `fetchDetails` off first to map the market cheaply; re-run with details on a filtered subset.
- **Salary studies**: salary is only present when the employer publishes it (roughly 1 in 10 postings) — filter `salary != null` downstream rather than assuming coverage.
- **Area filter** is an exact match on the site's own names; if a run returns 0 jobs, copy the area name from any posting on trabajando.cl. Keyword search is usually the more forgiving tool.
- The `region` facet counts reported by the site are available in one card-only run — useful to size a market before a deep scrape.

### Pricing — US$0.50 per 1,000 jobs

This Actor uses Apify's **pay-per-event** model and charges **per job delivered** (event `job-result`, **US$0.0005 per job = US$0.50 per 1,000 jobs**) plus a small run-start fee, on top of standard Apify platform usage. No subscription, no rental fee. You only pay for jobs actually pushed to your dataset.

### FAQ

**Is there a Trabajando.cl API?**
Not a public documented one. The site's own search runs through JSON endpoints that power its web frontend; this Actor reads those endpoints directly over plain HTTP — no browser, no HTML parsing — and normalizes the result into one schema. That makes it fast and resilient to visual redesigns.

**Which locations work?**
Any Chilean region or comuna as the site names it: `Metropolitana de Santiago`, `Antofagasta`, `Valparaíso`, `Providencia`, `Las Condes`, `Concepción`... The field is free text matched by the site itself, so region names and comuna names both work. Empty = all of Chile.

**Does it include salaries?**
When the employer publishes one — most Chilean postings hide it (`salary: null`), but the ones that show it report a clean number in CLP. The site's own salary facets show roughly 10,000+ of 12,000 postings carry an internal salary band, but only the published ones are exposed per posting.

**What does `confidential` mean?**
Chilean employers often post anonymously as "Empresa Confidencial". The flag makes those machine-detectable so you can exclude (or target) them.

**Can I tell remote jobs apart?**
Yes — filter with `jornada: "remote"` (Teletrabajo) or `"hybrid"` (Mixta) at input time, or by the `jornada` output field.

**Are dates really ISO?**
Yes: `publishedAt` is `YYYY-MM-DDTHH:MM:SS` in America/Santiago local time (the site's own clock), `expiresAt` is `YYYY-MM-DD`, and `scrapedAt` is full UTC ISO 8601.

**Is it legal to scrape job postings?**
The Actor only reads postings that Trabajando.cl publishes publicly, at a polite request rate, and collects no personal data — only job ads meant to be seen by as many people as possible. How you use the data is up to your own compliance requirements.

**How many jobs can one run return?**
As many as match your filters — the whole board (~12,000) fits in one run. Pagination at 50 jobs per page is verified; there is no hard site cap like on some marketplaces.

### Support

Found a bug or need a field the site publishes but the Actor doesn't return yet? Open an issue in the **Issues** tab — issues are typically answered **within 24 hours**, and field additions are cheap because the Actor reads structured JSON, not HTML.

### More scrapers by Fabrikit

- **[ATS Jobs Scraper — Greenhouse, Lever, Ashby & SmartRecruiters](https://apify.com/fabrikit/ats-jobs-api)** — job postings from any company on the four biggest ATS platforms, with ATS auto-detection and a built-in remote filter.
- **[Portal Inmobiliario Scraper — Chile Real Estate](https://apify.com/fabrikit/portal-inmobiliario-scraper)** — Chilean property listings with prices in CLP/UF, surfaces, GPS coordinates and seller type.
- **[App Reviews Scraper — App Store & Google Play](https://apify.com/fabrikit/app-reviews-unified)** — reviews from both mobile stores in one normalized dataset: rating, text, author, version and developer reply.

### Technical details

- Data source: Trabajando.cl's own JSON search endpoint (50 results per page, with region/schedule/salary facets) and per-posting JSON detail endpoint. No browser, no CSS-selector parsing — a visual redesign doesn't break anything.
- HTML fields (`description`, `requirements`) are converted to clean plain text; `<li>` requirement lists become structured string arrays.
- Coordinates equal to the site's `0.0,0.0` placeholder are returned as `null` instead of a fake point.
- Proxies are optional (`proxyConfiguration`); plain requests work, but enable RESIDENTIAL if your runs hit 403s.

***

### En español

Este Actor extrae ofertas de empleo de **Trabajando.cl** con filtros por palabra clave, región o comuna, área y jornada. Cada oferta incluye cargo, empresa (o marca `confidential` si es confidencial), comuna y región con coordenadas, jornada, sueldo cuando el empleador lo publica, años de experiencia, nivel de estudios, carreras objetivo, vacantes, fechas ISO de publicación y expiración, descripción completa y requisitos como lista estructurada. Exporta a CSV, Excel, JSON o Google Sheets con un clic, o prográmalo diario para monitorear ofertas nuevas. Precio: **US$0,50 por cada 1.000 empleos** (pago por resultado, sin suscripción). ¿Dudas o campos que faltan? Escríbenos en la pestaña **Issues** — respondemos en menos de 24 horas, en español o inglés.

# Actor input Schema

## `keyword` (type: `string`):

Free-text search over job titles and descriptions (e.g. `vendedor`, `ingeniero civil`, `react`). Leave empty to list all open jobs.

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

Free text matched against the job's location: a region (`Antofagasta`, `Metropolitana de Santiago`, `Valparaíso`) or a comuna (`Providencia`, `Las Condes`, `Concepción`). Leave empty to search all of Chile.

## `area` (type: `string`):

Job area as named on Trabajando.cl, exact match (e.g. `Comercial`, `Informática`, `Seguros`, `Otra Área`). Leave empty for all areas. If a run returns 0 jobs, check the spelling against the area shown on a posting.

## `jornada` (type: `string`):

Work-schedule filter. `remote` = Teletrabajo, `hybrid` = Mixta (Teletrabajo + Presencial), `field_work` = En terreno, `shifts` = Por Turnos, `internship` = Práctica.

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

Stop after this many jobs. The site serves 50 jobs per page; the whole board is ~12,000 open postings, so an unfiltered run with a high limit can cover all of it.

## `sort` (type: `string`):

`relevance` is the site default (featured jobs first). `newest` is the right choice for monitoring/alerting pipelines.

## `fetchDetails` (type: `boolean`):

Visit each job's own JSON endpoint (1 extra request per job) to add: area, contract type, salary when published, experience and education requirements, careers, vacancies, expiry date, external apply link, full description and structured requirements. Turn off for faster runs with search-card data only.

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

Trabajando.cl responds to plain requests. If runs from Apify's datacenter IPs start failing with 403s or empty pages, enable Apify RESIDENTIAL proxies here.

## Actor input object example

```json
{
  "keyword": "",
  "location": "",
  "area": "",
  "jornada": "any",
  "maxItems": 50,
  "sort": "relevance",
  "fetchDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

All job listings collected during the run

# 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 = {
    "keyword": "",
    "location": "",
    "area": "",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("fabrikit/trabajando-cl-jobs-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 = {
    "keyword": "",
    "location": "",
    "area": "",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("fabrikit/trabajando-cl-jobs-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 '{
  "keyword": "",
  "location": "",
  "area": "",
  "maxItems": 50
}' |
apify call fabrikit/trabajando-cl-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fabrikit/trabajando-cl-jobs-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/xNZdzMM9guBDa2ZOC/builds/yII0MQdDlv4mFHTKg/openapi.json
