Documentation
Errors from Sentry
Sentry already knows which errors your product throws. What it cannot tell you is which of your customers hit them. Kicklace takes Sentry's webhooks the way it takes Stripe's — one address, one secret — and an error becomes a row on the person who hit it, on the account they pay from, matched to the release it happened on. The stack trace stays in Sentry, where it belongs.
Kicklace is not an error tracker and will not become one. Sentry already does that job, and it holds the one thing a CRM never has: the user on the event. So Kicklace takes Sentry's webhooks the way it takes Stripe's — one address, one secret, a signature checked on every post — and answers a question neither tool answers on its own: which of my customers hit an error, and on which release.
What arrives becomes a row on the person who hit it, on the account they belong to, matched to the release it happened on. Nothing else of Sentry's payload is kept.
The screen is Settings → Integrations → Errors from Sentry, and only an owner or an admin can connect or disconnect it.
Setting it up
1. Make an internal integration in Sentry. In Sentry, open Settings → Developer Settings →
Custom Integrations → Create New Integration → Internal Integration. Give it a name, paste the
address Kicklace shows you as the Webhook URL, turn on Alert Rule Action, and under
Permissions give it Issue & Event: Read. Under Webhooks, tick issue.
An internal integration installs itself on your organization when you save it, so there is nothing to approve and nobody to invite.
2. Paste the Client Secret. Once the integration is saved, its own page in Sentry shows a Client ID and a Client Secret. The secret is what Kicklace checks every post against: Sentry signs the body with it, and without it nothing is taken. Paste it into the card.
It is encrypted the moment it arrives and never shown back. The screen says the day it was set and offers Replace.
3. Point an alert at it. A webhook URL on its own receives nothing: in Sentry it is an alert action, and an alert rule is what fires it. Open Alerts → Create Alert → Issues, choose when it should fire — "A new issue is created" is the useful one — and pick the action Send a notification via your integration.
On a Business or Enterprise plan you can also tick error under the integration's Webhooks. That
sends every error event rather than the first of each issue, which is what makes "how many
customers hit this" a real figure rather than a lower bound. On every other plan the alert rule is
the whole of it, and everything below still works.
What lands here
One row on the person's timeline, carrying exactly this:
| On the row | Where it comes from |
|---|---|
| the title | Sentry's own title for the event |
| the level | error, warning, fatal — whatever the SDK sent |
| the environment | production, staging |
| the release | the release string, exactly as your SDK set it |
| a link | web_url, which opens the event in Sentry |
| the issue | so the same problem collapses onto one row |
| the release record | where the release string named a deployment Kicklace knows |
The event name is error, so an automation answers it like any other: when the event error
happens, and the account is paying, tell me.
What is never stored
The stack trace. The request — its URL, its headers, its cookies, its query string. The breadcrumbs. The browser and device contexts. The SDK's own bag, the fingerprint, the hashes, the culprit's frames. Sentry's payload carries all of it and Kicklace drops every one of them before anything is written, because none of it is a fact about a customer and all of it is already kept properly one click away.
Who it lands on
An address is a person. If your SDK calls Sentry.setUser({ email }), the error lands on that
person — the one already here, or a new record made the way every other integration makes one.
A user id matches somebody already here. Sentry.setUser({ id }) is your own app's user id,
which is what identify writes down, so an error with an id Kicklace has already seen lands on that
person.
An error about nobody lands nowhere. No address and no id Kicklace knows means no row: a CRM will
not invent a customer out of an error. Those posts are still counted, and the card says so — "412
posts taken, none of them on anybody yet" is how you find out your SDK never calls setUser.
The account is not stored on the row. It is the link the person already has, read at the moment a screen asks, so an error follows somebody who is moved to another account instead of pointing at the one they used to be on.
A thousand errors are not a thousand rows
A bad deploy sends Sentry the same error four hundred times a minute. Four hundred rows on one person's timeline is not four hundred facts, and a timeline you cannot read is a timeline nobody opens.
So the same person hitting the same issue inside the hour is counted onto the row that is already
there. The row keeps a count, the time of the most recent hit, and the last ten of Sentry's own
event ids. Its detail line says "12 times". The next hour starts a new row, so a day of trouble still
reads as a day of trouble rather than one line.
A thousand errors are a thousand rows when a thousand people hit them: the collapse is per person, per issue, per hour, and never across people.
Only a new row fires an automation. The first hit of an issue in an hour is news; the four hundredth is the same news, and an automation that answered it four hundred times would be the reason nobody turns this on.
The release
Sentry's release is whatever your SDK was told to call it. Their own guidance gives two shapes — the
commit SHA, or package@version with an optional +build — and Kicklace peels both apart and looks
for a Release record whose SHA matches, including a short SHA matched against the full one.
Where it matches, the error carries the release on it, the account's Errors frame names it, and the
Release's own record page says how many errors and how many people it was hit by. Where it does not —
a release called 2.3.12, or no Vercel connected — the error keeps the release string and nothing is
joined. A missing join is an honest answer; a wrong one is not.
Issues
Sentry also posts when an issue is created, resolved, archived or assigned. An issue is a fact about your code rather than about a customer, so it becomes no row on anybody's timeline. Kicklace counts it and keeps the last twenty by name and link, on the card, so you can see what has been arriving.
When it goes wrong
A post whose signature is not yours is refused with 401 and nothing is written. A post about a
resource Kicklace has no use for — metric_alert, comment, installation — is answered 200 and
ignored, because a refusal only makes Sentry retry it for ever. Every refusal is a sentence, and your
Client Secret is in none of them.
Disconnecting stops the address answering. Every error already on a timeline stays: a webhook going away is not a reason to forget what a customer hit.
From Claude
describe_workspace says how many errors landed in the last 7 days, across how many people and how
many accounts — and that Kicklace holds no stack trace. find_records on accounts carries the count
beside the last-active date, and get_person says it for somebody who has hit one. There is no tool
that connects Sentry: the Client Secret is typed into a form, never into a message.