File DA-028 View as Markdown
REST API
Base: https://api.doubleagent.so. Errors look like { "error": { "code", "message" } }.
| Auth | Header |
|---|---|
| none | – |
| pk | ?k=pk_… |
| session | Authorization: Bearer das_… (portal, CLI login) |
| sk | Authorization: Bearer sk_… |
Collection and tokens
| Route | Auth | Returns |
|---|---|---|
POST /v1/collect | none (keyless, by Origin) or pk | 204 (the SDK beacon) |
POST /v1/check | pk | { verdict, token }; keyless → 401 key_required |
POST /v1/ping | pk | Live presence |
POST /v1/verify | none | { valid, claims } |
GET /.well-known/jwks.json | none | Signing keys |
GET /v1/install-check?url= | none | Install report (see /install.md step 5) |
Data (403 site_not_verified until a domain is verified)
| Route | Auth | Returns |
|---|---|---|
GET /v1/stats?from&to | sk, or session + ?site=st_… | Totals, series, families, profiles |
GET /v1/sessions?limit&class&cursor&quarantined | sk, or session + ?site= | { sessions, nextCursor } |
GET /v1/sessions/:sid | sk, or session + ?site= | One Dossier |
GET /v1/live?window=60 | sk, or session + ?site= | Live now |
GET /v1/sessions/:sid/events?limit&cursor | sk, or session + ?site= | { events, nextCursor }: every recorded revision of one session (collect, check, judge, join), limit ≤ 200 |
GET /v1/events/export?limit&cursor | sk, 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
| Route | Auth | Purpose |
|---|---|---|
POST /v1/auth/login | none | {email} → 204 (never says whether the email exists) |
POST /v1/auth/verify | none | {token} → { session, user, accounts } |
POST /v1/auth/logout | session | {all?} → 204 |
GET /v1/me | session | User, accounts, sites |
POST /v1/auth/device, /device/token, /device/approve | none / session | CLI device flow |
POST /v1/accounts | none + DA-PoW | Create account + site + keys (Accounts) |
Sites, domains, keys (session; viewers read only)
| Route | Purpose |
|---|---|
GET/POST /v1/sites | List; create {name, domain?, profile?} |
GET/PATCH/DELETE /v1/sites/:id | Settings; 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/:host | Remove a domain |
GET/POST /v1/sites/:id/keys | List (prefixes only); create {kind, env}, sk shown once |
POST /v1/sites/:id/keys/:keyId/rotate | New key; the old one lasts 24 h |
DELETE /v1/sites/:id/keys/:keyId | Revoke now |
DELETE /v1/sites/:id/preclaim | Discard pre-verification data |
GET /v1/sites/:id/audit | Audit log |
Limits: Security.