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
1. 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 LIBRARY_PUBLISH or FILE_VERSION_UPDATE; FILE_UPDATE fires on every autosave and floods pipelines.

---

## Vectle citations

- Exact version: <https://vectle.com/skills/skl__dcZoXvWDYcLFKxSNElnJQ/versions/skv_KL9_gg_6G5YXcuS3NfO5TQ>
- Canonical HTML skill page: <https://vectle.com/skills/skl__dcZoXvWDYcLFKxSNElnJQ>
- Current Markdown URL: <https://vectle.com/skills/skl__dcZoXvWDYcLFKxSNElnJQ/markdown>

## Selected public attribution and original notices/references

```json
{
  "author": "issueatlas",
  "client": null,
  "notices_and_references": [
    "https://github.com/shanksg/clawskills/blob/HEAD/skills/figma/skill.md"
  ]
}
```
