File DA-022 View as Markdown
Browser API
Every method on window.doubleagent, what it returns, and whether it needs a key. Use this page when you write code against the script: reading the verdict, getting a signed token for your server, or protecting a form.
Methods
| Method | Returns | Needs a key |
|---|---|---|
ready() | Promise<Verdict>: the provisional verdict, in about 1.5 s | No |
verdict() | The current Verdict, or null before the first one | No |
on('verdict' | 'final', fn) | An unsubscribe function. verdict runs on every new verdict, final on the server-checked one | No |
identify(sha256(userId)) | Nothing. Send a hash, never the raw id or an email | No |
ecommerce(event, payload) | Nothing. GA4-shaped view_item, add_to_cart, begin_checkout, purchase. See Ecommerce | No |
use(plugin, config?) | Nothing. Adds your own plugin. See Plugins | No |
flush() | Nothing. Sends the session report now | No |
reset({ reload }) | Promise<Verdict | undefined>. Ends the session and reloads the page. With { reload: false } it starts a new session and resolves with its first verdict | No |
push('method', ...args) or push(da => …) | Nothing. Queues a call until the script loads | No |
check(action, { signal }?) | Promise<Verdict>: the server-checked verdict, with token | Yes |
getToken(action?) | Promise<string>: a signed token, cached per action until it expires. Defaults to the page's action | Yes |
stripeToken() | Same as getToken('payment') | Yes |
protect(form, action?) | Nothing. Adds a hidden da_token field to the form on submit | Yes |
A verdict's fields are explained in Verdict.
Get a token for your server
const token = await doubleagent.getToken('signup');
await fetch('/api/signup', { method: 'POST', body: JSON.stringify({ email, da_token: token }) });
Or let the script add it to a form:
doubleagent.protect('#signup-form', 'signup');
Your server then verifies the token with @doubleagent-so/node. protect() waits at most 1.5 s for a token; if none arrives, the form submits without one and your server decides.
Errors
| Situation | What happens |
|---|---|
| No key (keyless install) | check(), getToken() and stripeToken() reject, and protect() throws, with DoubleAgentError code key_required. See Capabilities |
Cloud off (data-cloud="off") | check(), getToken() and stripeToken() reject with code cloud_disabled. protect() does nothing and the form submits as normal. See Plugins |
| Action name not allowed | check() throws bad action <name> |
Actions
Built in: pageview, search, login, signup, password_reset, add_to_cart, checkout, payment, gift_card, promo, post, message, lead_form, api_key.
You can use your own name too: letters, digits, / and _, up to 64 characters (newsletter, quote/request). A custom action recommends challenge once the chance of a bot or agent reaches 0.8, on every site profile.
Options
init() takes the same options as the script tag's attributes, and more. The full list is in Script tag › Options. The ones most code touches:
doubleagent.init({ key?, profile?, consent?: 'auto' | 'granted' | 'denied', mode?: 'analytics' | 'security',
block?: { adConversions?: 'bot' | 'bot+agent' | 'none', forms?: boolean }, siteSearch?: boolean, debug? })
siteSearch: false stops site-search terms (on by default).
Calling init({ key }) after a keyless install upgrades the page in place: tokens start working without a reload.
Next: Verify tokens on your server, or Plugins to send verdicts somewhere new.