BBREClient.request()
The request() method is the core function of the BBREClient
class and the foundation for all HTTP communication through the BBRE (Browser-Backed
Request Engine) service. Every other HTTP convenience method on the client, including
get(), post(), put(), delete(),
patch(), head(), and options(), is a thin wrapper
around request(). When you call request(), you pass a single
options object that describes the target URL, HTTP method, headers, body content, proxy
settings, fingerprint overrides, cookie handling, timeout behavior, and whether the
request should execute synchronously or asynchronously. The method processes these
options, sends the request to the BBRE API, waits for the result (either by polling or
by synchronous execution), and returns a standardized response object containing the
HTTP status code, response headers, body content, parsed data, cookies, processing
profile information, and timing data. This page provides a complete reference for every
request option, the response object structure, body handling strategies, cookie formats,
fingerprint merging behavior, synchronous versus asynchronous execution flows, and
practical code examples covering common and advanced usage patterns.
The request() method is asynchronous by default. It returns a Promise that
resolves to a response object when the request completes. In the default async flow, the
SDK sends a POST /request/create call to create a task, then polls
POST /request/result at the configured polling interval until the task
finishes. When you set sync: true in the options, the SDK instead sends a
single POST /request/execute call that blocks until the result is ready.
The url parameter is the only required option. All other options have
sensible defaults inherited from the client constructor configuration or from built-in
fallback values.
Method Signature
The request() method accepts a single options object as its argument. This
object contains all the parameters that control the HTTP request, including the target
URL, HTTP method, headers, body, proxy, fingerprint, cookies, and execution mode. The
method returns a Promise that resolves to a standardized response object. If the request
fails due to a network error, timeout, or API error, the Promise rejects with an error
object containing details about the failure.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
const response = await client.request(options);
The options parameter is a plain JavaScript object. The only required
property is url, which specifies the target URL for the request. All other
properties are optional and fall back to either the client constructor defaults or
built-in default values. The following sections describe every available option in detail.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
const response = await client.request({
url: "https://api.example.com/data",
method: "GET",
headers: { "Accept": "application/json" },
params: { page: 1, limit: 50 },
mode: "passive",
sensibility: "medium",
timeout: 120,
cookies: {},
fingerprint: {},
sync: false,
allowRedirects: true,
maxRedirects: 10,
verify: true
});
RequestOptions Parameters
The options object supports a comprehensive set of parameters that give you full control over every aspect of the HTTP request. Parameters are grouped into categories: target and method, body and data, network and proxy, browser identity, execution control, and security. The following table lists every parameter with its type, requirement status, default value, and description. Detailed explanations for key parameters follow in dedicated sections below.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string | required | - | The target URL for the HTTP request. Must be a fully qualified URL including the protocol (http or https). |
method |
string | optional | "GET" |
The HTTP method to use. Accepts standard methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. |
headers |
object | optional | {} |
Custom HTTP headers to include in the request. Merged with BBRE engine default headers. Your custom headers take precedence over defaults. |
body |
any | optional | - | The raw request body. Sent as-is without automatic serialization. Use for pre-formatted body content or binary data. |
data |
any | optional | - | Alias for body. If both body and data are provided, body takes precedence. |
json |
any | optional | - | JSON request body. Automatically serialized with JSON.stringify() and sets Content-Type: application/json header. |
files |
any | optional | - | File upload data for multipart form submissions. Accepts file objects or file path references. |
params |
object | optional | - | Query parameters appended to the URL. Object keys become parameter names and values become parameter values. Automatically URL-encoded. |
mode |
string | optional | from constructor | Override the client default mode for this request. Accepts "passive" or "adaptive". |
sensibility |
string | optional | from constructor | Override the client default sensibility for this request. Accepts "low", "medium", or "high". |
fingerprint |
object | optional | {} |
Request-level fingerprint attributes. Merged with the client default fingerprint. Request-level values override constructor defaults for matching keys. |
proxy |
object | optional | from constructor | Override the client default proxy for this request. Requires host and port. Optionally includes username and password. |
cookies |
object/string/array | optional | {} |
Request cookies. Accepts an object of key-value pairs, a raw cookie header string, or an array of cookie objects. |
timeout |
number | optional | from constructor | Override the client default timeout (in seconds) for this request. Controls the maximum wait time for the entire request lifecycle. |
sync |
boolean | optional | false |
When true, uses synchronous execution via POST /request/execute. When false (default), uses async task creation and polling. |
allowRedirects |
boolean | optional | true |
Whether to follow HTTP redirects (301, 302, 303, 307, 308). When false, the response contains the redirect status code and Location header. |
maxRedirects |
number | optional | 10 |
Maximum number of redirects to follow before stopping. Prevents infinite redirect loops. Only applies when allowRedirects is true. |
verify |
boolean | optional | true |
Whether to verify SSL/TLS certificates. Set to false to allow requests to servers with self-signed or expired certificates. |
auth |
object | optional | - | HTTP Basic or Digest authentication credentials. Object with username and password string properties. |
cert |
object | optional | - | Client certificate for mutual TLS authentication. Object with certificate and key data. |
sessionId |
string | optional | - | Session ID for session-bound requests. When provided, the request executes within the specified session context, sharing cookies and browser state. |
Async vs Sync Execution
The request() method supports two execution modes that determine how the
BBRE API processes your request and returns the result. The default asynchronous mode
creates a task and polls for the result, while the synchronous mode sends a single
blocking request that waits for the result before responding. Both modes return the
same response object format, so your response handling code works identically regardless
of which execution mode you choose.
Asynchronous Execution (Default)
When sync is false (the default), the SDK follows a two-step
process. First, it sends a POST /request/create call to the BBRE API with
your request options. The API responds immediately with a taskId. The SDK
then enters a polling loop, calling POST /request/result with the
taskId at the interval specified by the client pollingInterval
configuration. Each poll returns the current task status. When the status changes to
completed, the SDK extracts the response data and returns it. If the task
status becomes failed or the timeout is reached, the SDK throws an error.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY",
pollingInterval: 2000,
timeout: 120
});
async function asyncRequest() {
const response = await client.request({
url: "https://api.example.com/data",
method: "GET"
});
console.log("Status:", response.statusCode);
console.log("Body:", response.body);
}
asyncRequest();
The asynchronous flow is ideal for most use cases because it allows the BBRE engine to queue and process requests efficiently. The polling mechanism ensures that your application receives the result as soon as it is available without holding an open HTTP connection for the entire processing duration. This is especially important for adaptive mode requests that may take 30 seconds or more to complete.
Synchronous Execution
When sync is true, the SDK sends a single
POST /request/execute call that blocks until the BBRE engine finishes
processing the request. The API holds the connection open and returns the complete
response when the task finishes. There is no polling involved. This mode is simpler
but keeps an HTTP connection open for the entire processing duration, which may cause
issues with connection timeouts on slow requests or when processing many concurrent
requests.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function syncRequest() {
const response = await client.request({
url: "https://api.example.com/data",
method: "GET",
sync: true
});
console.log("Status:", response.statusCode);
console.log("Body:", response.body);
}
syncRequest();
Choosing Between Async and Sync
The following table compares the two execution modes to help you choose the right one for your use case. In general, the default asynchronous mode is recommended for production applications, while synchronous mode is convenient for simple scripts, testing, and scenarios where you need immediate results without polling overhead.
| Aspect | Async (default) | Sync (sync: true) |
|---|---|---|
| API Flow | POST /request/create then poll POST /request/result |
Single POST /request/execute |
| Connection Behavior | Short-lived connections for each poll request | Single long-lived connection held open until completion |
| Timeout Handling | Client-side timeout based on elapsed time across polls | Server-side timeout on the single connection |
| Concurrency | Better for high concurrency with many parallel requests | Each request holds a connection, limiting practical concurrency |
| Simplicity | Slightly more complex internal flow (transparent to the developer) | Simpler single-request flow |
| Best For | Production applications, batch processing, long-running requests | Simple scripts, testing, quick one-off requests |
Response Object
The request() method returns a standardized response object that provides
access to every aspect of the HTTP response. The response object is created by the
internal formatResponse function, which normalizes the raw API response
into a consistent structure regardless of whether the request was executed synchronously
or asynchronously. The response object includes the HTTP status code, response headers,
the raw body as a string, a parsed version of the body (automatically parsed as JSON
when the response Content-Type is application/json), cookies set by the
target server, profile information from the BBRE engine, and the total processing time.
Several convenience aliases are provided for common access patterns.
| Property | Type | Description |
|---|---|---|
success |
boolean | Always true when the request completes without errors. Indicates that the BBRE engine successfully processed the request and received a response from the target server. |
statusCode |
number | The HTTP status code returned by the target server. Common values: 200 (OK), 301 (Redirect), 403 (Forbidden), 404 (Not Found), 500 (Server Error). |
status |
number | Alias for statusCode. Provided for convenience and compatibility with other HTTP client libraries. |
headers |
object | The HTTP response headers as a key-value object. Header names are lowercase. Multiple values for the same header are joined with commas. |
body |
string | The raw response body as a string. Contains the unmodified content returned by the target server. |
data |
any | The parsed response body. Automatically parsed as JSON when the response Content-Type header contains application/json. Otherwise, contains the raw body string. |
text |
string | Alias for body. Provided for compatibility with libraries that use text as the response body property name. |
content |
string | Alias for body. Provided for compatibility with libraries that use content as the response body property name. |
cookies |
object | Cookies set by the target server in the response. Parsed from Set-Cookie headers into a key-value object where keys are cookie names and values are cookie values. |
profile |
object/null | The browser profile used by the BBRE engine for this request. Contains fingerprint details like user agent, platform, and screen resolution. May be null for some request types. |
processingTime |
number | The total time in milliseconds that the BBRE engine spent processing the request. Includes network time, rendering time (for adaptive mode), and any evasion delays. |
json() |
function | A convenience method that parses the body string as JSON and returns the resulting object. Throws a SyntaxError if the body is not valid JSON. |
Accessing Response Data
The response object provides multiple ways to access the response body depending on your
needs. Use body (or its aliases text and content)
for the raw string content. Use data for automatically parsed JSON content.
Use the json() method when you want explicit JSON parsing with error handling.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function accessResponseData() {
const response = await client.request({
url: "https://api.example.com/users",
method: "GET"
});
console.log("Success:", response.success);
console.log("Status Code:", response.statusCode);
console.log("Status (alias):", response.status);
console.log("Raw body:", response.body);
console.log("Text (alias):", response.text);
console.log("Content (alias):", response.content);
console.log("Parsed data:", response.data);
console.log("JSON parse:", response.json());
console.log("Headers:", response.headers);
console.log("Cookies:", response.cookies);
console.log("Profile:", response.profile);
console.log("Processing time:", response.processingTime, "ms");
}
accessResponseData();
Response Object Example
The following shows a typical response object structure returned by the
request() method when fetching a JSON API endpoint.
{
"success": true,
"statusCode": 200,
"status": 200,
"headers": {
"content-type": "application/json; charset=utf-8",
"content-length": "256",
"server": "nginx",
"date": "Wed, 15 Jan 2025 10:30:00 GMT"
},
"body": "{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}",
"data": {
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
},
"text": "{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}",
"content": "{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}",
"cookies": {
"session_id": "abc123def456",
"tracking": "xyz789"
},
"profile": {
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"platform": "Win32",
"language": "en-US"
},
"processingTime": 3450
}
Body Handling
The request() method provides four different ways to send a request body:
body, data, json, and files. Each
option handles serialization and Content-Type headers differently. Understanding when to
use each option ensures that your request body is formatted correctly for the target
server.
body Parameter
The body parameter sends the request body exactly as provided, without any
automatic serialization or Content-Type header modification. Use this when you have
pre-formatted body content, such as a raw string, URL-encoded form data, or XML content.
You are responsible for setting the appropriate Content-Type header when
using body.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function sendFormData() {
const response = await client.request({
url: "https://api.example.com/submit",
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "username=alice&password=secret123&remember=true"
});
console.log("Status:", response.statusCode);
}
sendFormData();
data Parameter
The data parameter is an alias for body. It behaves identically
and exists for compatibility with developers who are accustomed to HTTP client libraries
that use data as the body property name. If both body and
data are provided in the same options object, body takes
precedence and data is ignored.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function sendWithDataAlias() {
const response = await client.request({
url: "https://api.example.com/submit",
method: "POST",
headers: { "Content-Type": "text/plain" },
data: "This is a plain text body sent using the data parameter"
});
console.log("Status:", response.statusCode);
}
sendWithDataAlias();
json Parameter
The json parameter is the most convenient way to send JSON data. When you
provide a value for json, the SDK automatically serializes it using
JSON.stringify() and sets the Content-Type header to
application/json. This eliminates the need to manually serialize your data
and set the correct header. The json parameter accepts any value that is
serializable by JSON.stringify(), including objects, arrays, strings,
numbers, and booleans.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function sendJsonData() {
const response = await client.request({
url: "https://api.example.com/users",
method: "POST",
json: {
name: "Alice Johnson",
email: "[email protected]",
role: "developer",
preferences: {
theme: "dark",
notifications: true
}
}
});
console.log("Status:", response.statusCode);
console.log("Created user:", response.data);
}
sendJsonData();
files Parameter
The files parameter handles file upload data for multipart form submissions.
When you provide file data, the BBRE engine constructs a multipart/form-data request
body with the appropriate boundaries and Content-Type headers. This is useful for
uploading images, documents, or other binary files to target servers.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function uploadFile() {
const response = await client.request({
url: "https://api.example.com/upload",
method: "POST",
files: {
document: {
filename: "report.pdf",
content: "base64-encoded-file-content",
contentType: "application/pdf"
}
}
});
console.log("Upload status:", response.statusCode);
console.log("Upload result:", response.data);
}
uploadFile();
Body Priority Order
When multiple body parameters are provided in the same options object, the SDK applies the following priority order to determine which one to use. Only one body source is sent with the request.
| Priority | Parameter | Behavior |
|---|---|---|
| 1 (highest) | json |
Serialized with JSON.stringify(), Content-Type set to application/json |
| 2 | files |
Formatted as multipart/form-data with appropriate boundaries |
| 3 | body |
Sent as-is without modification |
| 4 (lowest) | data |
Alias for body, used only when body is not provided |
Cookie Handling
The cookies parameter in the request options accepts three different formats
to accommodate various cookie management patterns. You can pass cookies as a simple
key-value object, as a raw cookie header string, or as an array of cookie objects with
extended attributes. The BBRE engine normalizes all three formats into the appropriate
Cookie header before sending the request to the target server. Cookies
returned by the target server are available in the response object cookies
property as a parsed key-value object.
Object Format
The simplest and most common format is a plain JavaScript object where keys are cookie names and values are cookie values. This format is ideal when you have a small number of cookies with simple string values.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithObjectCookies() {
const response = await client.request({
url: "https://shop.example.com/cart",
method: "GET",
cookies: {
session_id: "abc123def456",
user_pref: "dark_mode",
currency: "USD"
}
});
console.log("Status:", response.statusCode);
console.log("Response cookies:", response.cookies);
}
requestWithObjectCookies();
String Format
You can pass cookies as a raw cookie header string in the standard
name=value; name=value format. This is useful when you have cookies from
a previous HTTP response or from browser developer tools that you want to replay exactly
as they were received.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithStringCookies() {
const cookieString = "session_id=abc123def456; user_pref=dark_mode; currency=USD";
const response = await client.request({
url: "https://shop.example.com/cart",
method: "GET",
cookies: cookieString
});
console.log("Status:", response.statusCode);
}
requestWithStringCookies();
Array Format
For advanced cookie management, you can pass an array of cookie objects. Each object
contains the cookie name and value as required properties,
with optional properties for domain, path, and other cookie
attributes. This format gives you the most control over cookie behavior.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithArrayCookies() {
const response = await client.request({
url: "https://shop.example.com/cart",
method: "GET",
cookies: [
{ name: "session_id", value: "abc123def456", domain: ".example.com", path: "/" },
{ name: "user_pref", value: "dark_mode", domain: ".example.com", path: "/" },
{ name: "currency", value: "USD", domain: ".example.com", path: "/shop" }
]
});
console.log("Status:", response.statusCode);
}
requestWithArrayCookies();
Forwarding Response Cookies
A common pattern is to capture cookies from one response and forward them to subsequent
requests. This maintains session state across multiple requests to the same target server.
The response cookies property returns an object that you can pass directly
as the cookies option in the next request.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function maintainCookieSession() {
const loginResponse = await client.request({
url: "https://shop.example.com/login",
method: "POST",
json: { username: "alice", password: "secret123" }
});
const sessionCookies = loginResponse.cookies;
const cartResponse = await client.request({
url: "https://shop.example.com/cart",
method: "GET",
cookies: sessionCookies
});
console.log("Cart status:", cartResponse.statusCode);
console.log("Cart data:", cartResponse.data);
}
maintainCookieSession();
Fingerprint Merging
When you provide a fingerprint object in the request options, it is merged
with the default fingerprint configured in the client constructor. The merging follows a
shallow merge strategy where request-level values override constructor-level values for
matching keys. Keys that exist only in the constructor default are preserved. Keys that
exist only in the request options are added. This allows you to set a base fingerprint
identity in the constructor and selectively override specific attributes for individual
requests without repeating the entire fingerprint configuration.
Merge Behavior
The following table illustrates how fingerprint merging works with a concrete example. The constructor sets a base fingerprint with platform, timezone, and language. The request overrides the timezone and adds a screen attribute. The final merged fingerprint contains all four attributes.
| Attribute | Constructor Default | Request Override | Final Merged Value |
|---|---|---|---|
platform |
"Win32" |
not specified | "Win32" (from constructor) |
timezone |
"America/New_York" |
"Europe/London" |
"Europe/London" (request overrides) |
language |
"en-US" |
not specified | "en-US" (from constructor) |
screen |
not specified | { width: 1920, height: 1080 } |
{ width: 1920, height: 1080 } (from request) |
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY",
fingerprint: {
platform: "Win32",
timezone: "America/New_York",
language: "en-US"
}
});
async function requestWithMergedFingerprint() {
const response = await client.request({
url: "https://geo-restricted.example.com/content",
method: "GET",
fingerprint: {
timezone: "Europe/London",
screen: { width: 1920, height: 1080 }
}
});
console.log("Status:", response.statusCode);
console.log("Profile used:", response.profile);
}
requestWithMergedFingerprint();
Complete Fingerprint Override
If you need to completely replace the constructor fingerprint for a specific request,
provide all the attributes you want in the request-level fingerprint object. Since the
merge is shallow, any constructor-level attributes that you do not include in the
request-level object will still be present in the final merged fingerprint. To ensure
a clean override, include every attribute you want and set unwanted attributes to
null or an empty value.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY",
fingerprint: {
platform: "Win32",
timezone: "America/New_York",
language: "en-US"
}
});
async function requestWithFullOverride() {
const response = await client.request({
url: "https://jp-site.example.com/content",
method: "GET",
fingerprint: {
platform: "MacIntel",
timezone: "Asia/Tokyo",
language: "ja-JP",
screen: { width: 2560, height: 1440 }
}
});
console.log("Status:", response.statusCode);
}
requestWithFullOverride();
Code Examples
The following examples demonstrate common usage patterns for the request()
method. Each example is a complete, runnable code snippet that shows a specific use case
with the appropriate request options and response handling.
Simple GET Request
The most basic usage of request() fetches a URL with the default GET method.
Only the url parameter is required. All other options use their default
values.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function simpleGet() {
const response = await client.request({
url: "https://api.example.com/products"
});
console.log("Status:", response.statusCode);
console.log("Products:", response.data);
console.log("Processing time:", response.processingTime, "ms");
}
simpleGet();
GET Request with Query Parameters
Use the params option to append query parameters to the URL. The SDK
automatically URL-encodes the parameter values and appends them to the URL.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function getWithParams() {
const response = await client.request({
url: "https://api.example.com/search",
method: "GET",
params: {
query: "wireless headphones",
category: "electronics",
minPrice: 50,
maxPrice: 200,
sort: "price_asc",
page: 1,
limit: 20
}
});
console.log("Status:", response.statusCode);
console.log("Search results:", response.data);
}
getWithParams();
POST Request with JSON Body
Use the json option to send a JSON request body. The SDK automatically
serializes the object and sets the Content-Type header.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function postWithJson() {
const response = await client.request({
url: "https://api.example.com/orders",
method: "POST",
json: {
productId: "PROD-12345",
quantity: 2,
shippingAddress: {
street: "123 Main Street",
city: "New York",
state: "NY",
zip: "10001"
},
paymentMethod: "credit_card"
}
});
console.log("Order status:", response.statusCode);
console.log("Order ID:", response.data.orderId);
}
postWithJson();
Synchronous Mode Request
Set sync: true to use the synchronous execution flow. The request is sent
to POST /request/execute and the response is returned directly without
polling.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function syncModeRequest() {
const response = await client.request({
url: "https://api.example.com/quick-data",
method: "GET",
sync: true,
timeout: 60
});
console.log("Status:", response.statusCode);
console.log("Data:", response.data);
}
syncModeRequest();
Request with Proxy Override
Override the client default proxy for a specific request by providing a proxy
object in the request options. This is useful when you need to route specific requests
through a different proxy server than the default.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithProxy() {
const response = await client.request({
url: "https://geo-restricted.example.com/content",
method: "GET",
proxy: {
host: "us-residential.proxy.com",
port: 8080,
username: "proxyuser",
password: "proxypass"
},
sensibility: "high"
});
console.log("Status:", response.statusCode);
console.log("Content:", response.body.substring(0, 200));
}
requestWithProxy();
Request with Cookies
Pass cookies to maintain session state or replay a specific browser session. This example shows the object format for cookies.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithCookies() {
const response = await client.request({
url: "https://dashboard.example.com/profile",
method: "GET",
cookies: {
auth_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
session_id: "sess_abc123def456",
preferences: "lang=en;theme=dark"
},
headers: {
"Accept": "application/json"
}
});
console.log("Profile status:", response.statusCode);
console.log("Profile data:", response.data);
console.log("Updated cookies:", response.cookies);
}
requestWithCookies();
Request with HTTP Authentication
Use the auth option to send HTTP Basic authentication credentials with
the request. The BBRE engine encodes the credentials and includes them in the
Authorization header.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithAuth() {
const response = await client.request({
url: "https://api.example.com/protected/resource",
method: "GET",
auth: {
username: "api_user",
password: "api_secret_key"
}
});
console.log("Status:", response.statusCode);
console.log("Protected data:", response.data);
}
requestWithAuth();
Adaptive Mode with High Sensibility
Override the client defaults to use adaptive mode with high sensibility for a specific request targeting a heavily protected website. This combination provides full browser rendering with maximum detection evasion.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY",
mode: "passive",
sensibility: "medium"
});
async function adaptiveHighSensibility() {
const response = await client.request({
url: "https://heavily-protected-site.com/data",
method: "GET",
mode: "adaptive",
sensibility: "high",
timeout: 240,
fingerprint: {
platform: "Win32",
timezone: "America/New_York",
language: "en-US",
screen: { width: 1920, height: 1080 }
}
});
console.log("Status:", response.statusCode);
console.log("Body length:", response.body.length);
console.log("Profile:", response.profile);
console.log("Processing time:", response.processingTime, "ms");
}
adaptiveHighSensibility();
Redirect Control
Control redirect behavior using the allowRedirects and
maxRedirects options. Disabling redirects is useful when you need to
inspect redirect responses or track redirect chains.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function inspectRedirect() {
const response = await client.request({
url: "https://short.example.com/abc123",
method: "GET",
allowRedirects: false
});
console.log("Status:", response.statusCode);
console.log("Location:", response.headers["location"]);
}
async function limitRedirects() {
const response = await client.request({
url: "https://chain.example.com/start",
method: "GET",
allowRedirects: true,
maxRedirects: 3
});
console.log("Final status:", response.statusCode);
console.log("Final URL body:", response.body.substring(0, 100));
}
inspectRedirect();
limitRedirects();
Session-Bound Request
Use the sessionId option to execute a request within an existing BBRE
session. Session-bound requests share cookies, browser state, and profile information
with other requests in the same session.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY",
mode: "adaptive"
});
async function sessionBoundRequest() {
const session = await client.createSession({
mode: "adaptive",
sensibility: "high"
});
const loginResponse = await client.request({
url: "https://app.example.com/login",
method: "POST",
json: { username: "alice", password: "secret123" },
sessionId: session.sessionId
});
const dashboardResponse = await client.request({
url: "https://app.example.com/dashboard",
method: "GET",
sessionId: session.sessionId
});
console.log("Login status:", loginResponse.statusCode);
console.log("Dashboard status:", dashboardResponse.statusCode);
console.log("Dashboard data:", dashboardResponse.data);
await client.closeSession(session.sessionId);
}
sessionBoundRequest();
PUT Request for Resource Update
Use the PUT method to update an existing resource on the target server. This example demonstrates updating a user profile with JSON data.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function updateResource() {
const response = await client.request({
url: "https://api.example.com/users/12345",
method: "PUT",
json: {
name: "Alice Johnson",
email: "[email protected]",
bio: "Software developer and open source contributor"
},
headers: {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UifQ"
}
});
console.log("Update status:", response.statusCode);
console.log("Updated user:", response.data);
}
updateResource();
DELETE Request
Use the DELETE method to remove a resource from the target server.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function deleteResource() {
const response = await client.request({
url: "https://api.example.com/users/12345",
method: "DELETE",
headers: {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UifQ"
}
});
console.log("Delete status:", response.statusCode);
console.log("Deleted:", response.data);
}
deleteResource();
SSL Verification Disabled
Set verify: false to disable SSL certificate verification. This is useful
for development environments with self-signed certificates or for accessing internal
services with expired certificates. Do not disable SSL verification in production
unless you understand the security implications.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithoutSslVerification() {
const response = await client.request({
url: "https://internal-dev.example.local/api/data",
method: "GET",
verify: false
});
console.log("Status:", response.statusCode);
console.log("Data:", response.data);
}
requestWithoutSslVerification();
Error Handling
The request() method throws errors when the BBRE API returns an error
response, when the request times out, or when a network-level failure occurs. Errors
are thrown as standard JavaScript Error objects with additional properties that provide
context about the failure. Always wrap your request() calls in try-catch
blocks to handle errors gracefully and implement appropriate retry or fallback logic.
Error Response Structure
When the BBRE API returns an error, the thrown error object contains the following properties that help you diagnose and handle the failure.
| Property | Type | Description |
|---|---|---|
message |
string | Human-readable error message describing the failure. |
code |
string | Machine-readable error code from the BBRE API (e.g., INSUFFICIENT_BALANCE, URL_REQUIRED). |
statusCode |
number | HTTP status code from the BBRE API response (e.g., 400, 401, 403, 408, 500). |
Basic Error Handling
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function safeRequest() {
try {
const response = await client.request({
url: "https://api.example.com/data",
method: "GET"
});
console.log("Status:", response.statusCode);
console.log("Data:", response.data);
} catch (error) {
console.error("Request failed:", error.message);
console.error("Error code:", error.code);
console.error("HTTP status:", error.statusCode);
}
}
safeRequest();
Retry Logic with Error Handling
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({ apiKey: "YOUR_API_KEY" });
async function requestWithRetry(options, maxRetries, delayMs) {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await client.request(options);
return response;
} catch (error) {
lastError = error;
const isRetryable = error.code === "SERVICE_UNAVAILABLE"
|| error.code === "SERVICE_TIMEOUT"
|| error.statusCode === 503
|| error.statusCode === 408;
if (!isRetryable || attempt === maxRetries) {
throw error;
}
const waitTime = delayMs * Math.pow(2, attempt - 1);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
throw lastError;
}
async function fetchWithRetry() {
try {
const response = await requestWithRetry(
{ url: "https://api.example.com/data", method: "GET" },
3,
1000
);
console.log("Status:", response.statusCode);
} catch (error) {
console.error("All retries failed:", error.message);
}
}
fetchWithRetry();
Common Error Codes
The following table lists the most common error codes you may encounter when using the
request() method, along with their causes and recommended solutions.
| Error Code | HTTP Status | Cause | Solution |
|---|---|---|---|
URL_REQUIRED |
400 | The url parameter was not provided in the request options. |
Ensure the options object includes a valid url string with the full protocol (http or https). |
INVALID_MODE |
400 | The mode parameter contains an invalid value. |
Use "passive" or "adaptive" as the mode value. Values are case-sensitive. |
INVALID_SENSIBILITY |
400 | The sensibility parameter contains an invalid value. |
Use "low", "medium", or "high" as the sensibility value. |
INSUFFICIENT_BALANCE |
402 | Your account balance is too low to process the request. | Add funds to your account through the MyDisct Solver dashboard before making additional requests. |
API_KEY_REQUIRED |
401 | No API key was provided in the client configuration. | Ensure the apiKey parameter is set in the BBREClient constructor. |
INVALID_API_KEY |
403 | The provided API key is not valid or has been revoked. | Verify your API key in the MyDisct Solver dashboard. Generate a new key if necessary. |
TASK_NOT_FOUND |
404 | The task ID returned by the create endpoint was not found during polling. | This is typically a transient error. Retry the request. If persistent, contact support. |
SERVICE_TIMEOUT |
408 | The request exceeded the configured timeout duration. | Increase the timeout value in the request options or client constructor. Consider using sync mode for faster response. |
SERVICE_UNAVAILABLE |
503 | The BBRE engine is temporarily unavailable due to high load or maintenance. | Implement retry logic with exponential backoff. Wait a few seconds before retrying. |
Best Practices
When sending JSON data, always use the json option instead of manually
serializing with JSON.stringify() and setting the Content-Type header.
The json option handles both serialization and header management
automatically, reducing the chance of formatting errors and making your code cleaner
and more readable.
Use the default asynchronous execution mode (sync: false) for production
applications. Async mode uses short-lived polling connections that are more resilient
to network interruptions and better suited for high-concurrency workloads. Reserve
synchronous mode for simple scripts, testing, and scenarios where you need the
simplest possible request flow.
Wrap every request() call in a try-catch block. Network requests can
fail for many reasons including timeout, insufficient balance, invalid parameters,
and temporary service unavailability. Implement retry logic with exponential backoff
for transient errors like SERVICE_UNAVAILABLE and
SERVICE_TIMEOUT. Log error codes and messages for debugging.
Set sensible defaults in the client constructor and override them at the request
level only when specific requests need different behavior. For example, keep the
default mode as "passive" for most requests and override to
"adaptive" only for targets that require full browser rendering. This
approach minimizes configuration duplication while maintaining flexibility.
When making multiple requests to the same target website, use a consistent fingerprint configuration. Set the base fingerprint in the constructor and avoid changing fingerprint attributes between requests to the same domain. Inconsistent fingerprints across requests can trigger bot detection systems that track browser identity consistency.
Always check response.statusCode before processing the response body.
A successful BBRE request (where success is true) means
the BBRE engine received a response from the target server, but the target server
may have returned a 403, 404, or 500 status code. Validate the status code to
ensure the target server returned the expected response before parsing the body.
For workflows that require maintaining state across multiple requests (login, form
submission, multi-page navigation), use BBRE sessions with the sessionId
option instead of manually managing cookies. Sessions automatically maintain cookies,
browser state, and profile consistency across all requests within the session,
providing a more reliable and simpler approach to stateful workflows.
Common Issues
Symptom: Request fails immediately with URL_REQUIRED
error.
Cause: The url property was not included in the
options object, or it was set to undefined, null, or an
empty string.
Solution: Ensure the options object always includes a valid
url string with the full protocol prefix (https:// or
http://). Check that any dynamic URL construction produces a valid
result before passing it to request().
Symptom: The target server returns a 400 Bad Request or ignores
the request body when sending JSON data using the body parameter.
Cause: When using body with a JSON string, the
Content-Type header is not automatically set to
application/json. The target server does not know to parse the body
as JSON.
Solution: Use the json parameter instead of
body for JSON data. The json option automatically handles
serialization and sets the correct Content-Type header. If you must use
body, manually set the Content-Type header to
application/json in the headers object.
Symptom: Requests to certain websites consistently fail with
timeout errors, even though the websites are accessible from a regular browser.
Cause: The default timeout of 120 seconds may be insufficient for
adaptive mode requests with high sensibility, especially on websites with complex
JavaScript rendering or aggressive bot detection that triggers additional processing
steps.
Solution: Increase the timeout value in the request
options. For adaptive mode with high sensibility, use 180 to 240 seconds. You can
also try switching to synchronous mode (sync: true) to eliminate
polling overhead, though this holds a connection open for the entire duration.
Symptom: The target server does not recognize the session or
authentication state despite providing cookies in the request options.
Cause: The cookie format may be incorrect, or the cookie values
may contain special characters that need encoding. When using the array format,
the domain property may not match the target URL domain.
Solution: Use the simple object format for cookies when possible.
Verify that cookie values are correctly formatted strings. When forwarding cookies
from a previous response, pass the response.cookies object directly
without modification. For complex cookie scenarios, consider using BBRE sessions
which handle cookie management automatically.
Symptom: The browser profile used for a request contains unexpected
fingerprint attributes that do not match the request-level fingerprint configuration.
Cause: The request-level fingerprint is merged with the constructor
default fingerprint using a shallow merge. Constructor-level attributes that are not
overridden in the request options are preserved in the final merged fingerprint.
Solution: Review both the constructor fingerprint and the
request-level fingerprint to understand the merge result. If you need a completely
different fingerprint for a specific request, include all desired attributes in the
request-level fingerprint object. Check the response.profile property
to see the actual fingerprint used for each request.