Capless
Docs For agents

For agents

Capless is built to be set up and operated by coding agents. Everything a human can do in the dashboard, an agent can do with one HTTP API or the MCP server, and every docs page is plain Markdown.

The one-liner

Tell your coding agent:

Add Capless analytics to this site. Instructions: https://capless.sh/llms.txt

The agent follows /AGENTS.md: create an account with the signup API, add the snippet, verify that events arrive, and hand you the dashboard link.

Machine-readable docs

URLWhat
/llms.txtIndex in llmstxt.org format, linking every page as Markdown
/llms-full.txtAll docs in one file
/docs/<page>.mdAny docs page as Markdown, e.g. /docs/cel.md
/AGENTS.mdInstall instructions an agent can follow verbatim
api.capless.sh/v1/openapi.yamlOpenAPI 3.1 spec
GET /v1/functionsThe CEL environment: variables per context, limits, number and regex rules

Signup API

POST https://api.capless.sh/v1/signup creates a user, a project on the 14-day trial, an API key and (with siteName) a web analytics site, in one call. No authentication.

FieldType
emailstring, requiredThe human's email. A verification email is sent to it.
passwordstring, optionalOmit it to sign in with emailed links only.
projectNamestring, optional
siteNamestring, optionalCreates a site and returns its snippet.
allowedOriginsstring[], optionalOrigins allowed to send events for the site, e.g. ["https://example.com"].
curl -s https://api.capless.sh/v1/signup \
  -d '{"email":"jane@example.com","projectName":"acme","siteName":"acme.com","allowedOrigins":["https://acme.com"]}'

201 Created:

{
  "user": { "id": "…", "email": "jane@example.com" },
  "project": { "id": "prj_…", "name": "acme", "plan": "trial", "trialEndsAt": "…" },
  "apiKey": "cpl_…",
  "site": { "key": "cs_…", "snippet": "<script async src=\"https://c.capless.sh/c.js\" data-site=\"cs_…\"></script>" },
  "dashboardUrl": "https://app.capless.sh/…",
  "mcp": { "url": "https://mcp.capless.sh/mcp", "headers": { "Authorization": "Bearer cpl_…" } }
}
  • apiKey is shown once. Store it where the project keeps secrets (e.g. .env as CAPLESS_API_KEY); never commit it and never put it in client-side code. The site key cs_… is public and write-only, so it is safe in HTML.
  • dashboardUrl is a one-time sign-in link valid for 15 minutes. Give it to the human.
  • 409 email_taken: the human already has an account. Ask them for an API key from the dashboard instead of creating another account.
  • 429 rate_limited: wait and retry later; do not loop.

End-to-end with curl

No CLI, no SDK. Replace the email and origin.

# 1. Account + site
curl -s https://api.capless.sh/v1/signup \
  -d '{"email":"jane@example.com","siteName":"acme.com","allowedOrigins":["https://acme.com"]}' > capless.json
export CAPLESS_API_KEY=$(node -p 'require("./capless.json").apiKey')
node -p 'require("./capless.json").site.snippet'    # paste before </head>
node -p 'require("./capless.json").dashboardUrl'    # give to the human

H="authorization: Bearer $CAPLESS_API_KEY"

# 2. After the site is loaded in a browser: events arrived?
curl -s https://api.capless.sh/v1/streams/web.events -H "$H"          # entryCount > 0
curl -s https://api.capless.sh/v1/streams/web.events/read -H "$H" -d '{"limitResultEntries":5}'

# 3. Your own data: a stream with a validator, an idempotent insert, a filtered read
curl -s https://api.capless.sh/v1/streams -H "$H" -d '{"name":"orders","validator":"entry.amount >= 0"}'
curl -s https://api.capless.sh/v1/streams/orders/entries -H "$H" \
  -d '{"idempotencyKey":"import-2026-10-30","entries":[{"user":"u1","amount":42},{"user":"u2","amount":7}]}'
curl -s https://api.capless.sh/v1/streams/orders/read -H "$H" -d '{"filter":"entry.amount > 10"}'

# 4. GDPR: erase one user everywhere
curl -s https://api.capless.sh/v1/streams/web.events/erasures -H "$H" -d '{"filter":"entry.userId == \"user_42\""}'

Delete capless.json once the key is stored safely.

MCP

The signup response includes a ready-made MCP config. Install it for Claude Code:

claude mcp add --transport http capless https://mcp.capless.sh/mcp --header "Authorization: Bearer cpl_…"

Then call the get_started tool. See MCP server for other clients and the full tool list.

Rules of thumb for agents

  • Retry writes with the same idempotencyKey; a retry returns the original result with duplicate: true.
  • Read with cursors, not offsets. Persist nextCursor; it never skips or repeats.
  • Dry-run CEL with POST /v1/functions/evaluate before using it on real data.
  • Errors carry a stable code; branch on it, not on the message.