Skip to main content

Core types

ChurnKitOptions

interface ChurnKitOptions {
  apiKey: string
  env?: 'production' | 'staging'
  baseUrl?: string
  timeout?: number                                   // default: 15000ms
  maxRetries?: number                                // default: 3
  onRequest?: (ctx: RequestContext) => void | Promise<void>
  onResponse?: (ctx: ResponseContext) => void | Promise<void>
}

CallOptions

interface CallOptions {
  signal?: AbortSignal
}

UserTraits

interface UserTraits {
  plan?: string
  mrr?: number
  email?: string
  name?: string
  company?: string
  signedUpAt?: string
  [key: string]: string | number | boolean | null | undefined
}

EventProperties

interface EventProperties {
  [key: string]: string | number | boolean | null | undefined
}

BulkEventItem

interface BulkEventItem {
  userId: string
  event: string
  properties?: EventProperties
  timestamp?: string   // ISO 8601
}

Risk types

RiskScore

interface RiskScore {
  userId: string
  score: number         // 0.0 → 1.0
  tier: RiskTier        // 'low' | 'medium' | 'high'
  signals: string[]
  recommendation: string
}

AtRiskUser

interface AtRiskUser {
  userId: string
  score: number
  tier: RiskTier
  signals: string[]
  recommendation: string
}

AtRiskResult

interface AtRiskResult {
  users: AtRiskUser[]
  total: number
  offset: number
  limit: number
}

AtRiskOptions

interface AtRiskOptions {
  threshold?: number    // default: 0.5
  plan?: string
  limit?: number        // default: 50, max: 200
  offset?: number       // default: 0
  signal?: AbortSignal
}

AtRiskAllOptions

interface AtRiskAllOptions {
  threshold?: number
  plan?: string
  pageSize?: number     // default: 100
}

RiskTier

type RiskTier = 'low' | 'medium' | 'high'

Watch types

WatchOptions

interface WatchOptions {
  threshold: number          // required, 0–1
  webhook: string            // required, https:// URL
  cooldown: CooldownString   // required, e.g. '24h', '7d'
}

CooldownString

A string matching ^[1-9]\d*[dh]$:
type CooldownString = string  // '1h', '24h', '7d', '30d', etc.

WatchedUser

interface WatchedUser {
  userId: string
  threshold: number
  webhook: string
  cooldown: string
}

Batcher types

BatcherOptions

interface BatcherOptions {
  flushInterval?: number              // ms, default: 5000
  maxSize?: number                    // default: 100, max: 500
  onFlush?: (count: number) => void
  onError?: (err: unknown) => void
}

EventBatcher

interface EventBatcher {
  push(event: BulkEventItem): void
  flush(): Promise<number>
  destroy(): Promise<void>
}

Observability types

RequestContext

interface RequestContext {
  method: string
  url: string
  headers: Record<string, string>  // mutable — add custom headers here
  body?: unknown
}

ResponseContext

interface ResponseContext {
  method: string
  url: string
  status: number
  durationMs: number
  attempt: number   // 0 = first attempt, 1 = first retry, etc.
}

Error types

ChurnKitError

class ChurnKitError extends Error {
  readonly status?: number
  readonly code?: ErrorCode | string
}

ErrorCode

const ErrorCode = {
  ABORTED:            'ABORTED',
  TIMEOUT:            'TIMEOUT',
  NETWORK_ERROR:      'NETWORK_ERROR',
  VALIDATION_ERROR:   'VALIDATION_ERROR',
  UNAUTHORIZED:       'UNAUTHORIZED',
  FORBIDDEN:          'FORBIDDEN',
  NOT_FOUND:          'NOT_FOUND',
  RATE_LIMITED:       'RATE_LIMITED',
  SERVER_ERROR:       'SERVER_ERROR',
  PAYLOAD_TOO_LARGE:  'PAYLOAD_TOO_LARGE',
} as const