Skip to content

Documentation

Install Kicklace

Three ways in, and most products use two of them: a script tag on your website, the kicklace package in your own server code, and the doors that fill it by themselves once you paste one address into Stripe, Clerk, Kinde, Vercel or GitHub. They all land on the same record. This is what to do, in the order to do it.

The tag, the package and the doors all land on the same record. Somebody reads your pricing page anonymously on Monday, leaves an address on Wednesday, signs up in your app on Friday and pays a month later: that is one person with one timeline, and none of the four things that recorded it had to know about the others.

Nothing here needs all of it on day one. The tag alone is useful within a minute. Everything below is inside one workspace, and every screen named is under /app/<your workspace>/settings.


Your website: one script tag

Settings → Your website shows the tag, already carrying your own public key:

<script async src="https://www.kicklace.com/api/in/YOUR_PUBLIC_KEY/track.js"></script>

It goes in the <head> of every page. From then on it records page reads, remembers how each visitor arrived — the campaign, the referrer, the ad click id — and can hear your signup forms without you touching them. There are no cookies. Where the tag goes, by platform has the exact steps for Webflow, Framer, WordPress, Squarespace, Carrd and Next.js; the tag is what it does and everything you can call on it.

Two things to do on that screen before the tag can post anything:

  1. Say where your site is. Kicklace only accepts posts from addresses you have listed, so a stranger cannot write into your workspace from theirs. Paste your address into Where is your site?; the www twin is stored beside it.
  2. Watch for the first visit. The band under the tag turns green by itself the moment a page read arrives, so you know it works before you go looking for it.

Your servers: one line of code

Your website knows about traffic. Only your own code knows that somebody signed up, activated, or paid — so that half is a package:

npm install kicklace
import { Kicklace } from "kicklace";

const kl = new Kicklace(process.env.KICKLACE_SECRET_KEY!);

await kl.track("signup", { email });
await kl.track("purchase", { email, value: 49, idempotencyKey: invoice.id });

It has no dependencies, runs anywhere fetch does, and never throws when Kicklace refuses something — a refusal comes back as { ok: false, error, message } with the sentence to act on inside it. The kicklace package is every method; Events is every name you can post and what each one does to the person's lifecycle.

The package opens no door of its own. Everything it does is POST /api/v1/events with your secret key as a bearer token, so any language that can make an HTTP request can do the same:

curl -X POST https://www.kicklace.com/api/v1/events \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"type":"purchase","email":"ada@example.com","value":49,"idempotency_key":"in_123"}'

What arrives with no code at all

Some of the most useful events are ones you never have to send, because the service they happen in will post them for you. Each is one address pasted into that service's dashboard and one signing secret brought back:

Door What lands Where
Stripe payments, refunds, subscriptions, trials, abandoned checkouts Settings → Integrations
Clerk or Kinde a new account is a signup; a sign-in, if you want it Settings → Integrations
Vercel every production deployment, as a record of its own Settings → Integrations
GitHub sponsors as purchases, issues as support messages, stars if you ask Settings → Integrations
Slack goes the other way: everything Kicklace tells you, in a channel Settings → Integrations

A Stripe payment lands as the same purchase event your own server would have posted, so an automation written for a purchase answers it without knowing Stripe exists.

A form Kicklace hosts for you

Some site builders own their forms so completely that no script can hear them. For those there is a page Kicklace hosts, wearing your workspace's name and colours:

https://www.kicklace.com/f/<your workspace>/<your list>

The list's own consent sentence is the label of a required tick box, so what the person agreed to is exactly what is stored. Link to it, or embed it in an iframe that sizes itself. Settings → Lists → your list → Share a signup form has the link and the one line of HTML.

Where the keys are

There are two, and they are not interchangeable.

Key Shape Where it belongs
Public key wk_… in the tag, in a page's source; it is public by design
Secret key sk_live_… on a server, in an environment variable, never in browser code

Mint and revoke secret keys under Settings → Your website → For your developers, or on Settings → Advanced → Developers, which gathers the keys, your website's heartbeat, the outgoing delivery log, the rate limits, and the four environment names in one place. A secret key is shown once and stored as a hash; if you lose it, revoke it and make another.

The four names the package and the tag read:

Name What it is
KICKLACE_SECRET_KEY your secret key, on the server only
NEXT_PUBLIC_KICKLACE_KEY your public key, for the tag
KICKLACE_URL where Kicklace is, if not https://www.kicklace.com
NEXT_PUBLIC_KICKLACE_URL where the tag is served from, if not the default

Set the workspace up by asking

Kicklace speaks the Model Context Protocol, so you can point Claude at a workspace and set it up in conversation instead of walking eight settings screens: the lists people join, the emails, the stages, the reports, the automations. It never sends an email and never deletes anything; a person does that. The MCP door is the protocol, Use Kicklace from Claude is the screen and what to ask it, and What the AI does is all of it in one place — including Ask Kicklace, the same tools inside the app, for people who have no Claude subscription.

What to do first

Install a starter. Settings → Setup → Starters offers four, and it leads the page while a workspace is still empty. The SaaS starter is the one most products want: one press of Set these up for me writes a Product updates list with the words people agree to, five emails to rewrite in your own words, and five automations — welcome somebody when they sign up, check in when they never got started, say thank you when they pay, ask why when they cancel, and put a task on your list when somebody goes quiet. Every automation lands paused, so nothing reaches anybody before you have read it. Starters says what each one holds.

Then, roughly in this order:

  1. Put the tag on your site and watch the band turn green.
  2. Install a starter, read the emails, switch an automation on.
  3. Post signup and purchase from your own server, or connect Stripe and your auth provider.
  4. Send from your own domain: Settings → Sending adds your sending domain, so mail comes from you rather than from a shared address.

Not yet

The Deploy Button starter, a whole Next.js project with the tag, a sign-up handler and a Stripe webhook already wired in, and npx kicklace init, which does the same wiring in a project you already have, both go up together with the version of the package that carries the command. Until they are published, npm install kicklace and the tag above are the way, and they are two minutes of work.