The full Google Jobs panel for any search — about 90–130 job cards where Google has that many, not the first ten. Title, company, location, source board, posted age, salary when shown, direct apply links and the full description on every row. You are never charged for a job that was not delivered.
1.0.12 — run it from an AI agent, and where feedback goes
Two additions to this page, nothing else: a one-line setup for running this actor from an AI agent over MCP (pin it by URL, no store search needed), and a note on where issues and feedback go. What the actor does and what it charges are unchanged.
1.0.11 — continue an earlier run without paying twice
A run that stopped at a cap can now be continued, and nothing you already have is charged
again. Until this build the summary row's advice after a cap was to raise the cap and re-run —
and the re-run, starting from an empty dataset, fetched and charged the whole head of the list a
second time. There is now a "Continue from an earlier run" input (resumeFromDatasetId): give it
the earlier run's dataset ID and every listing already in that dataset is skipped — never fetched,
never charged — so a higher cap collects only what is new. The summary row now carries the run's
own datasetId (what you paste next time) and, on a continued run, carriedOver: how many rows
were skipped because you already had them; the search rows say the same per search.
The advice is honest again. A capped run's summary now tells you exactly how to collect the
rest without paying for it twice, instead of telling you to re-run.
A dataset that cannot be read stops the run before it fetches anything, uncharged. Continuing
blind could have billed you twice, so the run refuses, says why on an uncharged row, and asks you
to check the ID.
1.0.10 — a bracketed note after the state no longer costs you the country
"Austin, TX (Hybrid)" now reads as Austin, TX, US. The shared location parser this
actor uses picked up one more rule: a note in brackets at the end of a location line is an
office note, not part of the place, so the state and country underneath it are read
normally instead of the whole tail being treated as one unknown fragment.
1.0.9 — the country on a listing is a country, and an optional field can be sent as null
location.country is now a real two-letter country code, or empty — never a state.
Google's panel prints "Seattle, WA" and "Chicago, IL", and until now the piece after the
comma was shipped as the country: "WA", "IL" — and "IL" is Israel's country code, so
a buyer filtering by country could not see the trap. Those now read country "US" with the
state in location.region, a postcode gets its own location.postcode field, and the
country of the search decides the cases that are genuinely ambiguous. A line naming its own
country keeps it ("Spain", "Netherlands", "United States"), and a line naming no country we
can prove leaves the field empty rather than guessing — Google's untouched line is always in
location.raw.
Optional fields now accept null. Templated callers — n8n, agent frameworks, anything
that fills a request from a form — send null for every field left unset, and the platform
used to refuse those runs before they started. Every optional field now accepts null and
reads it as "use the default" — the Country dropdown included, which needed its list of
choices checked by the actor rather than by the platform to get there. It is the same
dropdown with the same choices, and a country we cannot pin Google results to is still
reported on its own uncharged row rather than quietly swapped for another. queries is
still required.
1.0.8 — 2026-08-31
A search that comes back blocked or unreadable is now fetched again before it reports a
miss. Google's access checks are intermittent, and a single one used to be enough to turn a
search into an uncharged "please re-run" row on your first run. Each search now gets a second
attempt on our side, so a search that would have reported a block frequently delivers its full
panel instead. The second attempt is on us, there is still no result fee when both come up
short, and your maxItems and maxRunSeconds are unaffected.
A search that ran and matched nothing now says why on its own row. The row already read
outcome: empty and delivered: 0, but missReason was left blank — so a genuine empty
answer was indistinguishable from an ordinary delivery of zero in the one column you reconcile
a search against. It now reads CLEAN_EMPTY, matching what this page has always documented.
Uncharged either way.
A panel whose job cards we cannot read is no longer reported as an empty search. If Google
changes the panel's markup, the page still arrives looking healthy and our reader finds nothing
in it. That used to ship as "returned nothing" — a permanent-sounding verdict about your search
for a problem that is ours. It now ships as an uncharged, re-runnable row that says the page
could not be read, and it is listed in the run's errors.
API note: sending null for a numeric setting has meant "use the default" since 1.0.5. The
paste-block on this page still said not to send null; it now matches what the actor does.
1.0.7 — 2026-08-30
This page now states the price up front — from $1.00/1,000 job listings, all-inclusive pay per
event, no start fee, charged only on delivery — the same figure the store header and the Pricing
tab already showed. Nothing about what this actor delivers or charges changed.
1.0.6 — 2026-08-30
Suite links now point at the full live shelf — every actor named in this README is a live
store link. Nothing about what this actor delivers or charges changed.
1.0.5 — 2026-08-30
Finishing an interrupted run's billing can never risk a double charge. A run that
resumes after an interruption first settles anything its earlier attempt delivered but had
not yet billed. If that settlement is itself interrupted part-way, the run now stops at the
exact point of failure and records only what actually went through — a charge that may
already have landed is never sent again, and anything genuinely unbilled is finished by the
next resume. As always, charged never exceeds what was delivered.
Every kind of account-side refusal from our data-access provider now stops the run's
searches straight away, with the same clean stop that names the limit as ours, says
nothing was charged for the searches it stopped, and asks you to re-run. Previously one
refusal shape could still be retried before the stop engaged.
A numeric setting sent as null or an empty value now means "use the default" instead
of being read as the smallest allowed value, so templated API inputs that send null for
an untouched knob behave exactly like leaving the field out.
1.0.4 — 2026-08-29
When the limit that stopped a run is ours, the run now says so. If our own data access
runs out mid-run, the summary used to report it the same way it reports your cost cap being
reached — so the advice was to raise your maximum total charge, which could not have helped.
That stop now names itself as ours, says nothing was charged for the searches it stopped, and
asks you to re-run instead of to change a setting.
charged: true can no longer appear on a row that was not billed. Right at a cost cap it
was possible for a listing to ship marked as charged while the charge itself was declined. The
run now checks that a listing can actually be billed before delivering it, so the charged
column always reconciles against the invoice.
A search stopped before it could deliver is no longer lost. When maxItems or the run
clock ran out between fetching a search and reading its first listing, that search vanished:
no row, and missing from the summary's resumeCursor too. It now ships its own uncharged row
and stays in the resume list, so you can pick it up on the next run.
The summary's chargedEvents now covers the whole run, not just the last server. On a run
that moved between servers it reported only the final server's charges, so it disagreed with
the delivered count in the same row and read like an overbilling.
A run moved between servers now records what each part of it delivered. Where a search was
interrupted, only the first attempt's partial figures used to be written, and the listings the
run delivered afterwards had no search row at all.
The run no longer starts a search it cannot finish before the run timeout. A search begun
too close to the timeout could be cut off mid-flight, ending the run with no summary row. It
now stops cleanly first, with the summary and resume cursor intact.
One malformed job card can no longer fail the whole run. A single unreadable link in
Google's panel used to end the run early and lose every remaining search; that card is now
delivered like any other.
README: the full steadyfetch suite shelf, and a link to a live example dataset from a real run.
1.0.3 — 2026-08-29
A typo in an input field name now gets a helpful pointer instead of sample rows. If you
send your searches under a field this actor does not have — query instead of queries, say —
the run used to look identical to an empty run and answered with the uncharged sample rows, so
a typo looked like it had worked. It now returns one uncharged row that names the field it did
not recognise, names the field your searches belong in, and shows the exact shape to send.
Sample rows are reserved for a genuinely untouched input, and nothing is charged either way.
1.0.2 — 2026-08-28
First release. One search returns Google's full jobs panel — about 90–130 job cards
where Google has that many; niche searches return every card Google has.
Every row: title, company, location, source board (via), posted age, salary when
Google shows one, employment type, the job's full description text, and the real
apply links — every board Google's "Apply" buttons point at, in order.
The same job reached by two searches is delivered and charged once.
You are never charged for a job that was not delivered: blocked or unreadable pages
ship as uncharged re-runnable rows, an empty panel is an uncharged real answer, and
maxItems / maxRunSeconds stop the run cleanly with a summary row and a resume
cursor.
A run that is interrupted or moved between servers continues from its own dataset:
nothing already delivered is fetched, delivered or charged again.
With no input, the run returns uncharged sample rows showing the exact output shape.