# Arbeitnow Jobs Scraper (`devilscrapes/arbeitnow-jobs-scraper`) Actor

Scrape European job postings from Arbeitnow's public job board feed, with client-side filtering by remote status, tag/category, and location. Get titles, companies, descriptions, tags, and posting dates, ready for recruiter pipelines or hiring-intent signals.

- **URL**: https://apify.com/devilscrapes/arbeitnow-jobs-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />
</div>

## Arbeitnow Jobs Scraper

**💰 $1.70 / 1 000 job postings**  ·  pay only for results  ·  no credit card to try

*We do the dirty work so your dataset stays clean.* 😈

Scrape live job postings from Arbeitnow's job board and get them back as
clean, structured rows — titles, companies, tags, remote status, locations,
and full descriptions — ready for a recruiter pipeline or a hiring-intent
signal.

### 🎯 What this scrapes

Arbeitnow aggregates thousands of European job postings, heavy on tech and
remote-friendly roles. This Actor pulls straight from Arbeitnow's job board
feed and returns one row per posting matching your filters: title, company,
tags, job types, remote flag, location, posting date, and the full
description.

### 🔥 What we handle for you

- **Client-side filtering done right.** Arbeitnow's feed doesn't support
  server-side search — we fetch, filter, and stop as soon as we have enough
  matches, so a narrow filter combination doesn't force you to pay for pages
  of data you'll never see.
- **Egress under control.** Every page is a couple of megabytes whether or
  not anything on it matches. We cap total pages fetched per run so a filter
  that never matches can't run away with your budget.
- **Fault isolation.** One malformed job entry is logged and skipped — it
  never takes down the rest of your run.
- **Blocks, retries and backoff.** Requests go through Apify Proxy with
  retry and backoff already wired in. You don't tune it; we do.
- **Clean dates.** Posting timestamps come back as ISO-8601 UTC, not raw
  Unix seconds.

### 💡 Use cases

- **Recruiters and staffing agencies** — watch for new roles matching a
  tag or location and reach out first.
- **Job boards and aggregators** — backfill European and remote postings
  your existing sources miss.
- **Sales / BD teams** — hiring signals are a public budget signal; a
  company opening five engineering roles just funded a team.
- **Market research** — track which tags, locations, and job types a
  segment is hiring for over time.

### ⚙️ How to use it

1. Set `maxResults` and `maxPages` to bound how much you pull per run.
2. Optionally filter with `remoteOnly`, `tags`, and `locationContains` —
   filters AND together.
3. Use `startPage` to resume a schedule further into the feed without
   re-paying for pages you've already scraped.
4. Run it, then export to JSON, CSV or Excel — or pull the dataset straight
   from the Apify API.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `maxResults` | `integer` | no | `50` | Stop once this many filtered rows have been emitted (1-2000). |
| `maxPages` | `integer` | no | `3` | Hard cap on pages fetched per run, independent of `maxResults` (1-20). |
| `remoteOnly` | `boolean` | no | `false` | Keep only postings with `remote == true`. |
| `tags` | `array<string>` | no | `[]` | Case-insensitive substring match against any of the job's tags. |
| `locationContains` | `string \| null` | no | `null` | Case-insensitive substring match against location. |
| `startPage` | `integer` | no | `1` | First API page to fetch. |
| `proxyConfiguration` | `object` | no | `{"useApifyProxy": true}` | Apify Proxy configuration. |

#### Example input

```json
{
  "maxResults": 5,
  "maxPages": 1,
  "remoteOnly": true,
  "tags": ["Engineering"],
  "locationContains": null,
  "startPage": 1
}
```

### 📤 Output

One row per job posting matching your filters.

| Field | Type | Notes |
|---|---|---|
| `slug` | `string` | Stable-ish unique job identifier. |
| `title` | `string` | Job title. |
| `company_name` | `string` | Hiring company's name. |
| `description_html` | `string` | Raw HTML-escaped description, as received. |
| `remote` | `boolean` | Whether the posting is remote. |
| `url` | `string` | Canonical job URL on arbeitnow.com. |
| `tags` | `array<string>` | Free-text tags. |
| `job_types` | `array<string>` | Free-text employment types. |
| `location` | `string \| null` | Free-text location; empty on the wire becomes `null`. |
| `posted_at` | `string` | ISO-8601 UTC posting timestamp. |
| `page` | `integer` | Source API page — useful for egress/debugging audits. |

### 💰 Pricing

Pay-Per-Event — you pay only when these events fire:

| Event | USD | What it is |
|---|---:|---|
| `actor-start` | $0.20 | One-off warm-up charge per run |
| `result` | $0.0015 | Per job posting written to the dataset |

Example: 1 000 job postings = **$1.70 per run** ($0.20 start + 1000 x $0.0015).
No subscription, no minimum, no card required to try it.

### 🚧 Limitations

- **Client-side filtering only.** Arbeitnow's feed ignores server-side query
  parameters — every filter (`remoteOnly`, `tags`, `locationContains`) is
  applied after fetching. A narrow filter combination may need more pages
  fetched (bounded by `maxPages`) to find matches.
- **Egress-bounded, not exhaustive.** `maxPages` caps how far into the feed
  a run will look. A run can legitimately finish with zero matches if your
  filters don't appear within the pages scanned — that's a successful run,
  not a failure.
- **Feed snapshot, not an archive.** This reflects live postings at run
  time; schedule it if you need historical tracking.
- **Only what the employer publishes.** Location and tags appear as the
  employer entered them — free text, inconsistent casing.

### ❓ FAQ

**Do I need an Arbeitnow account or API key?**
No. This reads Arbeitnow's public job board feed.

**Why did my run return zero rows?**
Your filter combination didn't match anything within `maxPages` pages.
Increase `maxPages` or loosen `remoteOnly`/`tags`/`locationContains`.

**Can I search by keyword in the title or description?**
Not yet — Arbeitnow's feed doesn't expose server-side search, and title/
description substring filtering isn't currently wired in. Use `tags` and
`locationContains` for now.

**Can I run this on a schedule?**
Yes — use Apify Schedules with `startPage` to walk further into the feed
each run, or reset to `1` to catch newly posted jobs.

### 💬 Your feedback

Found a bug, or need a field we don't return yet? Open an issue on the
Actor's Issues tab — we read every one.

# Actor input Schema

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

Stop fetching once this many filtered rows have been emitted.

## `maxPages` (type: `integer`):

Hard cap on the number of API pages fetched per run, independent of maxResults. Bounds egress since every page is ~2.3 MB regardless of how many rows survive the filter.

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

Keep only job postings with remote = true.

## `tags` (type: `array`):

Case-insensitive substring match against any of the job's tags. Empty list = no tag filter.

## `locationContains` (type: `string`):

Case-insensitive substring match against the job's location. Leave empty for no location filter.

## `startPage` (type: `integer`):

First API page to fetch (1-indexed). Lets a schedule resume further into the feed without re-paying for earlier pages every run.

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

Apify Proxy configuration. No anti-bot behaviour has been observed on Arbeitnow's public JSON API, so the standard (non-residential) group is enough.

## Actor input object example

```json
{
  "maxResults": 5,
  "maxPages": 1,
  "remoteOnly": true,
  "tags": [
    "Engineering"
  ],
  "startPage": 1,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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 = {
    "maxResults": 5,
    "maxPages": 1,
    "remoteOnly": true,
    "tags": [
        "Engineering"
    ],
    "startPage": 1,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/arbeitnow-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 = {
    "maxResults": 5,
    "maxPages": 1,
    "remoteOnly": True,
    "tags": ["Engineering"],
    "startPage": 1,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/arbeitnow-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 '{
  "maxResults": 5,
  "maxPages": 1,
  "remoteOnly": true,
  "tags": [
    "Engineering"
  ],
  "startPage": 1,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call devilscrapes/arbeitnow-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/arbeitnow-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/Yr1zKPi2qjrKazcEa/builds/JpWKrOvSVSGII6Xeq/openapi.json
