Hyreflow
Integrations

Hyreflow Native

First-party scrapers metered in Hyreflow credits with no separate subscription: job scrapes across career pages, LinkedIn, Indeed and Arbeitsagentur (launch, then poll — charged per job returned), and LinkedIn post feeds for a person or a company (one call — charged per request).

Reach for Hyreflow Native on two triggers. "Find the open roles" — pull everything a company is hiring for off its career site, or search LinkedIn / Indeed / the German federal board by title and location. "What have they been posting?" — read a person's or a company's recent LinkedIn posts for launch, hiring, funding, exec-commentary and layoff signals. First-party scrapers you run on Hyreflow credits: no scraper subscription, no API key to manage.

Native (Hyreflow-metered, no BYOK) — first-party capability billed in Hyreflow credits; the provider-precedence waterfall does not apply.

Job scrapes and post feeds work differently, and they bill differently:

ShapeBilling
Job scrapesAsynchronous — launch, then pollPer job delivered; the launch is free, and an empty result costs nothing
Post feedsA single call returns a page of postsPer request — one page of up to 50 posts, whatever the page carries

Job scrapes: launch, then poll

A scrape takes a few minutes, so every job scraper is a two-step flow:

  1. Launch with a scrape_* tool (or its short alias) → returns { request_id, status: "QUEUED" }. Free.
  2. Poll the matching get_* tool with that request_idstatus moves QUEUEDRUNNINGCOMPLETED. When COMPLETED, result carries a page of jobs plus jobs_total, jobs_returned, jobs_filtered_out, limit, offset, has_more, and warnings. Poll roughly every 10s: re-polls dedup per job, so a tighter loop never costs extra — it only shortens the wait.

You're charged once per unique job delivered — each job in a scrape is billed exactly once. Re-polling, widening the limit, or overlapping page windows never double-charge; paging forward bills only the newly-delivered jobs.

Because a launch is free and returns immediately, you don't have to run scrapes one at a time. Launch several scrape_* calls up front, collect their request_ids, and poll them together — launches aren't serialized, and a batch of around 20 runs is a practical working size. A multi-angle sweep (the same titles across career pages, LinkedIn, Indeed, and Arbeitsagentur, or the same query across several cities) then costs roughly one scrape's wall-clock instead of the sum of every scrape run sequentially. Each run in the batch bills its own delivered jobs as you poll it, so a wide batch commits that spend at once — size the batch accordingly.

jobs_returned is only the current page — with the default limit of 10, a first poll showing 10 jobs says nothing about how many roles the scrape actually found. Check jobs_total and has_more to judge coverage before deciding you need another scrape.

Job scrapers

Launch (free)AliasPoll for resultsScrapes
scrape_career_pagescareer_pagesget_career_pagesA company's career site + its ATS (Greenhouse, Lever, Workday, Ashby)
scrape_linkedin_jobslinkedin_jobsget_linkedin_jobsLinkedIn jobs by title search and/or a company's LinkedIn page
scrape_indeed_jobsindeed_jobsget_indeed_jobsIndeed jobs by title + location (regional hosts)
scrape_arbeitsagentur_jobsarbeitsagentur_jobsget_arbeitsagentur_jobsBundesagentur für Arbeit (German federal job board)

The get_* pollers accept limit/offset (default 10, max 50) to page through result.jobs. A limit above 50 is rejected rather than quietly trimmed, so a paging loop can't silently skip the jobs a shortened page would have left behind. Advancing to a new page bills the jobs that page delivers. Dedup makes re-polling a window you already fetched free — it does not make the next window free, so has_more: true is not a reason to keep going. Stop once you have what was asked for; to walk the whole result deliberately, keep incrementing offset by limit and re-polling while result.has_more is true.

Post feeds: one call, one page

A post feed is not asynchronous — one call returns the posts inline, newest first:

ToolAliasReads
get_profile_postsprofile_postsA person's recent posts, from the handle in linkedin.com/in/<username>
get_company_postscompany_postsA company page's recent posts, from the handle in linkedin.com/company/<username>

One request returns one page of up to 50 posts and is charged as one request. To walk further back, pass the next_start the previous call returned while has_more is true — each page is another request, so it is another charge. limit trims how many posts come back (handy when you only want the last handful in context); it does not change what a request costs, so there is no saving in asking for fewer — and it is not the paging step, which is why next_start is the value to advance on.

Every post carries its full text, the post URL, when it was posted (both a timestamp and a date), reaction / comment / repost counts, the content type, the author, and any companies tagged in it. A company feed also reports total and total_page for the whole feed.

A request is charged whether or not the handle resolves — a page of 50 posts and an unreachable handle cost the same. When a handle can't be read, success is false and message says why, so check the handle against the profile URL before spending a request on it.

# a person's recent posts — one call, one charge
hyreflow tools execute profile_posts --payload '{"username":"acme-dana-reed","limit":10}'

# a company page's feed, second page
hyreflow tools execute company_posts --payload '{"username":"acme","start":50}'

Guidance

  • Career pages: narrow with target_titles (a list) or target_titles_prompt (a plain-English filter) — use one, not both.
  • LinkedIn / Indeed: pass titles_query (a string or an OR-list of titles) and locations; country selects the regional site. company_url on LinkedIn pulls a whole company's jobs.
  • rows and limit are separate knobs — size both to what was asked. rows on the launch bounds what the scraper collects upstream (Indeed defaults to 25; LinkedIn to the upstream default); limit on the poll bounds what one page hands back (10). They are independent, so rows: 15 with a default poll returns 10. For 15 roles send rows: 15 and poll with limit: 15 — one poll then delivers the ask and bills exactly it. arbeitsagentur_jobs and career_pages take no rows, so there the poll's limit and stopping at the ask are the only guard.
  • Arbeitsagentur: title and/or location; radius is in kilometres.
  • Each returned job carries title, location, employment type, salary (when available), the apply URL, and company fields — feed them straight into a sourcing or BD play.
  • Post feeds: username is the handle out of the LinkedIn URL, not the display name and not the full URL.
# 1. launch (free)
hyreflow tools execute linkedin_jobs \
  --payload '{"titles_query":"recruiter","locations":["London"],"rows":15}'
#    → { "request_id": "...", "status": "QUEUED" }

# 2. poll until COMPLETED (charged per job in result.jobs)
hyreflow tools execute hyreflow_native_get_linkedin_jobs \
  --payload '{"request_id":"<id>","limit":15}'

A job scrape is asynchronous — the launch returns a handle, not jobs. Keep polling the matching get_* until status is COMPLETED (or FAILED); a still-running or empty result costs nothing. A post feed has no launch half: the single call returns the posts.

On this page