Skip to main content
The Node.js SDK currently only exposes get() and post(). There is no put() method. If you need to send a PUT request, see Sending a PUT request below.
Besides client.get(), the SDK exposes client.post() for targets that expect a form submission or a data payload. It accepts the same config object as get, plus a third argument for headers and data.

Basic usage

const { ZenRows } = require("zenrows");

const client = new ZenRows("YOUR_ZENROWS_API_KEY");
const url = "https://httpbin.org/anything";

(async () => {
  const response = await client.post(
    url,
    {},
    {
      data: new URLSearchParams({
        key1: "value1",
        key2: "value2",
      }).toString(),
    },
  );

  const data = await response.json();

  console.log(data);
})();
data must be a string for form-encoded submissions. Encode a plain object with new URLSearchParams(obj).toString() first, as shown above. The SDK defaults the Content-Type header to application/x-www-form-urlencoded, so the body needs to match that format.

When to use POST

  • POST: submitting a form on the target site, triggering a search that requires a form submission, or calling a write endpoint on a target API.
  • GET (most cases): reading page content only needs client.get(). Reach for POST specifically when the target requires it.

Sending JSON instead of form data

Pass a plain object as data and override the Content-Type header to application/json. The SDK JSON.stringifys any object passed as data:
const response = await client.post(
  url,
  {},
  {
    headers: { "Content-Type": "application/json" },
    data: { key1: "value1" },
  },
);

Combining with request parameters

The config object (first argument after the URL) still works the same way it does for GET requests, so you can enable premium_proxy or other Universal Scraper API parameters:
const response = await client.post(
  url,
  { premium_proxy: true },
  { data: new URLSearchParams({ key1: "value1" }).toString() },
);
js_render only works with GET requests (client.get()). It is not supported on POST requests.

Sending a PUT request

The SDK doesn’t expose a put() method, so call the ZenRows API directly with native fetch for PUT:
const params = new URLSearchParams({
  url: "https://httpbin.org/anything",
  apikey: "YOUR_ZENROWS_API_KEY",
});

const response = await fetch(`https://api.zenrows.com/v1/?${params.toString()}`, {
  method: "PUT",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({ key1: "value1" }).toString(),
});
This loses the SDK’s automatic retries and concurrency queue for that call. If you need those for PUT-heavy workloads, consider using the Python SDK instead, which supports put() natively.

Troubleshooting

  • Target site doesn’t reflect the submitted data: Some forms require specific headers (like a Referer) to accept the submission. See Custom Headers.
  • Getting REQS005 Method Not Allowed: The target endpoint doesn’t accept the HTTP verb you’re using. ZenRows only supports GET, POST, and PUT at the API level; confirm the target expects one of these.
  • Body doesn’t match Content-Type: If data is a plain object, it’s sent as JSON regardless of what Content-Type you set. Either encode it as a string with URLSearchParams for form submissions, or explicitly set Content-Type: application/json when passing an object.

Pricing

POST requests are billed the same way as GET requests. Cost depends on the config you use, not the HTTP method:
ConfigurationCost multiplier vs. basic
Basic request1x
premium_proxy: true10x
See ZenRows Pricing for plan-specific rates.

FAQ (Frequently Asked Questions)

No. Only GET and POST are exposed as methods on the ZenRows class. See Sending a PUT request for a workaround using native fetch.
Yes. The config object (ZenRows/API options like premium_proxy) and data (the payload sent to the target) are independent arguments and can be combined.
The SDK doesn’t support this directly. Any object passed as data is run through JSON.stringify(), which doesn’t serialize a FormData instance correctly. For file uploads, call the ZenRows API directly with native fetch and a FormData body instead, the same way as the PUT workaround above.