Skip to main content

Advanced

Webhooks

Receive real-time notifications when Figma files, comments, or libraries change.

Webhooks push events to your server in real-time. Instead of polling the API, register a webhook and Figma will send HTTP POST requests to your endpoint when events occur.

Supported Events

EventTrigger
FILE_UPDATEA file is saved or modified
FILE_DELETEA file is deleted
FILE_VERSION_UPDATEA new version is created
FILE_COMMENTA comment is added or replied to
LIBRARY_PUBLISHA library is published

Creating a Webhook

1
Set up your endpoint
2
Create an HTTPS endpoint that accepts POST requests and returns a 200 status:
3
Express
app.post("/webhooks/figma", (req, res) => {
  const event = req.body;
  console.log(`Received ${event.event_type} for ${event.file_key}`);

  // Process the event asynchronously
  processEvent(event).catch(console.error);

  // Always respond quickly with 200
  res.status(200).send("OK");
});
Flask
@app.route("/webhooks/figma", methods=["POST"])
def figma_webhook():
    event = request.json
    print(f"Received {event['event_type']} for {event['file_key']}")

    # Process asynchronously
    process_event.delay(event)

    return "OK", 200
4
Register the webhook
5
curl -X POST "https://api.figma.com/v2/webhooks" \
  -H "X-Figma-Token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "FILE_UPDATE",
    "team_id": "YOUR_TEAM_ID",
    "endpoint": "https://your-server.com/webhooks/figma",
    "passcode": "your-secret-passcode",
    "description": "File update notifications"
  }'
6
Verify the passcode
7
Every webhook request includes a passcode field. Verify it matches the passcode you set during registration:
8
app.post("/webhooks/figma", (req, res) => {
  if (req.body.passcode !== process.env.FIGMA_WEBHOOK_PASSCODE) {
    return res.status(401).send("Unauthorized");
  }
  // Process event...
  res.status(200).send("OK");
});

Webhook Payload

{
  "event_type": "FILE_UPDATE",
  "passcode": "your-secret-passcode",
  "webhook_id": "wh_123456",
  "timestamp": "2024-01-15T10:30:00Z",
  "file_key": "abc123DEF",
  "file_name": "Design System",
  "triggered_by": {
    "id": "12345",
    "handle": "designer"
  }
}
{
  "event_type": "FILE_COMMENT",
  "passcode": "your-secret-passcode",
  "webhook_id": "wh_123456",
  "timestamp": "2024-01-15T10:30:00Z",
  "file_key": "abc123DEF",
  "file_name": "Design System",
  "comment": [{
    "id": "456",
    "text": "Can we adjust the spacing here?",
    "created_at": "2024-01-15T10:30:00Z"
  }],
  "triggered_by": {
    "id": "12345",
    "handle": "designer"
  }
}
{
  "event_type": "LIBRARY_PUBLISH",
  "passcode": "your-secret-passcode",
  "webhook_id": "wh_123456",
  "timestamp": "2024-01-15T10:30:00Z",
  "file_key": "abc123DEF",
  "file_name": "Component Library",
  "description": "Updated button variants",
  "triggered_by": {
    "id": "12345",
    "handle": "designer"
  }
}

Managing Webhooks

List your active webhooks:

curl -H "X-Figma-Token: YOUR_TOKEN" \
  "https://api.figma.com/v2/webhooks/YOUR_TEAM_ID"

Delete a webhook:

curl -X DELETE "https://api.figma.com/v2/webhooks/WEBHOOK_ID" \
  -H "X-Figma-Token: YOUR_TOKEN"

Figma will disable webhooks that consistently fail (return non-2xx status codes). Your endpoint must respond within 10 seconds and return a 200 status. Process events asynchronously.

Use a message queue (like SQS or Redis) to process webhook events. This ensures your endpoint responds quickly and events are processed reliably even under load.