// reference

SDK Reference

The JavaScript/TypeScript SDK ships as @customerlog/sdk, with framework wrappers @customerlog/react and @customerlog/next.

new CustomerLog(config)

route.ts
const customer = new CustomerLog({ apiKey: "cl_xxx", // required — from your project settings baseUrl: "https://event.customerlog.byorello.space", // optional — override for self-hosting });

Throws a CustomerLogError if apiKey is missing.

customer.log(options)

Sends an event to your project. Reads like console.log on purpose. Every field except channel and title is optional.

log-options.ts
await customer.log({ channel: "signups", // grouping, e.g. "signups" | "payments" | "errors" title: "User signed up", // human-readable title message: "Came in via Google OAuth", // free-text detail level: "info", // info | success | warning | error user: { id: "usr_123", email: "jane@doe.com", name: "Jane" }, metadata: { source: "google", plan: "pro" }, // structured key/values tags: ["growth", "oauth"], icon: "🚀", // optional emoji url: "https://example.com/signup", notify: true, // trigger Slack/email delivery });

Returns the created event as a Promise<LogResponse>. A failed request (bad API key, quota, network) rejects with a CustomerLogError.

The notify flag

Set notify: truewhen an event should trigger channel delivery (Slack message, email). Leave it off for high-frequency events you only want in the feed, so your team isn't pinged a thousand times a day.

Metadata best practices

  • Keep metadata flat and string/number/boolean-friendly.
  • Always include an identifier (user_id, order_id) so events are traceable.
  • Structured metadata + free text is what makes AI summaries useful later — the same shape is what the digest reads.

Errors and retries

try-catch.ts
import { CustomerLogError } from "@customerlog/sdk"; try { await customer.log({ channel: "payments", title: "Payment failed" }); } catch (err) { if (err instanceof CustomerLogError) { // 4xx/5xx with a server message console.error(err.status, err.message); } }