Create Asynchronous Request
The POST /request/create endpoint is the primary way to send HTTP requests through
the BBRE (Browser-Backed Request Engine) system. Unlike traditional HTTP clients, BBRE processes
your request through a real browser environment with realistic fingerprinting, anti-detection
evasion, and optional full browser automation. This endpoint operates asynchronously: you submit
your request parameters, receive a task ID immediately, and then poll for the result using the
POST /request/result endpoint. This asynchronous design allows BBRE to handle
complex processing like browser rendering, JavaScript execution, and adaptive anti-bot evasion
without forcing your application to maintain a long-lived HTTP connection. The create endpoint
supports a comprehensive set of parameters that give you fine-grained control over how the
request is executed, including the HTTP method, custom headers, request body, proxy configuration,
browser fingerprint customization, detection evasion sensitivity, cookie management, SSL
verification, redirect handling, and authentication credentials. Whether you are building a
simple web scraper, a sophisticated data pipeline, or an automation system that needs to bypass
advanced bot protection, this endpoint provides the flexibility and power you need. This page
covers every parameter in detail, shows working code examples in JavaScript, Python, and cURL,
explains the asynchronous workflow, and provides best practices for getting the most out of the
BBRE request system.
This endpoint creates a task and returns immediately with a task ID. The actual HTTP request is processed in the background by the BBRE engine. To retrieve the result, use the POST /request/result endpoint with the returned task ID. If you prefer a synchronous workflow where you get the result in a single call, use the POST /request/execute endpoint instead. The asynchronous approach is recommended for production systems because it gives you more control over timeout handling and allows you to process multiple requests concurrently.
Endpoint
Authentication
All requests to the BBRE API require authentication via an API key. You must include your API
key in the HTTP headers of every request. The API accepts the key through either the
x-api-key header or the apikey header. Both header names are
supported and functionally identical. If no API key is provided, the API returns a
401 error with the API_KEY_REQUIRED error code. If the provided
key is invalid, the API returns a 403 error with the INVALID_API_KEY
error code.
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key |
string | required | Your BBRE API key. You can find this in your MyDisct Solver dashboard. |
Content-Type |
string | required | Must be set to application/json for all requests. |
Request Body Parameters
The request body must be a JSON object containing the parameters for your HTTP request. The only
required parameter is url. All other parameters are optional and have sensible
defaults. The following table describes every parameter accepted by this endpoint, including
the data type, default value, and detailed usage information.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string | required | - | The target URL to request. Must be a valid, fully qualified URL including the protocol (http:// or https://). This is the only required parameter. Example: https://example.com/api/data |
method |
string | optional | "GET" |
The HTTP method to use for the request. Supported values: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. Case-insensitive. |
headers |
object | optional | {} |
Custom HTTP headers to include in the request. Provided as key-value pairs where both keys and values are strings. BBRE automatically adds standard browser headers (User-Agent, Accept, etc.) based on the fingerprint, so you only need to add headers specific to your use case. Example: {"Authorization": "Bearer token123", "Accept-Language": "en-US"} |
body |
string / object | optional | null |
The request body to send. Used primarily with POST, PUT, and PATCH methods. Can be a JSON object (which will be serialized automatically) or a string (sent as-is). When sending form data, provide a URL-encoded string and set the appropriate Content-Type header. |
params |
object | optional | null |
URL query parameters to append to the URL. Provided as key-value pairs. These are URL-encoded and appended to the URL automatically. Example: {"page": "1", "limit": "50"} would append ?page=1&limit=50 to the URL. |
mode |
string | optional | "passive" |
The request processing mode. "passive" mode sends the request through a browser-like HTTP client with realistic headers and fingerprinting but without full browser rendering. "adaptive" mode launches a full browser instance, renders the page, executes JavaScript, and handles dynamic content. Use passive for simple HTTP requests and adaptive when the target site requires JavaScript execution or has advanced bot detection. |
sensibility |
string | optional | "medium" |
The detection evasion sensitivity level. "low" provides basic evasion with faster processing, suitable for sites with minimal bot protection. "medium" balances evasion quality and speed, appropriate for most websites. "high" applies maximum evasion techniques including human-like timing delays, realistic mouse movements, and advanced fingerprint consistency checks, ideal for sites with sophisticated anti-bot systems like DataDome, PerimeterX, or Cloudflare. |
fingerprint |
object | optional | {} |
Custom browser fingerprint configuration. Allows you to specify browser identity attributes like userAgent, platform, screen (object with width and height), timezone, language, and webgl (object with vendor and renderer). Any attributes you do not specify will be generated automatically by BBRE to ensure internal consistency. See the Fingerprint and Profile Guide for detailed information. |
proxy |
object | optional | null |
Proxy server configuration for routing the request through a specific proxy. The object should contain host (string, required), port (number, required), and optionally username (string) and password (string) for authenticated proxies. Example: {"host": "proxy.example.com", "port": 8080, "username": "user", "password": "pass"} |
cookies |
object | optional | {} |
Cookies to include in the request. Provided as key-value pairs where keys are cookie names and values are cookie values. These cookies are sent with the request as if they were set by the browser. Useful for maintaining session state or passing authentication tokens. Example: {"session_id": "abc123", "preferences": "lang=en"} |
timeout |
number | optional | 30 |
Request timeout in seconds. The maximum time BBRE will spend processing the request before returning a timeout error. Valid range is 1 to 300 seconds. For passive mode, 30 seconds is usually sufficient. For adaptive mode with complex pages, consider increasing to 60-120 seconds. Sites with heavy JavaScript or multiple redirects may need higher values. |
allowRedirects |
boolean | optional | true |
Whether to follow HTTP redirects (301, 302, 303, 307, 308). When set to true, BBRE automatically follows redirect responses up to the maxRedirects limit. When set to false, the redirect response itself is returned without following it, which is useful when you need to inspect redirect headers or capture the redirect URL. |
maxRedirects |
number | optional | 10 |
Maximum number of HTTP redirects to follow. Only applies when allowRedirects is true. If the redirect chain exceeds this limit, the request fails with an error. Most legitimate websites use 1-3 redirects, so the default of 10 provides a generous margin. Reduce this value if you want to detect redirect loops early. |
verify |
boolean | optional | true |
Whether to verify SSL/TLS certificates. When set to true, requests to sites with invalid, expired, or self-signed certificates will fail. Set to false to skip certificate verification, which is useful for testing environments or internal sites with self-signed certificates. Always keep this enabled in production for security. |
auth |
object | optional | null |
HTTP Basic or Digest authentication credentials. The object should contain username (string) and password (string). These credentials are sent using the standard HTTP Authorization header. Example: {"username": "admin", "password": "secret"} |
sessionId |
string | optional | null |
An existing session ID to associate this request with. When provided, the request uses the session's browser context, cookies, and fingerprint. This allows you to make requests within an established session without using the session-specific endpoint. The session must be active and not expired. |
Mode Comparison: Passive vs Adaptive
Choosing the right mode for your request is one of the most important decisions you will make when using the BBRE API. The mode determines how your request is processed internally, which directly affects speed, cost, success rate, and the type of content you can access. Understanding the differences between passive and adaptive modes will help you optimize your integration for both performance and reliability.
| Aspect | Passive Mode | Adaptive Mode |
|---|---|---|
| Processing | Browser-like HTTP client with realistic headers and fingerprinting | Full browser instance with JavaScript execution and page rendering |
| Speed | Fast (typically 1-5 seconds) | Slower (typically 5-30 seconds depending on page complexity) |
| JavaScript | Not executed. Returns raw HTML as served by the server. | Fully executed. Returns the rendered DOM after JavaScript runs. |
| Bot Detection | Bypasses basic to moderate protection (header checks, IP reputation) | Bypasses advanced protection (browser fingerprinting, behavioral analysis) |
| Best For | APIs, static pages, server-rendered content, high-volume scraping | SPAs, JavaScript-heavy sites, sites with Cloudflare/DataDome/PerimeterX |
| Resource Usage | Low - no browser instance needed | High - requires a full browser instance |
As a general rule, start with passive mode and only switch to adaptive mode if your requests are being blocked or if the target site requires JavaScript rendering. Passive mode is significantly faster and more cost-effective, so it should be your default choice unless you have a specific reason to use adaptive mode.
Request Examples
The following examples demonstrate how to use the POST /request/create endpoint
in different programming languages and for different use cases. All examples show complete,
working code that you can copy and run directly. Remember to replace YOUR_API_KEY
with your actual BBRE API key.
Basic GET Request
The simplest possible request. This sends a GET request to the specified URL using passive mode with default settings. BBRE automatically generates a realistic browser fingerprint and handles all the anti-detection measures.
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";
async function createBasicRequest() {
const response = await axios.post(
API_BASE + "/request/create",
{
url: "https://example.com/products"
},
{
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
}
);
const taskId = response.data.task.id;
console.log("Task created:", taskId);
console.log("Status:", response.data.task.status);
return taskId;
}
createBasicRequest();
import requests
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
response = requests.post(
API_BASE + "/request/create",
headers=headers,
json={
"url": "https://example.com/products"
}
)
data = response.json()
task_id = data["task"]["id"]
print("Task created:", task_id)
print("Status:", data["task"]["status"])
curl -X POST https://bbre-solver-api.mydisct.com/request/create \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/products"
}'
POST Request with Body and Custom Headers
This example demonstrates sending a POST request with a JSON body and custom headers. This pattern is common when interacting with APIs behind bot protection, where you need to submit data while maintaining a realistic browser identity.
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";
async function createPostRequest() {
const response = await axios.post(
API_BASE + "/request/create",
{
url: "https://api.example.com/v2/search",
method: "POST",
headers: {
"Accept": "application/json",
"X-Requested-With": "XMLHttpRequest",
"Origin": "https://example.com"
},
body: {
query: "laptop",
category: "electronics",
page: 1,
limit: 50
},
mode: "passive",
sensibility: "medium"
},
{
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
}
);
console.log("Task ID:", response.data.task.id);
return response.data.task.id;
}
createPostRequest();
import requests
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
response = requests.post(
API_BASE + "/request/create",
headers=headers,
json={
"url": "https://api.example.com/v2/search",
"method": "POST",
"headers": {
"Accept": "application/json",
"X-Requested-With": "XMLHttpRequest",
"Origin": "https://example.com"
},
"body": {
"query": "laptop",
"category": "electronics",
"page": 1,
"limit": 50
},
"mode": "passive",
"sensibility": "medium"
}
)
data = response.json()
print("Task ID:", data["task"]["id"])
curl -X POST https://bbre-solver-api.mydisct.com/request/create \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://api.example.com/v2/search",
"method": "POST",
"headers": {
"Accept": "application/json",
"X-Requested-With": "XMLHttpRequest",
"Origin": "https://example.com"
},
"body": {
"query": "laptop",
"category": "electronics",
"page": 1,
"limit": 50
},
"mode": "passive",
"sensibility": "medium"
}'
Advanced Request with Proxy, Fingerprint, and Cookies
This example shows a fully configured request that uses a custom proxy, browser fingerprint, cookies, and adaptive mode with high sensibility. This configuration is suitable for accessing heavily protected websites that employ multiple layers of bot detection.
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";
async function createAdvancedRequest() {
const response = await axios.post(
API_BASE + "/request/create",
{
url: "https://protected-site.example.com/dashboard",
method: "GET",
mode: "adaptive",
sensibility: "high",
timeout: 120,
fingerprint: {
platform: "Win32",
timezone: "America/New_York",
language: "en-US",
screen: { width: 1920, height: 1080 }
},
proxy: {
host: "us-proxy.example.com",
port: 8080,
username: "proxyuser",
password: "proxypass"
},
cookies: {
session_token: "eyJhbGciOiJIUzI1NiJ9.abc123",
user_pref: "theme=dark"
},
headers: {
"Accept": "text/html,application/xhtml+xml",
"Accept-Encoding": "gzip, deflate, br"
},
allowRedirects: true,
maxRedirects: 5,
verify: true
},
{
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
}
);
console.log("Task ID:", response.data.task.id);
console.log("Message:", response.data.message);
return response.data.task.id;
}
createAdvancedRequest();
import requests
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
response = requests.post(
API_BASE + "/request/create",
headers=headers,
json={
"url": "https://protected-site.example.com/dashboard",
"method": "GET",
"mode": "adaptive",
"sensibility": "high",
"timeout": 120,
"fingerprint": {
"platform": "Win32",
"timezone": "America/New_York",
"language": "en-US",
"screen": {"width": 1920, "height": 1080}
},
"proxy": {
"host": "us-proxy.example.com",
"port": 8080,
"username": "proxyuser",
"password": "proxypass"
},
"cookies": {
"session_token": "eyJhbGciOiJIUzI1NiJ9.abc123",
"user_pref": "theme=dark"
},
"headers": {
"Accept": "text/html,application/xhtml+xml",
"Accept-Encoding": "gzip, deflate, br"
},
"allowRedirects": True,
"maxRedirects": 5,
"verify": True
}
)
data = response.json()
print("Task ID:", data["task"]["id"])
print("Message:", data["message"])
curl -X POST https://bbre-solver-api.mydisct.com/request/create \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://protected-site.example.com/dashboard",
"method": "GET",
"mode": "adaptive",
"sensibility": "high",
"timeout": 120,
"fingerprint": {
"platform": "Win32",
"timezone": "America/New_York",
"language": "en-US",
"screen": {"width": 1920, "height": 1080}
},
"proxy": {
"host": "us-proxy.example.com",
"port": 8080,
"username": "proxyuser",
"password": "proxypass"
},
"cookies": {
"session_token": "eyJhbGciOiJIUzI1NiJ9.abc123",
"user_pref": "theme=dark"
},
"headers": {
"Accept": "text/html,application/xhtml+xml",
"Accept-Encoding": "gzip, deflate, br"
},
"allowRedirects": true,
"maxRedirects": 5,
"verify": true
}'
Complete Asynchronous Workflow
The asynchronous request workflow consists of two phases: task creation and result retrieval. Understanding this flow is essential for building reliable integrations with the BBRE API. The following example demonstrates the complete workflow from creating a task to polling for and processing the result.
How the Async Flow Works
- Submit Request: Your application sends a POST request to
/request/createwith the target URL and configuration parameters. - Validation and Billing: The API validates all parameters, checks your account balance, and atomically deducts the request price from your balance.
- Task Creation: The API creates a processing task and sends it to the BBRE engine for execution. The task enters the
"processing"state. - Immediate Response: The API returns a response containing the task ID and status
"processing". Your application receives this within milliseconds. - Background Processing: The BBRE engine processes the request in the background, applying the specified mode, sensibility, fingerprint, and other settings.
- Poll for Result: Your application polls
POST /request/resultwith the task ID until the status changes to"completed"or"failed". - Automatic Refund: If the task fails during processing, the deducted balance is automatically refunded to your account.
Complete Workflow Example
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";
const apiHeaders = {
"Content-Type": "application/json",
"x-api-key": API_KEY
};
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function createAndPollRequest(url, options) {
const createResponse = await axios.post(
API_BASE + "/request/create",
{ url, ...options },
{ headers: apiHeaders }
);
const taskId = createResponse.data.task.id;
console.log("Task created:", taskId);
let attempts = 0;
const maxAttempts = 60;
const pollInterval = 2000;
while (attempts < maxAttempts) {
await sleep(pollInterval);
attempts++;
const resultResponse = await axios.post(
API_BASE + "/request/result",
{ taskId: taskId },
{ headers: apiHeaders }
);
const task = resultResponse.data.task;
if (task.status === "completed") {
console.log("Request completed successfully");
console.log("Status Code:", task.result.statusCode);
console.log("Body Length:", task.result.body.length);
return task.result;
}
if (task.status === "failed") {
console.log("Request failed:", task.error);
throw new Error("Task failed: " + task.error);
}
console.log("Still processing... attempt", attempts);
}
throw new Error("Polling timeout after " + maxAttempts + " attempts");
}
createAndPollRequest("https://example.com/data", {
mode: "passive",
sensibility: "medium",
timeout: 60
});
import requests
import time
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
def create_and_poll_request(url, options=None):
if options is None:
options = {}
payload = {"url": url}
payload.update(options)
response = requests.post(
API_BASE + "/request/create",
headers=headers,
json=payload
)
data = response.json()
task_id = data["task"]["id"]
print("Task created:", task_id)
max_attempts = 60
poll_interval = 2
for attempt in range(max_attempts):
time.sleep(poll_interval)
result_response = requests.post(
API_BASE + "/request/result",
headers=headers,
json={"taskId": task_id}
)
result_data = result_response.json()
task = result_data["task"]
if task["status"] == "completed":
print("Request completed successfully")
print("Status Code:", task["result"]["statusCode"])
print("Body Length:", len(task["result"]["body"]))
return task["result"]
if task["status"] == "failed":
print("Request failed:", task.get("error"))
raise Exception("Task failed: " + str(task.get("error")))
print(f"Still processing... attempt {attempt + 1}")
raise Exception("Polling timeout")
result = create_and_poll_request(
"https://example.com/data",
{"mode": "passive", "sensibility": "medium", "timeout": 60}
)
A polling interval of 2 seconds works well for most use cases. For passive mode requests,
results are typically available within 2-5 seconds. For adaptive mode requests, results
may take 10-30 seconds depending on page complexity and sensibility level. If you are
using the Node.js SDK (mydisctsolver-bbre), the polling is handled
automatically by the client.request() method.
Response Format
The POST /request/create endpoint returns a JSON response indicating whether the
task was created successfully. On success, the response includes the task ID that you will use
to retrieve the result. On failure, the response includes an error code and a descriptive
message explaining what went wrong.
Success Response (200)
{
"success": true,
"service": "MyDisct Solver BBRE",
"task": {
"id": "task_abc123def456",
"status": "processing"
},
"message": "Task is being processed"
}
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true for successful task creation. |
service |
string | Always "MyDisct Solver BBRE". Identifies the service that processed the request. |
task.id |
string | The unique task identifier. Use this ID to poll for the result via POST /request/result. |
task.status |
string | The initial task status. Always "processing" for newly created tasks. |
message |
string | A human-readable message describing the current state of the task. |
Error Responses
When a request fails, the API returns an error response with an appropriate HTTP status code, an error code string for programmatic handling, and a human-readable message. The following table lists all possible error responses for this endpoint, along with their causes and recommended solutions.
Authentication Errors
{
"success": false,
"service": "MyDisct Solver BBRE",
"error": "API_KEY_REQUIRED",
"message": "API key is required. Provide it via x-api-key header."
}
Insufficient Balance Error
{
"success": false,
"service": "MyDisct Solver BBRE",
"error": "INSUFFICIENT_BALANCE",
"message": "Insufficient balance for this request",
"required": 0.005,
"current_balance": 0.002,
"deficit": 0.003
}
Complete Error Code Reference
| HTTP Status | Error Code | Cause | Solution |
|---|---|---|---|
400 |
URL_REQUIRED |
The url parameter is missing from the request body. |
Include a valid URL in the request body. The URL must include the protocol (http:// or https://). |
400 |
INVALID_MODE |
The mode parameter contains an invalid value. |
Use either "passive" or "adaptive" as the mode value. |
400 |
INVALID_SENSIBILITY |
The sensibility parameter contains an invalid value. |
Use "low", "medium", or "high" as the sensibility value. |
400 |
INVALID_REQUEST |
The request body contains invalid or malformed data. | Check that the request body is valid JSON and all parameter types match the expected types described in the parameter table above. |
401 |
API_KEY_REQUIRED |
No API key was provided in the request headers. | Include your API key in the x-api-key or apikey HTTP header. |
402 |
INSUFFICIENT_BALANCE |
Your account balance is too low to cover the request cost. | Add funds to your account through the MyDisct Solver dashboard. The error response includes the required amount, your current_balance, and the deficit. |
403 |
INVALID_API_KEY |
The provided API key does not match any active account. | Verify that you are using the correct API key from your MyDisct Solver dashboard. Check for extra whitespace or truncated characters. |
403 |
ACCOUNT_SUSPENDED |
Your account has been suspended due to a policy violation. | Contact MyDisct Solver support to resolve the suspension. |
403 |
ACCOUNT_INACTIVE |
Your account is not currently active. | Log in to the MyDisct Solver dashboard and activate your account. |
500 |
SERVICE_ERROR |
An internal error occurred while processing the request. | Retry the request after a short delay. If the error persists, contact support with the task ID if available. |
503 |
SERVICE_UNAVAILABLE |
The BBRE processing service is temporarily unavailable. | Wait a few minutes and retry. This typically indicates temporary maintenance or high load. Implement exponential backoff in your retry logic. |
Error Handling Example
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";
async function createRequestWithErrorHandling(url) {
try {
const response = await axios.post(
API_BASE + "/request/create",
{ url: url, mode: "passive", sensibility: "medium" },
{
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
}
);
return response.data.task.id;
} catch (error) {
if (error.response) {
const data = error.response.data;
const status = error.response.status;
if (status === 401) {
console.log("Authentication failed. Check your API key.");
} else if (status === 402) {
console.log("Insufficient balance.");
console.log("Required:", data.required);
console.log("Current balance:", data.current_balance);
console.log("Deficit:", data.deficit);
} else if (status === 403) {
console.log("Access denied:", data.error);
} else if (status === 400) {
console.log("Invalid request:", data.error, data.message);
} else if (status >= 500) {
console.log("Server error. Retrying in 5 seconds...");
}
} else {
console.log("Network error:", error.message);
}
return null;
}
}
createRequestWithErrorHandling("https://example.com/data");
Pricing and Balance
Each request created through this endpoint has an associated cost that is deducted from your account balance at the time of task creation. The price is determined by the BBRE_REQUEST pricing tier configured in the system. The balance deduction happens atomically within a database transaction to ensure consistency. If the BBRE engine fails to process your request after the balance has been deducted, the amount is automatically refunded to your account. You do not need to take any action to receive the refund; it happens as part of the error handling pipeline.
You can check your current balance at any time using the
Account Balance endpoint. If your balance is
insufficient for a request, the API returns a 402 INSUFFICIENT_BALANCE error
that includes the required amount, your current balance, and the deficit, so you know exactly
how much you need to add.
Using the Node.js SDK
If you are working with Node.js, the mydisctsolver-bbre SDK provides a much
simpler interface for creating requests. The SDK handles the asynchronous polling automatically,
so you get the result directly without managing the create-and-poll workflow yourself. The
SDK also provides built-in error handling, automatic retries, and configurable polling intervals.
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY",
mode: "passive",
sensibility: "medium"
});
async function fetchWithSDK() {
const result = await client.get("https://example.com/products");
console.log("Status Code:", result.statusCode);
console.log("Headers:", JSON.stringify(result.headers));
console.log("Body Length:", result.body.length);
console.log("Cookies:", JSON.stringify(result.cookies));
return result;
}
fetchWithSDK();
const BBREClient = require("mydisctsolver-bbre");
const client = new BBREClient({
apiKey: "YOUR_API_KEY"
});
async function postWithSDK() {
const result = await client.post("https://api.example.com/v2/search", {
body: {
query: "laptop",
category: "electronics"
},
headers: {
"Accept": "application/json"
},
mode: "passive",
sensibility: "medium"
});
console.log("Status Code:", result.statusCode);
console.log("Response:", result.body);
return result;
}
postWithSDK();
The SDK internally calls POST /request/create and then polls
POST /request/result until the task completes. You can configure the polling
interval through the pollingInterval option in the BBREClient constructor.
For more details on the SDK, see the
Node.js SDK Overview.
Best Practices
Always begin your integration with passive mode and low or medium sensibility. This combination is the fastest and most cost-effective. Only escalate to adaptive mode or high sensibility if your requests are being blocked. Many websites, including those with basic bot protection, can be accessed successfully with passive mode. Jumping straight to adaptive mode with high sensibility wastes resources and slows down your pipeline unnecessarily.
When polling for results, use a consistent interval of 2-3 seconds and set a maximum number of polling attempts. For passive mode, results are typically ready within 2-5 seconds. For adaptive mode, expect 10-30 seconds. Avoid polling too aggressively (less than 1 second intervals) as this creates unnecessary load. If you are processing many requests concurrently, consider implementing exponential backoff or using the Node.js SDK which handles polling automatically.
The default timeout of 30 seconds works well for passive mode requests to most websites. For adaptive mode, increase the timeout to 60-120 seconds to account for browser startup, page rendering, and JavaScript execution. For sites with heavy content or slow servers, you may need even higher values. Setting the timeout too low causes unnecessary failures, while setting it too high delays error detection. Monitor your average response times and set the timeout to approximately 2-3 times your typical processing duration.
Always check for INSUFFICIENT_BALANCE errors before retrying failed requests.
The error response includes the exact amount needed, your current balance, and the deficit.
Implement a balance check in your pipeline that pauses processing when the balance drops
below a threshold, rather than letting requests fail one by one. You can use the
Account Balance endpoint to monitor your
balance programmatically.
When you need to add query parameters to the URL, use the params parameter
instead of manually concatenating them into the URL string. The params
parameter handles URL encoding automatically, which prevents issues with special
characters, spaces, and other characters that need to be escaped. This is especially
important when parameter values come from user input or external data sources.
Common Issues
Issue 1: Task Stays in Processing State
You create a task and poll for the result, but the status remains "processing"
for an extended period without completing or failing.
Solution: This typically happens when the timeout value is set too low for the target site's response time, or when using adaptive mode on a complex page. First, check that your timeout value is appropriate for the mode you are using. For adaptive mode, set the timeout to at least 60 seconds. Second, ensure your polling logic has a maximum attempt limit so it does not poll indefinitely. If the task does not complete within a reasonable time (2-3 times the timeout value), treat it as a failure and create a new task. The balance for failed tasks is refunded automatically.
Issue 2: Getting 400 INVALID_MODE or INVALID_SENSIBILITY
The API returns a 400 error with INVALID_MODE or INVALID_SENSIBILITY
even though you believe you are sending a valid value.
Solution: The mode parameter only accepts "passive" or
"adaptive" (lowercase). The sensibility parameter only accepts "low",
"medium", or "high" (lowercase). Check that you are not sending
uppercase values, values with extra whitespace, or misspelled values. Also verify that these
parameters are strings, not numbers or booleans. A common mistake is sending
"Passive" instead of "passive".
Issue 3: Request Succeeds but Returns Empty or Unexpected Body
The task completes successfully with a 200 status code, but the response body is empty, contains a bot detection page, or does not match what you see in a regular browser.
Solution: This usually means the target site's bot detection is blocking the request at a level that your current configuration cannot bypass. Try the following steps in order: (1) Switch from passive to adaptive mode, which uses a full browser and can handle JavaScript-based detection. (2) Increase the sensibility from low to medium or high, which applies more sophisticated evasion techniques. (3) Add a custom fingerprint with geographic settings that match the target site's expected audience. (4) If the site requires authentication or specific cookies, include them in the request. (5) Consider using a proxy with an IP address in the target site's expected geographic region.