Setup prompt
sync-jobs.mjs, that keeps a local file of job postings for the companies you watch. Each run uses the free organizations autocomplete to turn new domains into organization IDs, then the job post search (2 credits per request) to fetch active postings featured since the last run. New posts go to an NDJSON file you can load anywhere; a state file remembers the IDs, the last run date and every post already seen.
What you need
- Node.js 18 or newer (for the built-in
fetch). No packages. FORAGER_API_KEYandFORAGER_ACCOUNT_IDin the environment, from the Web App.companies.txt, one domain per line. Fictional sample:
companies.txt
The script
1
Call Forager with retries and keep state on disk
The helper treats
403 as fatal, retries 429 with backoff (autocomplete allows 10 requests per second per account) and returns everything else to the caller. State is a JSON file next to the script.sync-jobs.mjs (part 1 of 3)
2
Resolve domains to organization IDs once
Autocomplete is free and returns
text as “name - domain”, so the script keeps the first result whose text ends with the domain you asked for and stores the ID in the state file. A domain that stays unresolved is reported, not guessed.sync-jobs.mjs (part 2 of 3)
3
Fetch new postings and write them out
One search covers every watched company, because
organization_ids takes a list. date_featured_start is the previous run’s date (the first run uses today), is_active keeps closed postings out, and page walks the results until total_search_results is reached or the page cap stops the run. Posts whose id is already in the state file are dropped.sync-jobs.mjs (part 3 of 3)
4
Schedule it
Run it once by hand, then add it to cron. The environment file holds the two variables and nothing else.
crontab (02:15 every night)
Output (illustrative)
One line of new-jobs-2026-11-01.ndjson (illustrative)
Cost and limits
- Each search request costs 2 credits, so a night costs 2 credits per page fetched: at most 2 times
MAX_PAGES_PER_RUN(50 with the default). Autocomplete and the state file are free. - The page size is not documented, so the script stops on
total_search_results, on an empty page, or at the page cap, whichever comes first. - Autocomplete is limited to 10 requests per second per account; the script resolves each domain once and never again.
- A domain that resolves to the wrong company is the most common mistake. Check
sync-state.jsonafter the first run and correct an ID by hand if needed.
Adapt it
- Watch a team instead of a company list: add
titlewith a boolean text query such as"data engineer" OR "analytics engineer"to the search body. See Search job posts. - Send alerts: group
freshbyorganizationand post a summary to chat or email, as in the hiring signals recipe. - Thousands of companies, or history back more than a few weeks? The job post data feed delivers the whole index as files.
Related
Node.js quickstart
The client this script is built on, step by step.
Hiring signals recipe
The same data, framed as alerts for sales.
Job post search reference
Every filter and response field.
Find filter values
Which autocomplete feeds which filter.