Providers / April 25, 2026

How to receive Figma webhooks (file updates, comments, library publishes)

Figma webhook flow showing file update and comment events delivered to a sync agent

Figma fires webhooks for file events: when a file is updated, a new version is published, a library is republished, a comment is posted, or a file is deleted. They're how integrations (design-system sync, AI agents that read designs, status mirrors) stay in sync with what's happening in your Figma team.

Figma's auth model is unusual — instead of HMAC signatures or JWTs, you set a passcode when creating the webhook, and Figma includes that passcode in every request body. This guide covers what Figma sends, how the passcode model works, and what production reliability requires.

What Figma sends

Figma webhooks are JSON POST requests. A FILE_UPDATE event:

{
  "event_type": "FILE_UPDATE",
  "file_key": "abc123XYZ",
  "file_name": "Design System v2",
  "passcode": "your-configured-passcode",
  "timestamp": "2026-04-25T14:30:00.000Z",
  "webhook_id": "987654",
  "triggered_by": {
    "id": "111111111",
    "handle": "octavia"
  }
}

Common Figma event types:

  • FILE_UPDATE — file content was changed (debounced — Figma doesn't fire one per keystroke)
  • FILE_VERSION_UPDATE — a named version was saved
  • FILE_COMMENT — a comment was added to the file
  • LIBRARY_PUBLISH — a library file was published, propagating changes to consumers
  • FILE_DELETE — file was moved to trash

Each event type has different payload fields beyond the common ones. FILE_COMMENT includes the comment text; LIBRARY_PUBLISH includes the list of changes; FILE_VERSION_UPDATE includes the version name and description.

Figma's passcode authentication

When you create a Figma webhook (via the API), you set a passcode — a string up to 100 characters. Figma includes this passcode in the body of every webhook request. Your handler verifies that the passcode matches the value you stored.

This is a shared-secret pattern, not HMAC. Three things follow:

  1. The passcode is sent in the request body. Anyone who can read your webhook traffic can capture the passcode. Always use HTTPS.
  2. The passcode doesn't bind to the request body. Unlike an HMAC, an attacker who learns the passcode can forge requests with arbitrary content.
  3. Rotate by recreating the webhook. There's no in-place rotation; create a new webhook with a new passcode, switch traffic, then delete the old one.

The mitigations: long random passcode (don't reuse), unguessable URL, optional source-IP allowlisting, and treating webhooks as informational for state-changing actions (look up canonical state via the Figma API for high-stakes operations).

Figma's PING event

When you create a webhook, Figma sends an initial PING event to confirm the URL is reachable. Your handler should respond with 2xx. If it doesn't, Figma marks the webhook as failed and you'll need to inspect the failure log.

The PING event includes the same passcode field — handle it the same way you'd handle any other event.

Figma's retry policy

Figma retries failed webhooks (non-2xx, or no response within a few seconds) on a backoff schedule. After several consecutive failures, Figma may pause the webhook — visible as a status field on the webhook resource via the API. Past the retry window, missed events are gone unless you backfill from Figma's Files API.

This means:

  • Acknowledge fast — return 2xx in under a second
  • Be idempotent — Figma doesn't include a stable per-event UUID in all event types; for FILE_UPDATE use (file_key, timestamp) as a composite key, for FILE_COMMENT use the comment ID
  • Monitor webhook status — if Figma pauses your webhook, you stop receiving everything; check the webhook status periodically via the API
  • Have a recovery story — backfill via the Files API for missed events

DIY: minimal Figma webhook handler in Node

const expectedPasscode = process.env.FIGMA_WEBHOOK_PASSCODE!

export async function POST(req: Request) {
  const body = await req.text()
  const event = JSON.parse(body)

  // Passcode check
  if (event.passcode !== expectedPasscode) {
    return new Response('Bad passcode', { status: 401 })
  }

  // Handle the initial PING
  if (event.event_type === 'PING') {
    return new Response('ok', { status: 200 })
  }

  // Idempotency: composite key per event type
  // For FILE_UPDATE: (file_key, timestamp)
  // For FILE_COMMENT: comment_id
  // ...

  queueWork(event)

  return new Response('ok', { status: 200 })
}

Production needs more:

  • A persistence layer for the per-event-type idempotency keys
  • A queue for async work
  • A monitor for webhook status (so you notice when Figma pauses you)
  • A backfill path via the Files API
  • Routing by event_type and file_key — different files often need different downstream actions

Hooksbase: receive Figma webhooks without rebuilding the rest

Figma isn't one of Hooksbase's five pre-verified provider packs (Stripe, GitHub, Clerk, Slack, Resend). If you need the passcode checked before relay acceptance, do it in a small pre-ingest forwarder, then post the verified raw body to Hooksbase with the bearer ingest secret.

Setup:

  1. Create a webhook in Hooksbase with your application URL as the destination
  2. Create a Figma webhook via the Figma API (or your team's tooling) with your verification forwarder URL and your chosen passcode
  3. In the forwarder, verify the passcode, then POST the same raw body to the Hooksbase ingest URL with Authorization: Bearer <ingest secret>

You get:

  • Acknowledge in milliseconds to Figma — important because slow handlers can cause Figma to pause the webhook entirely
  • Idempotency for your destination — every dispatch includes a unique webhook-id header (Standard Webhooks-compatible) you can dedupe on, separate from the per-event-type composite key you'd use for Figma's payload
  • Retries with exponential backoff to your endpoint after Hooksbase accepts the event — downstream failures stay between Hooksbase and your handler
  • Routing rules by event_type or file_key — send LIBRARY_PUBLISH events to your design-system sync agent, FILE_COMMENT to comment triage, FILE_UPDATE for specific files to specialized handlers
  • Payload transforms — normalize the varying shapes across event types into something your handler can dispatch on uniformly
  • Deterministic replay — re-run a failed delivery with the same payload bytes while the payload is retained
  • Delivery history and DLQ

Common Figma webhook use cases for AI agents

  • Design-system sync agentLIBRARY_PUBLISH events trigger an agent that diffs the published changes, generates updated tokens for code (Tailwind config, CSS variables, design tokens JSON), and opens a PR
  • Comment triage agentFILE_COMMENT events trigger an agent that classifies the comment (question, blocker, polish), tags relevant designers, and links related issues
  • Documentation-update agentFILE_VERSION_UPDATE on a "designs" file triggers an agent that pulls the new screens, regenerates documentation, and notifies the docs team
  • Spec-handoff agentFILE_UPDATE on a spec file triggers an agent that detects which screens changed, regenerates spec docs, and pings the assigned engineer
  • Audit-trail agent — every FILE_UPDATE and FILE_VERSION_UPDATE flows into an audit log so design changes can be reviewed and reverted on regulated assets

Where to go next

Start free at app.hooksbase.com.

Related guides