# Get on Board Jobs Scraper — LATAM Tech Jobs with Salaries (`oswaldocarabano/getonbrd-jobs-scraper`) Actor

Scrape Get on Board (getonbrd.com), the LATAM tech job board: salary ranges in USD, remote eligibility by country, seniority, skill tags, perks, full job text and the hiring company. Or list companies hiring now. Official public API, no login. $0.45 per 1,000 jobs.

- **URL**: https://apify.com/oswaldocarabano/getonbrd-jobs-scraper.md
- **Developed by:** [Oswaldo Carabano](https://apify.com/oswaldocarabano) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 jobs

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?

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

## Get on Board Jobs Scraper — LATAM tech jobs with USD salaries

**Scrape [Get on Board](https://www.getonbrd.com) (getonbrd.com), the tech job
board of Latin America**, and get every open job as a clean row: the **salary
range in USD**, whether it is **remote** and which countries may apply,
seniority, skill tags, perks, the full job description and the hiring company.
Or get **one row per hiring company** with its open roles and salary range.

Built for **Latin America tech salary benchmarks**, **remote jobs in LATAM**,
recruiting and tech-hiring market research in Chile, Mexico, Colombia, Peru,
Argentina, Brazil and the rest of the region.

**No login. No cookies. No browser.** It reads Get on Board's own public API
(the getonbrd API), the same data anyone sees on the site.
**$0.45 per 1,000 jobs**, no start fee. Export to JSON, CSV or Excel.

***

### What you can use this for

| If you are… | You want |
|---|---|
| Benchmarking **tech salaries in Latin America** | USD monthly ranges on 41.2% of jobs, by seniority, category and country |
| A **recruiter or staffing agency** | companies hiring right now, their open roles, and how fast they reply |
| Building a **remote job board or newsletter** | remote jobs with the countries and regions allowed to apply |
| Tracking **skills demand** (React, Python, AWS…) | 100% of jobs carry skill tags — 7.7 per job on average |
| Doing **market research on LATAM tech hiring** | the whole board (about 1,000 open jobs) in one run, every day |

***

### What arrives in each job row

Every percentage below was measured on **23 Sep 2026 over the whole job board
(n = 934 open jobs, 18 categories)**, not a sample. **We do not promise a field
we have not measured.**

#### Always there — 100%

`job_id` · `url` · `title` · `company_name` · `company_country` ·
`company_website` · `company_logo` · `company_description` · `category_name` ·
`seniority` · `modality` (full time, part time, freelance, internship) ·
`remote` · `remote_modality` · `countries` · `published_at` ·
`applications_count` · `tags` · `description_text` / `description_html` ·
`projects_text` · `functions_text` (99.9%)

#### Usually there

| Field | Fill rate |
|---|---:|
| `company_benefits_html` | 98.5% |
| `description_headline` | 98.8% |
| `company_response_time_min_days` / `max` — how fast the company replies | 87.2% |
| `benefits_text` (job perks in the company's words) | 85.1% |
| `company_projects_html` | 84.8% |
| `company_long_description_text` | 80.4% |
| `desirable_text` (nice-to-have requirements) | 78.3% |
| `perks` / `perk_names` (health coverage, flexible hours…) | 56.3% |
| `cities` (office cities) | 55.2% |
| **`salary_min_usd_month` / `salary_max_usd_month`** | **41.2%** |
| `job_language` / `requires_english` | 39.0% |
| `eligible_countries` (who may apply to a remote job) | 22.2% — 49.5% of remote jobs |
| `moderation_flags` (Get on Board's own moderation notes) | 13.8% |
| `eligible_regions` | 9.7% |

**The salary depends on who posts.** 54.5% of jobs from non-Chilean companies
publish a range, 37.1% from Chilean ones, 52.4% of remote jobs. Filter with
`withSalaryOnly` or `minSalaryUsd`.

> **Salaries are USD gross per month.** Get on Board normalizes every salary to
> a monthly USD figure rounded to 100: a job posted as *USD 85,000 / year*
> arrives as *7,100 – 9,600*. We name the field accordingly
> (`salary_min_usd_month`) and also give the yearly figure (`salary_min_usd_year`).
> Want the salary exactly as posted? Turn on job-page details.

#### Job-page details (optional, `includeJobDetails`)

Reads each job's public page and adds what the API does not carry
(measured on 24 pages):

| Field | What it adds |
|---|---|
| `salary_original_min` / `max` / `period` / `currency` / `salary_text` | The salary exactly as posted — tells a yearly offer from a monthly one (14 of 14 salaried pages) |
| `remote_zone_text` | "candidates must reside in Colombia and Costa Rica" — **8 of 24 pages, vs 0 of 24 in the API** |
| `location_text`, `hybrid_offices_text` | "Santiago (Hybrid)" and the offices of a hybrid role |
| `reply_time_min_days` / `max` | "Replies between 13 and 29 days" |
| `last_checked_text` | When the company last reviewed applications (24 of 24) |
| `equity_offered`, `employment_type`, `date_posted` | Equity flag, schema.org employment type, ISO posting date |

#### Company rows (`outputType: companies`)

One row per company hiring in your scope (228 companies had open jobs on
23 Sep 2026): profile, website, logo, socials, reply time, plus
`open_jobs_count`, `open_job_titles`, `open_job_categories`, `remote_jobs_count`,
`jobs_with_salary_count`, the salary range across its jobs and its newest job
date. Or set `companySource: directory` for the full directory of about 17,000
company profiles.

***

### Input

| Field | Default | What it does |
|---|---|---|
| `outputType` | `jobs` | `jobs` or `companies` |
| `searchQueries` | *(empty)* | Full-text searches, e.g. `react`, `data engineer` |
| `categories` | *(empty)* | Any of the 18 Get on Board categories |
| `companies` | *(empty)* | Company slugs or URLs |
| `countryCode` | any | Jobs offered in a country, remote ones included |
| `remoteOnly`, `remoteModality` | off | Remote only, or pick fully remote / remote-in-zone / hybrid / on-site |
| `seniority`, `modality` | all | Level and employment type |
| `withSalaryOnly`, `minSalaryUsd` | off, 0 | Salary filters (USD per month) |
| `publishedWithinDays` | 0 | Only recent jobs |
| `maxResults` | 50 | Stop after this many rows |
| `includeJobDetails` | off | Add the job-page fields above |
| `language` | `en` | Language of category, country and perk names |

**How the inputs combine.** Jobs matching *any* query or *any* category are
returned once each. With nothing selected you get the **whole board**. With
companies and queries together, you get the matches from those companies.

Example — senior remote React jobs with a salary, with page details:

```json
{
  "searchQueries": ["react"],
  "remoteOnly": true,
  "seniority": ["senior", "expert"],
  "withSalaryOnly": true,
  "includeJobDetails": true,
  "maxResults": 200
}
```

***

### Pricing

Pay per event — you pay for rows delivered, never for errors:

| Event | Price |
|---|---:|
| Job delivered | $0.00045 |
| Company delivered | $0.0009 |
| Job-page details (per job, only when turned on and read) | $0.002 |
| Actor start | $0.00001 (platform minimum) |

1,000 jobs cost **$0.45**; with job-page details, **$2.45**. The whole board
(about 1,000 jobs) costs about half a dollar. Duplicates are never delivered twice within
a run, and error rows are free.

***

### Output example

```json
{
  "_type": "job",
  "job_id": "principal-engineer-cocoon-remote",
  "title": "Principal Engineer",
  "company_name": "Cocoon",
  "company_country": "US",
  "category_name": "Programming",
  "seniority": "Expert",
  "modality": "Full time",
  "remote": true,
  "remote_modality": "remote_local",
  "salary_min_usd_month": 7100,
  "salary_max_usd_month": 9600,
  "salary_min_usd_year": 85200,
  "job_language": "en",
  "tags": ["Java", "PostgreSQL", "CI/CD", "Spring Boot", "AWS"],
  "perk_names": ["Equity offered", "Paid sick days"],
  "applications_count": 78,
  "salary_original_min": 85000,
  "salary_original_max": 115000,
  "salary_original_period": "YEAR",
  "remote_zone_text": "Position is 100% remote, but candidates must reside in South America and Central America.",
  "equity_offered": true
}
```

***

### Reliability

- **Official public API**: Get on Board documents it for exactly this use. The
  private company API (applications, candidates) is never touched.
- **Polite by design**: Get on Board rate-limits bursts; the actor paces itself
  and, if asked to slow down, pauses every request together and says so in the
  status message.
- **Fast**: the whole board is about 20 API pages. The default run takes seconds.
- **Clear errors**: a bad input or a search with no matches ends green with an
  explanation row — never a silent empty dataset, never a charge.

### Data and privacy

Every row describes a job or a company. Get on Board jobs are always posted by a
company (0 of 934 without one), and the actor never reads applicant or candidate
data. For data removal requests, write to **privacy@actorstack.dev**.

# Actor input Schema

## `outputType` (type: `string`):

Jobs: every field of each posting plus its company. Companies: one row per company, with its open roles, salary range and categories aggregated from the jobs in scope.

## `companySource` (type: `string`):

Only used when Output type is Companies. 'Hiring now' respects your search and filters; 'directory' lists every company profile on Get on Board, without job aggregates.

## `searchQueries` (type: `array`):

Full-text searches, e.g. react, python, data engineer. Jobs matching ANY query or ANY selected category are returned, without duplicates. Leave empty and select no category to get the whole job board (934 open jobs on 23 Sep 2026).

## `categories` (type: `array`):

Get on Board categories. Combined with the search queries as an OR.

## `companies` (type: `array`):

Company slugs or Get on Board company URLs (e.g. globant or https://www.getonbrd.com/companies/globant). Alone: all open jobs of those companies. With search queries: only matches from those companies.

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

Jobs offered in this country, including remote jobs open to it. Applied by Get on Board to searches and categories (measured: Chile narrows 306 to 192 jobs).

## `remoteOnly` (type: `boolean`):

Only remote jobs (fully remote or remote within a zone).

## `remoteModality` (type: `array`):

Keep only these arrangements. Empty = all.

## `seniority` (type: `array`):

Keep only these levels. Empty = all.

## `modality` (type: `array`):

Keep only these employment types. Empty = all.

## `withSalaryOnly` (type: `boolean`):

41.2% of Get on Board jobs publish a salary range (54.5% of those posted by non-Chilean companies).

## `minSalaryUsd` (type: `integer`):

Keep jobs whose published salary reaches at least this monthly gross amount in USD. 0 = no filter. Jobs without a salary are dropped when this is set.

## `publishedWithinDays` (type: `integer`):

0 = any date.

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

Stop after this many rows (jobs or companies). The whole job board is about 1,000 jobs, so 1,000 gets everything.

## `includeJobDetails` (type: `boolean`):

Also read each job's public page: the salary exactly as posted with its period (month/year) and currency, where remote candidates must live, office locations, reply time, 'last checked', equity and employment type. One extra page per job, billed as a separate event.

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

Language of category, country and perk names. Job texts stay in the language the company wrote them in.

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

How many job pages to read at once when job-page details are on. 3 is fast and polite; Get on Board rate-limits bursts.

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

Optional. Get on Board answers without a proxy (measured). If requests start being refused, the actor retries through this proxy.

## Actor input object example

```json
{
  "outputType": "jobs",
  "companySource": "hiring",
  "searchQueries": [
    "react",
    "python"
  ],
  "categories": [],
  "companies": [],
  "countryCode": "",
  "remoteOnly": false,
  "remoteModality": [],
  "seniority": [],
  "modality": [],
  "withSalaryOnly": false,
  "minSalaryUsd": 0,
  "publishedWithinDays": 0,
  "maxResults": 40,
  "includeJobDetails": true,
  "language": "en",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per job (or per company with outputType = companies). Error rows, if any, are marked \_type = error and are never charged.

## `runSummary` (type: `string`):

What was delivered and charged, per-source match counts, network and timing figures.

## `errors` (type: `string`):

Every error of the run in one list (always written, empty when there were none).

# 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 = {
    "searchQueries": [
        "react",
        "python"
    ],
    "maxResults": 40,
    "includeJobDetails": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("oswaldocarabano/getonbrd-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 = {
    "searchQueries": [
        "react",
        "python",
    ],
    "maxResults": 40,
    "includeJobDetails": True,
}

# Run the Actor and wait for it to finish
run = client.actor("oswaldocarabano/getonbrd-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 '{
  "searchQueries": [
    "react",
    "python"
  ],
  "maxResults": 40,
  "includeJobDetails": true
}' |
apify call oswaldocarabano/getonbrd-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,oswaldocarabano/getonbrd-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/lQzYuPGAS0hkQXNVh/builds/6VZ24gEntrp2xaG5D/openapi.json
