Cells/Analytics & Access Log

Analytics & Access Log

Every Cell records its own traffic — no script tag, no code change, nothing to configure. The dashboard's Overview tab shows who is visiting (humans and bots, countries, browsers, top paths) and how the Cell is behaving (error rate, response time, scheduled and sensor activity). The Access log tab lists individual requests.

Analytics describe traffic; they are not billing. Tissue bills CPU time and stored bytes only — requests are free and unmetered.


What is measured

For each request the platform records the UTC hour, whether the caller looked like a human browser or a bot, the response status, and the response time. Human traffic is additionally broken down by country, browser family, request path, and referrer site; bot traffic is broken down by crawler name.

Platform-originated invocations — Pulse fires and Synapse sensor dispatches — are counted as events, separately from visitor traffic. A Cell on a * * * * * schedule shows 1,440 pulse events a day, not 1,440 visitors.

All aggregation happens on Tissue's own infrastructure. There is no third-party analytics service, no tracking pixel, and nothing is loaded into your visitors' browsers.


Visitors, without cookies

Unique-visitor counts use no cookie and no stored identifier. Each request is keyed by a hash of the visitor's IP address, user agent, the Cell's address, and a salt that rotates at UTC midnight:

visitor = sha256(daily_salt ‖ ip ‖ user_agent ‖ cell_address)

The raw IP and user agent never enter the analytics store — only the hash does, and once the salt rotates, yesterday's hashes cannot be linked to today's. The same person is a "new visitor" every day, so visitor counts are approximate by design; the dashboard marks them as such.


Bot classification

Classification is user-agent based. Well-known crawlers (search engines, AI crawlers, uptime monitors, link-preview fetchers) are matched by name; anything else that self-identifies as automated is grouped under Unknown agents. The dashboard tags named crawlers as Search, AI crawler, or Monitor — useful when deciding what your robots.txt should say, because you can see how much of your traffic is AI crawlers and which ones.

Two honest caveats: a bot that fakes a normal browser user agent is counted as a browser, and a privacy proxy can shift a visitor's country. Treat the split as a good estimate, not an audit.


Countries

The visitor's IP is resolved to a two-letter country code at ingest, and only the code is stored in analytics. Geolocation runs locally against the DB-IP Lite database — IP geolocation by DB-IP — with no lookup ever leaving the platform.


Retention

Data Kept for
Access log (individual requests, incl. IP) 30 days
Hourly analytics (traffic, countries, browsers, paths, bots) 90 days
Daily visitor counts 400 days

Deleting a Cell deletes its analytics.


Analytics API

Base URL: https://api.tissue.systems · Auth: Authorization: Bearer <token> (CLI JWT or tok_ API token) · Scope: cells:read

GET /v1/cells/{address}/analytics

Returns the rollups behind the Overview tab. hours may be 24, 168 (7 days), or 720 (30 days); other values snap to the nearest window. Default is 168.

curl "https://api.tissue.systems/v1/cells/dd0d1cd5x7k2q/analytics?hours=24" \
  -H "Authorization: Bearer $TISSUE_TOKEN"
{
  "series":   [{ "t": "2026-08-09T14", "requests": 412, "human": 371,
                 "bots": 41, "s4xx": 3, "s5xx": 0, "avgMs": 12 }],
  "totals":   { "requests": 5210, "human": 4903, "bots": 307,
                "s2xx": 5100, "s3xx": 80, "s4xx": 27, "s5xx": 3, "avgMs": 14 },
  "visitors": { "human": 892, "bots": 55, "approx": true },
  "countries": [["US", 2101], ["DE", 512]],
  "browsers":  [["Chrome", 2900], ["Safari", 1203]],
  "botAgents": [["Googlebot", 120], ["~unknown", 88]],
  "paths":     [["/", 3100], ["/api/notes", 900]],
  "referrers": [["news.ycombinator.com", 340]],
  "events":    { "http": 5210, "pulse": 288, "sensor": 0 }
}

series is gap-filled (quiet hours appear as zeros). Breakdown lists are [name, count] pairs for human traffic only; bots are broken down in botAgents, where ~unknown collects unnamed agents and ~other folds the tail past the top entries.

GET /v1/cells/{address}/access-log

Returns individual requests, newest first: { "entries": [...], "total": n }.

Parameter Meaning
limit, offset Paging (default limit=25)
status Exact code (404) or class (4xx)
method HTTP method
event http, pulse, or sensor
bot true (bots only) or false (humans only)
path Substring match on the URL path
curl "https://api.tissue.systems/v1/cells/dd0d1cd5x7k2q/access-log?status=5xx&bot=false" \
  -H "Authorization: Bearer $TISSUE_TOKEN"

Entries carry the request line, status, duration, IP, referrer, and — when resolved — country, browser, bot, event, and the daily visitor hash.