Register webhook
Registers a destination URL for the authenticated project. schemaVersion defaults to normalized-events.v1, the normalized Spectrum event shape; choose raw-inbound.v1 only if your project delivers on a platform Fusor already serves. Save both one-time secrets from the response: standardSigningSecret is the whsec_ secret for Standard Webhooks libraries, while signingSecret verifies the legacy Spectrum header.
Delivery format
Each event is delivered as an HTTP POST to your URL with these headers:
| Header | Meaning |
|---|---|
webhook-id | Stable event id. |
webhook-timestamp | UNIX epoch seconds at signing time. |
webhook-signature | One or more space-delimited v1,<base64> signatures. |
X-Spectrum-Webhook-Id | Legacy header. The id of this webhook, useful when you have multiple registered. |
X-Spectrum-Timestamp | Legacy header. UNIX epoch seconds at signing time. |
X-Spectrum-Signature | Legacy header. v0=<hex>, verified with signingSecret. |
Verifying the signature
Use a Standard Webhooks consumer library with standardSigningSecret. The signed content is webhook-id.webhook-timestamp.rawBody; always verify the exact raw request bytes before parsing JSON. During secret rotation the signature header contains signatures for both the new and overlapping old secret.
verify(rawBody, headers, standardSigningSecret)
Reject timestamps outside your replay-protection window and deduplicate by webhook-id.
Errors
Returns 409 if an active webhook with the same URL is already registered for this project. Registering a URL that was previously deleted is allowed and yields a new webhook with a new signing secret. Returns 503 when an explicitly legacy webhook cannot be registered with spectrum-webhook; the database insert is rolled back so the request can be retried.
Requires Authorization: Basic base64(projectId:projectSecret).
Path Parameters
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Body
normalized-events.v1, raw-inbound.v1 1message.received ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$