# Anura bot detection

Attach third-party visitor bot detection and invalid traffic signals from [Anura](https://www.anura.io/) to individual Certified Digital Records (CDRs).

Default is **off**. Anura only runs when you explicitly opt in for a specific capture.

Enabling Anura never delays your capture. `captureCDR()` returns your CDR ID on the same timeline as it does without Anura, and form submissions and page navigation are never held up waiting on an assessment.

## Enabling Anura on capture

Add the `anura` parameter to `captureCDR()`:

```javascript
await window.ExpressConsent.captureCDR({
  cid: "org_123456789",
  domain: "example.com",
  anura: true, // Use ExpressConsent's Anura instance
});
```

### Instance options

There are two modes:

* **ExpressConsent instance (`anura: true`):** Uses ExpressConsent's Anura instance, and you will be billed to your ExpressConsent account.
* **Your own instance (`anura: { instanceId: 123456789 }`):** Uses your existing Anura instance ID. Anura bills your account directly; ExpressConsent attaches the data to your CDRs and never bills you for Anura requests.

## Auto-collect requirement

> **Warning: Auto-collect required**
>
> Anura only runs when auto-collect is active on your organization. Passthrough accounts have auto-collect disabled and cannot use Anura. If Anura is requested on an account without auto-collect, capture and rendering still succeed, but Anura data is not retrieved or attached.

## Where results appear

Because Anura runs asynchronously, `captureCDR()` does **not** return Anura results in its client response. Results appear on downstream surfaces once retrieved:

* **Dashboard CDR view:** A dedicated **Bot Detection (Anura)** card showing assessment result (`good`, `warn`, or `bad`), device type, ad blocker detection, triggered rule sets, and invalid traffic classification. Hidden from print layouts.
* **Public share links:** Included on public share views and package share pages.
* **API:** Included on `GET /cdrs/{id}` when available (`anura` property on the record).
* **Webhooks:** Included in the `cdr.completed` payload when the assessment lands before or during render.

### Result shape

The `anura` property is identical on the API, the `cdr.completed` webhook, and share payloads:

```json
{
  "result": "bad",
  "invalidTrafficType": "SIVT",
  "mobile": 0,
  "adblocker": 0,
  "ruleSets": ["UE", "SP"],
  "billed": true,
  "queriedAtMs": 1704067200000
}
```

Only `result` (`good`, `warn`, or `bad`), `billed`, and `queriedAtMs` are always present:

* `billed`: whether the request was billed to your ExpressConsent account. Always `false` when you supply your own instance ID.
* `queriedAtMs`: when the assessment was retrieved, in milliseconds since the Unix epoch.

`invalidTrafficType`, `mobile`, `adblocker`, and `ruleSets` are returned only when the Anura instance is configured to report them and the value is applicable, so treat every one of them as optional. Anura often sends JSON `null` for those keys (for example `invalid_traffic_type` on a `good` result); ExpressConsent omits the field in that case rather than failing the assessment. See [Anura's result documentation](https://docs.anura.io/integration/script/result) for what each field means and the full set of possible values. ExpressConsent renames Anura's snake_case fields to camelCase (`invalid_traffic_type` becomes `invalidTrafficType`, `rule_sets` becomes `ruleSets`) to match the rest of our payloads, and does not include Anura's internal identifiers.

## Fail-open design

Anura failures never impact your capture or evidence pipeline:

* **Ad blockers or blocked scripts:** If `script.anura.io` is blocked by client ad blockers, browser extensions, or network policies, the capture and consent evidence still succeed without Anura data.
* **Timeouts and API errors:** If Anura returns an error, or does not produce an assessment in time, your CDR is still rendered, collected, and delivered by webhook as normal, just without Anura data.
* **Never throws:** Anura will never throw an error out of `captureCDR()` or interrupt a capture call.

## Client Hints (optional)

For improved visitor identification accuracy, you can optionally configure Anura's Client Hints headers on your web server response headers:

```http
Accept-CH: Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA-Model, Sec-CH-UA-Arch, Sec-CH-UA-Bitness
```

## Next

- [The cdr.completed event](https://expressconsent.com/docs/webhooks/cdr-completed): Every field on the webhook payload, when each one is present, and what it means.
- [API conventions](https://expressconsent.com/docs/reference/api): Base URL, authentication, the response envelope, and pagination for the server-to-server API.
