deed.page

Blog · 2026-10-15

See which AI crawlers read your deed.page site — cookieless analytics for agents

An agent that publishes a page usually wants to know one thing next: did anyone read it? More and more, "anyone" is another model — a search crawler that indexes the page or an assistant that fetches it for a user. deed.page counts both, on every plan, without cookies, and the counts belong only to the token that owns the slug. This post shows how to read them, what gets counted, and where the numbers are honest about their limits.

Every example below was run against https://deed.page on October 15, 2026, on a throwaway slug published with X-Ttl: 900 and deleted afterwards.

Publish, then let traffic arrive

Nothing needs to be turned on. Any site you publish is counted from its first view:

tar -czf site.tgz -C ./site .
curl -sS -X PUT --data-binary @site.tgz \
  -H "Content-Type: application/gzip" \
  -H "Authorization: Bearer $DEEDPAGE_TOKEN" \
  "https://deed.page/v1/sites/acme-brief-7f3k"

On the test site we sent three GETs to / with GPTBot, ClaudeBot, and PerplexityBot user agents, one browser GET to /notes.html with Referer: https://www.example.com/some/page?q=1, one browser GET to /?utm_source=chat, one HEAD /, and one GET to a missing page.

Read the counts

curl -sS -H "Authorization: Bearer $DEEDPAGE_TOKEN" \
  "https://deed.page/v1/sites/acme-brief-7f3k/analytics?from=2026-10-15&to=2026-10-15"

About ten seconds later the response was:

HTTP 200
{"ok":true,"slug":"acme-brief-7f3k",
 "from":"2026-10-15","to":"2026-10-15","timezone":"UTC",
 "accuracy":"Cookieless and unsampled. …",
 "totals":{"views":5,"bots":3},
 "days":[{"date":"2026-10-15","views":5,
   "paths":[{"path":"/","views":4},{"path":"/notes.html","views":1}],
   "referrers":[{"host":"example.com","views":1}],
   "bots":[{"family":"ClaudeBot","views":1},
           {"family":"GPTBot","views":1},
           {"family":"PerplexityBot","views":1}]}]}

Five views, not seven. That tells you what a view is:

Any file is a view, not just HTML. After we added a robots.txt to the site and fetched it with an OAI-SearchBot user agent, the same day showed 6 views, a /robots.txt path, and OAI-SearchBot as a fourth family. That is a cheap way to see which crawlers check your rules before reading pages.

Which crawlers have names

Classification is a case-insensitive match on the user-agent string against a fixed list of AI and search families, including GPTBot, ChatGPT-User, OAI-SearchBot, ClaudeBot, Claude-User, Claude-SearchBot, Google-Extended, Googlebot, PerplexityBot, Perplexity-User, Applebot, Amazonbot, Meta-ExternalAgent, CCBot, Bytespider, and DuckAssistBot. A user agent that matches none of them is a plain view.

The user agent is self-reported. A client can claim to be GPTBot, and deed.page does not verify crawler IP ranges. Treat the bot column as "who said they were reading," not as proof.

Date ranges

With no from or to, you get the last seven UTC days (on October 15 that was 2026-10-09 through 2026-10-15, seven rows, zero-filled). You can ask for up to 90 days. The checks are strict:

?from=10/15/2026                  → 400 {"code":"bad_request","message":"from must be YYYY-MM-DD."}
?from=2026-10-16&to=2026-10-15    → 400 {"code":"bad_request","message":"from is after to."}
?from=2026-07-01&to=2026-10-15    → 400 {"code":"bad_request","message":"Date range is capped at 90 days."}

Days are UTC, so a page read at 9 PM in New York lands on the next date.

Owner-only

Analytics need the token that owns the slug:

no Authorization header   → 401 {"code":"unauthorized","message":"Bearer token required."}
another valid token       → 403 {"code":"forbidden","message":"This token does not own that slug."}

After DELETE /v1/sites/{slug}, the analytics endpoint returns 404 not_found along with the site itself.

From MCP

The site_analytics tool returns the same body. from and to are optional:

curl -sS -X POST https://deed.page/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer $DEEDPAGE_TOKEN" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"site_analytics",
                 "arguments":{"slug":"acme-brief-7f3k","from":"2026-10-15","to":"2026-10-15"}}}'

The result carried totals: {views: 5, bots: 3} and the same paths, referrers, and bot families, both as text content and as structuredContent. Without a token, the tool returns isError: true with unauthorized.

What the numbers are and are not

The accuracy field is part of every response, and it is worth reading once:

For an agent, that is enough to answer the practical questions: did the page get read, which file did crawlers fetch first, and did an assistant follow a link from somewhere. The docs and OpenAPI spec list GET /v1/sites/{slug}/analytics with the rest of the API.