Skip to main content
Semver. Major versions are breaking; minor are additive; patch are bug fixes and metadata.
The SDK version is exported as SDK_VERSION and flows into the User-Agent header on every request — the backend can flag outdated clients.
This page mirrors packages/sdk/CHANGELOG.md — the npm package’s CHANGELOG.md is the canonical record.
1.4.0
2026-06-08 — `trial_expiring` property fix + 10-event doc consistency + Stripe import guide
Changed
  • Breaking: users.trialExpiring(userId, { trialDays }) — the property was renamed from daysLeft to trialDays. The live trial_expiring trigger reads properties.trialDays; the previous daysLeft was silently ignored, so the helper never actually drove the trigger. TypeScript callers passing { daysLeft } get a compile error and must rename to { trialDays }. In practice you rarely need this helper — the trigger is derived automatically from the most recent trial_started event’s trialDays, so calling trialStarted(userId, { trialDays }) once is enough.
Fixed
  • The README and an internal events.ts comment described “canonical 9” lifecycle events; corrected to 10 to match package.json and STANDARD_EVENT_NAMES. (The 10th helper, usageThresholdReached, shipped in 1.2.0; the prose lagged.)
Added
  • “Importing existing customers from Stripe”: founders with billing in Stripe can paste a read-only restricted key in the dashboard (Import → Stripe) for a one-time backfill of customers and subscription/invoice history as canonical lifecycle events, with welcome emails suppressed — a dashboard integration, not an SDK call.
NoteThis property rename is technically a SemVer-major change. It ships as a minor because 2.0.0 is reserved for removing the deprecated AIFollowups alias, and the break is confined to one rarely-used helper (flagged above).
1.3.0
2026-05-28 — `suppressTriggers` flag on `events.batch()`
Added
  • events.batch({ suppressTriggers: true }) — opt-in trigger suppression for historical seeding. Every TrackedUser touched by a suppressed batch gets suppressTriggersUntil set to a far-future date server-side, so trigger rules (welcome, onboarding_stall, etc.) won’t fire retroactively when you’re migrating customers into Vibefollow from an existing user base. The watermark dissolves automatically the first time the user emits a normal (non-suppressed) event — one-batch switch back to live mode.
  • POST /api/v1/events/batch request body now documents the optional suppressTriggers field with a “seeding historical users” cURL example.
WhyFounders importing an existing user base were occasionally shipping retroactive “welcome” emails to customers who’d signed up months earlier — a real production incident on 2026-05-27 with one customer sending 145+ welcomes from a backfill. The CSV import path has the same semantic via fire_welcome_emails: false; this brings the realtime API in line.Backwards compatibilityFully additive. Calling events.batch() with no options (or with the prior { maxSize, maxAgeMs } shape) sends suppressTriggers: false and behaves identically to 1.2.x. The server defaults missing field values to false, so older SDK versions remain compatible.
1.2.1
2026-05-25 — npm description + keywords cover the 10th helper
Changed
  • package.json description now explicitly names the 10 typed lifecycle helpers, the chunk() utility, automatic retries, the typed error hierarchy, and edge-runtime support. The previous wording understated v1.2.0 by stopping at “identify users, emit lifecycle events, bulk-backfill from existing data, and verify webhook signatures” — accurate but missing half the surface a discovery search would care about.
  • keywords extended with webhooks, ai, claude, revenue-manager for npm discovery.
Backwards compatibilityMetadata-only release. No runtime behaviour changes, no API changes, no type changes. The User-Agent header bumps from vibefollow-sdk/1.2.0vibefollow-sdk/1.2.1 so backend logs reflect the new patch.
1.2.0
2026-05-22 — bulk endpoints + chunk() helper for backfills
Added
  • users.identifyBulk(records) — upsert up to 1,000 users in one POST. Returns BulkIngestResponse with per-record validation errors so a single bad row never sinks the batch. Idempotent via the existing (project_id, external_user_id) unique on tracked_users; chunks that 429 or 5xx are safe to retry.
  • events.bulk(records) — same shape for events. Idempotent via the server-side events_dedupe_unique partial index; reimporting the same backfill twice is a no-op.
  • chunk(input, size) — exported generator that slices large arrays into ≤size slices for backfills > 1,000 records. Doesn’t materialise the source twice, so 5M-row backfills stay flat-memory.
  • New bulk types: BulkUserRecord, BulkEventRecord, BulkIngestError, BulkIngestResponse, plus the BULK_INGEST_MAX_RECORDS = 1000 constant.
  • New API reference pages: POST /api/v1/users/bulk and POST /api/v1/events/bulk.
WhyThe two SDK paths that existed before — per-record identify() / track() for live writes and events.batch()’s in-memory buffer for high-volume streaming — both made backfills awkward. Bulk closes the gap: one POST per 1,000 records, partial-success error reporting, and chunk() so a 50k backfill is a 50-iteration for loop with predictable memory.Backwards compatibilityFully additive. The legacy events.batch() in-memory buffer and the /api/v1/events/batch endpoint behind it remain supported.
1.1.0
2026-05-19 — usage_threshold_reached canonical event
Added
  • users.usageThresholdReached(userId, { usagePercent, meter?, limit? }) — 10th typed lifecycle helper. Emits usage_threshold_reached, the canonical event consumed by the backend’s plan_limit_upsell trigger rule.
  • STANDARD_EVENT_NAMES now contains 10 entries (was 9); StandardEventName type updated transparently.
1.0.2
2026-05-18 — homepage repointed to docs site
Changed
  • package.json homepage repointed from https://vibefollow.com to https://docs.vibefollow.com/sdk/overview now that the docs site is live. bugs.url remains https://vibefollow.com until the support@vibefollow.com mailbox is provisioned.
1.0.1
2026-05-17 — metadata + prose casing fix
Fixed
  • package.json description brand casing: VibeFollowVibefollow (the SDK class identifier VibeFollow stays unchanged; only marketing prose was corrected).
  • package.json homepage was https://docs.vibefollow.com/sdk (DNS unresolvable at publish time) — now https://vibefollow.com.
  • Explicit bugs.url pointing at https://vibefollow.com so npm’s auto-derivation no longer produces a gitlab.com/.../issues URL that leads to a sign-in wall.
  • README prose now uses Vibefollow consistently; code identifiers, env var names, and class names are unchanged.
  • Header literal corrected from X-VibeFollow-Signature to X-Vibefollow-Signature to match what the emission backend actually sends. HTTP headers are case-insensitive on read, so this is a documentation correction — verification continues to work for clients on 1.0.0.
1.0.0
2026-05-17 — initial public release
Added
  • VibeFollow class with users, events, and webhooks resources.
  • 9 typed lifecycle helpers on vf.users.* (signedUp, trialStarted, …).
  • events.track() for custom events and events.batch() for buffered emission.
  • webhooks.constructEvent() for signed delivery verification.
  • Typed error hierarchy: AuthError, ValidationError, RateLimitError, ServerError, NetworkError, WebhookSignatureError.
  • Auto-retry with exponential backoff plus jitter on transient failures.
  • Auto-Idempotency-Key on every POST.
  • Edge-runtime support: Node 20+, Cloudflare Workers (with nodejs_compat), Vercel Edge, Deno.
Endpoints documented
  • POST /api/v1/users — upsert user
  • POST /api/v1/events — track event
  • POST /api/v1/events/batch — batch track events