Documentation
Deployments from Vercel
Every production deploy lands as a release you can write about.
For the developer who ships on Vercel. Every production deploy becomes a release in Kicklace, named after its commit, with its branch, its commit message and a link to the build. There's no code to write and nothing to deploy.
A deploy is a record of its own rather than an event on a person, and that's what lets an email carry what shipped: a variable filled from your deploys when it sends.
It's under Connections → Vercel, and only an owner or an admin can change it.
Setting it up
Connections → Vercel → Add Kicklace in Vercel. Vercel asks which of your projects Kicklace may reach; pick them, come back, and choose this workspace. Kicklace writes its keys into those projects, allows their addresses as your website, and makes the deployments webhook itself. The secret Vercel hands back goes straight into Kicklace, locked away, never shown. Redeploy each project once so it picks up the new variables. Add Kicklace from Vercel is the install in full.
Until a secret is in, nothing is taken: Kicklace answers no_signing_secret and writes the refusal to
your heartbeat. A copy of Kicklace run without its Vercel install asks for the webhook by hand instead:
an address to paste into Vercel under Settings → Webhooks → Create Webhook with Deployment
Succeeded ticked, and the secret Vercel shows once, pasted back.
Vercel signs with x-vercel-signature, an HMAC-SHA1 of the raw body, hex, keyed with that secret.
Kicklace compares it in constant time and refuses anything else.
What a deploy becomes
Only deployment.succeeded with target: "production" is a release. A preview is somebody's branch,
and deployment.created, deployment.error and deployment.canceled are a build's own progress: a
customer hears about what shipped, not what was tried.
| Field | From |
|---|---|
| Name | the commit message's first line, or Deployment dpl_… when there's no commit |
url |
the deployment's page in Vercel, else the deployment's own host |
commit |
the whole commit message |
branch |
the branch it was built from |
sha |
the commit's SHA |
deploymentId |
Vercel's own id for it |
deployedAt |
the day Vercel says it happened |
The commit keys Vercel sends are prefixed with the git provider (githubCommitSha,
gitlabCommitMessage, bitbucketCommitRef), and Kicklace reads all three. A deploy made from the CLI
carries no commit and is still a real deploy: it's named after its id.
A deploy lands once. A second post of the same one answers already_recorded and writes nothing.
What a release changed
Where GitHub is connected and one of its repositories holds the commit, Kicklace reads GitHub's own compare against the previous production release once, and puts it on the release: the commits, the pull requests they name, and the files they touched (the first 50 commits and 200 files).
Without GitHub, the release carries its SHA and nothing else. Nothing is guessed, and nothing ever says a release caused a number to move.
Which customers met a release
Every event can say which deploy it happened on, and Kicklace joins it to that release. The tag reads
<meta name="kicklace-release">, which KicklaceTag from kicklace/next writes from Vercel's own
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA, and the package reads VERCEL_GIT_COMMIT_SHA on the server.
Events has the rest.
A release's own page
Its SHA, when it went out and where; what the compare found, under Changed; what Kicklace read on your own site since the release before, under What changed for a visitor; the four measures in the 48 hours after it against the 48 before; who met it; and the errors and support messages while it was live.
What changed for a visitor
Where your website is connected, Kicklace reads its public pages (the home page, then pricing, plans, product, features, sign-up and about, then the rest) once a release goes out, or once a day where none has. It keeps each page's title, headline, description, visible words and prices, and compares the read with the one before: a price that moved, a new headline, sentences gained or lost. One plain line goes on the release.
It says "after" the release, never "because" of it. A page that's mostly a JavaScript shell is named
unreadable rather than read as empty. Every read is polite: one pass, the user agent Kicklace,
robots.txt honoured, never a login form, never a POST.
Telling people what shipped
On your Lifecycle map, a Product updates list can send on a schedule, and its email can carry a variable filled from your deploys: each one's title, with its commit and pull request titles where GitHub is connected, one dated line each. A week with nothing deployed sends nothing.
What never happens
- Nothing is sent because you deployed.
- Kicklace never talks back to Vercel. Nothing of yours is started, stopped or promoted from here.
- Disconnecting keeps your releases. The address stops answering; every release stays.
- No traffic. Vercel has no webhook for visitors. Visits come from Kicklace's own tag.
The answers
| Answer | HTTP | What it means |
|---|---|---|
{ ok: true, status: "recorded", id } |
200 | A new release |
{ ok: true, status: "already_recorded", id } |
200 | This deploy is already here; nothing written |
{ ok: true, status: "ignored" } |
200 | A preview, a failed build, or something Kicklace has no use for |
{ ok: false, error: "unknown_endpoint" } |
404 | No workspace has that address |
{ ok: false, error: "no_signing_secret" } |
400 | The secret isn't in yet |
{ ok: false, error: "bad_signature" } |
400 | The signature didn't match this body |
{ ok: false, error: "too_large" } |
413 | Over 128 KB |
{ ok: false, error: "server_error" } |
500 | Kicklace fell over; Vercel should retry |
Every post is one row in your website's heartbeat (Connections → Your website), beside your website's own.