Linear Webhooks

A webhook lets Linear tell your own system when something changes. Instead of asking Linear again and again for new data, your server waits and receives a message the moment an issue, comment, or project updates.

How Webhooks Work

┌──────────┐   event happens   ┌──────────┐   HTTPS POST    ┌──────────────┐
│  Linear  │ ────────────────► │ Webhook  │ ──────────────► │  Your server │
│ workspace│  (issue created)  │ delivery │   JSON payload  │  /linear-hook│
└──────────┘                   └──────────┘                 └──────┬───────┘
                                                                   │
                                                          Reply HTTP 200 quickly

Everyday Comparison

Imagine waiting for a parcel. You can walk to the front door every five minutes and check. A doorbell saves the effort, because the courier rings when the parcel arrives. Polling through the API resembles the repeated walks. Webhooks resemble the doorbell.

Create a Webhook

  1. Open Settings > API.
  2. Find the Webhooks section and click New webhook.
  3. Enter the public HTTPS address of your endpoint.
  4. Choose one team or all public teams.
  5. Select the resource types to receive, such as Issues, Comments, or Projects.
  6. Save the webhook and copy the signing secret.

Admin access is required for workspace-level webhook settings.

Read the Payload

Linear sends a JSON body with a POST request. The body describes what changed.

{
  "action": "update",
  "type": "Issue",
  "createdAt": "2026-06-20T10:15:30.000Z",
  "url": "https://linear.app/acme/issue/ENG-204",
  "data": {
    "id": "a1b2c3",
    "title": "Fix login error",
    "priority": 2
  }
}
FieldMeaning
actionWhat happened: create, update, or remove
typeThe kind of object, such as Issue or Comment
dataThe current state of the object
urlA link to the object in Linear
createdAtThe time of the event

Verify the Sender

Anyone can post to a public address, so verify each request. Linear signs the raw request body with your webhook secret using HMAC-SHA256 and sends the result in the Linear-Signature header. Compute the same signature on your server and compare the two values. Reject the request when they differ.

const crypto = require("crypto");

function isValid(rawBody, signature, secret) {
  const hash = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return hash === signature;
}

Use the raw body bytes for the calculation. Parsed and re-encoded JSON can change the text and break the match.

Respond Correctly

Return an HTTP 200 status quickly. Linear treats slow or failed responses as errors and retries delivery a few times. Place heavy work in a background queue and respond first.

Handle Retries Safely

A retry can deliver the same event twice. Store a delivery identifier or the object version, and skip events you already processed. This habit is called idempotency.

Practical Uses

  • Post a message to a chat channel when a bug receives Urgent priority.
  • Copy issue data into a reporting database.
  • Start a build pipeline when an issue reaches a chosen status.
  • Update a customer-facing status page when a project completes.

Security Checklist

  • Serve the endpoint over HTTPS.
  • Store the signing secret in environment variables, not in code.
  • Verify every signature before reading the payload.
  • Log failures so you can spot delivery problems early.

Test Your Webhook

Build and test in small steps. Start with a simple endpoint that logs incoming requests. Create a test issue in Linear and confirm that the payload arrives. Add signature checks after that, and build the business logic last. A local tunnel tool can expose a development machine to the internet during testing.

Debug Failed Deliveries

Open the webhook settings page to review recent delivery attempts and responses. Common causes include wrong addresses, expired certificates, and server errors. Fix the cause and create another test event.

Choose Events Carefully

Subscribe only to the resource types you need. Fewer events mean less traffic, lower cost, and simpler code.