Skip to content

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.