File DA-023 View as Markdown
Plugins
A plugin lets you send Double Agent's verdict to a tool we don't support yet, or send each session to your own backend. Every built-in integration is a plugin, and so is the Double Agent cloud, so you can also run with the cloud off.
The shape of a plugin
doubleagent.use({
name: 'mytool', // unique; a later plugin with the same name replaces it
cat: 'analytics', // consent category: 'analytics' (default) | 'ads' | 'functional'
setup(ctx) { return () => {} }, // once per session; the teardown runs on reset() and pagehide
apply(verdict, ctx) {}, // every new verdict; ctx.event is 'da_classified' / 'da_final' once per session
report(payload, ctx) {}, // the session report; payload.reason is 'ready' | 'change' | 'hidden' | 'pagehide' | 'flush'
});
- A plugin you add is always on. It runs only when the visitor consented to its
cat. - Before the script loads, queue it:
doubleagent.push('use', plugin). With npm:init({ plugins: [plugin, [other, config]] }). ctx.fieldsholds the nineda_*properties.ctx.configis the second
argument of use().
ctx.send(url, body)posts JSON astext/plain, so there is no CORS preflight. It triessendBeaconfirst, then a
keepalive fetch.
- A plugin that throws is skipped (and logged with
debug: true). Other plugins and your page carry on.
Send verdicts to a tool we don't support
Everything stays in the browser. Nothing leaves the page except through the tool itself.
doubleagent.push('use', {
name: 'acme',
apply(v, ctx) {
if (!ctx.allowed) return;
window.acme?.setUserProperties({ da_class: ctx.fields.da_class, da_score: ctx.fields.da_score });
if (ctx.event) window.acme?.track(ctx.event, ctx.fields);
},
});
Send sessions to your backend
Your server gets the same session reports as the Double Agent cloud.
doubleagent.push('use', {
name: 'mybackend',
report(p, ctx) {
ctx.send('https://collect.example.com/da', { reason: p.reason, sid: p.sid, verdict: p.verdict, pages: p.pages });
},
});
Cloud off, your own backend only
Use this when no data may go to Double Agent. The script still detects in the page and your plugins still run.
<script>window.doubleagent=window.doubleagent||{q:[],push(){this.q.push(arguments)}};
doubleagent.push('use', { name: 'mybackend', report(p, ctx) { ctx.send('https://collect.example.com/da', p); } });</script>
<script async src="https://cdn.doubleagent.so/v1/doubleagent.js" data-cloud="off"></script>
With npm: doubleagent.init({ cloud: false, plugins: [mybackend] }).
With the cloud off, the script makes no request to Double Agent. Verdicts, integrations and your plugins keep working. What needs the cloud stops:
check(),getToken()andstripeToken()reject withDoubleAgentErrorcodecloud_disabled.protect()does nothing: the form submits without ada_token.on('final')never fires, because final verdicts come from the server.- No data in the portal, no live presence, no proof of work, no server checks of agent identity.
Next: Capabilities to compare what works with and without the cloud, or Agent Detector to run the engine on its own.