Docs

File DA-028 View as Markdown

REST API

Base: https://api.doubleagent.so. Errors look like { "error": { "code", "message" } }.

AuthHeader
none–
pk?k=pk_…
sessionAuthorization: Bearer das_… (portal, CLI login)
skAuthorization: Bearer sk_…

Collection and tokens

RouteAuthReturns
POST /v1/collectnone (keyless, by Origin) or pk204 (the SDK beacon)
POST /v1/checkpk{ verdict, token }; keyless → 401 key_required
POST /v1/pingpkLive presence
POST /v1/verifynone{ valid, claims }
GET /.well-known/jwks.jsonnoneSigning keys
GET /v1/install-check?url=noneInstall report (see /install.md step 5)

Data (403 site_not_verified until a domain is verified)

RouteAuthReturns
GET /v1/stats?from&tosk, or session + ?site=st_…Totals, series, families, profiles
GET /v1/sessions?limit&class&cursor&quarantinedsk, or session + ?site={ sessions, nextCursor }
GET /v1/sessions/:sidsk, or session + ?site=One Dossier
GET /v1/live?window=60sk, or session + ?site=Live now
GET /v1/sessions/:sid/events?limit&cursorsk, or session + ?site={ events, nextCursor }: every recorded revision of one session (collect, check, judge, join), limit ≤ 200
GET /v1/events/export?limit&cursorsk, or session + ?site={ events, nextCursor }: all events for the site, oldest first, limit ≤ 200 (default 100)

Every session is stored, humans included, and appears in these routes within about 30 seconds. /v1/stats accepts ranges up to 365 days. After a domain claim merges keyless history, data routes answer 503 claim_pending (retry shortly) until it is consolidated.

Collection telemetry: POST /v1/collect answers with header DA-Telemetry-Accepted: 0 when the event could not be queued for storage (detection still succeeded). POST /v1/check always includes telemetryAccepted: true|false in its JSON. Both only say whether storing the session was queued; they never affect the verdict.

Accounts and auth

RouteAuthPurpose
POST /v1/auth/loginnone{email} → 204 (never says whether the email exists)
POST /v1/auth/verifynone{token} → { session, user, accounts }
POST /v1/auth/logoutsession{all?} → 204
GET /v1/mesessionUser, accounts, sites
POST /v1/auth/device, /device/token, /device/approvenone / sessionCLI device flow
POST /v1/accountsnone + DA-PoWCreate account + site + keys (Accounts)

Sites, domains, keys (session; viewers read only)

RoutePurpose
GET/POST /v1/sitesList; create {name, domain?, profile?}
GET/PATCH/DELETE /v1/sites/:idSettings; webhook and integration secrets are write-only
POST /v1/sites/:id/domains{hostname} → token and methods
POST /v1/sites/:id/domains/:host/verify{method} → { verified, detail, claimed }
DELETE /v1/sites/:id/domains/:hostRemove a domain
GET/POST /v1/sites/:id/keysList (prefixes only); create {kind, env}, sk shown once
POST /v1/sites/:id/keys/:keyId/rotateNew key; the old one lasts 24 h
DELETE /v1/sites/:id/keys/:keyIdRevoke now
DELETE /v1/sites/:id/preclaimDiscard pre-verification data
GET /v1/sites/:id/auditAudit log

Limits: Security.