// event types

Event Types

Events are the heart of customer.log. Get the shape right and everything downstream — the feed, Slack messages, and AI summaries — gets better.

Channels

A channel is a user-defined grouping: "signups", "payments", "errors", or anything you invent. Every event belongs to exactly one channel, and channels are how you filter the feed.

Channels are auto-created the first time you log to them — no schema to register upfront. Predefined types (signups, payments, projects, navigation, events, errors) come with sensible defaults out of the box.

Anatomy of an event

event.ts
{ channel: "signups", // grouping title: "User signed up", // short, human-readable message: "Came in via Google OAuth", // free-text detail metadata: { user_id: "usr_123", email: "jane@doe.com", source: "google" }, tags: ["oauth", "growth"], icon: "🚀", notify: true, // whether to push via channels level: "success", // info | success | warning | error createdAt: "2026-07-31T09:00:00.000Z" }

Designing for AI summaries

The daily digest and weekly report are generated from your events, so write them for both humans and models:

  • Write titles as plain sentences: "Payment failed", not "chrg_fail_204".
  • Use message for context that can't fit in metadata.
  • Put repeatable facts in metadata — amounts, plans, sources, IDs.
  • Keep tags consistent ("oauth", "growth") so patterns become visible.

Custom channels and MCP

Custom channels work everywhere: SDKs, cURL, and the hosted MCP server. An MCP agent can call log_event with any channel you define, then use list_channels or get_recent_events to work with it.

custom-channel.ts
await customer.log({ channel: "trial-expired", // custom channels are supported title: "Trial expired", metadata: { account_id: "acct_123" }, });

Webhooks

Configure a project webhook from the project integration settings or the API. Every incoming event is delivered as a JSON customerlog.event payload. When a secret is configured, verify the X-CustomerLog-Signature header as sha256=HMAC_SHA256(secret, timestamp + "." + rawBody).

webhook-payload
{ "type": "customerlog.event", "event": { "channel": "payments", "title": "Payment succeeded", "metadata": {} } }

Good vs. noisy events

"Payment succeeded""Annual plan, card charged" — metadata: email, plan, amount. This is an upsell signal.
"cron ran"Logging every background job with no metadata just adds noise to the feed and the AI digest.

We care about your privacy

We use essential cookies to keep you signed in. We only ask for consent to use non-essential tracking cookies (visitor and page-view tracking). We never sell your data. Read our Privacy Policy and Terms of Use.