# Browser API

```ts
doubleagent.init({ key?, profile?, endpoint?, integrations?: 'auto' | { ga4: true, … },
  consent?: 'auto' | 'granted' | 'denied', mode?: 'analytics' | 'security',
  block?: { adConversions?: 'bot' | 'bot+agent' | 'none', forms?: boolean }, debug? })
```

| Method | Returns | Needs a key |
|---|---|---|
| `ready()` | Provisional verdict, about 1.5 s | No |
| `verdict()` | `Verdict \| null` | No |
| `on('verdict' \| 'final', fn)` | Unsubscribe function | No |
| `identify(sha256(userId))` | – (hash only) | No |
| `reset()` | – | No |
| `flush()` | Sends the beacon now | No |
| `check(action)` | Server-checked verdict and token | **Yes** |
| `getToken(action)` | Signed token, cached per action | **Yes** |
| `stripeToken()` | `getToken('payment')` | **Yes** |
| `protect(form, action)` | Hidden `da_token` on submit | **Yes** |

Without a key, `check`, `getToken` and `stripeToken` reject, and `protect` throws, with `DoubleAgentError` code `key_required`. See [Capabilities](/docs/capabilities).

Calling `init({ key })` after a keyless auto-init upgrades the page in place. Live presence stays off without a key.

Before load: `doubleagent.push('method', ...args)` or `doubleagent.push(da => …)`.

Actions: `pageview search login signup password_reset add_to_cart checkout payment gift_card promo post message lead_form api_key`, or your own `[A-Za-z0-9/_]`.
