# Jobicy Remote Job Listings Scraper (`vexaloom-labs/jobicy-remote-job-listings-scraper`) Actor

Search remote job listings from Jobicy by keyword, region, and seniority level. Returns job title, company, salary range, job type, category, and a direct application link for each role.

- **URL**: https://apify.com/vexaloom-labs/jobicy-remote-job-listings-scraper.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Jobs, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Jobicy Remote Jobs Scraper — Full 7-Day Feed & Filters

Jobicy publishes a rolling window of remote roles, and this actor reads the whole window rather than the first page. Search by keyword, location, industry, employment type, seniority, publication date or pay, and export complete job descriptions with structured salary, company and eligibility data. No login, API key or proxy is needed.

### What this actor does

- Reads the complete current Jobicy feed — every listing in the rolling 7-day window, not a fixed sample.
- Filters by keyword, 54 supported locations, 22 industries, job type, seniority, publication date and salary.
- Returns the full plain-text description, excerpt, industries, job types, seniority, location, country eligibility and company logo.
- Keeps structured salary values and adds annualised figures, so hourly, monthly and yearly ranges are easier to compare.
- Optionally fetches each job page for the exact expiry date, company website and applicant countries, and can check whether listings are still active.
- Omits empty fields rather than returning placeholders or invented data.

### Output per job

- `id` — Jobicy's numeric job ID
- `jobSlug` — Jobicy listing slug
- `title` — job title
- `company` — hiring company
- `companyLogo` — company logo URL
- `companyUrl` — company website (with `includeDetails`)
- `jobUrl` — canonical Jobicy listing URL
- `category` — industries joined with `; ` (legacy field)
- `industries[]` — industry labels
- `jobType` — employment types joined with `; ` (legacy field)
- `jobTypes[]` — employment type labels
- `jobLevel` — Jobicy's seniority value
- `location` — the job's remote eligibility text
- `countries[]` — countries parsed from the eligibility text
- `isWorldwide` — true when the role is open anywhere
- `excerpt` — short listing summary
- `description` — full plain-text job description
- `salaryMin`, `salaryMax` — published salary bounds
- `salaryCurrency`, `salaryPeriod` — pay currency and period
- `annualSalaryMin`, `annualSalaryMax` — annualised pay, when a period is published
- `publishedAt` — publication timestamp
- `ageDays` — days since publication
- `expiresAt` — listing expiry date (with `includeDetails`)
- `applicantCountries[]` — eligible applicant countries (with `includeDetails`)
- `listingStatus` — `active` when checked (with `onlyActive`)
- `statusCheckedAt` — when the status was checked
- `tags[]` — the listing's industries
- `recordType` — `job`
- `source` — `jobicy`
- `scrapedAt` — when the record was collected

### Output per status check

Mode `status` returns one record per requested job ID:

- `id` — Jobicy job ID
- `listingStatus` — `active`, `closed` or `unknown`
- `statusCheckedAt` — when Jobicy checked the listing
- `recordType` — `jobStatus`
- `source` — `jobicy`
- `scrapedAt` — when the record was collected

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` the live feed, fetch `byUrls`, or check `status` |
| `keyword` | string | – | Full-text Jobicy search, 3-50 characters |
| `geo` | string | – | Location or region slug; worldwide roles match every location. Legacy names such as `United States` are mapped; Jobicy lists Malaysia but its jobs API rejects that filter, so Malaysia is not offered. |
| `industry` | string | – | One Jobicy category |
| `jobType` | string | – | `Full-Time`, `Part-Time`, `Contract` or `Internship` |
| `jobLevel` | string | – | `Entry-Level`, `Junior`, `Midweight`, `Senior`, `Director` or `Internship`; legacy `Any` keeps listings labeled Any |
| `postedWithinDays` | integer | `0` | Keep jobs published in the last N days; 0 = no date limit |
| `salaryDisclosedOnly` | boolean | `false` | Keep only jobs with a published salary |
| `minAnnualSalaryUsd` | integer | `0` | Minimum annualised USD salary; other currencies are excluded |
| `excludeKeywords` | array | `[]` | Drop jobs whose title or company contains these terms |
| `onlyActive` | boolean | `false` | Keep only listings Jobicy reports as active |
| `includeDetails` | boolean | `false` | Add expiry, company website and applicant countries |
| `jobUrls` | array | `[]` | Jobicy URLs or numeric IDs (mode `byUrls` / `status`) |
| `maxItems` | integer | `50` | Maximum job listings to return (1-5,000) |

Mode-scoped fields are read only in their intended mode. The daily prefill uses `search` with `maxItems` 3.

#### Example: all current jobs

```json
{
  "mode": "search",
  "maxItems": 100
}
```

#### Example: senior Python roles open to applicants in the USA

```json
{
  "mode": "search",
  "keyword": "python",
  "geo": "usa",
  "jobLevel": "Senior",
  "jobType": "Full-Time",
  "maxItems": 50
}
```

#### Example: paid roles with detail data

```json
{
  "mode": "search",
  "industry": "engineering",
  "salaryDisclosedOnly": true,
  "minAnnualSalaryUsd": 120000,
  "includeDetails": true,
  "maxItems": 30
}
```

#### Example: fetch specific listings and check stored IDs

```json
{
  "mode": "byUrls",
  "jobUrls": [
    "https://jobicy.com/jobs/156858-senior-software-engineer-fundraising-remote",
    "156864"
  ],
  "maxItems": 10
}
```

```json
{
  "mode": "status",
  "jobUrls": ["156858", "156864", "147122"]
}
```

### Use cases

- **Recruiters** — build a daily shortlist of fresh remote roles by function, region and seniority.
- **Job boards and newsletters** — feed complete, structured listings into a site, digest or alerts.
- **Compensation research** — compare published salary ranges across industries and locations.
- **Talent-market analysis** — track remote hiring by category, type, level and country eligibility.
- **Job seekers** — export only roles that are open to their location and still active.

### FAQ

**Where does the data come from?**
Jobicy's public job feed and public job pages. No Jobicy account, login or API key is required. Each run reads Jobicy live; `publishedAt` and `ageDays` show freshness.

**Is this affiliated with Jobicy?**
No. This is an independent third-party actor that reads publicly available Jobicy listings.

**How many jobs can one run return?**
The complete current 7-day window, up to `maxItems` (maximum 5,000). The window usually contains roughly 1,000-1,500 roles; when it is exhausted, the run says so instead of returning invented data.

**Why is salary missing on some jobs?**
Only about half of current Jobicy listings publish structured pay. Missing salary fields are omitted, never estimated. A small number of source listings also contain unusual salary values; they are passed through unchanged for transparency.

**What is the difference between `location` and `countries`?**
`location` is Jobicy's own eligibility text. `countries[]` is the same text split into country names, and `isWorldwide` flags roles open anywhere.

**Why is Malaysia not in the location list?**
Jobicy's own location taxonomy lists Malaysia, but its jobs API rejects `geo=malaysia` with HTTP 400. The actor therefore offers the 54 usable locations. If a legacy task sends Malaysia, the filter is ignored with a clear status message instead of stopping the run.

**When should I enable `includeDetails`?**
Enable it when you need the exact expiry date, company website or applicant countries. It fetches each job page and can be slower; if a page is unavailable, the job is still returned with its feed fields and the optional fields are omitted.

**What does `onlyActive` do?**
It asks Jobicy for each listing's current status and keeps only `active` jobs. Use mode `status` when you want to check stored IDs without re-scraping the listings.

**Does the actor return the employer's own application link?**
No. Jobicy's public feed returns the Jobicy listing URL, and the employer application step is handled on Jobicy's site. The actor never substitutes an unrelated or invented apply URL.

**Can I fetch a job that is older than seven days?**
The search feed only covers the last seven days. If you already have a Jobicy job URL that is still live, mode `byUrls` can open it directly; mode `status` can check stored IDs outside the window.

# Actor input Schema

## `mode` (type: `string`):

Search the live Jobicy feed, fetch specific job URLs/IDs, or check stored job IDs. Leave blank for search.

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

Full-text search across Jobicy job content (3-50 characters). Leave blank to browse. Examples: python, marketing, product designer.

## `geo` (type: `string`):

Keep jobs open to this location or region. Jobicy treats worldwide roles as eligible for every location. Legacy display names such as United States or worldwide are mapped in code. Jobicy lists Malaysia in its taxonomy but its jobs API rejects that slug, so Malaysia is not offered.

## `industry` (type: `string`):

Keep jobs in one Jobicy category. Leave blank for all categories.

## `jobType` (type: `string`):

Keep one employment type. Leave blank for all types.

## `jobLevel` (type: `string`):

Keep one seniority level. Leave blank for all levels. Legacy Any is accepted and keeps listings Jobicy labels Any.

## `postedWithinDays` (type: `integer`):

Keep jobs published in the last N days. 0 means no date limit. Jobicy exposes the last 7 days.

## `salaryDisclosedOnly` (type: `boolean`):

Keep only listings where Jobicy publishes a salary range.

## `minAnnualSalaryUsd` (type: `integer`):

Keep USD listings whose annualised maximum salary meets this figure. Hourly pay is annualised at 2,080 hours; monthly pay at 12 months. 0 disables this filter.

## `excludeKeywords` (type: `array`):

Drop jobs whose title or company contains any of these terms (case-insensitive).

## `onlyActive` (type: `boolean`):

Check each listing's current status with Jobicy and keep only active jobs.

## `includeDetails` (type: `boolean`):

Fetch each job page for its exact expiry date, company website and applicant countries. Adds requests; unavailable pages are skipped.

## `jobUrls` (type: `array`):

Jobicy job URLs or numeric job IDs. Used only with mode byUrls or status.

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

Maximum job listings to return (1-5,000). Jobicy's live window usually contains about 1,000-1,500 jobs.

## Actor input object example

```json
{
  "mode": "search",
  "keyword": "",
  "geo": "",
  "industry": "",
  "jobType": "",
  "jobLevel": "",
  "postedWithinDays": 0,
  "salaryDisclosedOnly": false,
  "minAnnualSalaryUsd": 0,
  "excludeKeywords": [],
  "onlyActive": false,
  "includeDetails": false,
  "jobUrls": [],
  "maxItems": 3
}
```

# Actor output Schema

## `remoteJobs` (type: `string`):

Dataset containing the scraped Jobicy remote-job and listing-status records.

# 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 = {
    "mode": "search",
    "keyword": "",
    "maxItems": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/jobicy-remote-job-listings-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 = {
    "mode": "search",
    "keyword": "",
    "maxItems": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/jobicy-remote-job-listings-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 '{
  "mode": "search",
  "keyword": "",
  "maxItems": 3
}' |
apify call vexaloom-labs/jobicy-remote-job-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/jobicy-remote-job-listings-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/egBcBsVnU7LdO9mTp/builds/jVhcKYfKlFmoj7cg0/openapi.json
