Why marked exists
Real projects are mixed. The usual producer/consumer pair is the clearest case:
- the producer walks listing and search pages. These are the pages that get blocked, and there are a few hundred of them.
- the consumer walks the detail pages the producer found. There are a hundred thousand of them, and most hosts serve them without complaint.
marked, the spider says which requests are worth it and the rest go out direct and free.
Marking a request
marked reads one key: a truthy meta["unblock"] on the request.
meta={"page": 1, "unblock": True}). If you are migrating such a project, delete your middleware, set the job to marked, and change no spider code.
Opting out in all mode
In all mode two things stay direct:
Per-request options
When a request is routed, thesemeta keys shape that one call. They are ignored on requests that go out direct.
What routing changes about a request
Understanding this is what stops the two surprises below. A routed request is rewritten to call the API with your original URL as a parameter, and the API key is attached from the project. Your spider does not see any of that: the response is handed back with the original URL restored, so callbacks,response.follow, relative links and duplicate filtering all behave exactly as they did.
robots.txt is always fetched directly, never through the API, and is never charged. Routing it would be wrong three times over: it spends a paid call on an undefended file, the API rejects it, and a robots.txt that fails to load makes Scrapy behave as if there were no rules at all - so an unblocking platform would end up quietly ignoring robots rules on its users’ behalf.
In all mode, retries are capped at 2 if your project asks for more. Retrying through a paid API is paying repeatedly for the same page, and the API already retries internally. In marked mode your RETRY_TIMES is left alone, because most of that crawl is direct and free and capping it would make your own traffic give up early to save money that is not being spent.
Routing needs the project’s key
A routed job runs on the ScrapeUnblocker key stored on the project, which is taken from your account when the project is created. That is what makes the traffic count against your quota rather than anyone else’s. If a job is set tomarked or all and no usable key is stored, the job fails immediately with the reason on the row - it is not queued. Fix it under Settings → ScrapeUnblocker key. See projects for the three things you can do there.
Checking how much was actually routed
The middleware counts its own decisions into the crawl’s Scrapy stats, which are dumped at the end of the job log:
A
401 also writes a line into the log naming the likely cause: a key that does not match the host it is being used against. If the ratio of unblocked_requests to direct_requests is not what you expected, the mode is the first thing to check and the spider’s meta the second.
Changing the mode later
The mode is stored per job and per schedule, not per project, so it is chosen fresh each time you run and can differ between a manual test and the nightly schedule. Schedules that route every request are flagged as such in the schedules list, because a schedule spends money without anyone watching. Nothing that was already saved is quietly upgraded: a job or schedule created before the three modes existed keeps meaning what it meant - everything routed, or nothing.Next steps
Jobs
Run options in full, job states, and reading a crawl’s numbers.
Projects and settings
Where the ScrapeUnblocker key lives and how to replace it.

