> For the complete documentation index, see [llms.txt](https://docs.hypersolutions.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hypersolutions.co/akamai-web/sbsd-introduction.md).

# SBSD Introduction

SBSD (State Based Scraping Detection) is Akamai's passive sensor check. This page covers identifying basic SBSD and posting sensors to keep access valid.

#### Understanding Basic SBSD Protection

State Based Scraping Detection (SBSD) is an advanced bot protection mechanism used by Akamai. While our other guides cover handling SBSD challenges and 429 blocks, many websites implement SBSD in a passive mode that simply requires posting sensors proactively to maintain access. Our [Akamai Bypass API](https://hypersolutions.co/products/akamai) generates these sensors from a single HTTP call.

#### Identifying Basic SBSD

When you request a page with basic SBSD protection, you'll receive normal page content along with an SBSD script reference:

```html
<script src="/6mGXhhKgo3Cn/HH/EB0WcpIr3K/X0iuwmY3aY/UkZyWg/Dy/J1CmB4HUQ?v=99b02ce6-f91f-0f49-40ae-6f8493e30214"></script>
```

Note the absence of the `t` parameter - this distinguishes basic SBSD from hard challenges. The script only contains:

* **Path**: The script URL path
* **v parameter**: A UUID value
* **No t parameter**: This only appears in challenge scenarios

#### Implementation Flow

Basic SBSD protection follows a simple sequence:

1. **Initial Page Request**: Client requests the protected page
2. **Parameter Extraction**: Extract path and UUID from the script tag
3. **Script Fetch**: Request the SBSD script
4. **Sensor Submission**: Post two SBSD sensors (index 0 and 1)
5. **Continue Normally**: Proceed with your intended requests

#### Implementation Guide

**Step 1: Extract SBSD Parameters**

Parse the HTML response to extract the SBSD script parameters:

```javascript
const regex = /([a-z\d/\-_\.]+)\?v=([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
const matches = html.match(regex);
const path = matches[1];
const uuid = matches[2];
```

**Step 2: Fetch the SBSD Script**

Request the script using the extracted parameters:

```http
GET /[path]?v=[uuid] HTTP/2
Headers...
```

Save the script content for use in sensor generation.

**Step 3: Generate and Submit First Sensor**

Using our API service, generate the first SBSD payload with index 0:

```json
POST /sbsd HTTP/1.1
Content-Type: application/json

{
  "userAgent": "Mozilla/5.0...",
  "uuid": "99b02ce6-f91f-0f49-40ae-6f8493e30214",
  "pageUrl": "https://example.com/",
  "o": "cookie_value",
  "script": "script_content_from_step_2",
  "ip": "your_ip_address",
  "acceptLanguage": "en-US,en;q=0.9",
  "index": 0
}
```

The response contains the generated `payload` and a `context` string. Store that context, every SBSD call after this one sends it in place of the `script`.

Submit the generated payload to the SBSD endpoint:

```http
POST /[path] HTTP/2
Content-Type: application/json

{
  "body": "GENERATED_PAYLOAD_INDEX_0"
}
```

**Step 4: Generate and Submit Second Sensor**

Immediately follow with the second sensor using index 1. This call sends the `context` from the previous response instead of the `script`:

```json
POST /sbsd HTTP/1.1
Content-Type: application/json

{
  "userAgent": "Mozilla/5.0...",
  "uuid": "99b02ce6-f91f-0f49-40ae-6f8493e30214",
  "pageUrl": "https://example.com/",
  "o": "cookie_value",
  "context": "context_from_the_previous_response",
  "ip": "your_ip_address",
  "acceptLanguage": "en-US,en;q=0.9",
  "index": 1
}
```

{% hint style="warning" %}
`script` and `context` are mutually exclusive, a request containing both is rejected with an error. `context` is optional today and becomes mandatory soon, see [the context field](/api-reference/akamai.md#the-sbsd-context-field) for the minimum SDK versions.
{% endhint %}

Submit to the same endpoint:

```http
POST /[path] HTTP/2
Content-Type: application/json

{
  "body": "GENERATED_PAYLOAD_INDEX_1"
}
```

**Step 5: Proceed with Protected Requests**

After posting both sensors, you can make requests to protected endpoints without triggering SBSD challenges.

#### Generating the sensor with the SDK

Instead of calling `/sbsd` directly, the SDKs wrap it in a single call. Generate each sensor (index `0`, then `1`) with an `SbsdInput`. The call returns the payload and a context: the first call passes the script and an empty context, every call after it passes the returned context and no script.

{% tabs %}
{% tab title="Golang" %}
{% code overflow="wrap" %}

```go
sbsd, sbsdContext, err := session.GenerateSbsdData(ctx, &hyper.SbsdInput{
    Index:          index,        // 0, then 1
    UserAgent:      userAgent,
    Uuid:           uuid,
    PageUrl:        pageURL,
    OCookie:        oCookie,       // sbsd_o (or bm_so) cookie value
    Script:         scriptContent, // first call only, empty afterwards
    Context:        sbsdContext,   // empty on the first call
    AcceptLanguage: acceptLanguage,
    IP:             ip,
})
if err != nil {
    // Handle the error
}
// POST {"body": sbsd} to the SBSD script path, keep sbsdContext for the next call
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code overflow="wrap" %}

```python
sbsd, sbsd_context = session.generate_sbsd_data(hyper_sdk.SbsdInput(
    index=index,               # 0, then 1
    user_agent=user_agent,
    uuid=uuid,
    page_url=page_url,
    o_cookie=o_cookie,         # sbsd_o (or bm_so) cookie value
    script=script_content,     # first call only, empty afterwards
    accept_language=accept_language,
    ip=ip,
    context=sbsd_context,      # empty on the first call
))
# POST {"body": sbsd} to the SBSD script path, keep sbsd_context for the next call
```

{% endcode %}
{% endtab %}

{% tab title="JS / TS" %}
{% code overflow="wrap" %}

```javascript
import { SbsdInput, generateSbsdPayload } from "hyper-sdk-js";

// Constructor is positional: (index, uuid, oCookie, pageUrl, userAgent, script, ip, acceptLanguage, context)
const { payload, context } = await generateSbsdPayload(
    session,
    // scriptContent on the first call only, sbsdContext empty on the first call
    new SbsdInput(index, uuid, oCookie, pageUrl, userAgent, scriptContent, ip, acceptLanguage, sbsdContext)
);
// POST { body: payload } to the SBSD script path, keep context for the next call
```

{% endcode %}
{% endtab %}
{% endtabs %}

The `hyper-sdk-playwright` package handles the context for you, no code change needed.

#### Implementation Example

Here's a complete flow in pseudocode:

```javascript
// Step 1: Initial request
const response = await fetch("https://example.com/");
const html = await response.text();

// Step 2: Extract SBSD parameters
const regex = /([a-z\d/\-_\.]+)\?v=([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
const matches = html.match(regex);

if (!matches) {
  // No SBSD protection, continue normally
  return;
}

const path = matches[1];
const uuid = matches[2];

// Step 3: Fetch SBSD script
const scriptUrl = `https://example.com${path}?v=${uuid}`;
const scriptResponse = await fetch(scriptUrl);
const scriptContent = await scriptResponse.text();

// Step 4: Post both sensors
const postUrl = `https://example.com${path}`;
let sbsdContext = "";

for (let index = 0; index < 2; index++) {
  // Generate payload using our API. The first call sends the script,
  // every call after it sends the context and no script.
  const result = await generatePayload({
    userAgent: "YOUR_USER_AGENT",
    uuid: uuid,
    pageUrl: "https://example.com/",
    oCookie: getCookie("sbsd_o") || getCookie("bm_so"),
    script: sbsdContext === "" ? scriptContent : "",
    context: sbsdContext,
    ip: yourIp,
    acceptLanguage: "en-US,en;q=0.9",
    index: index
  });

  sbsdContext = result.context;

  // Submit sensor
  await fetch(postUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ body: result.payload })
  });
}

// Step 5: Continue with protected requests
const apiResponse = await fetch("https://example.com/api/data");
```

#### Key Differences from Challenge-Based SBSD

Basic SBSD protection differs from challenge scenarios:

1. **No blocking page** - Normal content loads immediately
2. **No t parameter** - Script URL only contains the v parameter
3. **Two sensors required** - Always post index 0 and index 1
4. **Proactive protection** - Sensors prevent future blocks rather than solving existing ones

#### Important Notes

1. **Cookie Management**: Use the `sbsd_o` or `bm_so` cookie value for the `o` parameter.
2. **Script and Context**: Send the `script` on the first `/sbsd` call only. Every call after it sends the `context` returned by the previous call and no `script`.
3. **Header Consistency**: Maintain consistent headers across all requests, including User-Agent and Accept-Language.
4. **Sensor Order**: Always post sensors in order (index 0 first, then index 1).

For handling blocking challenges or 429 responses with challenge tokens, refer to:

* [SBSD Challenge Flow](/akamai-web/sbsd-challenge-flow.md)
* [Handling 429 Status Codes](/akamai-web/handling-429-status-codes-with-sbsd-challenges.md)
