Use page.waitForResponse() to synchronize with a response triggered by an action, then inspect its HTTPResponse with methods such as status(), ok(), headers(), and json(). An HTTP error such as 404 is still a response; it is not the same as a request that failed to load.
Wait for the response before triggering the action
Create the response promise before clicking or submitting. If the page responds quickly, starting the wait afterward can miss the response. The following illustrative Node.js pattern matches an endpoint and status; replace the URL path and selector with ones specific to your page.
As an Amazon Associate I earn from qualifying purchases.
const responsePromise = page.waitForResponse(response =>
response.url().includes('/api/items') && response.status() === 200
);
await page.click('button.load-items');
const response = await responsePromise;
const payload = await response.json();
waitForResponse() accepts a URL or a predicate and resolves with the matching HTTPResponse. A predicate may also be asynchronous. Make the match specific enough to distinguish the intended request from unrelated page traffic.
Set a timeout or cancellation signal
The documented default timeout is 30 seconds. Pass a timeout in the wait options when a different limit fits your operation, or configure the page’s default timeout. The wait also accepts an abort signal, which is useful when the surrounding operation is cancelled. Check the signature for the Puppeteer release used by your project; the relevant API documentation is version 25.12.0.
#1 Best Overall
Inspect status, URL, headers, and request
An HTTPResponse represents a response received by a Puppeteer page. Its core inspection methods provide the status code, status text, success check, URL, headers, and body. This example waits by URL, then logs response metadata:
const response = await page.waitForResponse('/api/items');
console.log(response.status());
console.log(response.statusText());
console.log(response.ok());
console.log(response.url());
console.log(response.headers());
const request = response.request();
console.log(request.method(), request.resourceType());
response.request() returns the matching HTTPRequest. The request can provide its URL, method, resource type, frame, and redirect-chain information. A redirect chain can help explain how the browser reached the URL associated with the response.
Understand status and success
response.ok() is true for status codes from 200 through 299. Check status() when you need to distinguish specific outcomes, including redirects or HTTP errors. A 404 or 503 still represents a completed HTTP exchange, so inspect the response status rather than treating requestfailed as the detector for ordinary HTTP error responses.
Recommended Free Tools
Rank #2
Read headers carefully
Puppeteer’s returned header object uses lowercase header names. Duplicate header values are combined with commas, except Set-Cookie, whose values are separated by newlines. Account for this format when reading a particular header or handling cookies.
Choose the right response body reader
Pick the reader based on the response content and the next step in your code. The body-reading methods are asynchronous.
| Method | Use it for | Important caveat |
|---|---|---|
json() |
A JSON response you want as a JavaScript value. | Throws if the body cannot be parsed with JSON.parse. |
text() |
UTF-8 text such as plain text or markup. | Can throw if the content is not UTF-8. |
content() or buffer() |
Bytes for binary-oriented handling or downstream processing. | Browser re-encoding based on headers or heuristics can affect the returned data. |
For example, after waiting for the response, use await response.json() for an API payload, or await response.text() when you need text. Handle parse and encoding errors according to the expected response format instead of assuming every matching endpoint returns valid JSON.
Rank #3
Distinguish HTTP errors from failed requests
Puppeteer exposes different paths for an HTTP response and a loading failure. HTTP error responses such as 404 and 503 still complete as requests and are associated with requestfinished; inspect the HTTPResponse status or ok() to determine the HTTP-level result. A request that fails while loading uses requestfailed and may have no ordinary response to inspect. Redirects finish one request and initiate another for the redirected URL.
Monitor one action or ongoing page traffic
Use waitForResponse() when code must synchronize a particular action with one matching response. Page-level response and request event listeners are an option when you need to observe ongoing traffic rather than wait for a single action. These mechanisms serve different observation patterns; the API references do not establish that one is universally faster.
Inspect additional response metadata
Depending on the response and environment, HTTPResponse also provides methods to inspect cache or service-worker provenance, timing, remote address, security details, and the associated frame. Treat these as inspection data rather than guaranteed non-null values: availability can vary, and the frame may be null for navigation to an error page.
Rank #4
Mock a response with request interception
To fulfill a request yourself, enable interception before calling request.respond(). The following illustrates the documented mechanism for returning JSON for one endpoint and continuing other intercepted requests:
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/api/items')) {
void request.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify({items: []}),
});
} else {
void request.continue();
}
});
Every intercepted request needs a resolution path. In production code, account for asynchronous handler errors and the interception coordination model in the Puppeteer version in use. Calling respond() without interception enabled throws; responding to a data URL request is a no-op. The documented example uses a 404 response with a text body, so the same mechanism can also model an HTTP error when needed.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Troubleshoot common response-inspection problems
- The wait times out: confirm the action actually fires, the endpoint and predicate match the outgoing response, and the timeout is appropriate. Create the wait promise before triggering the action.
- The response is 404 but no request failure arrived: this is expected for an HTTP error response. Inspect
status()orok(); request loading failures use the separaterequestfailedpath. json()throws: the response body may not be valid JSON, or the matched response may not be the API response you intended. Check its URL, status, and expected payload format.text()fails on the payload: the body may not be UTF-8 text. Use a bytes-oriented reader for binary-oriented handling.- Header lookup does not match: use lowercase names in the returned header object. Remember that duplicate values are combined, with newline separation for
Set-Cookie. request.respond()throws: enable request interception before fulfilling requests and ensure the request is not a data URL.
Or skip the browser setup
If your goal is a website screenshot rather than inspecting an HTTP response inside Puppeteer, ScreenshotNeo returns an image or PDF from one GET request. It is a different tool and does not replace Puppeteer’s response-inspection APIs.
cURL example (see the ScreenshotNeo API documentation):
Quick Recap
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status. Its MCP server provides screenshot tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo’s free plan.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




