# jsfirm Aviation Jobs & Employers Scraper: Pilot & Engineer Jobs (`getascraper/jsfirm-aviation-jobs-scraper`) Actor

Scrape aviation job listings and the employer directory from jsfirm.com as JSON. Filter flight ops, maintenance and engineering, and ground roles by location, employer, and posting window. Employer profiles add website, address, job count, and aircraft models. $1.20 per 1,000 records.

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

## Pricing

from $0.90 / 1,000 aviation records

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

## ✈️ jsfirm Aviation Jobs & Employers Scraper: Pilot & Engineer Jobs

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;margin-bottom:0">
<tr>
<td style="padding:24px 28px;background:#EAF3FB;border:1px solid #C3DCF0;border-top:4px solid #14508C;color:#1C1917;border-radius:10px 10px 0 0">
<span style="font-size:23px;font-weight:800;color:#1C1917;line-height:1.3">Aviation job listings and employer profiles, as clean structured data.</span><br>
<span style="font-size:15px;color:#57534E;line-height:1.6">Pull pilot, maintenance and engineering, flight operations, and ground roles from jsfirm.com with filters for category, employment type, location, and posting date. Or pull the employer directory with each company's website, address, and aircraft models.</span>
</td>
</tr>
</table>
<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;margin-top:0">
<tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C3DCF0;vertical-align:top;border-top:none;color:#1C1917;border-radius:0 0 0 10px">
<span style="font-size:15px;font-weight:800;color:#0D3A66">🎯 Filter what matters</span><br>
<span style="font-size:12px;color:#57534E">Narrow by job category, permanent or contract, location, employer, and posting window of 7, 30, or 90 days.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C3DCF0;border-left:none;vertical-align:top;border-top:none;color:#1C1917">
<span style="font-size:15px;font-weight:800;color:#0D3A66">🏢 Employer directory</span><br>
<span style="font-size:12px;color:#57534E">Get each company's website, address, active job count, and the aircraft models it supports.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C3DCF0;border-left:none;vertical-align:top;border-top:none;color:#1C1917">
<span style="font-size:15px;font-weight:800;color:#0D3A66">📝 Full descriptions on request</span><br>
<span style="font-size:12px;color:#57534E">Turn on full job descriptions when a short snippet is not enough to judge a role.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #C3DCF0;border-left:none;vertical-align:top;border-top:none;color:#1C1917;border-radius:0 0 10px 0">
<span style="font-size:15px;font-weight:800;color:#0D3A66">🏷️ Paid placements marked</span><br>
<span style="font-size:12px;color:#57534E">Every listing shows whether the employer paid for enhanced placement, so you can separate promoted roles from the rest.</span>
</td>
</tr>
</table>

Aviation hiring is spread across specialist boards, airline career pages, and recruiters. This Actor reads the job and employer listings on jsfirm.com and returns one clean record per job or per employer, ready for a spreadsheet, a CRM, or your own pipeline.

### 🙋 Who uses it

**"I source pilots and engineers for airline and operator clients. I want the pilot and engineering postings from the last 7 days."**
Recruiters and staffing agencies run it on a schedule and filter by category, employment type, and posting window.

**"I want to know which operators are hiring, where they are based, and what aircraft they fly."**
Airline, MRO, and charter sales teams use the employer directory to build target lists with addresses, websites, and supported aircraft models.

**"I am building a job alert tool for aviation careers."**
Career sites and job seekers feed the output into their own alerts, filtered by category and keyword.

### 🔍 What does it do?

The Actor works in one of two modes, chosen with the `dataType` input.

- **Job listings:** returns one record per job. Each record has the title, employer, location, employment type, posting date, salary when the employer lists it, an apply link, and a short description. Turn on full descriptions for the complete text.
- **Employer directory:** returns one record per company. Turn on employer profiles for the website, address, active job count, description, and aircraft models.

Keyword and location work in both modes. The other filters apply to job listings only.

### 🚀 How to use it

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0">
<tr>
<td style="padding:16px 14px;width:33%;background:#EAF3FB;border:1px solid #C3DCF0;border-radius:10px 0 0 10px;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#14508C;letter-spacing:1px">STEP 1</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Choose what to collect</span><br>
<span style="font-size:12px;color:#57534E">Pick job listings or the employer directory, then add a keyword, location, or the job filters you need.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EAF3FB;border:1px solid #C3DCF0;border-left:none;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#14508C;letter-spacing:1px">STEP 2</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Run it</span><br>
<span style="font-size:12px;color:#57534E">The default run saves 20 records. Raise Max items for larger pulls.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EAF3FB;border:1px solid #C3DCF0;border-left:none;border-radius:0 10px 10px 0;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#14508C;letter-spacing:1px">STEP 3</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Export the dataset</span><br>
<span style="font-size:12px;color:#57534E">Download as JSON, CSV, or Excel, or send the results to your own tools.</span>
</td>
</tr>
</table>

### 📥 Input

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `dataType` | enum | No | `jobs` returns job listings. `employers` returns the employer directory. Default: `jobs`. |
| `keyword` | string | No | Free-text search, matched the same way as the site's search box. Works in both modes. |
| `location` | string | No | A city, state, or region, such as "Texas" or "Dallas". Works in both modes. |
| `company` | string | No | Limit job listings to one employer by name. Jobs only. |
| `category` | enum | No | One of the site's job categories: Business Operations, Flight Operations, Ground & Logistics, Learning & Development, or Maintenance & Engineering. Jobs only. |
| `employmentType` | enum | No | `all`, `permanent`, or `contractor`. Jobs only. Default: `all`. |
| `postedWithin` | enum | No | Any time, or only jobs posted in the last 7, 30, or 90 days. Jobs only. |
| `excludeKeyword` | string | No | Drop job listings that contain this word or phrase. Jobs only. |
| `maxItems` | integer | No | Maximum records to save in one run. Default: 20. Maximum: 5000. |
| `sort` | enum | No | Newest posted first, recently updated first, oldest posted first, or title A to Z. Jobs only. Default: newest posted first. |
| `includeDescription` | boolean | No | Fetch the full job description for each listing. Adds one request per job. Jobs only. Default: `false`. |
| `includeProfile` | boolean | No | Fetch each employer's profile. Adds one request per employer. Employers only. Default: `false`. |
| `proxyConfiguration` | object | No | Proxy settings. The default Apify proxy works for most runs. |

### 🧾 Data table

| Field | Type | Description |
| --- | --- | --- |
| `jobId` | integer | The site's job ID. |
| `jobTitle` | string | Job title as posted. |
| `companyName` | string | Employer name. |
| `companyId` | integer | The site's employer ID. |
| `location` | string | Location as shown on the listing. |
| `latitude`, `longitude` | number | Map coordinates when the listing has them. |
| `positionType` | string | The site's position type, such as a pilot or engineering category. |
| `employmentType` | string | `permanent` or `contractor`. |
| `salaryRange` | string | Salary text, only when the employer lists one. |
| `postedAt` | string | Posting date and time (ISO 8601). |
| `isNew` | boolean | Whether the site marks the listing as new. |
| `applicationMethod` | string | How to apply, such as external or on the site. |
| `applyUrl` | string | The employer's own application link, when the listing has one. |
| `companyLogoUrl` | string | Employer logo image. |
| `descriptionSnippet` | string | Short preview of the job description. |
| `description` | string | Full job description as plain text. Only with full descriptions turned on. |
| `isEnhanced`, `isSuperEnhanced` | boolean | Whether the employer paid for enhanced placement. |
| `displayTags` | array | Labels the site shows on the listing. |
| `city`, `state`, `country` | string | Employer location (employer mode). |
| `hasActiveJob` | boolean | Whether the employer has at least one active job (employer mode). |
| `websiteUrl` | string | Employer website (employer mode with profiles). |
| `activeJobCount` | integer | Active job count on the employer's profile (employer mode with profiles). |
| `addressLine` | string | Employer street address (employer mode with profiles). |
| `supportedAircraftModels` | array | Aircraft models the employer lists as supported (employer mode with profiles). |
| `supportedManufacturers` | array | Aircraft manufacturers the employer lists (employer mode with profiles). |
| `scrapedAt` | string | When the record was collected (ISO 8601). |

Fields the site does not return for a record are left out of that record. Nothing is filled with placeholder text.

### 💰 Pricing

The free plan runs are limited to 25 records per run, 3 runs per day, and a 30-minute wait between runs. Paid plans have no such limits. Pricing details appear on the Actor's Store page.

### ⭐ Enjoying jsfirm Aviation Jobs & Employers Scraper?

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0">
<tr>
<td style="padding:20px 24px 14px;background:#EAF3FB;border:1px solid #C3DCF0;border-left:5px solid #14508C;border-radius:10px 10px 0 0;color:#1C1917">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">If this saved you from checking job boards by hand, say so.</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps other recruiters and job seekers find it. Your feedback also tells us what to build next.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#14508C;border:1px solid #14508C;border-left:5px solid #14508C;border-top:none;border-radius:0 0 10px 10px;text-align:center;color:#FFFFFF">
<a href="https://apify.com/getascraper/jsfirm-aviation-jobs-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### 🔐 Data source and robots.txt

This Actor reads job and employer data that jsfirm.com publishes for anyone to view in its public job search. Please read this section before you run it.

- The site's `robots.txt` file disallows its API path for all user agents. This Actor reads that path anyway. The operator reviewed this conflict and chose to proceed knowingly.
- The Actor is anonymous. It uses no login, no account, no cookies, and no API keys. It does not access any page that requires a sign-in.
- You are responsible for how you use the data, including the site's terms of use and applicable data protection law. Use the data for lawful purposes and keep request volume modest.
- This Actor is independent. Its author is not affiliated with jsfirm.com, and the site has not endorsed it.

### ❓ FAQ

**Does the Actor need a jsfirm account?**
No. It reads the public job and employer data without signing in, and it never asks for your login.

**Why are some fields empty?**
The site does not return every field for every listing or employer. Those fields are left out of the record rather than filled with placeholder text.

**Can I run it on a schedule to catch new jobs?**
Yes. Use the posted-within filter with a 7-day window so each scheduled run returns recent postings.

**What is the difference between a job listing and an employer record?**
A job record describes one open role. An employer record describes one company, with its profile when you turn on employer profiles.

### 💡 Tips

- Use the keyword and location filters together for a precise pull, such as "Captain" in "Texas".
- Turn on full descriptions only when you need them. Each one adds a request per job, so runs take longer.
- Run the employer directory with profiles once a month to keep your company list current.

### 🔗 Other actors

- [Aviation Job Search Scraper: Pilot, Crew & Engineer Jobs UK/US](https://apify.com/getascraper/aviation-job-search-scraper) ↗ - Structured aviation job listings from AviationJobSearch.com's UK and US boards.
- [Workday jobs scraper](https://apify.com/getascraper/workday-tenant-jobs-monitor) ↗ - Job listings from Workday-hosted career sites, for monitoring new postings.
- [Lever jobs scraper](https://apify.com/getascraper/lever-jobs-monitor) ↗ - Job listings from Lever-hosted career sites.
- [Ashby Jobs Scraper: Hiring Change Monitor](https://apify.com/getascraper/ashby-jobs-monitor) ↗ - Job listings from Ashby career pages.

# Changelog

This Actor's version history is a separate document: https://apify.com/getascraper/jsfirm-aviation-jobs-scraper/changelog.md

# Actor input Schema

## `dataType` (type: `string`):

Job listings returns one record per open role. Employer directory returns one record per company, optionally with its profile details.

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

Free-text search, matched the same way as the site's own search box. Try a role such as 'Captain' or 'A\&P mechanic', or a company name. Leave empty to include everything.

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

A city, state, or region, such as 'Texas' or 'Dallas'. Matched the same way as the site's location search. Leave empty for all locations.

## `company` (type: `string`):

Limit job listings to one employer by name, such as 'Air Methods'. Ignored in employer mode.

## `category` (type: `string`):

Limit job listings to one of the site's job categories. Leave on 'Any category' to include all of them. Ignored in employer mode.

## `employmentType` (type: `string`):

Permanent or contract roles only, or both. Ignored in employer mode.

## `postedWithin` (type: `string`):

Keep only jobs posted within this many days. Leave on 'Any time' to include older postings. Ignored in employer mode.

## `excludeKeyword` (type: `string`):

Drop job listings that contain this word or phrase, such as 'helicopter' to skip rotor-wing roles. Ignored in employer mode.

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

Maximum number of records to save in one run. The default of 20 keeps a first run quick. Raise it for larger pulls; large values take proportionally longer.

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

Order in which job listings are returned. Newest postings first is the most useful for monitoring. Ignored in employer mode.

## `includeDescription` (type: `boolean`):

Fetch the complete job description for each listing. This adds one request per job and makes the run slower. Off by default; without it, only a short snippet is saved.

## `includeProfile` (type: `boolean`):

Fetch each employer's profile: website, address, active job count, description, and aircraft models they support. This adds one request per employer. Off by default. Ignored in job mode.

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

Proxy used for every request. The default Apify proxy is recommended. Switch to residential proxies only if runs fail with blocked or non-JSON responses.

## Actor input object example

```json
{
  "dataType": "jobs",
  "category": "",
  "employmentType": "all",
  "postedWithin": "",
  "maxItems": 20,
  "sort": "posted_desc",
  "includeDescription": false,
  "includeProfile": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "dataType": "jobs",
    "category": "",
    "employmentType": "all",
    "postedWithin": "",
    "maxItems": 20,
    "sort": "posted_desc",
    "includeDescription": false,
    "includeProfile": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/jsfirm-aviation-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 = {
    "dataType": "jobs",
    "category": "",
    "employmentType": "all",
    "postedWithin": "",
    "maxItems": 20,
    "sort": "posted_desc",
    "includeDescription": False,
    "includeProfile": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/jsfirm-aviation-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 '{
  "dataType": "jobs",
  "category": "",
  "employmentType": "all",
  "postedWithin": "",
  "maxItems": 20,
  "sort": "posted_desc",
  "includeDescription": false,
  "includeProfile": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call getascraper/jsfirm-aviation-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/jsfirm-aviation-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/1bSK5PJNVfAEoVxDz/builds/1KpbtrcgL6Q2Qr9Ao/openapi.json
