Skip to main content
Recruiters, job seekers and investors all want the same list: every open platform engineering role at the 300 companies they follow, with location, remote policy and pay, and what appeared since yesterday. Half of those careers pages are a plain list, and the other half sit on applicant-tracking systems where you have to search, filter and page through results. This program reads the plain ones as structured data, sends an agent to the rest, normalises and dedupes every role, and runs nightly to report what is new.

What you need

  • An Outcrawl API key in OUTCRAWL_API_KEY.
  • startups.csv with a header row and name,careersUrl per line.
  • A plan with enough browsers for your lanes: Free 2, Builder 5, Pro 25, Scale 100. Every key on your account shares one browser slot count. Browsers, agent runs, crawls, searches and scrapes that aren’t served from cache each hold a slot. A nightly job shares that count with anything else running on your account at the same hour.
  • Somewhere to run it nightly: cron, a CI schedule, or any scheduler.

How it works

1

Read each careers page as data

A scrape with formats: ['json'] and a schema turns a careers page into a list of roles: title, location, remote policy, posted pay, link. It is 1 credit a page.
2

Send an agent where a page needs clicking

Workday, iCIMS, Taleo, SuccessFactors and Oracle boards, and any page whose roles did not come back from the scrape, go to an agent. It uses the site’s own search and filters, pages through every result, opens each posting and returns the same schema. A rule tells it not to apply or sign in, and blocks it from creating an account.
3

Read only the postings that are new

Roles are keyed by their posting URL, without tracking parameters. A role seen on a previous night keeps its details; only a new one gets its posting scraped for pay and remote policy.
4

Lanes, retries and a nightly ceiling

Four lanes. A refused call (ConcurrencyLimitError, or QuotaExceededError on requests per minute) waits and retries: 20 seconds for a slot, or the retryAfterSeconds the error names. Running out of monthly credits stops. Every step reserves its maximum cost against the night’s ceiling before it starts.
5

Write the sheet and the news

roles.csv holds every open role, new-roles.json holds tonight’s new ones, and roles.json is the state for tomorrow. A company that could not be read tonight keeps yesterday’s roles, so a failure never reads as a closed role.

The program

Run it nightly. With cron, at 06:00:

What you get back

roles.csv, one row per open role, opened in any spreadsheet:
new-roles.json, only what appeared tonight, in the same shape:
And the line for your log:

What it costs

Rates from pricing: a scrape is 1 credit a page. An agent run is billed for the model’s usage, browser time and proxy usage, and a typical run costs about 15 credits a minute all in, proxy usage included. That is an estimate: the real figure depends on the task, and a page-heavy board costs more.
  • Careers pages: about 255 of the 300 read as a plain scrape, 255 credits a night.
  • Postings: only new roles are read. The first night that is every matching role, about 400 credits; after that, a few dozen a night.
  • Agents: about 45 startups on applicant-tracking sites, at about 90 s each, so about 23 credits a run, or about 1,035 credits a night.
  • A typical night: about 1,310 credits, and the first night about 1,690, both under the 2,000 ceiling. Thirty nights is about 39,300 credits, which fits Pro’s 50,000.
  • Wall clock: about 255 scrapes at a few seconds and 45 agent runs at 90 s, over 4 lanes, is about 20 minutes.

Make it yours

  • Send the agent startups weekly instead of nightly: they are about 80% of the cost.
  • Post new-roles.json to a Slack incoming webhook, one message per role.
  • Swap WANTED for any title, and add a location filter such as remote or London in the same place.
  • Keep closed roles in a second file with the date they disappeared, to see how long each role stayed open.

Scrape

One URL in, structured content out.

Agents

Tasks, caps, schemas and what a run returns.

Rules

Plain-language limits the run is held to.

Errors

What concurrency_limit and quota_exceeded mean, and which are retryable.