This is an archived copy of the SandyWP docs. It is kept online as a fallback and may be out of date. The maintained documentation lives at docs.sandywp.com.

Webhooks

When a visitor opens a demo from one of your public launch links, SandyWP can call your own endpoint when that sandbox becomes ready and again when its demo lease expires. Use these events to push the lead into your CRM, start an onboarding email, or log the demo in your own dashboard.

Set it up

  1. Click your profile in the top-right of the dashboard and choose Account.
  2. Open the Webhooks tab.
  3. Paste your Callback URL the HTTPS endpoint you want SandyWP to POST to.
  4. Leave Send demo launch events checked, then click Save webhook.
  5. Copy the signing secret shown right after saving, and store it in your receiver.

Click Send test to fire a sample event at your endpoint straight away no visitor needed. The panel shows the result of the most recent delivery, so you can tell at a glance whether your endpoint is healthy.

Just exploring? Paste a throwaway URL from a service like webhook.site to watch the payload arrive, then swap in your real endpoint later.

What you receive

SandyWP sends demo.ready once the launched sandbox is ready to serve its URL and demo.expired when the demo lease ends. Both events use the same payload shape; type and status identify the transition, while occurredAt records when it happened. The email field is null when the launch link doesn't collect an email.

{
  "id": "demo_ready_site_123",
  "type": "demo.ready",
  "occurredAt": "2026-08-02T12:00:02.000Z",
  "workspaceId": "workspace_123",
  "templateId": "template_123",
  "templateName": "Product demo",
  "siteId": "site_123",
  "siteUrl": "https://demo.example.com/site-123",
  "email": "[email protected]",
  "consent": true,
  "consentLabel": "I agree to receive product updates.",
  "status": "ready",
  "source": "template_launch"
}

For expiration, the lifecycle fields are:

{
  "id": "demo_expired_site_123",
  "type": "demo.expired",
  "occurredAt": "2026-08-02T13:00:02.000Z",
  "workspaceId": "workspace_123",
  "templateId": "template_123",
  "templateName": "Product demo",
  "siteId": "site_123",
  "siteUrl": "https://demo.example.com/site-123",
  "email": "[email protected]",
  "consent": true,
  "consentLabel": "I agree to receive product updates.",
  "status": "expired",
  "source": "template_launch"
}

Every request carries x-sandywp-signature, x-sandywp-event, x-sandywp-delivery, and an idempotency-key. If your endpoint is down, delivery retries with backoff and gives up after eight attempts.

Verify every request

Your callback URL is publicly reachable, so anyone who learns it could post fake events at it. That's what the signing secret is for: SandyWP signs each request with it, and your receiver recomputes the signature to confirm the request is genuine. Never skip this in production.

The API reference has a copy-paste verification snippet and the three details people get wrong (hash the raw body, the digest is base64url, compare in constant time).

The secret is shown once, when you first save the webhook or rotate it. Keep it in your receiver's environment or secret manager not in source control. Lost it? Click Rotate secret for a new one, then update your receiver.

Good practices

  • Respond quickly with a 2xx and do slow work afterwards; deliveries time out after ten seconds.
  • Deduplicate on the idempotency-key header retries reuse the same value.
  • Uncheck Send demo launch events to pause delivery while you work on your endpoint; the URL stays saved.

Availability

Webhooks are available on every paid plan. In a shared Workspace, members need the integrations capability the Workspace owner always has it.

Next steps

  • Templates create the public launch link that produces these events.
  • API reference manage the webhook programmatically and verify signatures.
  • Slack app get launches in a channel instead of your own endpoint.