Skip to main content

Overview

Every webhook event Fyatu delivers includes a sign field in the JSON body. This is an HMAC-SHA256 signature you must verify before processing the event.
The sign is computed over the raw data value only — not the full envelope. Your endpoint must recompute the same HMAC and compare it against sign before trusting anything in the payload.
Your webhookSecret is generated when you call POST /webhooks/secret/regenerate. It is shown once and never returned again. Store it securely in an environment variable — never in code or version control.

Signature Algorithm

Critical details:
  • Sign only the data value — not event, version, eventId, or sign itself
  • Use the exact bytes from the HTTP body for the data value — do not parse and re-serialize it
  • Always use constant-time comparison — never === or ==
Do not re-serialize data through a dictionary or map. Most JSON libraries sort map keys when encoding, which produces different bytes than the original and causes signature mismatch. The examples below all preserve the raw bytes.

Test Your Implementation

Use these known-good values to verify your implementation before going live. Full payload to feed into your handler:
Your verifySignature function should return true when given this payload and secret. If it returns false, your implementation has a bug — the most common cause is re-serializing data instead of using the raw bytes.

Verification Examples


Best Practices

Respond quickly

Return 200 within 10 seconds. Acknowledge first and process asynchronously if needed. Fyatu retries timed-out deliveries.

Make handlers idempotent

The same event may be delivered more than once. Use eventId or reference to deduplicate — store processed event identifiers in your database.

Use constant-time comparison

Always use timing-safe functions (timingSafeEqual, hash_equals, hmac.Equal). Variable-time === comparisons are vulnerable to timing attacks.

Never re-serialize through a map

Sign the raw data bytes as received. Re-encoding through a dictionary can change key order, producing a different HMAC. The Go example uses json.RawMessage to avoid this.

Retry Behavior

If your endpoint returns a non-2xx status or doesn’t respond within 10 seconds, Fyatu retries with exponential backoff: After 3 failed attempts the event is marked as undelivered. Use the Test Webhook endpoint to replay events during development.

Rotating Your Secret

If your webhookSecret is compromised, regenerate it immediately:
The new secret is returned once in the response and takes effect immediately. Update your environment variable before the old secret is invalidated.