Chat with us, powered by LiveChat
← Return to MyDisct Solver

Fetch Request Result

The POST /request/result endpoint retrieves the result of an asynchronous task that was previously created using the POST /request/create endpoint. After you submit a request through the create endpoint, the BBRE engine processes it in the background and you receive a task ID. This endpoint is how you check on that task and eventually retrieve the full response data once processing is complete. The result endpoint is designed around a polling pattern: your application calls it repeatedly with the task ID until the task reaches a terminal state (completed, failed, or timeout). When the task completes successfully, the response includes the full HTTP response from the target server, including the status code, response headers, response body, cookies set by the server, and the browser fingerprint profile that was used during the request. If the task fails or times out, the response includes error details and your account balance is automatically refunded. Once a task reaches the completed state, the result is cached internally, so subsequent calls with the same task ID return the cached result immediately without any additional processing. This page provides a complete reference for the result endpoint, including all possible response statuses, detailed field descriptions, polling implementation strategies with exponential backoff, complete workflow examples in JavaScript, Python, and cURL, error handling patterns, and best practices for building robust polling logic in production systems.

Polling Pattern

This endpoint is designed to be called repeatedly until the task reaches a terminal state. A task can be in one of four states: processing (still working), completed (result available), failed (error occurred), or timeout (processing exceeded the time limit). When the status is processing, wait a short interval and call the endpoint again. A polling interval of 2 seconds works well for most use cases. If you are using the Node.js SDK (mydisctsolver-bbre), the polling is handled automatically by the client.request() method, so you do not need to implement it yourself.

Endpoint

POST https://bbre-solver-api.mydisct.com/request/result

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. The task you are querying must belong to the authenticated user. You cannot retrieve results for tasks created by other accounts.

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 task ID of the asynchronous request you want to check. This endpoint accepts a single parameter. The task ID is the value returned by the POST /request/create endpoint when you initially submitted the request. Each task ID is unique and tied to your account, so you can only retrieve results for tasks that were created with your API key.

Parameter Type Required Description
taskId string required The unique task identifier returned by POST /request/create. This ID is used to track and retrieve the result of your asynchronous request. Example: "task_abc123def456"

Response Statuses

The result endpoint returns different response structures depending on the current state of the task. There are four possible task statuses, each with its own response format. Understanding these statuses is critical for building a reliable polling loop. The processing status means the task is still being worked on and you should poll again after a short delay. The completed status means the result is ready and includes the full HTTP response data. The failed and timeout statuses are terminal error states where the balance is automatically refunded to your account.

Status Terminal Balance Refund Description
processing No N/A The BBRE engine is still processing the request. Poll again after a short interval.
completed Yes No The request was processed successfully. The full result is included in the response.
failed Yes Yes The request failed during processing. The deducted balance is refunded automatically.
timeout Yes Yes The request exceeded the configured timeout duration. The deducted balance is refunded automatically.

Completed Response (200)

When the task completes successfully, the response includes the full HTTP response from the target server. The result object contains the HTTP status code, response headers, response body, cookies set by the server, and the browser fingerprint profile used during the request. The processingTime field indicates how long the BBRE engine took to process the request, measured in milliseconds. Once a task reaches the completed state, the result is cached, so calling this endpoint again with the same task ID returns the cached result immediately.

JSON
{
  "success": true,
  "service": "MyDisct Solver BBRE",
  "data": {
    "task": {
      "id": "task_abc123def456",
      "status": "completed",
      "result": {
        "statusCode": 200,
        "headers": {
          "content-type": "text/html; charset=utf-8",
          "server": "nginx",
          "x-powered-by": "Express",
          "cache-control": "no-cache"
        },
        "body": "<html><head><title>Example</title></head><body>...</body></html>",
        "cookies": {
          "session_id": "s3ss10n_v4lu3",
          "tracking": "tr4ck_abc"
        },
        "profile": {
          "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
          "platform": "Win32",
          "screen": {
            "width": 1920,
            "height": 1080
          },
          "timezone": "America/New_York",
          "language": "en-US"
        }
      }
    },
    "processingTime": 2345
  }
}

Processing Response (200)

When the task is still being processed by the BBRE engine, the response indicates that the task is in progress. This is the status you will see most frequently during polling. When you receive this response, wait for your configured polling interval (recommended: 2 seconds) and then call the endpoint again. The processing duration depends on the mode and sensibility settings used when creating the task. Passive mode requests typically complete within 2-5 seconds, while adaptive mode requests may take 10-30 seconds or longer depending on page complexity and the target site's response time.

JSON
{
  "success": true,
  "service": "MyDisct Solver BBRE",
  "data": {
    "task": {
      "id": "task_abc123def456",
      "status": "processing"
    }
  },
  "message": "Task is still processing"
}

Failed Response (200)

When the BBRE engine encounters an error while processing the request, the task enters the failed state. This can happen for various reasons: the target server returned an unrecoverable error, the proxy connection failed, the browser instance crashed during adaptive mode processing, or an internal service error occurred. When a task fails, the balance that was deducted when the task was created is automatically refunded to your account. You do not need to take any action to receive the refund. The error object in the response contains a message describing what went wrong.

JSON
{
  "success": true,
  "service": "MyDisct Solver BBRE",
  "data": {
    "task": {
      "id": "task_abc123def456",
      "status": "failed"
    },
    "error": {
      "message": "Request failed"
    }
  }
}

Timeout Response (200)

When the BBRE engine cannot complete the request within the configured timeout duration, the task enters the timeout state. The timeout value is set when creating the task through the timeout parameter on the POST /request/create endpoint (default: 30 seconds). Timeout is a specific type of failure that indicates the request took too long rather than encountering a processing error. Like the failed state, the balance is automatically refunded when a task times out. If you frequently encounter timeouts, consider increasing the timeout value, switching to passive mode for faster processing, or checking whether the target server is responding slowly.

JSON
{
  "success": true,
  "service": "MyDisct Solver BBRE",
  "data": {
    "task": {
      "id": "task_abc123def456",
      "status": "timeout"
    },
    "error": {
      "message": "Request timeout"
    }
  }
}

Response Field Descriptions

The following table describes every field that can appear in the response from this endpoint. Not all fields are present in every response. The fields available depend on the task status. For example, the result object is only present when the status is completed, and the error object is only present when the status is failed or timeout.

Field Type Description
success boolean Indicates whether the API call itself was successful. Always true for valid requests, even if the task status is failed or timeout.
service string Always "MyDisct Solver BBRE". Identifies the service that processed the request.
data.task.id string The unique task identifier that was provided in the request body.
data.task.status string The current status of the task. One of: "processing", "completed", "failed", or "timeout".
data.task.result object The full HTTP response data. Only present when status is "completed".
data.task.result.statusCode number The HTTP status code returned by the target server (e.g., 200, 301, 403, 500).
data.task.result.headers object The HTTP response headers from the target server as key-value pairs. Header names are lowercase.
data.task.result.body string The response body from the target server. For HTML pages, this is the full HTML source. For JSON APIs, this is the JSON string. For adaptive mode, this is the rendered DOM after JavaScript execution.
data.task.result.cookies object Cookies set by the target server during the request, as key-value pairs. Useful for maintaining session state across multiple requests.
data.task.result.profile object / null The browser fingerprint profile used during the request. Contains fields like userAgent, platform, screen, timezone, and language. May be null if profile data is not available.
data.processingTime number The total time the BBRE engine spent processing the request, in milliseconds. Only present when status is "completed". Useful for monitoring performance and tuning timeout values.
data.error object Error details. Only present when status is "failed" or "timeout".
data.error.message string A human-readable description of what went wrong during processing.
message string A human-readable status message. Present when the task is still processing.

Basic Usage Examples

The following examples show how to call the POST /request/result endpoint to check the status of a task. These are single-call examples that demonstrate the request format. For complete polling implementations that handle all status transitions, see the Polling Implementation section below.

JavaScript
const axios = require("axios");

const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";

async function fetchResult(taskId) {
  const response = await axios.post(
    API_BASE + "/request/result",
    { taskId: taskId },
    {
      headers: {
        "Content-Type": "application/json",
        "x-api-key": API_KEY
      }
    }
  );

  const data = response.data.data;
  console.log("Task ID:", data.task.id);
  console.log("Status:", data.task.status);

  if (data.task.status === "completed") {
    console.log("Status Code:", data.task.result.statusCode);
    console.log("Body Length:", data.task.result.body.length);
    console.log("Processing Time:", data.processingTime, "ms");
  }

  return data;
}

fetchResult("task_abc123def456");
Python
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/result",
    headers=headers,
    json={"taskId": "task_abc123def456"}
)

data = response.json()["data"]
print("Task ID:", data["task"]["id"])
print("Status:", data["task"]["status"])

if data["task"]["status"] == "completed":
    print("Status Code:", data["task"]["result"]["statusCode"])
    print("Body Length:", len(data["task"]["result"]["body"]))
    print("Processing Time:", data["processingTime"], "ms")
Bash
curl -X POST https://bbre-solver-api.mydisct.com/request/result \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "taskId": "task_abc123def456"
  }'

Polling Implementation Guide

Building a robust polling loop is essential for working with the asynchronous BBRE request system. A well-designed polling implementation handles all four task statuses correctly, uses appropriate intervals to avoid unnecessary API calls, implements a maximum attempt limit to prevent infinite loops, and optionally uses exponential backoff to reduce load during longer processing times. The following sections cover different polling strategies from simple to production-grade.

Simple Polling Loop

The simplest polling approach uses a fixed interval between each check. This works well for most use cases and is easy to understand and debug. The loop checks the task status on each iteration and exits when a terminal state is reached.

JavaScript
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
};

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function pollForResult(taskId) {
  const maxAttempts = 60;
  const pollInterval = 2000;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const response = await axios.post(
      API_BASE + "/request/result",
      { taskId: taskId },
      { headers: apiHeaders }
    );

    const data = response.data.data;
    const status = data.task.status;

    if (status === "completed") {
      console.log("Completed in", data.processingTime, "ms");
      return data.task.result;
    }

    if (status === "failed") {
      throw new Error("Task failed: " + data.error.message);
    }

    if (status === "timeout") {
      throw new Error("Task timed out: " + data.error.message);
    }

    console.log("Attempt", attempt, "- still processing...");
    await sleep(pollInterval);
  }

  throw new Error("Polling limit reached after " + maxAttempts + " attempts");
}

pollForResult("task_abc123def456");

Polling with Exponential Backoff

Exponential backoff is a more sophisticated polling strategy that starts with short intervals and gradually increases the wait time between each attempt. This approach is ideal for production systems because it reduces the number of API calls during longer processing times while still providing fast response detection for quick tasks. The backoff starts at 1 second and doubles with each attempt, capped at a maximum interval to prevent excessively long waits.

JavaScript
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
};

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function pollWithBackoff(taskId, options) {
  const maxAttempts = options.maxAttempts || 30;
  const initialInterval = options.initialInterval || 1000;
  const maxInterval = options.maxInterval || 10000;
  const backoffMultiplier = options.backoffMultiplier || 2;

  let currentInterval = initialInterval;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const response = await axios.post(
      API_BASE + "/request/result",
      { taskId: taskId },
      { headers: apiHeaders }
    );

    const data = response.data.data;
    const status = data.task.status;

    if (status === "completed") {
      return data.task.result;
    }

    if (status === "failed") {
      throw new Error("Task failed: " + data.error.message);
    }

    if (status === "timeout") {
      throw new Error("Task timed out: " + data.error.message);
    }

    console.log("Attempt", attempt, "- waiting", currentInterval, "ms");
    await sleep(currentInterval);

    currentInterval = Math.min(
      currentInterval * backoffMultiplier,
      maxInterval
    );
  }

  throw new Error("Polling limit reached");
}

pollWithBackoff("task_abc123def456", {
  maxAttempts: 30,
  initialInterval: 1000,
  maxInterval: 10000,
  backoffMultiplier: 2
});
Python
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 poll_with_backoff(task_id, max_attempts=30, initial_interval=1, max_interval=10):
    current_interval = initial_interval

    for attempt in range(1, max_attempts + 1):
        response = requests.post(
            API_BASE + "/request/result",
            headers=headers,
            json={"taskId": task_id}
        )

        data = response.json()["data"]
        status = data["task"]["status"]

        if status == "completed":
            return data["task"]["result"]

        if status == "failed":
            raise Exception("Task failed: " + data["error"]["message"])

        if status == "timeout":
            raise Exception("Task timed out: " + data["error"]["message"])

        print(f"Attempt {attempt} - waiting {current_interval}s")
        time.sleep(current_interval)

        current_interval = min(current_interval * 2, max_interval)

    raise Exception("Polling limit reached")

result = poll_with_backoff("task_abc123def456")
Bash
TASK_ID="task_abc123def456"
API_KEY="YOUR_API_KEY"
MAX_ATTEMPTS=30
INTERVAL=2

for i in $(seq 1 $MAX_ATTEMPTS); do
  RESPONSE=$(curl -s -X POST https://bbre-solver-api.mydisct.com/request/result \
    -H "Content-Type: application/json" \
    -H "x-api-key: $API_KEY" \
    -d "{\"taskId\": \"$TASK_ID\"}")

  STATUS=$(echo $RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['task']['status'])")

  echo "Attempt $i - Status: $STATUS"

  if [ "$STATUS" = "completed" ]; then
    echo "Task completed!"
    echo $RESPONSE | python3 -m json.tool
    break
  fi

  if [ "$STATUS" = "failed" ] || [ "$STATUS" = "timeout" ]; then
    echo "Task ended with status: $STATUS"
    echo $RESPONSE | python3 -m json.tool
    break
  fi

  sleep $INTERVAL
done

Complete Create-and-Poll Workflow

The most common usage pattern combines the POST /request/create and POST /request/result endpoints into a single workflow. The following examples demonstrate the complete flow from creating a task to retrieving and processing the result. These are production-ready examples that handle all status transitions, implement proper error handling, and use exponential backoff for efficient polling.

JavaScript Complete Workflow

JavaScript
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
};

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function bbRequest(url, options) {
  const createResponse = await axios.post(
    API_BASE + "/request/create",
    {
      url: url,
      method: options.method || "GET",
      mode: options.mode || "passive",
      sensibility: options.sensibility || "medium",
      headers: options.headers || {},
      body: options.body || null,
      timeout: options.timeout || 30
    },
    { headers: apiHeaders }
  );

  const taskId = createResponse.data.task.id;
  console.log("Task created:", taskId);

  let interval = 1000;
  const maxInterval = 10000;
  const maxAttempts = 60;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    await sleep(interval);

    const resultResponse = await axios.post(
      API_BASE + "/request/result",
      { taskId: taskId },
      { headers: apiHeaders }
    );

    const data = resultResponse.data.data;
    const status = data.task.status;

    if (status === "completed") {
      console.log("Completed in", data.processingTime, "ms");
      return {
        statusCode: data.task.result.statusCode,
        headers: data.task.result.headers,
        body: data.task.result.body,
        cookies: data.task.result.cookies,
        profile: data.task.result.profile,
        processingTime: data.processingTime
      };
    }

    if (status === "failed") {
      throw new Error("Request failed: " + data.error.message);
    }

    if (status === "timeout") {
      throw new Error("Request timed out: " + data.error.message);
    }

    interval = Math.min(interval * 1.5, maxInterval);
  }

  throw new Error("Polling limit reached");
}

async function main() {
  const result = await bbRequest("https://example.com/products", {
    mode: "passive",
    sensibility: "medium",
    timeout: 60
  });

  console.log("HTTP Status:", result.statusCode);
  console.log("Content-Type:", result.headers["content-type"]);
  console.log("Body Length:", result.body.length);
  console.log("Cookies:", JSON.stringify(result.cookies));
  console.log("Total Time:", result.processingTime, "ms");
}

main();

Python Complete Workflow

Python
import requests
import time

API_BASE = "https://bbre-solver-api.mydisct.com"
API_KEY = "YOUR_API_KEY"

api_headers = {
    "Content-Type": "application/json",
    "x-api-key": API_KEY
}

def bbre_request(url, method="GET", mode="passive", sensibility="medium",
                 custom_headers=None, body=None, timeout=30):
    create_response = requests.post(
        API_BASE + "/request/create",
        headers=api_headers,
        json={
            "url": url,
            "method": method,
            "mode": mode,
            "sensibility": sensibility,
            "headers": custom_headers or {},
            "body": body,
            "timeout": timeout
        }
    )

    create_data = create_response.json()
    task_id = create_data["task"]["id"]
    print("Task created:", task_id)

    interval = 1
    max_interval = 10
    max_attempts = 60

    for attempt in range(1, max_attempts + 1):
        time.sleep(interval)

        result_response = requests.post(
            API_BASE + "/request/result",
            headers=api_headers,
            json={"taskId": task_id}
        )

        data = result_response.json()["data"]
        status = data["task"]["status"]

        if status == "completed":
            print(f"Completed in {data['processingTime']}ms")
            return {
                "statusCode": data["task"]["result"]["statusCode"],
                "headers": data["task"]["result"]["headers"],
                "body": data["task"]["result"]["body"],
                "cookies": data["task"]["result"]["cookies"],
                "profile": data["task"]["result"]["profile"],
                "processingTime": data["processingTime"]
            }

        if status == "failed":
            raise Exception("Request failed: " + data["error"]["message"])

        if status == "timeout":
            raise Exception("Request timed out: " + data["error"]["message"])

        interval = min(interval * 1.5, max_interval)

    raise Exception("Polling limit reached")

result = bbre_request(
    "https://example.com/products",
    mode="passive",
    sensibility="medium",
    timeout=60
)

print("HTTP Status:", result["statusCode"])
print("Content-Type:", result["headers"].get("content-type"))
print("Body Length:", len(result["body"]))
print("Total Time:", result["processingTime"], "ms")

cURL Complete Workflow

Bash
API_KEY="YOUR_API_KEY"

CREATE_RESPONSE=$(curl -s -X POST https://bbre-solver-api.mydisct.com/request/create \
  -H "Content-Type: application/json" \
  -H "x-api-key: $API_KEY" \
  -d '{
    "url": "https://example.com/products",
    "mode": "passive",
    "sensibility": "medium",
    "timeout": 60
  }')

TASK_ID=$(echo $CREATE_RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['task']['id'])")
echo "Task created: $TASK_ID"

MAX_ATTEMPTS=60
INTERVAL=2

for i in $(seq 1 $MAX_ATTEMPTS); do
  RESULT=$(curl -s -X POST https://bbre-solver-api.mydisct.com/request/result \
    -H "Content-Type: application/json" \
    -H "x-api-key: $API_KEY" \
    -d "{\"taskId\": \"$TASK_ID\"}")

  STATUS=$(echo $RESULT | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['task']['status'])")

  if [ "$STATUS" = "completed" ]; then
    echo "Task completed!"
    echo $RESULT | python3 -m json.tool
    exit 0
  fi

  if [ "$STATUS" = "failed" ] || [ "$STATUS" = "timeout" ]; then
    echo "Task ended with status: $STATUS"
    echo $RESULT | python3 -m json.tool
    exit 1
  fi

  echo "Attempt $i - still processing..."
  sleep $INTERVAL
done

echo "Polling limit reached"

Using the Node.js SDK

If you are working with Node.js, the mydisctsolver-bbre SDK handles the entire create-and-poll workflow automatically. When you call client.request() or any of the HTTP shorthand methods like client.get(), the SDK internally creates the task, polls for the result with configurable intervals, and returns the final result directly. You never need to call the result endpoint manually when using the SDK. The SDK also handles error states, throwing appropriate exceptions for failed and timed-out tasks.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({
  apiKey: "YOUR_API_KEY",
  mode: "passive",
  sensibility: "medium",
  pollingInterval: 2000
});

async function fetchPage() {
  const result = await client.get("https://example.com/products");

  console.log("Status Code:", result.statusCode);
  console.log("Body Length:", result.body.length);
  console.log("Cookies:", JSON.stringify(result.cookies));

  if (result.profile) {
    console.log("User Agent:", result.profile.userAgent);
    console.log("Platform:", result.profile.platform);
  }

  return result;
}

fetchPage();
JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({
  apiKey: "YOUR_API_KEY"
});

async function fetchWithErrorHandling() {
  try {
    const result = await client.get("https://protected-site.example.com/data", {
      mode: "adaptive",
      sensibility: "high",
      timeout: 120
    });

    console.log("Status Code:", result.statusCode);
    console.log("Body:", result.body.substring(0, 200));
    return result;
  } catch (error) {
    console.log("Request failed:", error.message);
    return null;
  }
}

fetchWithErrorHandling();

The SDK's pollingInterval option controls how frequently the SDK checks for results. The default is 2000 milliseconds (2 seconds). For high-throughput applications processing many concurrent requests, you may want to increase this value to reduce API call volume. For latency-sensitive applications, you can decrease it to detect completed tasks faster. See the Node.js SDK Overview for more configuration options.

Error Responses

When a request to the result endpoint itself fails (as opposed to the underlying task failing), the API returns an error response with an appropriate HTTP status code, an error code string for programmatic handling, and a human-readable message. These errors relate to the API call itself, not to the task processing. Task-level failures are reported through the task status field as described in the Response Statuses section above.

Missing Task ID Error

JSON
{
  "success": false,
  "service": "MyDisct Solver BBRE",
  "error": "TASK_ID_REQUIRED",
  "message": "Task ID is required"
}

Task Not Found Error

JSON
{
  "success": false,
  "service": "MyDisct Solver BBRE",
  "error": "TASK_NOT_FOUND",
  "message": "Task not found"
}

Complete Error Code Reference

HTTP Status Error Code Cause Solution
400 TASK_ID_REQUIRED The taskId parameter is missing from the request body. Include the taskId field in the JSON request body. The task ID is the value returned by POST /request/create.
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.
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.
404 TASK_NOT_FOUND No task exists with the provided task ID, or the task belongs to a different account. Verify that the task ID is correct and was returned by a previous POST /request/create call made with the same API key. Task IDs are case-sensitive. Also check that the task has not expired from the system.
500 SERVICE_ERROR An internal error occurred while retrieving the task status. Retry the request after a short delay. If the error persists, contact support with the task ID.

Error Handling Example

JavaScript
const axios = require("axios");

const API_BASE = "https://bbre-solver-api.mydisct.com";
const API_KEY = "YOUR_API_KEY";

async function fetchResultSafely(taskId) {
  try {
    const response = await axios.post(
      API_BASE + "/request/result",
      { taskId: taskId },
      {
        headers: {
          "Content-Type": "application/json",
          "x-api-key": API_KEY
        }
      }
    );

    return response.data;
  } catch (error) {
    if (error.response) {
      const status = error.response.status;
      const data = error.response.data;

      if (status === 400) {
        console.log("Bad request:", data.error, data.message);
      } else if (status === 401) {
        console.log("Authentication failed. Check your API key.");
      } else if (status === 403) {
        console.log("Access denied:", data.error);
      } else if (status === 404) {
        console.log("Task not found. Verify the task ID:", taskId);
      } else if (status >= 500) {
        console.log("Server error. Will retry on next poll cycle.");
      }
    } else {
      console.log("Network error:", error.message);
    }

    return null;
  }
}

fetchResultSafely("task_abc123def456");

Result Caching Behavior

Once a task reaches the completed state, the result is cached internally by the BBRE system. This means that subsequent calls to POST /request/result with the same task ID will return the cached result immediately without any additional processing or delay. This caching behavior is useful in several scenarios: if your application crashes after the task completes but before it processes the result, you can safely call the result endpoint again to retrieve the data. If multiple parts of your application need the same result, they can all call the endpoint independently without concern about duplicate processing or additional costs.

The caching applies only to completed tasks. Tasks in the processing state always trigger a fresh status check against the BBRE engine. Tasks in the failed or timeout state also return their cached error information immediately. There is no additional charge for retrieving a cached result. The result remains available for retrieval as long as the task record exists in the system.

Automatic Balance Refund

When you create a task through POST /request/create, the request cost is deducted from your account balance immediately. If the task subsequently fails or times out during processing, the deducted amount is automatically refunded to your account. You do not need to take any action to receive the refund; it is handled as part of the BBRE error processing pipeline. The refund happens at the moment the task transitions to the failed or timeout state, which means your balance is restored before you even receive the error response from the result endpoint.

This automatic refund mechanism ensures that you are only charged for successfully completed requests. If you are monitoring your balance programmatically, be aware that the balance may temporarily decrease when a task is created and then increase again if the task fails. You can use the Account Balance endpoint to check your current balance at any time, and the Usage History endpoint to see detailed transaction records including refunds.

Best Practices

Use Exponential Backoff for Polling

Instead of polling at a fixed interval, implement exponential backoff that starts with a short interval (1 second) and gradually increases (2s, 4s, 8s) up to a maximum cap (10 seconds). This approach detects fast-completing tasks quickly while reducing unnecessary API calls for longer-running tasks. Exponential backoff is especially important when processing many concurrent requests, as it significantly reduces the total number of polling calls your application makes. For passive mode requests that typically complete in 2-5 seconds, the first few polls at short intervals will catch most results. For adaptive mode requests that may take 10-30 seconds, the backoff prevents dozens of unnecessary polling calls.

Always Set a Maximum Polling Attempt Limit

Never create an infinite polling loop. Always define a maximum number of attempts or a maximum total polling duration. A reasonable limit is 2-3 times the task timeout value. For example, if you created the task with a 30-second timeout, set your polling limit to 60-90 seconds total. If the task has not reached a terminal state within this window, treat it as a failure in your application logic. This prevents your application from hanging indefinitely if something unexpected happens. The BBRE engine will eventually transition the task to a terminal state, but your application should not depend on this for its own stability.

Handle All Four Status Values Explicitly

Your polling logic should explicitly handle all four possible task statuses: processing, completed, failed, and timeout. Do not assume that a non-completed status means the task is still processing. The failed and timeout statuses are terminal states that require different handling than processing. For failed and timeout, you should log the error, potentially retry with different parameters, and move on. For processing, you should continue polling. Treating failed or timeout as processing would cause your application to poll indefinitely for a task that will never complete.

Handle Network Errors in Your Polling Loop

Network errors (connection timeouts, DNS failures, HTTP 500 errors) can occur during polling without meaning the task itself has failed. Your polling loop should catch these errors and continue polling rather than treating them as task failures. The task continues processing on the BBRE engine regardless of whether your polling call succeeds. Implement a separate counter for consecutive network errors and only abort if you experience multiple failures in a row (for example, 5 consecutive network errors). This makes your integration resilient to temporary network issues.

Use the SDK for Simpler Polling

If you are working with Node.js, the mydisctsolver-bbre SDK eliminates the need to implement polling logic entirely. The SDK's client.request() method handles task creation, polling, status checking, and error handling internally. It uses a configurable polling interval and throws appropriate exceptions for failed and timed-out tasks. Using the SDK reduces your code complexity and eliminates an entire category of potential bugs related to polling implementation. See the Node.js SDK Overview for installation and configuration details.

Common Issues

Issue 1: TASK_NOT_FOUND Error When Polling

Problem

You receive a 404 TASK_NOT_FOUND error when calling the result endpoint with a task ID that was returned by the create endpoint.

Solution: This error has several possible causes. First, verify that you are using the exact task ID string returned by the create endpoint without any modifications, extra whitespace, or truncation. Task IDs are case-sensitive. Second, confirm that you are using the same API key for both the create and result calls. Each task is associated with the account that created it, and you cannot retrieve results for tasks created by other accounts. Third, check that you are not accidentally using a task ID from a different environment (for example, using a production task ID against a staging API). If you are storing task IDs in a database or queue, ensure the storage mechanism preserves the full string without modification.

Issue 2: Task Stays in Processing State Indefinitely

Problem

You are polling for a task result, but the status remains "processing" for much longer than expected without transitioning to a terminal state.

Solution: The most common cause is that the task timeout value set during creation is longer than your expected processing time. The BBRE engine will continue processing until the timeout is reached. For passive mode, tasks typically complete within 2-5 seconds. For adaptive mode, 10-30 seconds is normal depending on page complexity. If the task is taking significantly longer than these ranges, the target server may be slow to respond, or the page may have complex JavaScript that takes time to execute. Ensure your polling loop has a maximum attempt limit so it does not run forever. As a rule of thumb, set your polling timeout to 2-3 times the task timeout value. If the task still has not completed by then, treat it as a failure in your application and create a new task if needed.

Issue 3: Completed Task Returns Unexpected Body Content

Problem

The task completes successfully but the response body contains a bot detection page, a CAPTCHA challenge, or content that does not match what you see in a regular browser.

Solution: This indicates that the target site's bot detection identified the request as automated. The task itself completed successfully because the HTTP request was made and a response was received, but the response content is a challenge page rather than the expected content. To resolve this, try escalating your configuration: switch from passive to adaptive mode, increase the sensibility from low to medium or high, add a custom fingerprint with geographic settings matching the target audience, or use a proxy with an IP address in the expected region. You can check the result.statusCode field to detect challenge pages (many bot detection systems return 403 or redirect to a challenge URL). See the Hybrid Workflow Guide for strategies on combining passive and adaptive modes effectively.