Cosmovex Tools

Linear webhook signature not verifying? See the delivery and check Linear-Signature

Linear with Hookwatch Webhook Tester

This inbox is set up for Linear webhooks. Create a webhook in your workspace settings with this URL, change an issue, and the delivery appears here with Linear-Event, Linear-Delivery and the full payload. The Signature tab is already set to Linear-Signature, a hex HMAC-SHA256 of the raw body, so you only paste the signing secret.

  1. Copy the inbox URL. Linear requires a public HTTPS URL that answers 200 within 5 seconds; this one does.
  2. In Linear open Settings → API → Webhooks → New webhook. Paste the URL, choose the teams and the resource types to receive, and save.
  3. Change an issue in one of those teams, or press Send a signed test Linear event here to see a known-good Issue delivery.
  4. Select the request. Linear-Event shows the resource type and the body's action field shows create, update or remove.
  5. Paste the signing secret in the Signature tab, which is set to Linear-Signature, HMAC-SHA256, hex. Then check webhookTimestamp in the body: it should be within a minute of the time the request arrived.
linear webhook signature verification linear webhook testerlinear webhook secretlinear webhook payloadlinear webhook eventslinear-signature header
Open Hookwatch Webhook Tester Free · Pro $5/mo · no account

What to know

Linear signs each delivery with HMAC-SHA256 over the raw request body, keyed with the webhook's signing secret, and sends the hex digest in the Linear-Signature header with no sha256= prefix. Two habits from other providers break it: stripping a prefix that is not there, and base64-decoding a value that is hex. As always, compute the digest over the exact bytes received and only then parse the JSON. The @linear/sdk package includes a webhook helper that does the comparison for you.

Replay protection is in the body rather than a header. Every payload carries webhookTimestamp, a Unix time in milliseconds, and Linear's guidance is to reject deliveries where it is more than about a minute from your server time, checked after the signature. The tool verifies the signature only; the Body tab shows webhookTimestamp and the list shows when the request arrived, so you can see how much clock skew your check has to allow.

A payload has action (create, update or remove), type (Issue, Comment, Project, Cycle, IssueLabel, Reaction…), data with the entity, url, organizationId, webhookId and, on updates, updatedFrom with the previous values of the fields that changed. updatedFrom is the field to read when you only care about state transitions, for example moving an issue to Done. Headers include Linear-Delivery, a UUID per payload, and Linear-Event with the entity type.

A delivery fails when the server is unavailable, takes longer than 5 seconds or answers anything other than 200. Linear retries up to three times, after one minute, one hour and six hours, and may disable a webhook that stays unresponsive; you then re-enable it in settings. Store Linear-Delivery and ignore ids you have seen, because a retry can arrive after your first, slow attempt actually succeeded.

Updated · Cosmovex

Questions

Where is the Linear webhook signing secret?

Open Settings → API → Webhooks in Linear and select the webhook. The signing secret is shown on its detail page. Only workspace admins can create and view webhooks.

Is Linear-Signature hex or base64?

Hex, with no prefix: the plain HMAC-SHA256 digest of the raw body. The Signature tab on this page is already set to that, so a Valid result means your secret is correct.

How do I stop replayed Linear webhooks?

Verify the signature, then check webhookTimestamp in the body, a Unix time in milliseconds, and reject deliveries more than about 60 seconds from your server time. Also store Linear-Delivery and skip ids you have already processed.

Why did Linear disable my webhook?

Its deliveries kept failing: the endpoint was down, answered something other than 200, or took longer than 5 seconds. After three retries over about six hours Linear may disable it. Fix the endpoint and re-enable the webhook in settings.

Can I use a localhost URL for Linear webhooks?

No. Linear needs a public HTTPS URL. Use this inbox to see what Linear sends, then Copy as curl (free) to resend a stored delivery to your local server from a terminal, or with Pro Replay it from the browser.

The free plan covers everything on this page. Hookwatch Webhook Tester Pro ($5/mo, billed monthly) is described on the Hookwatch Webhook Tester page.