Skip to main content
News/General

New SDK Majors: Akamai Telemetry, Client Hints, SBSD scriptUrl and Kasada strict

Go v4, Python 4.0 and JS 5.0 are out. Every generate call now returns a result object, the APIs return the full set of Accept-CH client hints, Akamai gets a telemetry endpoint for sites that protect their API with an Akamai-BM-Telemetry header, SBSD takes a scriptUrl and Kasada takes strict.

Hyper Solutions5 min read
On this page
General
TLS fingerprint
Header order
Client hints

New major versions of all three SDKs are out: Go v4.0.0, Python 4.0.0 and JS 5.0.0, plus hyper-sdk-playwright 1.0.0-beta.16. They carry four API changes, and one change to the SDKs themselves that makes this the last major you will need for a while.

Key Takeaways

  • Every generate call now returns a result object instead of loose values. New fields arrive as properties from now on, so a field added later no longer means another major version. This is the breaking part of the upgrade.
  • Client hints, on every product. Akamai, DataDome, Incapsula and Kasada now return the full set of Accept-CH client hints for the device the payload describes: 24 headers, ready to send.
  • Akamai-BM-Telemetry. Some sites protect their API calls with an Akamai-BM-Telemetry request header instead of a sensor post. Two new endpoints generate that header for you.
  • SBSD scriptUrl. Send the src of the SBSD script tag and the payload carries the script's own values, the way a browser's does.
  • Kasada strict. Opt in to refuse a payload when a script contains a signal we cannot identify yet, instead of getting one with that signal filled in.

Upgrade the SDK

Go          github.com/Hyper-Solutions/hyper-sdk-go/v4   v4.0.0
Python      hyper-sdk                                    4.0.0
JS/TS       hyper-sdk-js                                 5.0.0
Playwright  hyper-sdk-playwright                         1.0.0-beta.16

On Go the module path moves to /v4, so it is an import change as well as a version bump. The /v3 module is now marked deprecated and will not get these features.

If you use hyper-sdk-playwright, upgrade to 1.0.0-beta.16 and you are done. It handles client hints, the SBSD scriptUrl and the telemetry header for you.

Result objects

This is the one change that touches code you already have. Every generate call returns a single result object, and you read the payload, the context and the new client hints off it.

Go, before and after:

// v3
sensorData, sensorContext, err := session.GenerateSensorData(ctx, input)

// v4
res, err := session.GenerateSensorData(ctx, input)
sensorData := res.Payload
sensorContext = res.Context
hints := res.ClientHints

Python:

# 3.x
payload, context = session.generate_sensor_data(sensor_input)

# 4.0.0
res = session.generate_sensor_data(sensor_input)
payload, context, hints = res.payload, res.context, res.client_hints

JS/TS. Calls that resolved to a plain string now resolve to an object too, so generateReese84Sensor, generatePixelData, generateTagsPayload, generateKasadaPow and generateBotIDHeader need a .payload:

// 4.x
const reese84 = await generateReese84Sensor(session, input);

// 5.0.0
const { payload, clientHints } = await generateReese84Sensor(session, input);

Two smaller breaking changes come with it:

  • SBSD no longer takes an index. SBSD chains through context: the first call sends the script with an empty context, and every call after it sends the context it got back. A hard block, an SBSD POST with a t parameter, always starts a new chain with the script and an empty context.
  • DataDome's hints move to clientHints. In JS, the interstitial and slider results used to return them as headers.

Client hints

Chrome sends client hints on every request, and sites that ask for more through an Accept-CH response header get more. Until now you had to make those values up, and a sec-ch-viewport-width that does not match the device in your payload is exactly the kind of mismatch that gets a session flagged.

The APIs now return all 24 hints for the device the payload was generated for: the sec-ch-ua family, device memory and pixel ratio, viewport, network (ect, rtt, downlink) and the sec-ch-prefers-* preferences. Brands and full versions come from your user agent; everything else comes from the device.

You do not send all 24 on every request. The rule is the browser's:

  • sec-ch-ua, sec-ch-ua-mobile and sec-ch-ua-platform go on every request.
  • Any other hint only goes to an origin whose Accept-CH header asked for it.
  • Cross-origin requests get only the first three.

The hints are under ClientHints / client_hints / clientHints on every result. On Kasada they sit next to headers, which still holds the x-kpsdk-* headers you send on the protected request, so forwarding the whole headers map stays safe. The client hints guide has the full key list and code.

Akamai-BM-Telemetry

Some Akamai sites never post sensor data. Instead, the page's own XHR and fetch calls to the protected API carry an Akamai-BM-Telemetry header, and the API answers 403 without a valid one.

Two new endpoints cover it:

  • /v1/telemetry/params returns the path of the site's get_params request. Request it once per session and keep the j from its response.
  • /v1/telemetry takes the same input as a sensor request plus that j, and returns the complete header value. Call it before every protected request, chaining context, and never reuse a header.

Go:

params, err := session.GetTelemetryParams(ctx, &hyper.TelemetryParamsInput{PageUrl: pageURL, Script: script})
// GET pageOrigin + params.Path once and keep the j from its JSON response

res, err := session.GenerateTelemetry(ctx, &hyper.TelemetryInput{
    SensorInput: hyper.SensorInput{
        Abck: abck, Bmsz: bmsz, PageUrl: pageURL, ScriptUrl: scriptURL,
        UserAgent: userAgent, IP: ip, AcceptLanguage: acceptLanguage,
        Context: params.Context,
    },
    J: j,
})
// send res.Header as Akamai-BM-Telemetry, keep res.Context for the next request

Python and JS follow the same shape (get_telemetry_params / generate_telemetry, getTelemetryParams / generateTelemetry). The Akamai-BM-Telemetry guide shows how to recognise these sites and walks through the flow in all three languages.

SBSD scriptUrl

The SBSD endpoint takes an optional scriptUrl: the absolute src of the SBSD script tag, query included, exactly as the page loads it.

A browser's SBSD fingerprint includes signals about the script itself, and those differ between an SBSD script on a normal page and one on a block page. With scriptUrl set, the payload carries the script's own values; without it, the API falls back to defaults. Send it whenever you have the script tag.

res, err := session.GenerateSbsdData(ctx, &hyper.SbsdInput{
    // ...the fields you already send
    ScriptUrl: "https://example.com/.well-known/sbsd?v=7ac10a5c-7a4e-fddd-611f-39dcf23f1722&t=99543528",
})

It is script_url= in Python and the last constructor argument of SbsdInput in JS.

Kasada strict

Kasada ships new signals now and then. When a script contains one we cannot identify yet, the API fills it in as best it can and returns a payload. That is the right default for most integrations.

If you would rather fail fast, set strict. A script with an unidentified signal then returns an error instead of a payload, and you can retry later or fall back.

res, err := session.GenerateKasadaPayload(ctx, &hyper.KasadaPayloadInput{
    // ...the fields you already send
    Strict: true,
})

It is strict=True in Python and the last constructor argument of KasadaPayloadInput in JS. It defaults to off.

If something is unclear

Working end-to-end examples for every language and TLS client are in the examples repo, already on the new versions, and the API reference is in the docs. Our Claude Code and Codex plugins know about all of this too.

Read this through first, then come and ask. We are in Discord and happy to look at a capture if your integration does something the examples do not cover.

Try it yourself

Solve Akamai, DataDome, Incapsula and Kasada in one request

Skip the browser. Generate the sensor data, tokens and cookies you just read about over plain HTTP, with a free one-week trial.