File DA-005 View as Markdown

Capabilities

This page shows what works with no key, what a public key adds, and what needs your secret key on the server. Read it when you hit a key_required error, or when you are deciding whether to create an account.

There are three tiers:

  • Keyless: just the script tag. Every visitor gets a verdict in the browser and your tools get the labels. Free.
  • Public key (pk_live_…): add data-key to the same tag. You need an account and a

verified domain. This adds signed tokens, live presence and webhooks.

  • Secret key (sk_live_…): for your server only, never in the page. It reads your data and reports what your

server saw.

WhatKeylessPublic keySecret key (server)
Verdict in the browser: ready(), verdict(), on('verdict'), identify(), reset(), push, use()✓✓–
Labels in your tools (GA4, GTM, Meta Pixel, Stripe and the others) and holding back bot ad conversions✓✓–
Sessions collected and shown in the portalKept by hostname until you claim the domain✓–
on('final'), the final verdict from the Handler (off today, so it doesn't fire yet)✗✓–
Live presence (the portal's Live page)✗✓–
Signed tokens: check(action), getToken(), stripeToken(), protect(form)✗ key_required✓ from verified domains–
Verify a token: verifyToken in @doubleagent-so/node, offline with our public JWKS✓✓✓
Read data: getSession, /v1/sessions, /v1/stats, /v1/live✗In the portal✓ Bearer sk_…
Report from your server: /v1/evaluate (outcomes and callers), /v1/hits (crawlers at the edge)✗✗✓ needs a verified domain
Debrief webhook and server relabel (GA4, Klaviyo, Mixpanel, Shopify, Stripe)✗✓ set up in Settings–
/v1/install-check, the JWKS, signature bundles✓✓✓

Keyless data

Nobody can see keyless data until someone verifies the domain. Until then Double Agent keeps 30 days of it: totals, plus up to 1,000 sessions per hostname that were not clearly human. When you claim the domain, that history becomes yours.

The key_required error

Any token method on a keyless install rejects with DoubleAgentError('key_required'), and the message links here. protect(form) does not throw: the form still submits, with an empty da_token field, and your server decides.

Move up a tier

Add your public key to the tag you already have. Nothing else changes, and the keyless history stays with the site once the domain is verified.

<script>window.doubleagent=window.doubleagent||{q:[],push(){this.q.push(arguments)}};</script>
<script async src="https://cdn.doubleagent.so/v1/doubleagent.js" data-key="pk_live_xxx" data-profile="auto"></script>

Create secret keys in the portal under API keys, or with npx @doubleagent-so/cli keys create --kind sk. Keep them in a server-only environment variable.

Running with no cloud

data-cloud="off" keeps everything in the browser: verdicts and tool labels still work, but nothing reaches Double Agent, so there is no portal data and no signed tokens. See Plugins.

Next: create an account, claim your domain, or verify tokens on your server.