# Catho Job Scraper: Brazilian Job Listings with Salary (`bogdiehard/catho-job-scraper`) Actor

Extracts Brazilian job listings from catho.com.br by keyword: title, company, salary in reais, city, positions, posting date and sponsored flag. Public data only.

- **URL**: https://apify.com/bogdiehard/catho-job-scraper.md
- **Developed by:** [Demetrius Greses Jr](https://apify.com/bogdiehard) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Catho Job Scraper: Brazilian Job Listings with Salary

Extracts Brazilian job listings from catho.com.br by keyword, with title, company, salary in reais, city, open positions, posting date and sponsored flag, for recruiters, job aggregators and labor-market analysts in Brazil.

### Use cases

- **Recruiters and staffing agencies** track the open roles for a keyword across Brazil and see which listings are sponsored or have an active recruiter.
- **Job aggregators and HR-tech teams** load listings with company, city and salary into their own search or job alerts.
- **Labor-market analysts** count open positions per keyword and measure how salaries are offered, as a number or as "A Combinar" (to be agreed), week to week.
- **Career researchers** compare posting dates, city spread and the share of confidential postings across job families.

### Sample output

Three rows from a real run (keyword `desenvolvedor`, default settings):

| id | title | company | city | salaryText | postedAt |
| --- | --- | --- | --- | --- | --- |
| 38717766 | Desenvolvedor | Tecla T | Fortaleza | R$ 10.000 | 2026-10-06T03:00:00.000Z |
| 38604820 | Desenvolvedor(a) | QUALY RH | Limeira | R$ 8.000 | 2026-10-01T03:00:00.000Z |
| 38566483 | Desenvolvedor | HIGHENG | Rio de Janeiro | A partir de R$ 4.000,00 | 2026-09-25T03:00:00.000Z |

One item as JSON from a run with `fetchDetails` on (the description is shortened with "…"):

```json
{
    "id": "38717766",
    "title": "Desenvolvedor",
    "company": "Tecla T",
    "confidentialCompany": false,
    "city": "Fortaleza",
    "state": "CE",
    "postalCode": "60160-196",
    "positions": 1,
    "extraCities": 0,
    "salary": 10000,
    "salaryText": "R$ 10.000",
    "salaryMin": 9001,
    "salaryMax": 10000,
    "benefitsCount": null,
    "employmentType": "Prestador de serviços (PJ)",
    "postedAt": "2026-10-06T03:00:00.000Z",
    "postedText": "Publicada em 06/10",
    "updated": false,
    "sponsored": false,
    "activeRecruiter": false,
    "description": "Uma empresa especializada em joias em ouro 18k, reconhecida pela qualidade, sofisticação e excelência no atendimento. Atuando no mercado de Fortaleza, a marca s …",
    "jobUrl": "https://www.catho.com.br/vagas/desenvolvedor/38717766",
    "sourceUrl": "https://www.catho.com.br/vagas/desenvolvedor/38717766",
    "scrapedAt": "2026-10-13T00:05:41.795Z"
}
```

With the default settings (`fetchDetails` off), `description`, `employmentType`, `state`, `postalCode`, `salaryMin` and `salaryMax` are null. Salary is in Brazilian reais (BRL).

### Pricing

**$2.50 per 1,000 results.** A 500-result run costs about $1.25. You pay only for results saved to your dataset, plus Apify's standard start fee of $0.00005 per run. Apify Silver and Gold plan users get lower per-result prices automatically.

Set **Max results** to cap what a run can cost. The Actor stops cleanly when it reaches your spending limit.

### Input

See the input tab for full configuration options.

| Field | Type | Description |
| --- | --- | --- |
| `queries` | array | Job keywords, one per entry, for example `desenvolvedor` or `analista de dados`. Each keyword is read as a catho.com.br keyword listing page: accents are removed and spaces become hyphens. |
| `startUrls` | array | Keyword listing pages on catho.com.br, for example `https://www.catho.com.br/vagas/desenvolvedor/`. Search pages (`/buscar/vagas/` or any `q=` query), job pages and other sites are ignored. |
| `maxPagesPerQuery` | integer | Result pages to read for each keyword, 20 jobs per page. From 1 to 42, default 5. The Actor also stops early when the site has no new jobs for a keyword. |
| `fetchDetails` | boolean | Also open each job page to add the description, employment type, posting day, salary range, state and postal code. Off by default; one extra request per job. If a job page still refuses the request after several tries, the job is returned with its listing fields only, so no job is lost. |
| `maxItems` | integer | Maximum number of results to return. Default 100, maximum 50,000. You are charged per result. |
| `proxyConfiguration` | object | Apify datacenter proxy by default. |

Example input, two keywords:

```json
{
    "queries": ["desenvolvedor", "python"],
    "maxPagesPerQuery": 42,
    "maxItems": 1000
}
```

Example input, with job pages:

```json
{
    "queries": ["analista de dados"],
    "fetchDetails": true,
    "maxItems": 100
}
```

### Integrations

- **API:** run the Actor and fetch results with the [Apify API](https://docs.apify.com/api/v2) or the JavaScript and Python clients.
- **AI agents:** call it as a tool through the [Apify MCP server](https://mcp.apify.com).
- **No-code:** connect it to Make, Zapier or n8n, or export results straight to Google Sheets.
- **Scheduling:** run it daily or hourly with Apify Schedules and get fresh listings on each run.

### FAQ

**What are the limits?** The site lists a limited number of jobs per keyword, and the Actor reads until the listing runs out. The results counter can show more than the listing reaches: `desenvolvedor` runs to page 42 with one job on it, about 820 job cards in all, and `python` ended on page 31 with about 570 distinct jobs. For more coverage, add more specific keywords. There is no location filter in this version: the site's city URL form returned no job cards in testing, so the Actor reads keyword searches only. Sponsored jobs repeat on several pages and are returned once. Listings show the day without a year or a time: the year is the most recent past one and `postedAt` is midnight in America/Sao_Paulo. About 60% of listings show "A Combinar" (salary to be agreed), so `salary` is null for them; read `salaryText` for the wording. Requests run two at a time, at most 40 a minute.

**Is this legal?** The Actor collects public listing data only, with no login. It does not request the search pages that robots.txt disallows (`/buscar/vagas/` and any URL with a `q=` or `utm_source=` query). It crawls at a polite rate and retires its session and backs off on 401, 403 and 429 responses. It is not affiliated with, endorsed by or connected to Catho. You are responsible for how you use the data.

**What is never collected?** Recruiter names: the listing shows only a badge for an active recruiter. The company of a confidential posting: the card shows "Empresa Confidencial", the field stays null, and the job page's company name is not read. Street addresses from job pages are not output. E-mail addresses, phone numbers, web links and social handles in job descriptions are replaced by `[email]`, `[phone]`, `[link]` and `[handle]`. Company names are kept as published on the listing. Descriptions are company text and can mention people by name, so review them before you reuse them.

**Something broke or a field is missing?** Open an issue on the Actor's Issues tab. We answer within one business day and usually ship a fix within 48 hours.

### Related Actors

- [Jobware DE Job Scraper](https://apify.com/bogdiehard/jobware-de-job-scraper) — German job listings from jobware.de, with the same kind of job fields.
- [Personio Jobs Scraper](https://apify.com/bogdiehard/personio-jobs-scraper) — job postings from companies that publish on Personio career pages.

### Changelog

- **0.1** (2026-10-12) — First release: keyword listing pages, salary and positions parsing, sponsored and recruiter flags, optional job-page enrichment.

# Actor input Schema

## `queries` (type: `array`):

Job keywords, one per entry, for example desenvolvedor or analista de dados. Each keyword is read as https://www.catho.com.br/vagas/<keyword>/ (accents removed, spaces become hyphens). The site lists at most 42 pages, about 820 jobs, per keyword.

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

Keyword listing pages on catho.com.br, for example https://www.catho.com.br/vagas/desenvolvedor/. Search pages (/buscar/vagas/ or any q= query), job pages and other sites are ignored.

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

Result pages to read for each keyword, 20 jobs per page. The site lists at most 42 pages per keyword.

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

Also open each job page to add the full description, employment type, posting day, salary range, state and postal code. One extra request per job, so the run is slower.

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

Maximum number of results to return. You are charged per result.

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

Apify datacenter proxy is used by default.

## Actor input object example

```json
{
  "queries": [
    "desenvolvedor"
  ],
  "maxPagesPerQuery": 5,
  "fetchDetails": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `stats` (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 = {
    "queries": [
        "desenvolvedor"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bogdiehard/catho-job-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 = {
    "queries": ["desenvolvedor"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("bogdiehard/catho-job-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 '{
  "queries": [
    "desenvolvedor"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call bogdiehard/catho-job-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bogdiehard/catho-job-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/au92c5w2CAcl1IyqP/builds/di6qwzfahjVOyYFiS/openapi.json
