Anura bot detection

Attach third-party visitor bot detection and invalid traffic signals from Anura (opens in a new tab) 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

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 (opens in a new tab) 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