Skip to main content
Instead of polling the API for changes, you can subscribe to webhooks and receive HTTP POST requests when events happen—a worker is created, a payment completes, a leave request is submitted, and more. This guide walks you through configuring a webhook endpoint and handling your first event.

How webhooks work

  1. You register an HTTPS endpoint in Plane.
  2. You select which events you want to receive.
  3. When a matching event occurs, Plane sends a signed HTTP POST to your endpoint.
  4. Your server verifies the signature and processes the event.
Plane uses Svix for reliable webhook delivery, including automatic retries and a monitoring dashboard.

Configure your endpoint

1

Navigate to webhook settings

In your Plane dashboard, go to Developers > Webhooks. You need admin access.
2

Add an endpoint

Click Add Endpoint and enter the URL where you want to receive events. This must be a publicly accessible HTTPS URL.
3

Select events

Choose which event types to subscribe to. You can start with all events or pick specific types like payment.created or worker.updated.
4

Save and copy your signing secret

After saving, copy the signing secret. You need this to verify that incoming webhooks are genuinely from Plane.
Store your signing secret securely. Do not commit it to version control.

Handle incoming webhooks

When an event fires, Plane sends a POST request with a JSON payload:
Example payload
{
  "type": "payment.created",
  "data": {
    "id": "pt_ogdEjSnSqNYxtW1sd3pC3hFX",
    "amount": "1000.00",
    "currency": "USD",
    "date": "2024-01-15",
    "status": "pending",
    "worker": "wr_xyz789",
    "workspace": "ws_def456"
  }
}

Verify the signature

Every webhook includes headers for signature verification. Always verify signatures before processing events in production.
import { Webhook } from "svix";
import express from "express";

const app = express();

app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const wh = new Webhook("whsec_your_signing_secret");

  try {
    const event = wh.verify(req.body, {
      "svix-id": req.headers["svix-id"],
      "svix-timestamp": req.headers["svix-timestamp"],
      "svix-signature": req.headers["svix-signature"],
    });

    console.log("Received event:", event.type);

    // Process the event based on type
    switch (event.type) {
      case "payment.created":
        // Handle new payment
        break;
      case "worker.updated":
        // Handle worker update
        break;
    }

    res.status(200).send("OK");
  } catch (err) {
    console.error("Verification failed:", err.message);
    res.status(400).send("Invalid signature");
  }
});

app.listen(3000);
Install the Svix library for your language: npm install svix (Node.js) or pip install svix (Python).

Best practices

Return a 2xx status within 30 seconds. If your processing takes longer, acknowledge receipt immediately and handle the event asynchronously with a queue or background job.
Webhooks may be delivered more than once. Use the svix-id header to deduplicate events and make your processing idempotent.
Configure webhooks inside a sandbox first. Sandbox webhooks deliver events for test activity only, so you can validate your handler without affecting live data.

Monitor delivery

Plane’s webhook dashboard (powered by Svix) shows you:
  • All sent webhooks with payloads and response codes
  • Failed deliveries with retry status
  • Endpoint health and success rates
Access the dashboard from Developers > Webhooks in your Plane dashboard.

Next steps

Events reference

See every event type Plane can send.

Webhooks reference

Full webhook documentation including retry behavior and payload structure.