# Remote Jobs Aggregator: Jobicy & We Work Remotely (`openfeeds/remote-jobs-feed-aggregator`) Actor

Remote jobs from Jobicy and We Work Remotely in one deduplicated feed with salary ranges, location eligibility, seniority and categories. New-jobs monitor mode, pay only per job returned.

- **URL**: https://apify.com/openfeeds/remote-jobs-feed-aggregator.md
- **Developed by:** [OpenFeeds](https://apify.com/openfeeds) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 job returneds

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

### What does Remote Jobs Aggregator do?

Remote Jobs Aggregator reads the public **remote jobs** feeds of [Jobicy](https://jobicy.com/) (its public Jobs API) and [We Work Remotely](https://weworkremotely.com/) (its public RSS feeds) and returns **one clean, deduplicated feed**: one row per remote job, with the **salary range**, **location eligibility** (countries, regions, worldwide), category, employment type, seniority, ISO dates, the canonical listing URL and a ready-made credit line.

Use it as a **remote jobs API** for your own job board, newsletter or bot, or switch on the **new-jobs monitor** to get only the jobs you have not seen yet. You pay only per remote job returned.

It has no person fields: emails, phone numbers and personal profile links in job texts are removed (best effort), and it only reads public, machine-readable feeds under their published terms.

### Why use Remote Jobs Aggregator?

- 📰 **Job boards and newsletters:** fill a niche remote job board or a weekly newsletter with fresh remote jobs that already carry the board credit.
- 🤖 **Slack/Discord bots and AI agents:** clean JSON with flat fields, ready for an LLM tool or a chat bot posting new remote jobs every hour.
- 📊 **Research:** track remote demand by category, salary range and region.

What you get compared with copying the feeds yourself:

- **Deduplicated:** a job listed on both boards becomes one row (charged once), with the other listing in `alsoFoundOn`.
- **Normalized:** the same categories, employment types, seniority levels and location fields for both boards.
- **Salary ranges:** structured on Jobicy, parsed from the description on We Work Remotely (`salarySource` tells you which).
- **Location eligibility you can filter:** ISO country codes, regions (EUROPE, EMEA, NORTH_AMERICA, LATAM, AMERICAS, APAC) and `isWorldwide`.
- **Terms-respecting:** two sources whose terms allow reuse with attribution; every row carries `attribution`, `sourceName`, `sourceUrl` and the canonical `url`.
- **Reliable:** each board runs on its own, so if one fails the other still delivers; a recent cache is served if a board is down.
- **Fair on the free plan:** full rows, no truncation.
- **Hourly-safe:** re-runs within 60 minutes are re-served from your last pass and not charged again.

As an Apify Actor it also gets scheduling, the API, webhooks and integrations (Make, Zapier, Google Sheets and more) for free.

### What data can you get?

| Field | Example | What it means |
|---|---|---|
| `title`, `companyName` | Art Director, Brand Social · Upstart | Job title and hiring company |
| `url` / `applyUrl` | `https://jobicy.com/jobs/154937-…` | Canonical listing on the board; send applicants here |
| `attribution` | Job via Jobicy | Credit line to show next to the job |
| `source`, `sourceName`, `sourceUrl` | jobicy · Jobicy · `https://jobicy.com/` | The board the row comes from |
| `category` | design | Normalized category (17 values, same for both boards) |
| `employmentType` | FULL_TIME | FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERNSHIP, OTHER |
| `seniority` | DIRECTOR | ENTRY, MID, SENIOR, DIRECTOR (Jobicy level, or title words on We Work Remotely) |
| `countryCodes`, `regions` | \["CA","US"] · \[] | Location eligibility (ISO 3166-1 alpha-2, regions) |
| `isWorldwide` | false | true = open worldwide, false = restricted, null = unknown |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | 138600 · 192000 · USD · YEAR | Salary range |
| `publishedAt`, `expiresAt` | 2026-10-09T17:58:40Z | ISO 8601 dates (UTC) |
| `descriptionMarkdown` / `descriptionHtml` | … | Full description; emails, phone numbers and personal profile links removed |
| `alsoFoundOn` | \[{ "source": "weworkremotely", … }] | The same job on the other board |
| `firstSeenAt` | 2026-10-13T06:00:09Z | New-jobs monitor: when the job was first returned |

**About "Anywhere" on We Work Remotely:** almost every We Work Remotely listing says "Anywhere in the World", even when the text names countries or a US state. That is the board's default, not a promise, so those jobs get `isWorldwide: null` (unknown) and their countries, if any, in `countryCodes`. With a country or region filter, the **Keep jobs without reliable location** option decides whether such jobs stay in. Jobicy's "Anywhere" is a real worldwide flag (`isWorldwide: true`).

### How to get remote jobs from Jobicy and We Work Remotely

1. Open the Actor and choose the **job boards** (both are selected by default).
2. Optionally add **filters**: keywords, categories, employment types, seniority, candidate countries or regions, salary minimum, posting age. Keywords match **whole words** (`ai` finds "AI Engineer", not "Chainguard"; a plural s also matches); end a keyword with `*` to match word beginnings (`develop*` finds developer and development).
3. Set **Max jobs** (newest first). A full pull is about 1,100 remote jobs.
4. Click **Start**. A run takes about 15–25 seconds.
5. Download the dataset as JSON, CSV, Excel or HTML, call it from the API, or **schedule** the Actor (hourly or slower) with **Only new jobs** switched on.

### How much does it cost to get remote jobs?

Pay per event: you pay only for remote jobs returned after your filters.

| Apify plan | Price per job | Per 1,000 jobs |
|---|---|---|
| Free | $0.0010 | $1.00 |
| Bronze | $0.0009 | $0.90 |
| Silver | $0.00075 | $0.75 |
| Gold and higher | $0.0006 | $0.60 |

Plus a tiny start fee of $0.00005 per run.

- A 50-job test costs about **$0.05**; a full pull of about 1,100 jobs about **$1.10** on the free plan.
- **Monitor runs charge only new jobs.**
- **Re-runs within 60 minutes are free** for jobs you were already charged for: a job charged in the last 60 minutes is not charged again, whether it comes from your last pass (`servedFromCache: true`) or from another feed that lists the same job.
- Never charged: jobs removed by your filters, jobs skipped by the monitor, duplicates, expired listings, failed or skipped boards, and empty runs.
- Your spending limit is respected: the run stops cleanly with "Stopped at your spending limit after N jobs".

### Scheduling and the new-jobs monitor

**Schedule hourly or slower.** Jobicy asks for at most one new pass per hour, and We Work Remotely's feeds refresh hourly (`ttl` 60), so faster schedules add nothing:

- **60-minute pass cache:** the first run in an hour fetches both boards and keeps the result in a key-value store in your account (`remote-jobs-feed-aggregator-cache`). Runs in the next 60 minutes re-serve that pass: no requests, no repeat charges.
- **Jobicy options** (`jobicyGeo`, `jobicyIndustry`, `jobicyTag`) define the Jobicy pass. If you change them within the hour, Jobicy is skipped until the next hour (`SKIPPED_COOLDOWN` in the run summary) and We Work Remotely still runs. For most uses, leave them empty and use the general filters, which work on both boards and never trigger the cooldown.
- **Only new jobs (`onlyNew`):** returns only jobs that earlier runs with the same **State store name** have not returned. The **first run returns every current match** up to Max jobs; later runs return only new ones. A job that moves to the other board does not alert again. Use **one state store name per monitor** (for example one per saved search).

### Crediting the sources (required)

Both boards allow reuse of their listings **with attribution**:

- Show the `attribution` text (for example "Job via Jobicy") next to each job and link it to `url`.
- Keep the canonical listing URL unchanged and send applicants to `applyUrl` (the board's listing page).
- Never present the jobs as your own listings.

### Input

See the **Input** tab for all options. Example: senior Python or data jobs open to candidates in Germany, with a salary, as a monitor:

```json
{
    "sources": ["jobicy", "weworkremotely"],
    "maxItems": 200,
    "keywords": ["python", "data engineer"],
    "seniority": ["SENIOR"],
    "countries": ["DE"],
    "includeUnknownLocation": false,
    "requireSalary": true,
    "onlyNew": true,
    "stateStoreName": "senior-python-de",
    "descriptionFormat": "markdown"
}
```

### Output

You can download the dataset in various formats such as JSON, HTML, CSV or Excel. The **Overview** view shows title, company, category, location, worldwide flag, employment type, salary range, publication date, link and credit. Two real rows from a local run on 13 October 2026 (an hourly re-run, so `servedFromCache` is true; excerpts and descriptions shortened):

```json
[
    {
        "uniqueId": "jobicy:154937",
        "source": "jobicy",
        "sourceName": "Jobicy",
        "sourceJobId": "154937",
        "attribution": "Job via Jobicy",
        "sourceUrl": "https://jobicy.com/",
        "feedUrl": "https://jobicy.com/api/v2/remote-jobs?count=200",
        "title": "Art Director, Brand Social",
        "companyName": "Upstart",
        "companyLogoUrl": "https://jobicy.com/data/server-nyc0409/galaxy/mercury/2025/06/bc2cfa2b-221-1.jpeg",
        "companyWebsite": null,
        "companyHeadquarters": "United States | Remote",
        "url": "https://jobicy.com/jobs/154937-art-director-brand-social",
        "applyUrl": "https://jobicy.com/jobs/154937-art-director-brand-social",
        "category": "design",
        "categoriesRaw": ["Creative & Design"],
        "tags": null,
        "employmentType": "FULL_TIME",
        "employmentTypeRaw": "Full-Time",
        "seniority": "DIRECTOR",
        "seniorityRaw": "Director",
        "senioritySource": "board",
        "locationRaw": "Canada, USA",
        "isWorldwide": false,
        "regions": [],
        "countryCodes": ["CA", "US"],
        "subdivision": null,
        "salaryMin": 138600,
        "salaryMax": 192000,
        "salaryCurrency": "USD",
        "salaryPeriod": "YEAR",
        "salarySource": "structured",
        "salaryText": "138,600–192,000 USD per year",
        "excerpt": "About Upstart At Upstart, we’re united by a mission that matters: to radically reduce the cost and complexity of borrowing for all Americans. …",
        "descriptionMarkdown": "**About [Upstart](https://jobicy.com/company/upstart)**\n\nAt Upstart, we’re united by a mission that matters: …",
        "descriptionHtml": null,
        "publishedAt": "2026-10-09T17:58:40Z",
        "expiresAt": "2026-11-10T07:30:57Z",
        "alsoFoundOn": [
            {
                "source": "weworkremotely",
                "sourceName": "We Work Remotely",
                "url": "https://weworkremotely.com/remote-jobs/upstart-art-director-brand-social",
                "attribution": "Job via We Work Remotely"
            }
        ],
        "servedFromCache": true,
        "fetchedAt": "2026-10-13T00:59:52Z",
        "scrapedAt": "2026-10-13T01:07:30Z",
        "firstSeenAt": null
    },
    {
        "uniqueId": "weworkremotely:lawnstarter-software-engineering-manager-7",
        "source": "weworkremotely",
        "sourceName": "We Work Remotely",
        "sourceJobId": "lawnstarter-software-engineering-manager-7",
        "attribution": "Job via We Work Remotely",
        "sourceUrl": "https://weworkremotely.com/",
        "feedUrl": "https://weworkremotely.com/categories/all-other-remote-jobs.rss",
        "title": "Software Engineering Manager",
        "companyName": "LawnStarter",
        "companyLogoUrl": "https://wwr-pro.s3.amazonaws.com/logos/0171/6517/logo.gif",
        "companyWebsite": "http://lawnstarter.com",
        "companyHeadquarters": "Brazil",
        "url": "https://weworkremotely.com/remote-jobs/lawnstarter-software-engineering-manager-7",
        "applyUrl": "https://weworkremotely.com/remote-jobs/lawnstarter-software-engineering-manager-7",
        "category": "other",
        "categoriesRaw": ["All Other Remote"],
        "tags": null,
        "employmentType": "FULL_TIME",
        "employmentTypeRaw": "Full-Time",
        "seniority": null,
        "seniorityRaw": null,
        "senioritySource": null,
        "locationRaw": "Anywhere in the World",
        "isWorldwide": null,
        "regions": [],
        "countryCodes": [],
        "subdivision": null,
        "salaryMin": 120000,
        "salaryMax": 140000,
        "salaryCurrency": "USD",
        "salaryPeriod": "YEAR",
        "salarySource": "description",
        "salaryText": "$120,000-$140,000 USD",
        "excerpt": "About LawnStarter LawnStarter is the nation's leading on-demand marketplace for lawn care and related services, …",
        "descriptionMarkdown": "**About LawnStarter**\n\nLawnStarter is the nation's leading on-demand marketplace …",
        "descriptionHtml": null,
        "publishedAt": "2026-10-05T16:09:17Z",
        "expiresAt": "2026-11-04T16:09:17Z",
        "alsoFoundOn": [],
        "servedFromCache": true,
        "fetchedAt": "2026-10-13T01:00:01Z",
        "scrapedAt": "2026-10-13T01:07:30Z",
        "firstSeenAt": null
    }
]
```

The run also writes a **RUN-SUMMARY** record (see the Output tab): per board the status (OK, PARTIAL, ERROR, BLOCKED, RATE_LIMITED, DISABLED, SKIPPED), the mode (FRESH, CACHED, SKIPPED_COOLDOWN, STALE_CACHE), requests, jobs read and when the next fresh pass is allowed; plus totals (unique, duplicates merged, filtered out, already seen, expired, output, charged, served free).

### Tips

- **Cheapest monitor:** schedule hourly with `onlyNew` and your filters; you pay only for new matching jobs (a typical hour brings a handful).
- **Smaller output:** set `descriptionFormat` to `none` if you only need the listing data and link.
- **Filters before charging:** every filter runs before charging, so narrow filters cost less.

### FAQ

#### Is it legal to use this remote jobs data?

The Actor reads only a public API (Jobicy) and public RSS feeds (We Work Remotely) that the boards publish for reuse, under their published terms: credit the board and keep the link to the original listing. It sends an honest user agent, reads each source at most once per hour per user, never passes a bot challenge and never fetches web pages. It has no person fields, and emails, phone numbers and personal profile links in job texts are removed (best effort). Our Actors are ethical and do not extract any private user data. However, job descriptions are written by employers and could, rarely, still contain personal data; personal data is protected by the GDPR in the European Union and by other regulations around the world, so if you are unsure whether your use is legitimate, consult your lawyers.

#### Why only these two job boards?

Many other remote job boards do not allow their listings to be passed on to third parties, or require a followed backlink on every page where the data appears, which a dataset cannot guarantee. More boards may be added once their terms are checked.

#### Why about 1,100 jobs?

Jobicy's API covers the last 7 days (with a 3-hour delay), about 750 jobs; We Work Remotely's feeds hold about 390 current listings. After removing duplicates that is about 1,100 remote jobs per full pull.

#### How reliable is the contact-detail removal?

It is best effort: emails (also inside links) become `[email removed]`, phone numbers with 7 or more digits become `[phone removed]`, links to personal profile pages (LinkedIn `/in/` and `/pub/`, XING profiles) are unlinked or become `[link removed]`, and "contact person / recruiter:" lines are dropped. Company pages and other links stay. It cannot be switched off.

#### Which storages does it create in my account, and how do I delete them?

Two named key-value stores: `remote-jobs-feed-aggregator-cache` (the 60-minute pass cache and charge marks) and, only in monitor mode, the store named in **State store name** (default `remote-jobs-feed-aggregator-monitor`, the list of already returned jobs). Delete them any time under **Storage → Key-value stores** in Apify Console; the next run simply starts fresh.

#### What happens if a board is down or blocks requests?

The other board still runs. A failed board is served from a cache up to 24 hours old if one exists (`STALE_CACHE`); otherwise its status in RUN-SUMMARY says what happened. The run fails only when every selected board failed and there was nothing to serve.

#### Can I use it through the API or from an AI agent?

Yes. Use the **API** tab for ready-made code, or call the Actor from any MCP-capable agent. Rows are flat JSON with stable field names.

#### I found a problem or need a feature

Please open an issue in the **Issues** tab; we read every report.

### Changelog

- **1.0 (2026-10-13):** First release. Jobicy public Jobs API and We Work Remotely RSS feeds; cross-board dedupe; salary ranges, location eligibility, categories, employment type and seniority; filters; new-jobs monitor; 60-minute pass cache with free re-serves; per-board isolation and stale-cache fallback.

# Actor input Schema

## `sources` (type: `array`):

Boards to read: Jobicy (public Jobs API) and We Work Remotely (public RSS feeds). Each row credits its board in the attribution, sourceName and sourceUrl fields. If one board fails, the other still delivers.

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

Maximum number of deduplicated remote jobs returned after your filters, newest first. A full pull from both boards is about 1,100 jobs. Free-plan users get full rows (no truncation).

## `keywords` (type: `array`):

Keep jobs whose title, company, category or tags contain any of these words or phrases as whole words (case- and accent-insensitive; a plural s also matches, so engineer finds Engineers, but ai does not match Chainguard). End a keyword with \* to match word beginnings, e.g. develop\* finds developer and development. Leave empty to keep all jobs.

## `searchInDescription` (type: `boolean`):

Also match the keywords (whole words, as above) in the full job description, not only in title, company, category and tags.

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

Drop jobs whose title or company contains any of these words or phrases as whole words (case- and accent-insensitive; a plural s also matches, so intern drops Intern and Interns but keeps International). End a keyword with \* to match word beginnings.

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

Keep jobs in these normalized categories (the same category list for both boards). Leave empty for all categories.

## `employmentTypes` (type: `array`):

Keep jobs with these employment types. Leave empty for all.

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

Keep jobs at these levels. When set, jobs without a known level are dropped. Jobicy gives a level; for We Work Remotely it is read from title words (junior, senior, lead, director …).

## `countries` (type: `array`):

Location eligibility: keep jobs a candidate in one of these countries can apply for, as ISO 3166-1 alpha-2 codes (US, GB, DE …). A job matches when it lists the country, a region containing it (DE is in EUROPE and EMEA) or is open worldwide.

## `regions` (type: `array`):

Location eligibility: keep jobs open to these regions, to a country inside them, or worldwide. Countries and regions are alternatives (a job matching either is kept).

## `includeUnknownLocation` (type: `boolean`):

With a country or region filter set, also keep jobs whose board gives no reliable location eligibility. Most We Work Remotely jobs say "Anywhere in the World", which is the board default and not a guarantee (isWorldwide is null for them).

## `requireSalary` (type: `boolean`):

Keep only jobs with a salary range (structured on Jobicy, parsed from the description on We Work Remotely).

## `minYearlySalary` (type: `integer`):

Keep only yearly salary ranges in the currency below whose maximum (or minimum when no maximum is given) is at least this value. No currency conversion. 0 = no minimum.

## `minYearlySalaryCurrency` (type: `string`):

3-letter ISO currency code used by the minimum yearly salary filter, e.g. USD, EUR, GBP.

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

Keep jobs published in the last N days. Jobicy itself covers about the last 7 days. 0 = no age limit.

## `onlyNew` (type: `boolean`):

Return only remote jobs that earlier runs with the same state store name have not returned yet, and charge only for those. The first run returns every current match up to Max jobs. A job that moves to the other board does not alert again.

## `stateStoreName` (type: `string`):

Named key-value store in your account that remembers which jobs were already returned. Use one name per monitor (for example one per saved search).

## `jobicyGeo` (type: `string`):

Jobicy server-side location filter. Jobicy allows one new pass per hour per user; the three Jobicy options form that pass, so changing them within the hour skips Jobicy until the next hour (the other board still runs).

## `jobicyIndustry` (type: `string`):

Jobicy server-side category filter (part of the hourly Jobicy pass, see Jobicy location).

## `jobicyTag` (type: `string`):

Jobicy server-side keyword search (part of the hourly Jobicy pass, see Jobicy location). For most uses the general Keywords filter is better.

## `wwrCategories` (type: `array`):

We Work Remotely category feeds to read. Leave empty to read all 11 categories.

## `descriptionFormat` (type: `string`):

Which description fields to include: Markdown, clean HTML, both, or none (smallest output). Emails, phone numbers and personal profile links are removed in every format (best effort).

## Actor input object example

```json
{
  "sources": [
    "jobicy",
    "weworkremotely"
  ],
  "maxItems": 200,
  "keywords": [
    "python",
    "data engineer"
  ],
  "searchInDescription": false,
  "excludeKeywords": [
    "intern",
    "internship",
    "commission only"
  ],
  "categories": [
    "software-development",
    "data"
  ],
  "employmentTypes": [
    "FULL_TIME",
    "CONTRACT"
  ],
  "seniority": [
    "SENIOR"
  ],
  "countries": [
    "DE",
    "AT"
  ],
  "regions": [
    "EUROPE"
  ],
  "includeUnknownLocation": true,
  "requireSalary": false,
  "minYearlySalary": 100000,
  "minYearlySalaryCurrency": "USD",
  "postedWithinDays": 3,
  "onlyNew": true,
  "stateStoreName": "remote-python-jobs-monitor",
  "jobicyGeo": "europe",
  "jobicyIndustry": "engineering",
  "jobicyTag": "python",
  "wwrCategories": [
    "remote-full-stack-programming-jobs",
    "remote-devops-sysadmin-jobs"
  ],
  "descriptionFormat": "markdown"
}
```

# Actor output Schema

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

All remote job rows in the default dataset.

## `overview` (type: `string`):

Remote job rows in the overview table view.

## `summary` (type: `string`):

Per-source status, mode (FRESH, CACHED, SKIPPED_COOLDOWN, STALE_CACHE) and totals (RUN-SUMMARY record).

# 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 = {
    "sources": [
        "jobicy",
        "weworkremotely"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("openfeeds/remote-jobs-feed-aggregator").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 = {
    "sources": [
        "jobicy",
        "weworkremotely",
    ],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("openfeeds/remote-jobs-feed-aggregator").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 '{
  "sources": [
    "jobicy",
    "weworkremotely"
  ],
  "maxItems": 50
}' |
apify call openfeeds/remote-jobs-feed-aggregator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,openfeeds/remote-jobs-feed-aggregator"
        }
    }
}
```

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/gxMibvLpe7iUkHKEO/builds/GL0C73Ie0qPwXNwrB/openapi.json
