ZenRows (get and post) resolves with a standard Response object, the same one native fetch returns. The SDK doesn’t wrap or transform it, so everything you already know about the Fetch API applies directly.
Commonly used properties and methods
| Property / method | Returns | Use it when |
|---|---|---|
await response.text() | Response body as a string | Reading HTML or plain text |
await response.json() | Parsed JSON | The body is JSON (e.g. json_response: true) |
await response.arrayBuffer() | Response body as raw bytes | Handling binary data (PDFs, screenshots, images) |
response.status | HTTP status code, e.g. 200 | Checking exactly what happened |
response.ok | true if status is 200-299 | Quick success check |
response.headers | Headers object | Reading ZenRows monitoring headers |
response.url | The final URL that was requested | Debugging what was actually sent |
- Text / HTML
- Binary (PDF, screenshot)
- JSON
Reading ZenRows-specific headers
ZenRows adds monitoring headers to every response, useful for debugging and tracking usage:Zr- to distinguish them from ZenRows’ own headers. See the full list in the Universal Scraper API setup guide.
Checking success before using the body
Because the SDK resolves with the response as-is rather than throwing on error status codes, always confirm the request succeeded first:Error Handling and Retries
More on this pattern, plus how to configure automatic retries.
Troubleshooting
await response.json()throws aSyntaxError: The body isn’t JSON. Confirm you requestedjson_response: trueor that the target actually returns JSON before calling.json().- Saved file (PDF, screenshot, image) is corrupted: You wrote
response.text()instead ofresponse.arrayBuffer(), or forgot to wrap it inBuffer.from(...)before writing to disk. - Calling
response.text()twice throws an error: AResponsebody can only be read once. Store the result of the first call in a variable and reuse it instead of calling.text()/.json()again. response.urldoesn’t match the URL you passed: This is expected. It’s the full URL sent to ZenRows’ API (including yourapikeyand config as query parameters), not the target URL by itself.
Pricing
The response itself doesn’t add cost. ZenRows adds two headers to help you track usage:X-Request-Cost: the dollar cost of the request (e.g.,0.001)X-Request-Credits: the number of credits consumed by the request
| Configuration | Cost multiplier vs. basic |
|---|---|
| Basic request | 1x |
js_render: true | 5x |
premium_proxy: true | 10x |
js_render: true + premium_proxy: true | 25x |
FAQ (Frequently Asked Questions)
Is the response object specific to ZenRows?
Is the response object specific to ZenRows?
No. It’s the standard
Response object from the Fetch API. Any Fetch API documentation or Stack Overflow answer about it applies here too.How do I get the response as a JavaScript object?
How do I get the response as a JavaScript object?
Call
await response.json() if the body is JSON. For example, when using json_response: true or autoparse: true on structured data.Where do I find how much a request cost?
Where do I find how much a request cost?
Check the response headers:
X-Request-Cost gives you the dollar cost (e.g., 0.001) and X-Request-Credits gives you the number of credits consumed. Read them with response.headers.get("X-Request-Cost") and response.headers.get("X-Request-Credits").