— DOCUMENTATION · v0.1

The saasboost SDK.

Two lines of TypeScript. Attribute signups, trials, and paid conversions back to the seller who sent the visitor. Never throws, sub-2 KB minified, zero deps on the server.

saasbooston npm2 KBminified0 depson server60 daysref TTL
— 01

Install

Pick your package manager — or drop the CDN bundle in a <script> tag.

# Install
pnpm add saasboost
— 02

Quickstart — browser

Initialize once at the root of your app. The first time a visitor lands via ?ref=jane123-acme, saasboost captures the ref and stores it in localStorage for 60 days. Every subsequent track() and conversion() auto-attaches it.

import saasboost from 'saasboost'

// One-line init. Do this at the root of your app.
saasboost.init('sk_live_acme_a8e92f...')
— 03

Framework recipes

Vue 3 / Nuxt

import saasboost from 'saasboost'

export default defineNuxtPlugin(() => {
  saasboost.init('sk_live_acme_a8e92f...')
})

React / Next.js

'use client'
import { useEffect } from 'react'
import saasboost from 'saasboost'

export function SaaSBoostProvider({ children }) {
  useEffect(() => {
    saasboost.init('sk_live_acme_a8e92f...')
  }, [])
  return children
}

Plain HTML (CDN)

The IIFE bundle exposes a global saasboost.

<script src="https://cdn.jsdelivr.net/npm/saasboost/dist/saasboost.min.js"></script>
<script>
  saasboost.init('sk_live_acme_a8e92f...')
  saasboost.track('signup', { email: 'jane@stripe.com' })
</script>
— 04

Server SDK

Use the server SDK from inside your billing webhook so conversions are reported the moment money moves — not dependent on a browser session. Node 20+ native fetch, zero runtime deps.

import { SaaSBoostServer } from 'saasboost/server'

const sb = new SaaSBoostServer(process.env.SAASBOOST_KEY!)

// Inside your Stripe / Lemonsqueezy webhook handler:
export async function handleOrderPaid(order) {
  await sb.conversion({
    // The seller's slug, captured at signup and stored with the user.
    // Without it the conversion is unattributed.
    refId: order.metadata.saasboost_ref,
    email: order.customer_email,
    // Stripe sends cents → divide by 100. Backend wants DOLLARS.
    amount: order.amount_total / 100,
    currency: order.currency
  })
}
By default the server SDK never throws. If you want errors to propagate (so your queue retries), pass { throwOnError: true }.
— 05

API reference

Browser

saasboost.init(apiKey, options?)

Initialize the SDK. Captures ?ref= from the URL (if present) or reads the stored ref. Prepares the network client.

PARAMETERS
apiKeystringYour public listing key, like `sk_live_acme_a8e92f...`
options.apiBasestring?Host root only — SDK appends `/api/v1/...`. Default `https://api.saasboost.app`. In dev use `http://localhost:3333`, NOT `.../api/v1`.
options.forceClearOnEmptyUrlboolean?When true and URL has no `?ref=`, wipe stored ref. Default: false
saasboost.track(event, payload?)

Track a non-conversion event. Known names: `signup`, `trial`, `demo`, `newsletter`. Anything else is recorded as `type=custom`.

PARAMETERS
eventstringEvent name (any string).
payload.emailstring?Privacy-truncated server-side before display.
payload (rest)RecordArbitrary metadata. Capped at 20 keys / 2 KB.
saasboost.conversion(payload)

Fire a conversion. Attributed to the stored ref id. Call this when real money moves.

PARAMETERS
payload.amountnumberRequired. In DOLLARS, not cents. `49` = $49.00, not $0.49.
payload.emailstring?Privacy-truncated server-side.
payload.currencystring?3-letter ISO code. Defaults to USD server-side.
payload.refIdstring?Browser fills this in automatically from the stored ref. Pass manually only if you need to override.
saasboost.getRef() / saasboost.clearRef()

Read or clear the currently-stored ref id. Useful for debugging attribution or dropping it on logout.

Server

new SaaSBoostServer(apiKey, options?)

Construct a server-side client.

PARAMETERS
apiKeystringYour listing API key.
options.apiBasestring?Host root only — same rule as the browser SDK. No `/api/v1`.
options.throwOnErrorboolean?Default false. Set true inside webhook handlers so retries fire on failure.
options.fetchfunction?Custom fetch implementation (e.g. for Cloudflare Workers).
sb.track(event, payload?) / sb.conversion(payload)

Same shape as the browser SDK, but you pass refId yourself. The conversion field is `refId` — not `ref`. Sending `ref` is silently dropped and the event lands unattributed.

PARAMETERS
payload.refIdstring?The slug (the part after /r/). Without it, the conversion has no attribution and is invisible to the seller.
payload.amountnumberIn DOLLARS, not cents. Divide Stripe `amount_total` by 100.
payload.emailstring?Customer email (privacy-truncated server-side).
payload.currencystring?3-letter ISO code. Defaults to USD.
— 06

How attribution works

  1. A seller shares https://saasboost.app/r/jane123-acme.
  2. The visitor clicks. SaaSBoost logs the click and 302-redirects to https://yoursite.com?ref=jane123-acme.
  3. Your site loads. saasboost.init() captures the ref and stores it in localStorage for 60 days.
  4. The visitor browses, signs up, starts a trial, eventually pays.
  5. Each event (signup, trial, conversion) is reported with the stored ref id.
  6. SaaSBoost attributes the conversion to jane and pays her per your commission terms.

If the visitor returns from a different referral link later, the most recent click wins. If they wipe their browser storage, the chain is broken — by design, and it matches every other attribution tool.

Stuck? Found a bug?
We read every report. Email us — usually reply within a few hours.
Email support →