Session Request
The POST /session/request endpoint sends an HTTP request within an active BBRE
(Browser-Backed Request Engine) session, preserving cookies, fingerprint identity, proxy
configuration, and browser state across every request in the session. This is the primary
endpoint you use after creating a session with
POST /session/create. When you send a request
through a session, the BBRE engine automatically includes all cookies accumulated from
previous requests, applies the same browser fingerprint that was configured at session
creation, routes the request through the same proxy, and uses the same mode and sensibility
settings. This means you can log into a website with one request and then access
authenticated pages with subsequent requests without manually managing cookies or
authentication tokens. The session request endpoint accepts the target URL, HTTP method,
custom headers, request body, query parameters, additional cookies, timeout, redirect
settings, SSL verification, and authentication credentials. Cookies you provide in the
request are merged with the session's existing cookie jar, and cookies returned by the
target server are automatically merged back into the session for future requests. If the
BBRE engine generates a browser profile during processing and the session does not already
have one, the profile is saved to the session and returned in subsequent responses. The
session's request counter is incremented after each successful request, which you can
monitor through the POST /session/status
endpoint. This page provides complete documentation for every parameter, explains session
state inheritance and cookie management in detail, includes working code examples in
JavaScript, Python, and cURL, demonstrates multi-step workflow patterns, covers all error
codes, and offers best practices for effective session-based request handling.
Session requests differ fundamentally from standalone requests made through POST /request/create or POST /request/execute. Standalone requests are stateless: each request starts with a clean browser context, no cookies, and no memory of previous interactions. Session requests are stateful: they inherit the mode, sensibility, fingerprint, and proxy from the session, automatically carry forward cookies from previous requests, and maintain a consistent browser identity across the entire session lifecycle. Use standalone requests when each request is independent and does not need to share state with other requests. Use session requests when you need to perform multi-step workflows like logging in and then accessing protected pages, navigating through checkout processes, or interacting with websites that track user state through cookies and sessions.
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, including session requests. 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 or belongs to a suspended or inactive account, the API returns a
403 error with the appropriate error code (INVALID_API_KEY,
ACCOUNT_SUSPENDED, or ACCOUNT_INACTIVE).
| 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 session ID, target URL, and optional
configuration for the HTTP request. The sessionId and url
parameters are required. All other parameters are optional and have sensible defaults. Note
that session-level settings like mode, sensibility, fingerprint, and proxy are inherited from
the session configuration and cannot be overridden per-request. The following table describes
every parameter accepted by this endpoint, including the data type, default value, validation
rules, and detailed usage information.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
sessionId |
string | required | - | The unique identifier of the active session to send the request through. This is the session.id value returned by the POST /session/create endpoint. The session must be in active status and must not have expired. If the session ID is missing, the API returns a 400 SESSION_ID_REQUIRED error. If the session does not exist, the API returns a 404 SESSION_NOT_FOUND error. If the session has been closed or has expired, the API returns a 400 SESSION_CLOSED or 400 SESSION_EXPIRED error respectively. |
url |
string | required | - | The target URL to send the request to. Must be a valid HTTP or HTTPS URL. This is the web page or API endpoint you want to access within the session context. The URL is validated for proper format, and invalid URLs result in a 400 INVALID_REQUEST error. You can use different URLs for each request within the same session, which is the typical pattern for multi-step workflows like navigating from a login page to a dashboard. |
method |
string | optional | "GET" |
The HTTP method to use for the request. Accepted values are GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS. The value is case-insensitive during validation but should be provided in uppercase for clarity. If an unsupported method is provided, the API returns a 400 INVALID_REQUEST error. Use GET for fetching pages and data, POST for submitting forms and sending data, and other methods as needed by the target API. |
headers |
object | optional | {} |
Custom HTTP headers to include in the request. These headers are merged with the session's default headers and the BBRE engine's automatically generated headers. Use this to set headers like Accept, Referer, Origin, or any custom headers required by the target website. The BBRE engine automatically manages headers related to the browser fingerprint (like User-Agent), so you typically do not need to set those manually. |
body |
any | optional | null |
The request body to send with the request. For POST, PUT, and PATCH requests, this typically contains form data, JSON payloads, or other content. When sending JSON data, the body should be a JavaScript object or a JSON-serializable value. The BBRE engine handles content type negotiation based on the body format and any Content-Type header you specify in the headers parameter. |
params |
object | optional | {} |
Query string parameters to append to the URL. Each key-value pair in this object is URL-encoded and appended to the target URL as query parameters. For example, {"page": 2, "sort": "date"} would append ?page=2&sort=date to the URL. Using this parameter is cleaner than manually constructing query strings in the URL, especially when parameter values contain special characters that need encoding. |
cookies |
object | optional | {} |
Additional cookies to include in this specific request. These cookies are merged with the session's existing cookie jar using the pattern {...sessionCookies, ...requestCookies}, which means request-level cookies override session cookies with the same name. This is useful when you need to set or override specific cookies for a particular request without permanently modifying the session's cookie jar. Note that cookies returned by the target server in the response are automatically merged back into the session's cookie jar for future requests. |
timeout |
number | optional | 120 |
Request timeout in seconds. This is the maximum time the BBRE engine will wait for the target server to respond to this specific request. Valid values range from 1 to 300 seconds. If the request takes longer than the specified timeout, the API returns a 408 SERVICE_TIMEOUT error. This timeout is separate from the session timeout: the session timeout controls how long the session stays alive, while this timeout controls how long a single request within the session can take. For fast API endpoints, a timeout of 30-60 seconds is usually sufficient. For pages that load slowly or require heavy server-side processing, increase the timeout to 120-300 seconds. |
allowRedirects |
boolean | optional | true |
Whether to follow HTTP redirects (301, 302, 303, 307, 308) automatically. When set to true, the BBRE engine follows redirects up to the maxRedirects limit and returns the final response. When set to false, the engine returns the redirect response itself, including the Location header, without following it. Disabling redirects is useful when you need to inspect redirect chains, capture intermediate responses, or handle redirects manually in your application logic. |
maxRedirects |
number | optional | 10 |
The maximum number of redirects to follow when allowRedirects is true. If the redirect chain exceeds this limit, the engine stops following redirects and returns the last response received. This prevents infinite redirect loops from hanging your request. For most websites, the default value of 10 is more than sufficient. Reduce this value if you want to limit redirect depth for performance reasons. |
verify |
boolean | optional | true |
Whether to verify SSL/TLS certificates for HTTPS requests. When set to true, the BBRE engine validates the target server's SSL certificate and rejects connections to servers with invalid, expired, or self-signed certificates. When set to false, SSL verification is disabled, allowing connections to servers with certificate issues. Disabling SSL verification is sometimes necessary for development environments or internal servers with self-signed certificates, but it should never be disabled in production for security reasons. |
auth |
object | optional | null |
HTTP Basic Authentication credentials to include in the request. The object should contain username (string) and password (string) fields. When provided, the BBRE engine adds an Authorization: Basic header to the request with the Base64-encoded credentials. This is useful for accessing APIs or web pages that use HTTP Basic Authentication. For other authentication methods (Bearer tokens, API keys, OAuth), use the headers parameter to set the appropriate Authorization header manually. |
Session State Inheritance
One of the most important concepts to understand about session requests is that several critical settings are inherited from the session and cannot be overridden on a per-request basis. When you create a session with POST /session/create, you configure the mode, sensibility, fingerprint, and proxy. These settings are locked to the session for its entire lifetime and apply uniformly to every request made through that session. This design is intentional: anti-bot systems track consistency across requests, and changing your browser fingerprint or IP address mid-session would immediately flag the session as suspicious.
| Setting | Source | Per-Request Override | Explanation |
|---|---|---|---|
mode |
Session creation | No | The operating mode ("passive" or "adaptive") is set when the session is created and applies to all requests. Passive sessions use lightweight HTTP clients, while adaptive sessions use full browser instances. You cannot switch modes within a session because the underlying infrastructure is different for each mode. |
sensibility |
Session creation | No | The detection evasion level ("low", "medium", or "high") is set at session creation. Changing sensibility mid-session would create inconsistent behavior patterns that anti-bot systems could detect, so it remains fixed for the session's lifetime. |
fingerprint |
Session creation | No | The browser fingerprint (user agent, platform, screen resolution, timezone, language, WebGL renderer) is locked at session creation. Anti-bot systems track fingerprint consistency across page loads, so presenting different fingerprints within the same session would trigger detection. The fingerprint remains identical for every request in the session. |
proxy |
Session creation | No | The proxy configuration is set at session creation and routes all session requests through the same proxy server. Changing the IP address mid-session is one of the strongest signals for bot detection systems, so the proxy remains fixed. If you need to use a different proxy, create a new session with the desired proxy configuration. |
The parameters you can control per-request are: url, method,
headers, body, params, cookies,
timeout, allowRedirects, maxRedirects,
verify, and auth. These are request-specific settings that
naturally vary between different pages and API calls within the same browsing session, just
as they would in a real browser.
Cookie Management
Cookie management is one of the most powerful features of BBRE sessions. The session maintains a persistent cookie jar that accumulates cookies across all requests, exactly like a real browser. Understanding how cookies flow through the session is essential for building reliable multi-step workflows, especially those involving authentication.
Cookie Merge on Request
When you send a request through a session, the BBRE engine merges cookies from two sources:
the session's existing cookie jar and any cookies you provide in the request's
cookies parameter. The merge follows this pattern:
{
"effectiveCookies": "{ ...session.cookies, ...request.cookies }"
}
This means request-level cookies take precedence over session cookies with the same name.
If the session has a cookie named theme with value dark and you
send a request with cookies: {"theme": "light"}, the request uses
theme=light. The session's original theme cookie is not
permanently modified by this override; it only affects the current request.
Cookie Merge on Response
After the BBRE engine processes the request and receives a response from the target server,
any cookies included in the response (via Set-Cookie headers) are automatically
merged back into the session's cookie jar:
{
"updatedSessionCookies": "{ ...session.cookies, ...response.cookies }"
}
This automatic cookie persistence is what makes session-based authentication work. When you
send a login request and the server responds with a session cookie (like
JSESSIONID or connect.sid), that cookie is automatically stored
in the session and included in all subsequent requests. You do not need to extract cookies
from responses and manually include them in future requests.
Cookie Flow Example
Consider a three-step workflow: visiting a homepage, logging in, and accessing a dashboard. Here is how cookies flow through the session:
| Step | Action | Session Cookies Before | Session Cookies After |
|---|---|---|---|
| 1 | GET homepage | {} (empty) |
{"_ga": "GA1.2.123", "csrf": "abc123"} |
| 2 | POST login | {"_ga": "GA1.2.123", "csrf": "abc123"} |
{"_ga": "GA1.2.123", "csrf": "def456", "session_id": "xyz789"} |
| 3 | GET dashboard | {"_ga": "GA1.2.123", "csrf": "def456", "session_id": "xyz789"} |
{"_ga": "GA1.2.123", "csrf": "def456", "session_id": "xyz789"} |
Notice how the csrf cookie was updated after the login request (the server
issued a new CSRF token), and the session_id cookie was added. By step 3, the
dashboard request automatically includes all three cookies, giving it access to the
authenticated session.
Profile Data
The BBRE engine can generate a browser profile during request processing. A profile contains detailed information about the browser identity used for the request, including the user agent string, platform, screen dimensions, installed plugins, WebGL renderer, and other attributes that together form the browser's fingerprint as seen by the target website. The profile is particularly useful for debugging and for understanding exactly what identity the BBRE engine presented to the target server.
Profile capture works differently in sessions compared to standalone requests. In a session, the profile is captured during the first request that generates one and is then persisted to the session. If the session already has a profile from a previous request, subsequent requests do not overwrite it. This means the profile reflects the browser identity from the first interaction, which is the identity that the target website associates with the session. You can retrieve the session's profile at any time through the POST /session/status endpoint or through the response of any session request.
The profile field in the response is null when no profile has been generated
yet. Once a profile is captured, it contains an object with fields like
userAgent, platform, screen, timezone,
language, webgl, and other browser-specific attributes. See the
Fingerprint and Profile Guide for a
complete breakdown of profile fields and how to interpret them.
Response Format
The session request endpoint returns a JSON response containing the result of the HTTP request made through the session. On success, the response includes the task status, the HTTP response from the target server (status code, headers, body, cookies), and the processing time. On failure, the response includes an error code and a descriptive message.
Success Response (200)
A successful session request returns the following structure. The task.result
object contains the actual HTTP response from the target server, including the status code,
response headers, response body, and any cookies set by the server. The
processingTime value indicates how long the BBRE engine took to process the
request in milliseconds.
{
"success": true,
"service": "MyDisct Solver BBRE",
"task": {
"id": "task_abc123def456",
"status": "completed",
"result": {
"statusCode": 200,
"headers": {
"content-type": "text/html; charset=utf-8",
"set-cookie": "session_id=xyz789; Path=/; HttpOnly",
"x-request-id": "req-12345"
},
"body": "<!DOCTYPE html><html><head><title>Dashboard</title></head><body>Welcome back, user!</body></html>",
"cookies": {
"session_id": "xyz789",
"_ga": "GA1.2.123456"
},
"profile": null
}
},
"processingTime": 1842
}
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true for successful responses. |
service |
string | Always "MyDisct Solver BBRE". Identifies the service that processed the request. |
task.id |
string | The unique identifier for this specific request task. Each session request generates a new task ID. |
task.status |
string | The task completion status. For successful requests, this is always "completed". |
task.result.statusCode |
number | The HTTP status code returned by the target server (e.g., 200, 301, 403, 404, 500). This is the status code of the final response after following any redirects (if allowRedirects is true). |
task.result.headers |
object | The HTTP response headers returned by the target server. Header names are lowercased. This includes headers like content-type, set-cookie, location, and any custom headers the server sends. |
task.result.body |
string | The response body from the target server. For HTML pages, this contains the full HTML source. For JSON APIs, this contains the JSON string. For binary content, this may be Base64-encoded depending on the content type. |
task.result.cookies |
object | Cookies set by the target server in the response. These cookies are automatically merged into the session's cookie jar for future requests. The object maps cookie names to their values. |
task.result.profile |
object / null | The browser profile generated by the BBRE engine during processing. Contains fingerprint details like user agent, platform, screen dimensions, and WebGL information. This is null if no profile was generated for this request. |
processingTime |
number | The total time in milliseconds that the BBRE engine took to process the request, including network time to the target server, any browser rendering time (in adaptive mode), and evasion technique application time. |
Request Examples
The following examples demonstrate how to send requests within a BBRE session using
different programming languages and for different use cases. All examples assume you have
already created a session using the
POST /session/create endpoint and have the
session ID available. Remember to replace YOUR_API_KEY with your actual BBRE
API key and YOUR_SESSION_ID with the session ID returned from session creation.
Basic GET Request Within a Session
The simplest session request fetches a page using the default GET method. The session's cookies, fingerprint, and proxy are automatically applied. This is the pattern you use after logging in to access authenticated pages.
const response = await fetch("https://bbre-solver-api.mydisct.com/session/request", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify({
sessionId: "YOUR_SESSION_ID",
url: "https://example.com/dashboard"
})
});
const data = await response.json();
console.log("Status Code:", data.task.result.statusCode);
console.log("Response Body:", data.task.result.body);
console.log("Cookies:", data.task.result.cookies);
console.log("Processing Time:", data.processingTime, "ms");
import requests
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
SESSION_ID = "YOUR_SESSION_ID"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": SESSION_ID,
"url": "https://example.com/dashboard"
}
)
data = response.json()
result = data["task"]["result"]
print("Status Code:", result["statusCode"])
print("Cookies:", result["cookies"])
print("Processing Time:", data["processingTime"], "ms")
curl -X POST https://bbre-solver-api.mydisct.com/session/request \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"sessionId": "YOUR_SESSION_ID",
"url": "https://example.com/dashboard"
}'
POST Request with Form Data
Submitting form data through a session is common for login flows, search queries, and data submission. The session automatically carries forward any cookies set by previous requests, including CSRF tokens that many websites require for form submissions.
const response = await fetch("https://bbre-solver-api.mydisct.com/session/request", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify({
sessionId: "YOUR_SESSION_ID",
url: "https://example.com/api/login",
method: "POST",
body: {
username: "myuser",
password: "mypassword"
},
headers: {
"Accept": "application/json"
},
timeout: 60
})
});
const data = await response.json();
const result = data.task.result;
console.log("Login Status:", result.statusCode);
console.log("Session Cookies:", result.cookies);
import requests
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
SESSION_ID = "YOUR_SESSION_ID"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": SESSION_ID,
"url": "https://example.com/api/login",
"method": "POST",
"body": {
"username": "myuser",
"password": "mypassword"
},
"headers": {
"Accept": "application/json"
},
"timeout": 60
}
)
data = response.json()
result = data["task"]["result"]
print("Login Status:", result["statusCode"])
print("Session Cookies:", result["cookies"])
curl -X POST https://bbre-solver-api.mydisct.com/session/request \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"sessionId": "YOUR_SESSION_ID",
"url": "https://example.com/api/login",
"method": "POST",
"body": {
"username": "myuser",
"password": "mypassword"
},
"headers": {
"Accept": "application/json"
},
"timeout": 60
}'
Request with Custom Cookies and Query Parameters
You can provide additional cookies and query parameters for specific requests within a session. The cookies you provide are merged with the session's existing cookies, and query parameters are appended to the URL. This is useful when you need to pass pagination parameters, search filters, or override a specific cookie for one request.
const response = await fetch("https://bbre-solver-api.mydisct.com/session/request", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify({
sessionId: "YOUR_SESSION_ID",
url: "https://example.com/api/products",
method: "GET",
params: {
page: 2,
limit: 50,
sort: "price_asc",
category: "electronics"
},
cookies: {
currency: "USD",
region: "us-east"
},
timeout: 90
})
});
const data = await response.json();
const products = JSON.parse(data.task.result.body);
console.log("Products found:", products.length);
console.log("Response cookies:", data.task.result.cookies);
import requests
import json
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
SESSION_ID = "YOUR_SESSION_ID"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": SESSION_ID,
"url": "https://example.com/api/products",
"method": "GET",
"params": {
"page": 2,
"limit": 50,
"sort": "price_asc",
"category": "electronics"
},
"cookies": {
"currency": "USD",
"region": "us-east"
},
"timeout": 90
}
)
data = response.json()
result = data["task"]["result"]
products = json.loads(result["body"])
print("Products found:", len(products))
print("Response cookies:", result["cookies"])
curl -X POST https://bbre-solver-api.mydisct.com/session/request \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"sessionId": "YOUR_SESSION_ID",
"url": "https://example.com/api/products",
"method": "GET",
"params": {
"page": 2,
"limit": 50,
"sort": "price_asc",
"category": "electronics"
},
"cookies": {
"currency": "USD",
"region": "us-east"
},
"timeout": 90
}'
Multi-Step Workflow Example
The real power of session requests becomes apparent in multi-step workflows where each request builds on the state established by previous requests. The following example demonstrates a complete login-then-scrape workflow: creating a session, visiting the login page to collect initial cookies and CSRF tokens, submitting login credentials, and then accessing a protected dashboard page. This is one of the most common patterns for session usage.
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";
const authHeaders = {
"Content-Type": "application/json",
"x-api-key": API_KEY
};
async function loginAndScrapeWorkflow() {
const createResponse = await axios.post(
API_BASE + "/session/create",
{
mode: "passive",
sensibility: "medium",
timeout: 300
},
{ headers: authHeaders }
);
const sessionId = createResponse.data.session.id;
console.log("Session created:", sessionId);
const homepageResponse = await axios.post(
API_BASE + "/session/request",
{
sessionId: sessionId,
url: "https://example.com/login"
},
{ headers: authHeaders }
);
console.log("Homepage status:", homepageResponse.data.task.result.statusCode);
console.log("Initial cookies:", homepageResponse.data.task.result.cookies);
const loginResponse = await axios.post(
API_BASE + "/session/request",
{
sessionId: sessionId,
url: "https://example.com/api/auth/login",
method: "POST",
body: {
email: "[email protected]",
password: "securepassword123"
},
headers: {
"Accept": "application/json",
"Referer": "https://example.com/login"
}
},
{ headers: authHeaders }
);
console.log("Login status:", loginResponse.data.task.result.statusCode);
console.log("Auth cookies:", loginResponse.data.task.result.cookies);
const dashboardResponse = await axios.post(
API_BASE + "/session/request",
{
sessionId: sessionId,
url: "https://example.com/dashboard",
headers: {
"Referer": "https://example.com/login"
}
},
{ headers: authHeaders }
);
console.log("Dashboard status:", dashboardResponse.data.task.result.statusCode);
console.log("Dashboard body length:", dashboardResponse.data.task.result.body.length);
const profileResponse = await axios.post(
API_BASE + "/session/request",
{
sessionId: sessionId,
url: "https://example.com/api/user/profile",
headers: {
"Accept": "application/json"
}
},
{ headers: authHeaders }
);
const userProfile = JSON.parse(profileResponse.data.task.result.body);
console.log("User:", userProfile.name);
console.log("Email:", userProfile.email);
await axios.post(
API_BASE + "/session/close",
{ sessionId: sessionId },
{ headers: authHeaders }
);
console.log("Session closed successfully");
}
loginAndScrapeWorkflow();
import requests
import json
API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"
headers = {
"Content-Type": "application/json",
"x-api-key": API_KEY
}
create_response = requests.post(
API_BASE + "/session/create",
headers=headers,
json={
"mode": "passive",
"sensibility": "medium",
"timeout": 300
}
)
session_id = create_response.json()["session"]["id"]
print("Session created:", session_id)
homepage_response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": session_id,
"url": "https://example.com/login"
}
)
print("Homepage status:", homepage_response.json()["task"]["result"]["statusCode"])
login_response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": session_id,
"url": "https://example.com/api/auth/login",
"method": "POST",
"body": {
"email": "[email protected]",
"password": "securepassword123"
},
"headers": {
"Accept": "application/json",
"Referer": "https://example.com/login"
}
}
)
print("Login status:", login_response.json()["task"]["result"]["statusCode"])
dashboard_response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": session_id,
"url": "https://example.com/dashboard",
"headers": {
"Referer": "https://example.com/login"
}
}
)
print("Dashboard status:", dashboard_response.json()["task"]["result"]["statusCode"])
profile_response = requests.post(
API_BASE + "/session/request",
headers=headers,
json={
"sessionId": session_id,
"url": "https://example.com/api/user/profile",
"headers": {
"Accept": "application/json"
}
}
)
user_profile = json.loads(profile_response.json()["task"]["result"]["body"])
print("User:", user_profile["name"])
requests.post(
API_BASE + "/session/close",
headers=headers,
json={"sessionId": session_id}
)
print("Session closed successfully")
Node.js SDK Usage
The mydisctsolver-bbre Node.js SDK provides the BBRESession class
that wraps session creation, request sending, and session closing into a clean, high-level
API. The BBRESession.request() method handles authentication headers, request
formatting, and response parsing automatically. It also provides convenient access to the
session's cookies, profile, and status without making separate API calls.
Basic SDK Session Request
const { BBRESession } = require("mydisctsolver-bbre");
const session = new BBRESession({
apiKey: "YOUR_API_KEY",
mode: "passive",
sensibility: "medium"
});
async function fetchPageWithSDK() {
await session.start();
console.log("Session started");
const response = await session.request({
url: "https://example.com/dashboard"
});
console.log("Status:", response.statusCode);
console.log("Body length:", response.body.length);
console.log("Cookies:", response.cookies);
await session.close();
console.log("Session closed");
}
fetchPageWithSDK();
SDK Login Workflow
The SDK makes multi-step workflows particularly clean. The request() method
accepts the same parameters as the API endpoint (url, method, body, headers, cookies,
timeout, etc.) and returns the parsed response directly. Cookie management happens
automatically behind the scenes.
const { BBRESession } = require("mydisctsolver-bbre");
const session = new BBRESession({
apiKey: "YOUR_API_KEY",
mode: "passive",
sensibility: "high",
timeout: 300
});
async function loginWorkflowSDK() {
await session.start();
const loginResponse = await session.request({
url: "https://example.com/api/login",
method: "POST",
body: {
username: "user",
password: "pass"
}
});
console.log("Login status:", loginResponse.statusCode);
const dashboardResponse = await session.request({
url: "https://example.com/dashboard"
});
console.log("Dashboard status:", dashboardResponse.statusCode);
console.log("Dashboard HTML length:", dashboardResponse.body.length);
const ordersResponse = await session.request({
url: "https://example.com/api/orders",
params: { page: 1, limit: 25 },
headers: { "Accept": "application/json" }
});
const orders = JSON.parse(ordersResponse.body);
console.log("Total orders:", orders.total);
await session.close();
}
loginWorkflowSDK();
SDK with Error Handling
Production code should always wrap session operations in try/finally blocks to ensure sessions are closed even when errors occur. The SDK throws errors for API failures, so you can catch them and handle each error type appropriately.
const { BBRESession } = require("mydisctsolver-bbre");
const session = new BBRESession({
apiKey: "YOUR_API_KEY",
mode: "passive"
});
async function safeSessionWorkflow() {
try {
await session.start();
const response = await session.request({
url: "https://example.com/protected-page",
timeout: 60
});
if (response.statusCode === 200) {
console.log("Page loaded successfully");
console.log("Content length:", response.body.length);
} else if (response.statusCode === 403) {
console.log("Access denied, authentication may be required");
} else {
console.log("Unexpected status:", response.statusCode);
}
} catch (error) {
console.error("Session request failed:", error.message);
} finally {
await session.close();
console.log("Session cleaned up");
}
}
safeSessionWorkflow();
Session Request vs Standalone Request
Choosing between session requests and standalone requests depends on your specific use case. The following comparison helps you understand when to use each approach and what trade-offs are involved.
| Feature | Session Request | Standalone Request |
|---|---|---|
| Endpoint | POST /session/request |
POST /request/create or POST /request/execute |
| State Persistence | Cookies, fingerprint, and browser state persist across requests | Each request starts with a clean state, no memory of previous requests |
| Cookie Management | Automatic cookie accumulation and forwarding between requests | Cookies must be manually extracted and passed to each request |
| Fingerprint Consistency | Same fingerprint across all requests in the session | New fingerprint generated for each request (unless manually specified) |
| Proxy Consistency | Same proxy for all requests in the session | Proxy must be specified per-request |
| Mode/Sensibility | Inherited from session, consistent across all requests | Specified per-request, can vary between requests |
| Setup Required | Must create a session first, then send requests through it | No setup needed, send requests directly |
| Resource Usage | Session holds server resources for its entire lifetime | Resources allocated and released per-request |
| Best For | Login flows, multi-step workflows, authenticated scraping, checkout processes | Independent page fetches, one-off API calls, parallel requests to different sites |
| Concurrency Limit | Maximum 10 active sessions per account | No session limit, limited by account rate limits |
As a general rule, use session requests when your workflow involves two or more sequential requests to the same website that need to share state. Use standalone requests when each request is independent or when you need to make many parallel requests to different websites. You can also combine both approaches: use standalone requests for initial reconnaissance (checking if a site is accessible, determining its structure) and then switch to session requests for the actual multi-step workflow.
Error Codes
The following table lists all error codes that can be returned by the session request endpoint, along with their HTTP status codes, descriptions, and recommended solutions. Implementing proper error handling for each of these codes ensures your application can recover gracefully from any failure scenario during session-based workflows.
| HTTP Status | Error Code | Description | Solution |
|---|---|---|---|
400 |
SESSION_ID_REQUIRED |
The sessionId parameter is missing from the request body. |
Include the sessionId field in your JSON request body. This is the session ID returned by POST /session/create. |
400 |
URL_REQUIRED |
The url parameter is missing from the request body. |
Include the url field in your JSON request body with the target URL you want to access within the session. |
400 |
INVALID_REQUEST |
The request contains invalid data. This can be triggered by an invalid URL format, an unsupported HTTP method, or a timeout value outside the 1-300 range. | Check the URL format (must be a valid HTTP or HTTPS URL), verify the method is one of GET, POST, PUT, DELETE, PATCH, HEAD, or OPTIONS, and ensure the timeout is between 1 and 300 seconds. |
400 |
SESSION_CLOSED |
The session has been explicitly closed using POST /session/close and can no longer accept requests. |
Create a new session using POST /session/create. Closed sessions cannot be reopened. If you need to continue a workflow, you will need to re-establish any state (login, cookies) in the new session. |
400 |
SESSION_EXPIRED |
The session has exceeded its timeout duration and has expired. No further requests can be made through this session. | Create a new session with a longer timeout value. Calculate the total time your workflow needs and add a buffer. The maximum timeout is 300 seconds (5 minutes). For longer workflows, break them into multiple sessions. |
401 |
API_KEY_REQUIRED |
No API key was provided in the request headers. | Include your API key in the x-api-key or apikey header. |
403 |
INVALID_API_KEY |
The provided API key is not valid or does not exist. | Verify your API key in the MyDisct Solver dashboard. Ensure you are copying the complete key without extra spaces. |
403 |
ACCOUNT_SUSPENDED |
Your account has been suspended. | Contact MyDisct Solver support for information about your account suspension. |
403 |
ACCOUNT_INACTIVE |
Your account is inactive. | Activate your account through the MyDisct Solver dashboard or contact support. |
404 |
SESSION_NOT_FOUND |
No session exists with the provided session ID. The session may have been deleted or the ID may be incorrect. | Verify the session ID is correct. If the session was created recently, ensure you are using the exact session.id value from the creation response. If the session was created a long time ago, it may have been cleaned up by the system. |
408 |
SERVICE_TIMEOUT |
The BBRE engine timed out while processing the request. This happens when the target server takes too long to respond or when the BBRE processing exceeds the request timeout. | Increase the timeout parameter for this request. If the target server is consistently slow, consider using a longer timeout (up to 300 seconds). Also check if the target URL is accessible and responding normally. |
500 |
SERVICE_ERROR |
An internal server error occurred while processing the session request. | Retry the request after a short delay (2-5 seconds). If the error persists, the issue may be with the target website or the BBRE engine. Contact support if retries do not resolve the problem. |
Error Response Example
{
"success": false,
"service": "MyDisct Solver BBRE",
"error": {
"code": "SESSION_EXPIRED",
"message": "Session has expired. Please create a new session."
}
}
Error Handling Example
async function sendSessionRequestWithRetry(sessionId, url, maxRetries) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch("https://bbre-solver-api.mydisct.com/session/request", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify({
sessionId: sessionId,
url: url,
timeout: 120
})
});
const data = await response.json();
if (data.success) {
return data.task.result;
}
const errorCode = data.error.code;
if (errorCode === "SESSION_EXPIRED" || errorCode === "SESSION_CLOSED") {
throw new Error("Session is no longer active: " + errorCode);
}
if (errorCode === "SESSION_NOT_FOUND") {
throw new Error("Session does not exist: " + sessionId);
}
if (errorCode === "SERVICE_TIMEOUT" && attempt < maxRetries) {
const delay = attempt * 2000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
if (errorCode === "SERVICE_ERROR" && attempt < maxRetries) {
const delay = attempt * 3000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw new Error("Request failed: " + errorCode + " - " + data.error.message);
} catch (networkError) {
if (attempt === maxRetries) throw networkError;
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
}
sendSessionRequestWithRetry("session_abc123", "https://example.com/page", 3);
Advanced Usage Patterns
Request with HTTP Basic Authentication
Some websites and APIs use HTTP Basic Authentication. You can pass credentials through the
auth parameter, and the BBRE engine will add the appropriate
Authorization header automatically.
const response = await fetch("https://bbre-solver-api.mydisct.com/session/request", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify({
sessionId: "YOUR_SESSION_ID",
url: "https://api.example.com/v2/data",
method: "GET",
auth: {
username: "api_user",
password: "api_secret"
},
headers: {
"Accept": "application/json"
}
})
});
const data = await response.json();
console.log("API Response:", data.task.result.body);
Disabling Redirects for Inspection
When you need to inspect redirect chains or capture intermediate responses, disable automatic redirect following. This is useful for debugging authentication flows where the server redirects to different pages based on login success or failure.
const response = await fetch("https://bbre-solver-api.mydisct.com/session/request", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify({
sessionId: "YOUR_SESSION_ID",
url: "https://example.com/api/login",
method: "POST",
body: {
username: "user",
password: "pass"
},
allowRedirects: false
})
});
const data = await response.json();
const result = data.task.result;
if (result.statusCode === 302) {
const redirectUrl = result.headers["location"];
console.log("Redirect target:", redirectUrl);
if (redirectUrl.includes("/dashboard")) {
console.log("Login successful, redirecting to dashboard");
} else if (redirectUrl.includes("/login")) {
console.log("Login failed, redirecting back to login page");
}
}
Paginated Data Collection
Sessions are ideal for collecting paginated data because the session maintains authentication and cookies across all page requests. The following pattern iterates through pages until all data is collected.
const axios = require("axios");
const API_BASE = "https://bbre-solver-api.mydisct.com";
const authHeaders = {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
};
async function collectPaginatedData(sessionId) {
let allItems = [];
let currentPage = 1;
let hasMore = true;
while (hasMore) {
const response = await axios.post(
API_BASE + "/session/request",
{
sessionId: sessionId,
url: "https://example.com/api/items",
method: "GET",
params: {
page: currentPage,
per_page: 100
},
headers: {
"Accept": "application/json"
},
timeout: 60
},
{ headers: authHeaders }
);
const body = JSON.parse(response.data.task.result.body);
allItems = allItems.concat(body.items);
console.log("Page", currentPage, "- Items:", body.items.length);
hasMore = body.items.length === 100;
currentPage++;
}
console.log("Total items collected:", allItems.length);
return allItems;
}
Best Practices
Many websites set cookies and CSRF tokens when you first visit a page. Before submitting a login form or any other form, send a GET request to the page that contains the form. This allows the session to collect initial cookies and tokens that the server expects to see with the form submission. Skipping this step is one of the most common reasons for login failures, because the server rejects form submissions that do not include the expected CSRF token or session initialization cookie.
When navigating between pages within a session, set the Referer header to
the URL of the previous page. This mimics natural browser behavior where each page
navigation includes a referer pointing to the page the user came from. Anti-bot systems
commonly check referer consistency, and missing or incorrect referer headers can trigger
detection. For form submissions, also set the Origin header to the target
site's origin (e.g., https://example.com).
Set the per-request timeout based on the expected response time of the
target endpoint. Fast API endpoints typically respond within 5-10 seconds, so a timeout
of 30-60 seconds provides a comfortable buffer. Heavy pages with lots of JavaScript or
server-side processing may need 120-180 seconds. Avoid using the maximum 300-second
timeout for every request, because if a target server is down, you will wait the full
timeout before getting an error. Shorter timeouts for fast endpoints let you detect
failures quickly and retry or fail gracefully.
Wrap your session workflow in a try/finally block (or try/except/finally in Python) to ensure the session is closed even when an error occurs mid-workflow. Unclosed sessions remain active until they expire, consuming one of your 10 active session slots. If your application crashes frequently without closing sessions, you can quickly exhaust your session limit and be unable to create new sessions until the old ones expire.
When using high sensibility sessions on websites with aggressive bot detection, add small delays (1-3 seconds) between consecutive requests. While the BBRE engine applies its own evasion techniques, sending requests in rapid succession can still trigger rate-based detection systems. A short delay between requests makes the traffic pattern look more like a human browsing naturally. This is especially important for workflows that make many requests in sequence, such as paginated data collection or multi-page form submissions.
For workflows that take a significant portion of the session timeout, periodically check the session status using POST /session/status to verify the session is still active and to monitor the remaining time before expiration. This allows you to proactively handle situations where the session is about to expire, rather than discovering the expiration when a request fails. The status endpoint also shows the request count and total charged amount, which is useful for monitoring and cost tracking.
Common Issues
Issue 1: Login Succeeds but Subsequent Requests Return Unauthenticated Content
You send a login request through the session and receive a 200 status code, but when you access a protected page in the next request, you get redirected to the login page or receive a 403 response. The authentication cookies do not seem to be carrying over between requests.
Solution: First, check the login response body to confirm the login
actually succeeded (some sites return 200 even for failed logins with an error message in
the body). Second, verify that the login response includes cookies by checking the
task.result.cookies field. If no cookies are returned, the target site may
use a different authentication mechanism (like JWT tokens in the response body) that you
need to extract and pass as a header in subsequent requests. Third, make sure you are
visiting the login page with a GET request before submitting the login form, as many sites
require initial cookies (CSRF tokens, session initialization) to be present before
accepting form submissions.
Issue 2: SESSION_EXPIRED Error During a Workflow
Your multi-step workflow fails partway through with a 400 SESSION_EXPIRED
error. The session was created with the default 120-second timeout, and the workflow
takes longer than expected due to slow target server responses.
Solution: Increase the session timeout when creating the session. Calculate the total expected duration of your workflow by estimating the time for each request (including BBRE processing time and target server response time) and adding a 50-100% buffer. For example, if your workflow involves 5 requests that each take approximately 15 seconds, the total is 75 seconds. With a 100% buffer, set the timeout to 150 seconds. The maximum session timeout is 300 seconds. For workflows that genuinely need more time, consider breaking them into multiple shorter sessions, transferring necessary state (like authentication tokens) between sessions manually.
Issue 3: SERVICE_TIMEOUT on Specific Requests
Certain requests within your session consistently fail with 408 SERVICE_TIMEOUT
while other requests to the same site succeed. The failing requests target pages that
are particularly heavy or require significant server-side processing.
Solution: Increase the per-request timeout parameter for the
slow requests. The default timeout is 120 seconds, but you can set it up to 300 seconds for
individual requests. If the target page is consistently slow, it may be loading large
amounts of JavaScript, making many sub-requests, or performing heavy server-side computation.
In adaptive mode, the BBRE engine needs to fully render the page, which adds to the
processing time. If increasing the timeout does not help, the target server may be
experiencing issues or may be blocking the request. Try the same URL with a standalone
request to determine if the issue is session-specific or target-specific.
Issue 4: Cookies Not Being Sent with Requests
You expect certain cookies to be included in your session requests, but the target server behaves as if the cookies are not present. The session's cookie jar appears to be empty or missing expected cookies.
Solution: Check the task.result.cookies field in the response
of each request to see which cookies the target server is setting. Some cookies have
domain restrictions, path restrictions, or HttpOnly/Secure flags that may affect how they
are sent. Also verify that you are using the correct session ID for all requests. If you
accidentally use a different session ID, the request will use a different cookie jar. You
can also use the POST /session/status endpoint
to inspect the session's current state and verify it is the session you expect.