Sift Docs
Reference

API reference

Create sites, check installation, and read stats over HTTP.

The API is built for both humans and autonomous agents. Every endpoint takes an Authorization: Bearer <token> header.

Base URL:

https://sift.agentonboard.xyz

Authentication

Tokens are AgentOnboard identity tokens: short-lived RS256 JWTs scoped to sift.agentonboard.xyz. See Agent API for how an agent gets one, and the discovery document for the machine-readable version of this page.

Endpoints

MethodPathPurpose
POST/api/v1/agents/signupCreate the calling account, or sign in if it exists.
GET/api/v1/agents/sitesList sites the account can access.
POST/api/v1/agents/sitesRegister a new site.
GET/api/v1/agents/sites/{domain}Site details, role, verification status, snippet.
PATCH/api/v1/agents/sites/{domain}Update domain, timezone, or public visibility.
DELETE/api/v1/agents/sites/{domain}Delete a site and purge its data. Owner only.
GET/api/v1/agents/stats/{domain}Stats, timeseries, and breakdowns.
GET/api/v1/agents/stats/{domain}/realtimeVisitors active in the last 5 minutes.

Create an account

POST /api/v1/agents/signup takes no body. Calling it for an email that already has an account signs in instead of creating a duplicate.

curl -X POST https://sift.agentonboard.xyz/api/v1/agents/signup \
  -H "Authorization: Bearer $SIFT_TOKEN"
{ "user": "usr_...", "created": true }

List sites

curl https://sift.agentonboard.xyz/api/v1/agents/sites \
  -H "Authorization: Bearer $SIFT_TOKEN"
{
  "sites": [
    {
      "id": "site_...",
      "domain": "example.com",
      "timezone": "Europe/Berlin",
      "isPublic": false,
      "role": "owner"
    }
  ]
}

Create a site

curl -X POST https://sift.agentonboard.xyz/api/v1/agents/sites \
  -H "Authorization: Bearer $SIFT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.com","timezone":"Europe/Berlin"}'
{
  "site": { "id": "site_...", "domain": "example.com", "timezone": "Europe/Berlin", "isPublic": false },
  "snippet": "<script defer data-domain=\"example.com\" src=\"https://sift.agentonboard.xyz/js/sift.js\"></script>"
}

timezone defaults to UTC. Success is 201. Errors:

StatusBodyCause
400Invalid domain format. Enter a valid hostname like 'example.com'.Not a valid hostname.
409This domain is already registered on Sift.Domain is taken.

Read stats

curl "https://sift.agentonboard.xyz/api/v1/agents/stats/example.com?period=7d" \
  -H "Authorization: Bearer $SIFT_TOKEN"

period accepts today, yesterday, 7d, 30d, month, last-month. For a custom range, pass from and to as ISO timestamps instead.

{
  "ok": true,
  "domain": "example.com",
  "period": "7d",
  "range": { "from": "2026-10-25T00:00:00.000Z", "to": "2026-11-01T00:00:00.000Z" },
  "stats": { "visitors": 1284, "pageviews": 3021, "bounceRate": 41, "visitDuration": 96 },
  "series": [
    {
      "date": "2026-10-25",
      "label": "Oct 25",
      "visitors": 172,
      "pageviews": 401,
      "viewsPerVisit": 2.3,
      "bounceRate": 38,
      "visitDuration": 104
    }
  ],
  "breakdowns": {
    "pages": [],
    "entryPages": [],
    "exitPages": [],
    "sources": [],
    "channels": [],
    "countries": [],
    "regions": [],
    "cities": [],
    "devices": [],
    "browsers": [],
    "os": []
  }
}

Realtime

curl https://sift.agentonboard.xyz/api/v1/agents/stats/example.com/realtime \
  -H "Authorization: Bearer $SIFT_TOKEN"
{
  "ok": true,
  "domain": "example.com",
  "data": {
    "currentVisitors": 3,
    "series": [{ "date": "09:41", "label": "09:41", "visitors": 2, "pageviews": 3 }],
    "topPages": [{ "name": "/pricing", "visitors": 2, "pageviews": 3 }],
    "topSources": [{ "name": "Google", "visitors": 2, "pageviews": 3 }],
    "topCountries": [{ "name": "DE", "visitors": 2, "pageviews": 3 }]
  }
}

Errors

StatuscodeWhat it means
401anyToken rejected. Get a fresh token and retry once.
403ACCOUNT_REQUIREDIdentity is valid but has no Sift account. Call /signup, then retry.
403—Authenticated but not allowed to act on this site.
404—Site not found, or not visible to this account.
500RESOLVER_ERROR, CONFIG_ERRORAccount lookup or configuration failed. Retry later; do not re-authenticate.

What the API does not expose

  • Creating a second user or inviting members.
  • Reading individual pageviews. Only aggregates and breakdowns.
  • Writing events. Ingestion is the browser script's job.

That last one is deliberate: there is no server-side event API, so nothing can fabricate traffic.

On this page