Using webhooks

Get a signed POST whenever something happens on your account — without polling our dashboard or parsing emails.

Webhooks are how our platform tells your platform something happened. You register an HTTPS URL, pick the events you care about, and we POST a small JSON payload to your URL whenever one fires. Common uses:

  • A Slack channel that pings the team the moment a site goes live.
  • A Zapier zap that creates a Google Sheet row whenever a project is approved.
  • A CRM webhook that updates a customer's record when a domain purchase completes.

The six events. We send a webhook for each of these:

  • project.ready_for_review — our team marked your site ready for your review.
  • project.approved — you approved a site preview.
  • project.revisions_requested — you requested changes on a preview.
  • project.published — your site went live.
  • domain.purchased — a domain purchase completed.
  • subscription.canceled — your subscription was canceled.

Browse the payload shapes first. Before you wire anything up, head to Integrations → [Browse event reference](/app/integrations/events). Each event card shows the full delivery body, the headers we send, and copy-pasteable signature-verification snippets in Node.js and Python. The placeholder data is safe to drop into a local test — no real customer info.

Setting up an endpoint.

  1. Open Integrations in your dashboard.
  2. Click Add endpoint and paste your HTTPS URL — http:// and private IPs (localhost, 192.168.*, AWS metadata) are rejected.
  3. Pick the events to subscribe to. You can subscribe to all six or just one.
  4. Click Create endpoint. We'll show you the signing secret once — copy it into your secret manager. You can't read it again later (rotation is the only way to recover from a lost secret).

Verifying the signature. Every delivery carries an X-MM-Signature: sha256=<hex> header — the HMAC-SHA256 of the raw body using your signing secret. Recompute it on your side and constant-time-compare before trusting the payload. The full Node.js and Python verification snippets live on the event reference page.

Testing without firing real events. Once your endpoint is registered, use the Send test action — it dispatches the sample payload for any event type to your URL using your real signing secret. The body carries a _test: true flag under data so your handler can short-circuit safely (skip writing to billing, skip sending a customer email, etc.).

Retries and auto-disable. We retry up to three times on 5xx and network errors with exponential backoff. We don't retry 4xx responses — your endpoint is telling us the request is wrong, and retrying wouldn't help. Endpoints that fail ten consecutive deliveries are automatically disabled; you'll see the disabled state on the Integrations page on your next visit, and you can re-enable + retry the failed deliveries from the per-endpoint deliveries view.

Security notes.

  • Always verify the signature. The signature is the only way to prove the request came from us — without it, anyone can POST to your URL.
  • Use a fresh secret per endpoint. Don't share a signing secret across two endpoints; if one leaks, you only have to rotate one.
  • Never put the secret in client-side code. Server-side only.
  • Treat the secret like a password. Environment variable or secret manager, never source control.

If something looks wrong, the per-endpoint deliveries view shows every attempt — request body, response body, status code, latency. The retry button replays an individual delivery against your URL using the same code path as the original.

Was this helpful?

Related