Public
Like
driftline-analytics
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
index.http.ts
https://tijs--db5b135ccc4511f08d4d42dde27851f2.web.val.run
Anonymous analytics service for ATProto app views, hosted on Valtown.
- Anonymous by design: users are identified by pseudonymous IDs derived from DIDs
- Per-app-view isolation: same user gets different IDs across different app views
- Simple event model: accounts, views, and actions
- JSON stats API
Base URL: https://driftline.val.run
GET /
POST /collect
Headers: X-API-Key: <your-api-key>
Content-Type: application/json
Body (single event):
{
"v": 1,
"appView": "kipclip.com",
"env": "prod",
"ts": "2025-01-15T10:30:00.000Z",
"uid": "a1b2c3d4e5f6",
"type": "action",
"name": "checkin_created",
"screen": "CheckinScreen",
"props": { "placeType": "cafe" }
}
Body (batch):
{
"events": [...]
}
Event types:
account- Track account creation (once per user)view- Track screen impressionsaction- Track user actions
All stats endpoints require the X-API-Key header.
GET /stats/:appView?env=prod
GET /stats/:appView/accounts?env=prod
GET /stats/:appView/users?env=prod
GET /stats/:appView/events?env=prod
See @tijs/driftline-client for the TypeScript client library.
User IDs are derived using SHA-256:
uid = sha256(salt + did).slice(0, 12)
- Each app view uses its own salt
- Same DID produces different UIDs across app views
- Server never sees the original DID
Create API keys (requires ADMIN_SECRET env var):
POST /admin/api-keys
Headers: X-Admin-Secret: <admin-secret>
Body: { "appView": "your-app.com" }
deno task fmt # Format code deno task lint # Lint code deno task check # Type check deno task deploy # Format, lint, check, and push to Valtown