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_…): adddata-keyto 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.
| What | Keyless | Public key | Secret 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 portal | Kept 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.