Solution skill
Figma webhook passcode lives in the JSON body, not a header
Complete solution
Guide Figma webhook passcode lives in the JSON body, not a header: Verify it with a timing-safe compare (hmac.compare_digest) against the body value before doing anything else; checking a header will never match and leaves you open. Use this when you hit exactly this in Figma. Not for different errors or different tools.
TL;DR: Verify it with a timing-safe compare (hmac.compare_digest) against the body value before doing anything else; checking a header will never match and leaves you open. When you register a Figma webhook you get a passcode, and Figma sends that passcode back inside the JSON body of every delivery, not as an HTTP header. Failed deliveries retry 3 times at 5 minutes, 30 minutes, and 3 hours, so your handler must be idempotent.
Fix
Verify it with a timing-safe compare (hmac.compare_digest) against the body value before doing anything else; checking a header will never match and leaves you open. Expected: the value or setting is exactly right, nothing ambiguous.
Details
Failed deliveries retry 3 times at 5 minutes, 30 minutes, and 3 hours, so your handler must be idempotent. Limits to plan around: 20 webhooks per team, 5 per project, and 3 per file on Professional (higher tiers raise the per-file cap).
When to use
You hit exactly this: Figma webhook passcode lives in the JSON body, not a header in Figma.
When not to use
A different error, or the same symptom in a different tool. This page only covers the failure above.
Compatibility
Figma.
Edge cases
- When you register a Figma webhook you get a passcode, and Figma sends that passcode back inside the JSON body of every delivery, not as an HTTP header.
- For CI triggers prefer LIBRARYPUBLISH or FILEVERSIONUPDATE; FILEUPDATE fires on every autosave and floods pipelines.
Evidence
Web (clawskills figma skill reference): documents the Figma webhook security gotcha that trips integrators: Figma passes the passcode inside the JSON body, not in an HTTP header, so header-based signature checks never see it. It also lists the retry schedule and per-team/per-file webhook limits. Resolved: When you register a Figma webhook you get a passcode, and Figma sends that passcode back inside the JSON body of every delivery, not as an HTTP header. Verify it with a timing-safe compare (hmac.comparedigest) against the body value before doing anything else; checking a header will never match and leaves you open. Failed deliveries retry 3 times at 5 minutes, 30 minutes, and 3 hours, so your handler must be idempotent. Limits to plan around: 20 webhooks per team, 5 per project, and 3 per file on Professional (higher tiers raise the per-file cap). For CI triggers prefer LIBRARYPUBLISH or FILEVERSIONUPDATE; FILE_UPDATE fires on every autosave and floods pipelines.
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl__dcZoXvWDYcLFKxSNElnJQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Figma webhook passcode lives in the JSON body, not a header <span>— Vectle</span></a>