/install millimetric-track
Millimetric Track
Send analytics events to Millimetric's API. Server-side keys only (sk_live_…). The classifier auto-derives source/medium/campaign from url + referrer + click IDs — don't try to set those yourself.
When to Use
- User asks to log/track/emit/send/record an event
- Linking an anonymous visitor to a known user (
identify) - Bulk-uploading events from a backfill or webhook
- Processing a "forget me" / GDPR erasure request
- Wiring server-side instrumentation (Express, Fastify, Hono, Next.js route handler, cron job, queue worker)
When NOT to Use
- Reading data → use
millimetric-query - Connecting an AI agent to Millimetric → use
millimetric-mcp-setup - Browser instrumentation → tell the user to drop in the
\x3Cscript src="https://cdn.millimetric.ai/v1/a.js" data-key="pk_live_…">snippet instead —pk_*keys must never appear in shell or server code
Setup
export MILLIMETRIC_KEY=sk_live_... # server key, scope: ingest
export MILLIMETRIC_HOST=https://api.millimetric.ai
For local dev against the Worker: MILLIMETRIC_HOST=http://localhost:8787.
Quick start
Track a single event
curl -X POST "$MILLIMETRIC_HOST/v1/track" \
-H "Authorization: Bearer $MILLIMETRIC_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "signup",
"anonymous_id": "u_abc",
"user_id": "user_42",
"url": "https://yoursite.com/?utm_source=facebook&utm_medium=cpc&fbclid=abc",
"properties": { "plan": "free" }
}'
Response: 202 Accepted, body { "ok": true, "event_id": "..." }.
Identify (link anonymous → user)
curl -X POST "$MILLIMETRIC_HOST/v1/identify" \
-H "Authorization: Bearer $MILLIMETRIC_KEY" \
-H "Content-Type: application/json" \
-d '{
"anonymous_id": "u_abc",
"user_id": "user_42",
"traits": { "email": "[email protected]", "plan": "pro" }
}'
After this, include user_id on every subsequent track call for that visitor.
Batch (up to 500 events per request, ≤256 KB body)
curl -X POST "$MILLIMETRIC_HOST/v1/batch" \
-H "Authorization: Bearer $MILLIMETRIC_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [
{ "event": "purchase", "anonymous_id": "u_1", "user_id": "user_1", "properties": { "amount_cents": 4900 } },
{ "event": "purchase", "anonymous_id": "u_2", "user_id": "user_2", "properties": { "amount_cents": 1900 } }
]
}'
Each event in the batch supports the same fields as /v1/track. Batch is rate-limited at 5/sec, burst 20.
Forget (GDPR delete)
curl -X POST "$MILLIMETRIC_HOST/v1/forget" \
-H "Authorization: Bearer $MILLIMETRIC_KEY" \
-H "Content-Type: application/json" \
-d '{ "user_id": "user_42" }'
Requires an sk_* key — pk_* is rejected with 403 forget_requires_secret_key.
Field reference (track / batch event)
| Field | Required | Notes |
|---|---|---|
event |
yes | 1–128 chars. System events start with $ ($pageview, $identify). |
event_id |
no | Idempotency key, 1–128 chars. |
timestamp |
no | ISO 8601. Defaults to server time. |
anonymous_id |
no | Caller-supplied UUID. Server generates one if omitted. |
user_id |
no | Stable internal user id. |
session_id |
no | Defaults to ${anonymous_id}-${30min_bucket}. |
url |
no | Landing URL with utm_*, fbclid, gclid. Classifier reads this. |
path |
no | Path only. |
referrer |
no | document.referrer or server Referer. Classifier reads this. |
properties |
no | Free-form JSON, capped at 8 KB after JSON.stringify. |
The Worker enriches every event with source, medium, campaign, source_confidence, source_rule_id, country, device_type, browser, os, ip_hash. Don't send these — they're ignored.
Node SDK alternative
npm i @millimetric/track-node
import { init, track, identify, flush } from "@millimetric/track-node";
init({ key: process.env.MILLIMETRIC_KEY!, host: "https://api.millimetric.ai" });
track({
event: "purchase",
anonymous_id: req.cookies.aid,
user_id: user.id,
properties: { amount_cents: 4900, currency: "usd" }
});
await flush(); // important in serverless handlers
Common errors
| Status | error |
Fix |
|---|---|---|
| 400 | invalid_payload |
event missing or properties > 8 KB. |
| 401 | malformed_api_key |
Key doesn't match (pk|sk|rk)_*_*_*. |
| 401 | invalid_api_key |
Key not found in DB. |
| 403 | origin_not_allowed |
Using pk_* from a non-allowlisted origin — switch to sk_* for server-side. |
| 403 | forget_requires_secret_key |
/v1/forget called with pk_*. |
| 429 | rate_limited |
Back off using the Retry-After header. Track: 50/s, burst 200. Batch: 5/s, burst 20. |
Key hygiene
pk_live_…→ browser snippet only. Never paste into shell, server code, or this skill.sk_live_…→ server-side ingest. Use here.rk_live_…→ read-only — for the query skill, not this one.
See also
- Query/analytics →
millimetric-query - AI agent / MCP setup →
millimetric-mcp-setup - Attribution rules: https://api.millimetric.ai (docs/concepts/attribution.md)
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install millimetric-track - After installation, invoke the skill by name or use
/millimetric-track - Provide required inputs per the skill's parameter spec and get structured output
What is Millimetric Track?
Emit analytics events to Millimetric (track, identify, batch, forget). Use when the user wants to send a custom event, log a signup/purchase/pageview, link a... It is an AI Agent Skill for Claude Code / OpenClaw, with 77 downloads so far.
How do I install Millimetric Track?
Run "/install millimetric-track" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Millimetric Track free?
Yes, Millimetric Track is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Millimetric Track support?
Millimetric Track is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Millimetric Track?
It is built and maintained by soybelli (@soybelli); the current version is v1.0.0.