Repository navigation
feat(extract): remove the autoparse fallback and add zenrows extract prepare - #47
Merged
Merged
Conversation
…g back to autoparse On 403 REQS007 (domain not prepared yet) or the legacy 402 AUTH010, `zenrows extract` used to retry with the deprecated autoparse. That hid the prepare step, charged for an Autoparse call and often returned unusable data. The error is now reported, not retried, and names the next step: Extract hasn't prepared <domain> yet. Prepare it with POST /v1/extract/prepared-domains (a few example URLs, a few minutes, no credits), then retry; or run with --autoparse. `--autoparse` stays as the explicit opt-in and now warns that Autoparse is deprecated. The adapter's `fallbackAutoparse` option defaults to false. The empty-result check now treats a payload whose fields are all null or empty (recursively) as empty, so page scaffolding no longer reads as data. Skills, docs and the capability matrix describe the prepare step, mark autoparse deprecated and drop the fallback wording.
Removing the autoparse fallback leaves REQS007 as the answer on a domain Extract has not prepared yet, so CLI users need a way to prepare one. - `zenrows extract prepare <domain> --url <u> [--url <u>...]` submits the domain with 1 to 5 example URLs to POST /v1/extract/prepared-domains and returns at once. `--wait` (off by default) polls until ready or failed, up to `--timeout`. On 409 in_progress it follows the running preparation. - `zenrows extract prepare status <domain>` shows progress, the failure code and detail, the account's monthly allowance and the next step. - Errors name the next step: EXTRACT_PREPARE_INVALID (400), EXTRACT_PREPARE_NOT_FOUND (404), EXTRACT_PREPARE_IN_PROGRESS (409), EXTRACT_PREPARE_OUT_OF_ALLOWANCE (429), EXTRACT_PREPARE_UNAVAILABLE (503 overloaded / disabled), EXTRACT_PREPARE_FAILED (failed status, with the step for its failure code), EXTRACT_PREPARE_TIMEOUT. - The REQS007 error now prints the exact command: zenrows extract prepare <domain> --url <url>. Skills, README and the capability matrix teach the flow: extract, REQS007, prepare, poll, extract again.
…he error REQS007 has two causes. On a domain not prepared yet, preparing it is the fix. On a prepared domain, the gateway answers REQS007 with "Extract did not recognise this page" when it does not cover that kind of page, and resubmitting the domain only returns its existing ready record. The old wording sent agents round extract, prepare (ready at once), extract again. - A REQS007 whose body says the page was not recognised is now EXTRACT_PAGE_NOT_RECOGNISED: use --css or contact support with the URL; no prepare command. - `zenrows extract prepare` answering ready at once sets `already_prepared` and says that a REQS007 on that domain means the kind of page is not covered, instead of "run the extract again". - The REQS007 error no longer offers --autoparse; it offers --css. - failureNextStep says whether the attempt used an allowance slot from failure.slot_consumed, not from the failure code. - `zenrows extract prepare` never creates a Free plan account; the unused --no-signup flag is gone. - Each function in http.ts has its own doc comment again. - normalizeDomain keeps the full host: Extract prepares each host on its own (a prepared es.wikipedia.org does not cover pt.wikipedia.org). - Poll interval: 30 seconds, shared with the MCP server.
jonathan-zenrows
marked this pull request as ready for review
October 15, 2026 14:11
…for an unrecognised page The API now says which REQS007 it is in a `reason` field: domain_not_prepared, page_not_recognised or domain_not_enabled. The error is classified by that field first; matching the API's sentences stays only as the fallback for an API that does not send it yet, and says so in a comment. page_not_recognised does not mean that a kind of page is missing: on a prepared domain Extract learns a new kind of page on its first request, so the page is not one Extract extracts (a home, search, login or category page) or a transient failure kept it from trying. The error now gives the API's advice in the API's order: try a product, article or listing page; if this page should work, retry it once in a few minutes, not in a loop; otherwise use css. It no longer says "not covered" or sends to support first, and it still says that preparing again changes nothing. domain_not_enabled says that preparing does not help, and offers css. The "ready" and "already prepared" next steps say the same thing for a later page_not_recognised. Skills, help, README, docs and tool descriptions now tell one story with one vocabulary: prepared, ready, page kind, allowance slot, a few minutes, about every 30 seconds.
…tract, not a search or category page Production extracts search and category pages on prepared domains: a prepared domain learns any new kind of page on its first request. The example list "a home, search, login or category page" for a page Extract did not recognise was therefore wrong for two of its four entries, and it contradicted the advice to send a search results URL as an example. The page-not-recognised wording now says "a page with nothing to extract, such as a home page", everywhere it appears.
A domain Extract has not prepared yet is now EXTRACT_DOMAIN_NOT_PREPARED (it was EXTRACT_DOMAIN_NOT_ENABLED), and a domain Extract is not enabled for is now EXTRACT_DOMAIN_NOT_ENABLED (it was EXTRACT_DOMAIN_NOT_ALLOWED). Help, skills, docs, the capability registry and tests use the new names. Code that compared against the old EXTRACT_DOMAIN_NOT_ENABLED did so to fall back to autoparse, and that fallback no longer exists.
zenrows extract no longer retries a refused Extract request with Autoparse, on any REQS007 or AUTH010, whatever the caller passes. The adapter option fallbackAutoparse is still accepted so existing callers keep working, but it is deprecated and has no effect: when it is true, the CLI prints one deprecation warning on stderr. fellBackToAutoparse is gone from the outcome, the run artifact and the --json output, since it can never be true. The explicit --autoparse flag is unchanged.
jonathan-zenrows
approved these changes
Oct 20, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
zenrows extractno longer retries with the deprecated Autoparse when Extract has not prepared a domain. It reports the error with the exact command to prepare the domain, and this PR adds that command (zenrows extract prepare), so users can prepare a domain themselves and extract again.Flow:
zenrows extract <url>→ REQS007 →zenrows extract prepare <domain> --url <url> --wait→zenrows extract <url>.Breaking / behaviour changes
403 REQS007(or the legacy402 AUTH010),zenrows extractmakes one request and reports the error with the prepare step. No code path retries withautoparse=trueany more, whatever the caller passes. The adapter optionfallbackAutoparseis still accepted so existing callers keep working, but it is deprecated and has no effect; when it istrue, the CLI prints one deprecation warning on stderr.--autoparseis a different thing (the user asks for Autoparse directly) and is unchanged: it still runs Autoparse and warns that it is deprecated.fellBackToAutoparseis removed from the adapter outcome, the run artifact and the--jsonoutput, since it can never betruenow.null,""or[], at any depth, is nowempty: true. Before, only{},[],nulland blank strings were empty, so page scaffolding read as data.--validatefails on such results and the plain run prints the empty-result warning.0andfalsestill count as data.EXTRACT_DOMAIN_NOT_PREPARED(it wasEXTRACT_DOMAIN_NOT_ENABLED). A domain Extract is not enabled for isEXTRACT_DOMAIN_NOT_ENABLED. The page case is the newEXTRACT_PAGE_NOT_RECOGNISED. Code that compared against the oldEXTRACT_DOMAIN_NOT_ENABLEDdid so to fall back to Autoparse, and that fallback no longer exists, so there is nothing left for that comparison to do.REQS007: three cases, three answers
The API answers REQS007 in three cases. It names the case in a
reasonfield, which arrives with an upcoming API deploy. The CLI reads that field first. Until the deploy, it falls back to the problemtitleanddetail, which the API sends today. A comment insrc/core/http.tsmarks that fallback for removal.reasondomain_not_preparedEXTRACT_DOMAIN_NOT_PREPAREDzenrows extract prepare <domain> --url <url>command,--wait, status, and--cssmeanwhilepage_not_recognisedEXTRACT_PAGE_NOT_RECOGNISED--css. Preparing again does not change itdomain_not_enabledEXTRACT_DOMAIN_NOT_ENABLED--css, or contact support to have the site enabled; preparing does not helppage_not_recognisedis not a missing page kind. On a prepared domain Extract learns a new kind of page on its first request, so this answer means the page is not one Extract extracts (a home, search, login or category page), or a transient failure kept it from trying. Sending the agent topreparewould loop, because resubmitting a prepared domain returns itsreadyrecord at once. That is why a submit answeringreadyat once setsalready_prepared: true, and why thereadynext step repeats the page advice. None of the messages offer Autoparse.zenrows extract preparezenrows extract prepare <domain> --url <u> [--url <u>...] [--wait [--timeout <s>]]callsPOST /v1/extract/prepared-domains(X-API-Key) and returns at once.--urltakes 1 to 5 full http(s) URLs; anything else is rejected before any request.--waitpolls every 30 seconds (the same interval the MCP server tells agents) untilreadyorfailed; default timeout 900 seconds.zenrows extract prepare status <domain>shows status, state, roles, the failure, the monthly allowance (used / limit / remaining) and the next step.www.; it is not reduced to the registrable domain, because Extract prepares each host on its own (verified in production, below).preparingprepare status …)readyat oncealready_prepared: true; do not loop, use--cssin_progressEXTRACT_PREPARE_IN_PROGRESSonly when this account cannot read itinvalid_argument/ 409idempotency_conflictEXTRACT_PREPARE_INVALID(withreason)not_found(status)EXTRACT_PREPARE_NOT_FOUND, with the prepare commandout_of_allowanceEXTRACT_PREPARE_OUT_OF_ALLOWANCE(with used / limit); do not retry this month, use--cssoverloaded/disabledEXTRACT_PREPARE_UNAVAILABLE; retry in a few minutes, do not loopfailedEXTRACT_PREPARE_FAILED, exit 1, with the step for the failure code; whether the attempt used an allowance slot comes fromfailure.slot_consumed--waitruns outEXTRACT_PREPARE_TIMEOUT, with the status commandDocs and skills
skills/extract,skills/zenrows,agent-plugin/skills/*,README.md,docs/capabilities.md, the competitor-intelligence workflow, the pricing template andregistry/*.jsonteach the flow, the do-not-loop rule and the host rule. They mark Autoparse deprecated and say "any prepared domain (you can prepare one yourself)". Theagent-pluginextract skill describes the MCP server'sprepare_domain/prepared_domain_statustools, which ship in the matching zenrows-mcp PR.Production smoke test of the fallback removal
Local build of this branch against
https://api.zenrows.com, key from the environment, every request to the API counted. Target:https://web-scraping.dev/product/1, a domain that is not prepared (absent fromGET /v1/extract/domains) and not forbidden (a plain fetch returns200).zenrows extract <url>, defaultsextract=auto&mode=auto, 403)EXTRACT_DOMAIN_NOT_PREPARED(server code REQS007), first suggested commandzenrows extract prepare web-scraping.dev --url https://web-scraping.dev/product/1 --waitrunExtractwithfallbackAutoparse: trueextract=auto&mode=auto, 403)No step called prepare, so no allowance slot was used.
Verified against production
Local build of this branch against
https://api.zenrows.com, no base override, key from the environment. Second pass, with the final texts. The production API does not sendreasonyet, so these runs also exercise the title fallback. They ran before the code rename: the same output now starts✗ [EXTRACT_DOMAIN_NOT_PREPARED].The already-prepared submit used no allowance slot: the allowance stayed at
1 of 10before and after.The
page_not_recognisedREQS007 still does not reproduce in production: search, login, cart and listing pages on prepared domains all came back200with data. That path is covered by tests that use the API's body, with and withoutreason.From the first pass, still valid:
pt.wikipedia.organswers REQS007 althoughes.wikipedia.orgis ready, andwww.scrapethissite.comis stored asscrapethissite.com.scrapeme.live: REQS007, thenprepare --waitreachedreadyin 2 min 31 s, then the extract returned200with data. That run used one slot.Ordering
Release this only after the API deploy that adds the
reasonfield to REQS007 is live in production. The client readsreasonfirst and keeps a title match only for an API without it, but the docs describereason, and the docs and both client releases should go out after the API carries it.Release
No version change here. Per
docs/contributing.md, release-please sets the version from thefeat(extract)title after merge.Tests
npm run typecheckandnpm run build: clean. The repo has no linter beyondtsc.npm test: 394 passed, 0 failed.fallbackAutoparse: trueon REQS007 and on AUTH010: one request,EXTRACT_DOMAIN_NOT_PREPAREDwith the prepare command, and exactly one deprecation warning on stderr. No warning without the option or with itfalse.reasonand, separately, from the title only. Each test checks the advice order forpage_not_recognised, and that no prepare command and no Autoparse appear where they must not.refusalReasonprefers the field, and ignores a reason it does not know.prepare: 202 preparing, ready at once (already_prepared),--waitending in ready, failed and timeout, 409 followed and 409 unreadable, 400, 429, 503 overloaded and disabled,--urlvalidation, no automatic account creation.statuswith and without the allowance, and on 404.slot_consumed.zenrows extract.