Arbeitnow Jobs Scraper: Job Listings with Filters
Pricing
from $0.70 / 1,000 job listings
Arbeitnow Jobs Scraper: Job Listings with Filters
Scrape job listings from Arbeitnow with filters by keyword, location, tag, job type, visa sponsorship and posting date. One row per job with title, company, location, job types, tags, publication time, canonical URL and description as text and HTML. Export to JSON, CSV or Excel.
Pricing
from $0.70 / 1,000 job listings
Rating
0.0
(0)
Developer
MrBridge
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Share
Arbeitnow Jobs Scraper
Arbeitnow Jobs Scraper collects job listings from the Arbeitnow job board (https://www.arbeitnow.com). Filter by search term, location, tag, job type, remote flag and age, and get one clean row per job, ready for JSON, CSV or Excel. No API key is needed.
Set maxPages to 1 and maxItems to 10: the Actor reads the newest page of the feed and returns the 10 most recent listings with title, company, location, remote flag, tags, publication time, the canonical Arbeitnow URL and the job description as text and as HTML. Add the search term python to keep only the listings that mention it. E-mail addresses and phone numbers found in the descriptions are masked, links are kept.
What is Arbeitnow Jobs Scraper?
Arbeitnow publishes a public job board feed. The Actor reads that feed through its public API, applies your filters, removes duplicates and returns structured rows. The feed holds the newest listings of every kind, about 300 per page, newest first. Most of them are on-site jobs, only about 3 in 100 are flagged remote, which is why remoteOnly is off by default. Many listings are in Germany, in German or in English.
What data can I extract with it?
One row per job: source, job ID (the Arbeitnow slug), title, company, location, remote flag, job types, tags, publication time, canonical Arbeitnow URL, description as text and as HTML, scrape time. Arbeitnow serves no salary, no company logo and no seniority level, so those columns are always empty.
How can I use the results?
- Feed a job board or a newsletter with fresh listings and a link back to each Arbeitnow page.
- Track which companies hire for a skill, a city or a language.
- Build a list of employers that sponsor a visa or relocation.
- Send new matches for a search term to a spreadsheet, a chatbot or a notification service.
Data source and terms
All rows come from Arbeitnow (https://www.arbeitnow.com), through its public job board API. Arbeitnow asks anyone who reuses the data to follow these terms, and so does this Actor:
- Credit Arbeitnow with a direct link to https://www.arbeitnow.com wherever you republish the data.
- Keep the canonical URL. Every row carries it in the
urlfield. Send applicants to that URL, never to a copy. - The feed is updated every hour. A schedule faster than hourly returns the same rows.
- 3 requests per minute at most. Arbeitnow limits its API to 3 requests per minute. The Actor waits 30 seconds between two requests and never retries, so a run reads a page every 30 seconds.
maxPagesdefaults to 3 for that reason. - No salary, no logo. Arbeitnow does not serve them.
- Contacts are masked, links are kept. E-mail addresses and phone numbers found in descriptions are replaced by neutral markers before the rows are returned. Links stay, with their
hrefindescriptionHtml. Amailto:ortel:anchor, and a link that carries an e-mail address, is replaced by its text. A bare link of that kind in a text becomes[link removed]. Phone numbers are not looked for inside a URL. - Scope. By default every listing of the pages read is returned, remote or not. Set
remoteOnlyto keep only the listings Arbeitnow flags as remote. The Actor reads the newest pages only, older listings are not covered.
The OUTPUT record of each run repeats the coverage note and the attribution to give to Arbeitnow.
How to use it
- Open the Actor in Apify Console.
- Enter search terms if you want to narrow the feed, and set
maxPagesandmaxItems. - Start the run. Rows appear in the dataset as they are delivered.
Input
| Field | Meaning | Default |
|---|---|---|
searchTerms | Up to 10 terms, 50 bytes at most each. A job is kept when one term appears in its title, tags or description | empty (all) |
locations | Keep jobs whose location contains one of these texts, case-insensitive | empty (all) |
tags | Keep jobs with one of these Arbeitnow tags (exact match, case-insensitive) | empty (all) |
jobTypes | Keep jobs with one of these types as Arbeitnow writes them (exact match, case-insensitive) | empty (all) |
postedWithinDays | Keep jobs published in the last N days (1 to 365) | empty |
remoteOnly | Keep only the listings flagged remote | false |
visaSponsorship | Ask Arbeitnow for the visa sponsoring listings only. The filter is applied by Arbeitnow | false |
maxPages | Pages of the feed to read, 1 to 20 (one page every 30 seconds) | 3 |
maxItems | Hard cap on jobs returned and billed, 1 to 10000 | 100 |
includeDescription | Add the description as text and HTML | true |
The Console form pre-fills searchTerms with python, maxPages with 1 and maxItems with 10. Example input, used for the sample row below (the stored page holds no Python listing, so the example has no search term):
{"maxPages": 1,"maxItems": 10}
Terms, locations, tags and job types are lowercased, deduplicated and sorted. searchTerms, locations, tags, jobTypes, remoteOnly and postedWithinDays are applied by the Actor on the pages it reads, so a rare filter needs more pages. visaSponsorship is the only filter applied by Arbeitnow, which then returns a different list with a deeper time range. The OUTPUT record says how many pages were read.
Invalid input ends the run successfully with one BAD_INPUT row in the errors dataset and no job. It covers an empty or too long term, more than 10 terms, and a value of the wrong type. A page count or an item cap out of range never reaches the Actor: the platform refuses it before the run starts.
Output
Jobs go to the default dataset, one row per job, in the order Arbeitnow gives them (newest first). Problems go to a separate errors dataset and are never billed. The OUTPUT record of the key-value store summarizes the run.
| Field | Type | Meaning |
|---|---|---|
source | string | Always Arbeitnow |
jobId | string | Arbeitnow slug of the job |
title | string | Job title, spaces normalized (see below) |
company | string | Company name |
companyLogo | null | Always empty, Arbeitnow serves no logo |
location | string or null | Location as Arbeitnow writes it |
remote | boolean | The remote flag of Arbeitnow |
jobTypes | array | Types as Arbeitnow writes them, in English, German or Dutch, sometimes mixed with seniority |
level | null | Always empty |
categories | array | Always empty |
tags | array | Arbeitnow tags |
salaryMin, salaryMax | null | Always empty, Arbeitnow serves no salary |
salaryCurrency, salaryPeriod, salaryText | null | Always empty |
publishedAt | string or null | Publication time, ISO 8601 in UTC |
url | string | Canonical Arbeitnow page of the job |
descriptionText | string or null | Description as text, line breaks kept |
descriptionHtml | string or null | Description as HTML |
scrapedAt | string | Time the row was built, ISO 8601 in UTC |
descriptionText and descriptionHtml are absent when includeDescription is false. The other fields are always present, with null when Arbeitnow gives no value.
title, company and location are cleaned the same way: HTML entities are decoded, tags are removed, and any run of spaces, tabs or line breaks becomes a single space, trimmed at both ends. So Sales Manager - Mid Market Paris (two spaces) is returned as Sales Manager - Mid Market Paris. The title is therefore not byte for byte the one Arbeitnow serves. In location a comma is also followed by exactly one space, so Canada, USA is returned as Canada, USA.
This is one real row from the example input above, built by the Actor from a stored Arbeitnow response:
{"source": "Arbeitnow","jobId": "senior-software-developer-dortmund-389547","title": "(Senior) Software Developer (m/w/d)","company": "Loopario","companyLogo": null,"location": "Dortmund","remote": false,"jobTypes": [],"level": null,"categories": [],"tags": ["Software Development"],"salaryMin": null,"salaryMax": null,"salaryCurrency": null,"salaryPeriod": null,"salaryText": null,"publishedAt": "2026-10-06T13:01:02.000Z","url": "https://www.arbeitnow.com/jobs/companies/loopario/senior-software-developer-dortmund-389547","descriptionText": "Lust auf spannende Software-Projekte?\nDann bist du bei uns genau richtig! Wir suchen einen engagierten Senior Software Developer (m/w/d) mit Erfahrung in .NET / C#.\nW","descriptionHtml": "<p><strong>Lust auf spannende Software-Projekte?</strong></p>\n<p>Dann bist du bei uns genau richtig! Wir suchen einen engagierten Senior Software Developer (m/w/d) mit Erfahrung in .NET / C#.</p>\n<p>W","scrapedAt": "2026-10-26T18:53:00.000Z"}
The example comes from a test fixture, so the description is cut after a few lines and the HTML stops in the middle of a tag pair. A real run returns the full description.
Limits
maxItemsstops the run once that many jobs have been delivered. The default is 100.maxPagescaps the pages read, 20 at most. A page holds about 300 listings, and the run stops earlier when Arbeitnow announces no next page. A run of 20 pages lasts at least 10 minutes.- Requests are spaced by 30 seconds, retries and failed requests included, so a run never sends more than the 3 requests per minute that Arbeitnow allows.
- Each request is bounded at 110 seconds, answer included, so a stalled answer cannot hold the run. The later pages of the feed weigh about 3 MB and Arbeitnow serves them slowly, sometimes over a minute.
- A network error, a timeout, a truncated answer or a server error (5xx) is retried once: the retry starts after the longer of Retry-After (or the backoff) and the limiter interval, counted from the start of the failed attempt. If the retry fails too, the run writes one
FETCH_FAILEDrow, keeps the jobs already delivered and ends withstoppedByset tofetchFailed. - A 429 is never retried, because a retry would use up the rate limit. If Arbeitnow answers 429, the run ends there with a
RATE_LIMITEDrow. - If Arbeitnow answers 400 to a request, the run stops with one
BAD_INPUTrow that carries the HTTP status and the message, and ends SUCCEEDED withstoppedByset tobadInput. - After 3 blocked responses in a row the run stops cleanly and ends SUCCEEDED.
- Each run is a snapshot of the newest pages of the feed at that moment.
Billing
One event is billed per delivered job. Errors, duplicates and filtered-out listings are never billed. The Pricing tab of the Actor shows the current prices.
When the platform moves a run to another server or restarts it while it works, the run picks up at the page it was reading. It saves its progress after every page, and on a restart it first reads the jobs already in its dataset: a job already returned is neither returned nor billed again, and the OUTPUT counters cover the whole run. In the rare case where the run stops between saving a job and billing it, that job is delivered once and never billed. The feed changes every hour, so a listing can slip from a page not yet read to a page already read during the move and be missed.
Run summary and early stops
stoppedBy in the OUTPUT record says why a run ended early. It keeps the first reason only, so a pageBudget stop hides a maxItems or chargeLimit stop that would have come later.
null: all the requested work was done.maxItems: themaxItemscap was reached.chargeLimit: the maximum charge set for the run was reached.deadline: the run reached its internal time limit, 90 seconds before the run timeout. The request in flight is abandoned and the jobs already delivered stay.circuitOpen: too many blocked responses in a row.pageBudget: the page budget of the run was spent.badInput: Arbeitnow answered 400 to a request.fetchFailed: a page could not be fetched, even after its retry. That page and the next ones were not read, and thecoverageNotesays "The walk ended on an error after page N".
Two fields show how far a run went: pagesPlanned is the number of pages the run planned to read (maxPages), and lastPageRead is the number of the last page read (1 is the newest page), or null when no page was read. When lastPageRead is below pagesPlanned and stoppedBy is null, check errorsByKind: if it is empty, the run reached the end of the feed. Otherwise the reason is there, for example RATE_LIMITED (Arbeitnow answered 429), TARGET_BLOCKED or SCHEMA_CHANGED, and the errors dataset has the row. A non-empty errorsByKind does not always mean that the run stopped: a LISTING_INVALID row skips one listing and stops nothing.
pageTimings lists the pages fetched, in reading order and 20 at most: page (its number, 1 is the newest), attempts (HTTP requests it took), ms (from the start of its first request to the end of the answer, a retry included) and bytes (size of the answer, 0 when the request failed). A page over a minute is slow on the Arbeitnow side. Expect a run to last about 30 seconds per page plus the emission of the jobs, longer when a page is slow. The default memory is 512 MB.
pagesRereadAfterResume counts the pages read a second time because the run was moved or restarted while it was applying them, usually 0 and one page at most per restart. These pages are also counted in pagesRead, and their jobs already returned in duplicatesSkipped.
Changes in 0.1.7: OUTPUT has the new field pagesRereadAfterResume. Input and rows are unchanged.
Changes in 0.1.5: OUTPUT has the new field pageTimings.
Changes in 0.1.2: stoppedBy can be fetchFailed (a run that ended on a failed page used to say null), and OUTPUT has the two new fields lastPageRead and pagesPlanned. The other fields keep their names and meaning.
Every business error is written to the errors dataset with a kind: BAD_INPUT, TARGET_BLOCKED, RATE_LIMITED, FETCH_FAILED, UPSTREAM_ERROR, SCHEMA_CHANGED or LISTING_INVALID. The OUTPUT record counts them in errorsByKind. The OUTPUT record is written at the end of every run, even one that hits its time limit. If the platform refuses to store a row, the run ends as FAILED, and the OUTPUT record still holds the counters reached until then.
Frequently asked questions
Why do I get fewer jobs than maxItems?
The Actor reads at most maxPages pages, and your filters narrow what those pages hold. Only about 3 listings in 100 are remote, so remoteOnly needs more pages. When all the pages are read, the run ends with stoppedBy set to null.
Can I use Arbeitnow Jobs Scraper via MCP?
Yes. Any Apify Actor can be called from an MCP client through the Apify MCP server. See the Apify MCP documentation for the setup. For a ready-made MCP server over remote job boards, use Remote Jobs MCP.
Your feedback
We're always working on improving the performance of our Actors. So if you've got any technical feedback for Arbeitnow Jobs Scraper or simply found a bug, please create an issue on the Actor's Issues tab.
More free tools, scrapers, MCP servers and data studies from the same team: mr-bridge.com.
Legal & responsible use
The data comes from Arbeitnow (https://www.arbeitnow.com). Link back to Arbeitnow and name it as the source when you republish the data, and keep the canonical Arbeitnow URL of each job. Arbeitnow has its own terms of use, and it may restrict automated access or commercial reuse. Before you rely on the output, in particular for commercial use, confirm that your use is permitted by those terms. You remain responsible for how you use the results and for complying with the source's terms and with the laws that apply to you.