Core Concepts

Request Config

Every Rezo request method accepts a configuration object. The request() method takes a full RezoRequestConfig; convenience methods like get(url, options?) merge the options into the config automatically.

const response = await rezo.request({
  url: 'https://api.example.com/users',
  method: 'GET',
  timeout: 5000
});

// Equivalent shorthand
const response = await rezo.get('https://api.example.com/users', {
  timeout: 5000
});

URL and Method

url

The target URL for the request. Can be a string or a URL object. When a baseURL is configured on the instance, relative URLs are resolved against it.

{ url: 'https://api.example.com/users' }
{ url: '/users' }  // resolved against baseURL
{ url: new URL('https://api.example.com/users') }

method

The HTTP method. One of GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, or CONNECT. Default is GET when using the callable form.

{ method: 'POST' }

baseURL

Prepended to url unless url is absolute. Typically set on the instance rather than per-request.

{ baseURL: 'https://api.example.com/v2' }
// url: '/users' becomes 'https://api.example.com/v2/users'

Headers

headers

Request headers. Accepts multiple formats: a plain object, an array of [key, value] tuples, a Headers instance, or a RezoHeaders instance.

// Plain object
{ headers: { 'Authorization': 'Bearer token123', 'Accept': 'application/json' } }

// Array of tuples
{ headers: [['Authorization', 'Bearer token123'], ['Accept', 'application/json']] }

// RezoHeaders instance
import { RezoHeaders } from 'rezo';
const h = new RezoHeaders();
h.set('Authorization', 'Bearer token123');
{ headers: h }

Query Parameters

params

An object of query parameters appended to the URL. Values are properly encoded.

{ params: { page: 2, limit: 10, tags: 'node,typescript' } }
// URL becomes: ...?page=2&limit=10&tags=node%2Ctypescript

paramsSerializer

Custom function to serialize query parameters. Replaces the default encoding logic.

{
  params: { ids: [1, 2, 3] },
  paramsSerializer: (params) => qs.stringify(params, { arrayFormat: 'brackets' })
}
// URL becomes: ...?ids[]=1&ids[]=2&ids[]=3

Request Body

Rezo supports multiple body formats. Only one should be set per request.

body

The raw request body. Can be a string, Buffer, FormData, or any serializable object. Content type is auto-detected when not set.

{ body: JSON.stringify({ name: 'Alice' }) }
{ body: Buffer.from('binary data') }

json

A JavaScript object serialized as JSON. Automatically sets Content-Type: application/json.

{ json: { name: 'Alice', email: 'alice@example.com' } }

form

An object serialized as URL-encoded form data. Automatically sets Content-Type: application/x-www-form-urlencoded.

{ form: { username: 'alice', password: 'secret' } }

formData

An object or RezoFormData instance for multipart uploads. Automatically sets Content-Type: multipart/form-data with boundary.

{ formData: { file: buffer, name: 'photo.jpg' } }

import { RezoFormData } from 'rezo';
const fd = new RezoFormData();
fd.append('file', buffer, { filename: 'doc.pdf' });
{ formData: fd }

multipart

Alias for formData.

{ multipart: { file: buffer, name: 'photo.jpg' } }

Response Handling

responseType

Controls how the response body is parsed. Default is 'auto'.

ValueDescription
'auto'Auto-detect from Content-Type header (default)
'json'Parse as JSON object
'text'Return as string
'buffer'Return as Node.js Buffer
'arrayBuffer'Return as ArrayBuffer
'blob'Return as Blob (browser)
// Force JSON parsing
{ responseType: 'json' }

// Get raw HTML
{ responseType: 'text' }

// Get binary data
{ responseType: 'buffer' }

validateStatus

A function that determines whether the HTTP status code should resolve or reject the promise. Default: status >= 200 && status < 300.

// Accept all 2xx and 3xx
{ validateStatus: (status) => status >= 200 && status < 400 }

// Never throw on any status code
{ validateStatus: () => true }

// Only accept 200
{ validateStatus: (status) => status === 200 }

// Disable status validation (same as () => true)
{ validateStatus: null }

decompress

Whether to automatically decompress gzip, deflate, and brotli responses. Default is true.

{ decompress: false }

Authentication

auth

Basic authentication credentials. Sets the Authorization: Basic ... header.

{
  auth: {
    username: 'alice',
    password: 'secret123'
  }
}

Timeouts

timeout

Request timeout in milliseconds. Covers the entire request from connection to response. Default is no timeout.

{ timeout: 5000 }  // 5 seconds

Redirects

followRedirects

Whether to automatically follow HTTP redirects (3xx responses). Default is true.

{ followRedirects: false }

maxRedirects

Maximum number of redirects to follow before throwing. Default is 10.

{ maxRedirects: 5 }

Retry

retry

Configuration for automatic retry on failed requests. Accepts a boolean, a number, or a detailed config object.

// Retry up to 3 times
{ retry: 3 }

// Enable with default settings
{ retry: true }

// Full configuration
{
  retry: {
    limit: 5,              // Max retry attempts
    delay: 1000,           // Base delay in ms
    backoff: 2,            // Exponential backoff multiplier (1s, 2s, 4s, 8s...)
    maxDelay: 30000,       // Cap delay at 30 seconds
    retryOn: [408, 429, 500, 502, 503, 504],
    retryOnTimeout: true,
    retryOnNetworkError: true,
    methods: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'],
    condition: (error, attempt) => attempt < 3,
    onRetry: (error, attempt, delay) => {
      console.log(`Retry ${attempt} after ${delay}ms: ${error.code}`);
    },
    onRetryExhausted: (error, totalAttempts) => {
      console.log(`All ${totalAttempts} retries failed`);
    }
  }
}

Backoff strategies:

{ retry: { backoff: 2 } }               // Exponential: 1s, 2s, 4s, 8s...
{ retry: { backoff: 'exponential' } }    // Same as 2
{ retry: { backoff: 'linear' } }         // Linear: 1s, 2s, 3s, 4s...
{ retry: { backoff: (attempt) => Math.min(attempt * 1000, 30000) } }  // Custom

Cookies

jar

A RezoCookieJar instance for managing cookies on this request. When set, overrides the instance-level jar for this request only.

import { RezoCookieJar } from 'rezo';

const jar = new RezoCookieJar();
{ jar }

cookies

Cookies to send with the request. Accepts multiple formats: an array of Cookie objects, serialized cookies, a Netscape-format string, or an array of Set-Cookie strings.

// Set-Cookie header array
{ cookies: ['session=abc123; Domain=example.com; Path=/'] }

// Serialized objects
{ cookies: [{ key: 'session', value: 'abc123', domain: 'example.com' }] }

Rate Limit Waiting

waitOnStatus

Automatically wait and retry when receiving rate-limit responses. Runs before the retry system.

// Wait on 429 status (default behavior)
{ waitOnStatus: true }

// Wait on specific status codes
{ waitOnStatus: [429, 503] }

waitTimeSource

Where to extract the wait time from rate-limit responses. Default is 'retry-after'.

// Standard Retry-After header
{ waitTimeSource: 'retry-after' }

// Custom header
{ waitTimeSource: { header: 'X-RateLimit-Reset' } }

// JSON response body path
{ waitTimeSource: { body: 'data.retry_after' } }

// Custom function
{
  waitTimeSource: (response) => {
    const reset = response.headers.get('x-ratelimit-reset');
    return reset ? parseInt(reset) - Math.floor(Date.now() / 1000) : null;
  }
}

maxWaitTime

Maximum time to wait in milliseconds. If the extracted wait time exceeds this, the request fails instead of waiting. Default is 60000.

{ maxWaitTime: 120000 }  // 2 minutes max

maxWaitAttempts

Maximum number of wait attempts before giving up. Default is 3.

{ maxWaitAttempts: 5 }

defaultWaitTime

Fallback wait time in milliseconds when the source returns nothing. Default is 1000.

{ defaultWaitTime: 2000 }

Proxy

proxy

Proxy configuration as a URL string or a detailed options object. Supports HTTP, HTTPS, SOCKS4, and SOCKS5.

// URL string
{ proxy: 'http://proxy.example.com:8080' }
{ proxy: 'socks5://user:pass@127.0.0.1:1080' }

// Detailed options
{
  proxy: {
    protocol: 'http',
    host: 'proxy.example.com',
    port: 8080,
    auth: {
      username: 'user',
      password: 'pass'
    },
    timeout: 10000
  }
}

useProxyManager

Whether to use the instance-level ProxyManager for this request. Set to false to bypass proxy rotation on a per-request basis.

{ useProxyManager: false }

Caching

cache

Per-request cache mode, following the Fetch API cache directive. The instance must have caching enabled.

// Force fresh request, bypass cache
{ cache: 'reload' }

// Never store this response
{ cache: 'no-store' }

// Only return cached response (throws if not cached)
{ cache: 'only-if-cached' }

// Use cached response if available, otherwise fetch
{ cache: 'force-cache' }

dnsCache

Per-request DNS cache configuration.

// Enable with defaults
{ dnsCache: true }

// Custom TTL and max entries
{ dnsCache: { ttl: 300000, maxEntries: 500 } }

Connection

keepAlive

Whether to keep the TCP connection alive for reuse. Default is false.

{ keepAlive: true }

keepAliveMsecs

How long to keep idle connections alive in milliseconds. Only applies when keepAlive is true. Default is 60000.

{ keepAlive: true, keepAliveMsecs: 30000 }

httpVersion

Control the HTTP protocol version. When http2 is true, the adapter uses HTTP/2 where supported.

http2

Enable HTTP/2 for this request (Node.js HTTP adapter only).

{ http2: true }

Cancellation

signal

An AbortSignal to cancel the request.

const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

const response = await rezo.get('https://api.example.com/slow', {
  signal: controller.signal
});

Stealth

Stealth configuration is set at the instance level via RezoDefaultOptions.stealth. See the Stealth documentation for details on browser fingerprint spoofing.

Queue

queue

Assign a specific queue for this request, overriding the instance queue.

import { RezoQueue } from 'rezo';

const priorityQueue = new RezoQueue({ concurrency: 1 });
{ queue: priorityQueue }

Debugging

debug

Enable debug logging for this request. Logs request/response details to the console.

{ debug: true }

verbose

Enable verbose logging with detailed internal information.

{ verbose: true }

trackUrl

Log the redirect chain with status codes and retry attempts.

{ trackUrl: true }

Advanced Options

contentType

Explicitly set the Content-Type MIME type for the request.

{ contentType: 'application/xml' }

encoding

Character encoding for the request body and response data.

{ encoding: 'utf-8' }

maxBodyLength

Maximum allowed size of the request body in bytes.

{ maxBodyLength: 10 * 1024 * 1024 }  // 10 MB

maxRate

Maximum transfer rate in bytes per second. Single number for both directions, or a [upload, download] tuple.

{ maxRate: 1024 * 1024 }           // 1 MB/s for both
{ maxRate: [512 * 1024, 1024 * 1024] }  // 512 KB/s up, 1 MB/s down

transformRequest

Array of functions to transform the request data before sending.

{
  transformRequest: [
    (data, headers) => {
      // Modify data or headers
      return data;
    }
  ]
}

transformResponse

Array of functions to transform the response data after receiving.

{
  transformResponse: [
    (data) => {
      // Transform response data
      return data.results;
    }
  ]
}

rejectUnauthorized

Whether to reject requests with invalid SSL certificates. Default is true.

// Allow self-signed certificates (testing only)
{ rejectUnauthorized: false }

hooks

Per-request lifecycle hooks merged with instance hooks.

{
  hooks: {
    beforeRequest: [(options) => {
      console.log('Sending request to:', options.url);
    }],
    afterResponse: [(response) => {
      console.log('Got status:', response.status);
      return response;
    }]
  }
}

beforeRedirect

Callback invoked before following a redirect. Return false to stop, true to follow, or an object for granular control.

{
  beforeRedirect: ({ status, url, headers, sameDomain }) => {
    if (!sameDomain) return false;  // Block cross-domain redirects
    if (status === 303) {
      return { redirect: true, url: url.toString(), method: 'GET' };
    }
    return true;
  }
}

dnsLookup

Custom DNS lookup function replacing Node.js’s default dns.lookup.

{
  dnsLookup: (hostname, options, callback) => {
    // Custom resolution logic
    callback(null, '127.0.0.1', 4);
  }
}