A lead scraper's price is not set by how many pages you pull. It is set by how hard those pages fight back, and by each vendor's private definition of a failed request. On ZenRows' published rates, one balance of 250,000 credits fetches about 250,000 plain pages or about 10,000 well defended ones. Same plan, same money, twenty five times the yield.
Two of the three scraping vendors I priced this week put the same promise on the pricing page: you only pay for successful requests. Both of them then define a failed request in the very next sentence, and neither definition is the one you are carrying in your head. The third vendor does not use the word at all, which turns out to be the most honest position of the lot.
The word failure is the vendor's to define. The status code is not.
The mistake: you budgeted by page count
The question I get is always a row count. Forty thousand contacts from these directories, what does that cost. Across 500+ projects I have never been able to answer it, because the row count is the input the buyer can see and it is close to irrelevant to the invoice.
ZenRows publishes the proof on its own pricing page. At 250,000 monthly credits the page reads: "Runs about 250K standard pages, 50K with JavaScript, or 10K hard-protected, all from one shared balance." That is the same $57 a month Launch plan costing you roughly two hundredths of a cent per page on an open directory and just over half a cent per page on a site with a real anti-bot wall in front of it. Nothing about your project changed. The target's defences did.
Those three figures imply the exchange rate: a plain page costs 1 credit, a JavaScript page about 5, a hard-protected page about 25. Run 18,000 pages through it. If 12,000 are plain and 6,000 are protected, that is 12,000 credits plus 150,000, so the protected third of the job is 93 percent of the bill. Work the same 18,000 pages as all-plain and you have quoted 18,000 credits. The row count was identical in both cases and the invoice was nine times apart.
Three vendors, three definitions of a failed request
ZenRows is the most direct. Its pricing FAQ asks "Do you charge for failed requests?" and answers: "Never. You only spend credits on successful requests. Not Found (404) and Gone (410) responses count as successful results." So a dead page is a success, and you pay for it.
Firecrawl, on rates effective 4 September 2026, splits it the same way and says the quiet part out loud: "A scrape that returns no result is not charged. A page that responds with an error status such as 403 or 404 is still returned to you and costs 1 credit." One credit is one page on its Hobby plan, which is $19 a month for 5,000 credits.
Apify declines the framing altogether. Its pricing page describes pay per usage as "you only pay for the platform usage consumed by the Actor's runs: compute units, data transfer, storage operations, and residential or SERP proxies", at $0.2 per compute unit on Free and Starter and $0.16 on the $199 Scale plan. The words success, failed and refund do not appear anywhere on that page. That is a measurement of the pricing page, not an accusation: Apify bills consumption, and a blocked request consumes the same compute and proxy bandwidth as a successful one. Our Apify and Firecrawl comparison covers what each is actually good at.
I asked for 10,000 supplier pages and got 6,200 usable rows.
No vendor bills on this, because no vendor can see the schema you needed filled.
The request did not come back with a response at all.
A block comes back with a response. That is precisely why it is billable.
The status code that decides your bill
Read those three carve-outs together and one status code is doing all the work. MDN defines HTTP 403 as the server having "understood the request but refused to process it", and adds that "authenticating or re-authenticating makes no difference". That is a description of being blocked.
Firecrawl names 403 in the list of statuses it charges for. ZenRows names 404 and 410 as billable successes and does not mention 403 in that answer at all, which means the single status that decides a scraping budget is the one its pricing FAQ leaves unaddressed. Neither vendor is hiding anything; both published it. The problem is that a buyer reads "we never charge for failed requests" and stops there, which is exactly where the sentence stops being true for them.
This is not a reason to distrust any of the three. It is a reason to stop treating the phrase as information. All three sentences are true, they are published in plain sight, and they describe three different products. The buyer's error is reading one promise and assuming it is the industry's default, then discovering the carve-out on the invoice rather than on the pricing page.
Three moves before you sign anything
Sample 200 of the deepest pages, not the homepage
A homepage is the least defended page on any site, so testing against it tells you nothing. Take the page you actually need, the one behind the search box with the contact details on it, pull 200 of them, and count how many come back with your field populated. That ratio is your real price multiplier. All three vendors here publish a free tier big enough to run that sample: ZenRows 5,000 credits a month, Firecrawl 1,000, Apify $5 of platform usage.
Ask about the status code, not about failure
Send the vendor one written question: what do you charge for a 403? Do not ask whether they charge for failed requests, because you have now seen three different answers to that question and all three were technically true. Get the answer in writing before the card goes in.
Quote your client on usable rows, never on pages attempted
If you sell a list build on pages attempted you have handed your client your vendor's definition of success and kept none of the risk yourself. Price on delivered, deduplicated, field-complete rows. It is the only unit both sides can check, and the tools you pick then become your problem rather than theirs.
One more line item people fold into the scrape and should not. Scraped contacts are raw material, and getting them into an inbox is a separate build with its own domains, authentication and warm-up. We run that half as cold email infrastructure, and in my experience the teams who quote scraping and sending as one number nearly always underfund the second one. Worth reading where the legal line sits before either.
The bottom line
Price the defences, not the rows. Get the 403 answer in writing. Then quote your own client in the only unit that survives contact with a bot wall, which is usable rows delivered. Do that and the scraping bill becomes the most predictable line in the project instead of the one that ruins the margin in month two.