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:
- 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
wwwtwin is stored beside it. - 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:
- Put the tag on your site and watch the band turn green.
- Install a starter, read the emails, switch an automation on.
- Post
signupandpurchasefrom your own server, or connect Stripe and your auth provider. - 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.