Skip to main content

Overview

identify() links a user ID to a set of traits. Call it when a user signs up, logs in, or changes their plan. The scoring model uses traits like plan and mrr to contextualize risk. You don’t need to call identify() before every event — identify once, then just track events.

Signature

churn.identify(
  userId: string,
  traits: UserTraits,
  options?: CallOptions
): Promise<{ ok: boolean }>

Parameters

userId
string
required
A stable, unique identifier for the user. Must be a non-empty string.
traits
UserTraits
required
An object of user properties. All fields are optional but at least one is recommended.
options.signal
AbortSignal
An AbortSignal to cancel the request. The SDK throws ChurnKitError with code ABORTED if the signal fires.

UserTraits

FieldTypeDescription
planstringPricing plan ('free', 'pro', 'enterprise')
mrrnumberMonthly recurring revenue in cents (e.g. 4900 = $49)
emailstringUser’s email address
namestringUser’s display name
companystringCompany name
signedUpAtstringISO 8601 timestamp of signup
[key]string | number | boolean | nullAny custom trait

Examples

Basic identification

await churn.identify('user_123', {
  email: 'alice@acme.com',
  name: 'Alice Smith',
  plan: 'pro',
  mrr: 4900,
})

On login

// After successful authentication
await churn.identify(session.userId, {
  plan: user.plan,
  mrr: user.mrrCents,
  email: user.email,
})

Plan upgrade

// After Stripe webhook confirms upgrade
await churn.identify(userId, {
  plan: 'enterprise',
  mrr: 29900,
})

Custom traits

await churn.identify('user_123', {
  plan: 'pro',
  industry: 'fintech',
  team_size: 12,
  referral_source: 'producthunt',
})

With abort signal

const controller = new AbortController()
setTimeout(() => controller.abort(), 3000)

await churn.identify('user_123', { plan: 'pro' }, { signal: controller.signal })

Return value

{ ok: true }

Errors

CodeWhen
VALIDATION_ERRORuserId is empty or not a string
UNAUTHORIZEDAPI key is invalid or revoked
TIMEOUTRequest exceeded timeout ms
ABORTEDAbortSignal fired
Calling identify() with an empty traits object ({}) is allowed but a warning is logged — no data is stored.