Akamai BMP sensor data API
Akamai BMP (Bot Manager Premier) and Akamai BAP (Bot and Abuse Protection) are Akamai's mobile SDK-based bot detection solutions. They collect sensor data from iOS and Android devices to distinguish real users from automated traffic. Our API handles the entire sensor generation pipeline itself.
We do not support illicit use of our API, and we will not hesitate to block any users who abuse it. We are committed to providing a safe and secure experience for all of our users, and we will take action against anyone who violates our terms of service. Unblocking may only be possible after ID KYC verification and/or valid justification.
Low success rates? Please contact us and we will help you troubleshoot your implementation.
Getting started
To confirm an app uses Akamai BMP, look for the presence of Akamai BMP HTTP traffic - typically a GET to /_bm/get_params, /_sec/sdk_challenge.js or a header x-acf-sensor-data. The sensor payload itself is an encrypted, versioned string.
Our API consists of four endpoints - two platforms (ios and android), two endpoints each:
| Operation | Endpoint | Description |
|---|---|---|
| Create session | GET /akamai-bmp/{platform}/init | Returns a device matching your version/model filters + session state |
| Generate sensor | POST /akamai-bmp/{platform}/sensor | Builds and returns a complete sensor payload |
Supported BMP versions
| Platform | Versions |
|---|---|
| Android | 3.3.9, 3.4.0, 4.0.0, 4.0.5, 4.0.6, 4.1.3, 4.1.4 |
| iOS | 3.2.6, 3.3.9, 4.0.0, 4.0.2, 4.0.4, 4.0.6, 4.1.4, 4.2.0, 4.3.0, 4.4.0 |
This list might be incomplete. More versions can be provided free of charge upon request. Please contact us if you need a specific version.
If your app is unsupported, please do not hesitate to contact us!
Android is currently not supported.
Key customer-side detection vectors
- Proxies - Akamai is very sensitive to proxy quality. At very least, use a sticky/static proxy from country of app's target audience. We recommend using a high-quality residential or ISP proxy provider.
- TLS fingerprint - Your HTTP client must match the TLS fingerprint of the target platform.
- Header order - Header order must match real requests' one. Use HTTP proxy to inspect the actual request/response bodies.
Flow
We provide a Golang SDK for your convenience, but you can also use our API with any programming language that supports HTTP requests. For convenience, we will use our SDK in the examples below.
1. Initialize an iOS session
Session management
You should maintain the provided session object - it holds the internal state responsible for coherent payloads (encrypted keys, timestamps, DCI status). Our SDK gives you a simple interface to create a session:
session, err := client.AkamaiBMPIOSSession(
"4.2.0", // BMP version
"com.xyz.app", // bundle identifier
"1.0.0", // app version
).
WithIOSVersion("26.5.0").
Create(ctx)
Please note that this charges you just like a normal sensor generation request, but the first generation of sensor is provided for free.
2. GET /_bm/get_params
This endpoint returns a JSON object with DCI and/or POW challenge data. You must pass the response when building the Sensor request.
Typical URL is: https://example.com/_bm/get_params?type=sdk-dci&starttime=123&systemVersion=26.5&model=iPhone&deviceHardwareType=iPhone15/3&appIdentifier=com.example.app&deviceId=EB9F7215-5DC4-48C7-BBF8-9DA793FA6AD3
Please use following values for query parameters when building the URL:
| Parameter | Code |
|---|---|
| starttime | session.StartMillis() |
| systemVersion | session.IOSVersion() |
| deviceHardwareType | strings.ReplaceAll(session.Model(), ",", "/") |
| deviceId | session.UDID() |
Using Veris Labs provided parameters will ensure that the generated sensor is coherent, valid and therefore accepted by Akamai BMP.
Please maintain ORIGINAL query parameters ordering.
3. GET /_sec/sdk_challenge.js (optional)
Request the DCI JavaScript challenge. It's dynamically generated on a per-request basis. While most apps do not require it, some apps may suffer low success rates without it.
Typical URL is: https://example.com/_sec/sdk_challenge.js?os=ios&starttime=123&systemVersion=26.5&model=iPhone&deviceHardwareType=iPhone15/3&appIdentifier=com.example.app&deviceId=EB9F7215-5DC4-48C7-BBF8-9DA793FA6AD3&serverSideSignal=xyz\
| Parameter | Code |
|---|---|
| starttime | session.StartMillis() |
| systemVersion | session.IOSVersion() |
| deviceHardwareType | strings.ReplaceAll(session.Model(), ",", "/") |
| deviceId | session.UDID() |
Using Veris Labs provided parameters will ensure that the generated sensor is coherent, valid and therefore accepted by Akamai BMP.
Please maintain ORIGINAL query parameters ordering.
Make sure serverSideSignal is properly escaped!
4. Generate an iOS sensor
Sensor returns a sensor builder. Pass the /_bm/get_params JSON response and if you have it, the DCI JavaScript source to the builder. Then call Generate to get the final sensor payload.
sensor, _, err := session.Sensor().
WithParams(params).
WithDCIScript(dciScript). // optional
Generate(ctx)
if err != nil {
return err
}
5. Use the result
Send sensor in the x-acf-sensor-data header to the target Akamai endpoint and enjoy a high success rate. If you are not satisfied with the success rate, please contact us and we will help you troubleshoot your implementation.
Complete example (SDK)
Imports and HTTP helpers are omitted for brevity. Assume getBmParams,
getDCIScript, and postBMPSensor reuse the same configured HTTP client,
proxy, headers, and TLS fingerprint.
func runFlow(ctx context.Context, verisClient *veris.Client) error {
const (
targetURL = "https://example.com"
appPackage = "com.xyz.app"
)
session, err := verisClient.AkamaiBMPIOSSession(
"4.2.0",
appPackage,
"1.0.0",
).
WithIOSVersion("26.5.0").
Create(ctx)
if err != nil {
return err
}
params, err := getBmParams(ctx, targetURL, appPackage, session)
if err != nil {
return err
}
dciScript, err := getDCIScript(ctx, targetURL, appPackage, session, params)
if err != nil {
return err
}
sensor, _, err := session.Sensor().
WithParams(params).
WithDCIScript(dciScript). // optional
Generate(ctx)
if err != nil {
return err
}
if err := postBMPSensor(ctx, targetURL, sensor); err != nil {
return err
}
return nil
}
Usage notes
- Reuse a session for one coherent sequence. The SDK serializes generations on the session and updates its state after successful call.
- Challenge inputs are plain strings. Pass the
/_bm/get_paramsJSON response and DCI JavaScript without base64 encoding. - iOS supports device filtering by exact version, version range, and model. Contact us and we might be able to find a sweet spot for your usecase!
- Use an HTTP proxy to inspect actual request/response bodies. Mobile SDK payloads are sensitive to exact field order and encoding.