QueueUp / docs

Events & retries

The wire protocol for QueueUp webhook deliveries. Event envelope, full event catalog, headers, retries.

Webhooks let your server react to QueueUp activity in real time. When something happens on a waitlist (a signup, a confirmation), QueueUp signs and POSTs an event to a URL you configured.

This page documents the wire protocol: the JSON shape of every event, the headers that ride alongside it, and the retry policy. For panel configuration see Webhook integrations. For verification code samples see Verifying webhooks.

The binding model

A webhook integration is org-scoped configuration: a name plus a URL plus a signing secret. To start receiving events you bind it to one or more waitlists from the waitlist’s setup page (under Integrations).

Each binding is a routing rule. A single waitlist can have multiple bindings, and the same integration can be bound more than once on the same waitlist with different event scopes. That’s useful when you want different events to fire different consumers, or just want explicit per-event rules.

Event filtering is per-binding (per-waitlist), not per-integration. The same webhook URL can subscribe to all events on waitlist A and only subscriber.confirmed on waitlist B.

Event envelope

Every delivery has the same outer shape. The data field carries the event-type-specific payload.

{
  "id": "evt_42",
  "type": "webhook.ping",
  "created_at": "2026-05-03T18:30:00Z",
  "data": {
    "integration_id": 7,
    "tested_by": "[email protected]"
  }
}

Use id as your idempotency key. Deliveries are at-least-once: a network blip during your 200 OK response can cause a retry, so dedupe on the consumer side.

Headers

Every delivery includes the following request headers:

HeaderValue
X-QueueUp-EventThe event type, e.g. subscriber.joined
X-QueueUp-Delivery-IdA unique id per delivery attempt
X-QueueUp-TimestampUnix seconds at sign time
X-QueueUp-Signaturev1=<hex hmac> (see Verifying webhooks)

Any custom headers configured on the integration ride alongside these on every delivery. The reserved set above plus Content-Type, Content-Length, Host, and User-Agent are managed by QueueUp and can’t be overridden.

Event catalog

The envelope shape is stable across every event. What changes is the data payload. Each event below is documented with a complete example and a field reference. Timestamps are RFC 3339 strings in UTC.

webhook.ping

Sent only when you click Send test on a webhook integration’s detail page. Useful for confirming signature verification and routing without waiting for a real signup. This event bypasses per-binding event scoping; it always lands at the integration you tested.

{
  "id": "evt_42",
  "type": "webhook.ping",
  "created_at": "2026-05-03T18:30:00Z",
  "data": {
    "integration_id": 7,
    "tested_by": "[email protected]"
  }
}
FieldTypeNotes
integration_idnumberThe integration that received the test.
tested_bystringThe email of the panel user who clicked the button. Optional.

subscriber.joined

Fires once per signup, on every new subscriber row. When the waitlist requires email confirmation, the row is in pending state at emit time and a follow-up subscriber.confirmed will land later if the link is clicked. When confirmation is off, state is active and subscriber.joined is the only signal you’ll get for this subscriber.

Idempotent re-signups on a still-pending row re-emit subscriber.joined (gated by a per-email cooldown) so a fresh confirmation email goes out. Use the envelope id to dedupe.

{
  "id": "evt_1042",
  "type": "subscriber.joined",
  "created_at": "2026-05-03T18:30:12Z",
  "data": {
    "subscriber_id": 8401,
    "waitlist_id": "46dc645f-6d47-4cbd-86cd-c68f2cce0901",
    "email": "[email protected]",
    "state": "pending",
    "referral_code": "K7M9PX",
    "referrer_id": 8377,
    "status_token": "9b1f4a...32 hex chars",
    "priority_score": 5,
    "joined_at": "2026-05-03T18:30:12Z"
  }
}
FieldTypeNotes
subscriber_idnumberStable id for this subscriber row.
waitlist_idstring (UUID)The waitlist this signup belongs to.
emailstringThe email exactly as the subscriber submitted (display case preserved).
statestring"pending" when double opt-in is on and the email hasn’t been confirmed yet, "active" otherwise.
referral_codestringThe 6-character code minted for this subscriber.
referrer_idnumberThe subscriber_id of whoever referred this signup (matched on ?queueup_ref=<code>). Omitted when there’s no referrer.
status_tokenstringThe 32-character hex token used in the hosted status page URL (/s/<token>).
priority_scorenumberThe subscriber’s current priority score. Bumps when this subscriber refers others.
joined_atstringRFC 3339 timestamp of the signup.

subscriber.confirmed

Fires when a pending subscriber clicks the confirmation link and the row flips to active. Only emitted by waitlists with email confirmation turned on; waitlists without double opt-in will never produce this event.

{
  "id": "evt_1108",
  "type": "subscriber.confirmed",
  "created_at": "2026-05-03T18:42:55Z",
  "data": {
    "subscriber_id": 8401,
    "waitlist_id": "46dc645f-6d47-4cbd-86cd-c68f2cce0901",
    "email": "[email protected]",
    "confirmed_at": "2026-05-03T18:42:55Z",
    "status_token": "9b1f4a...32 hex chars"
  }
}
FieldTypeNotes
subscriber_idnumberSame id as the matching subscriber.joined.
waitlist_idstring (UUID)The waitlist the subscriber belongs to.
emailstringThe email exactly as the subscriber submitted.
confirmed_atstringRFC 3339 timestamp of the flip from pending to active.
status_tokenstringThe hosted status page token.

Retry policy

Failed deliveries retry on a schedule with jitter. Total wall-clock budget per delivery is about 33 hours.

AttemptDelay before next
11 minute
25 minutes
330 minutes
42 hours
56 hours
624 hours, then dead-letter

Decision rules:

  • 2xx. Success.
  • 4xx (other than 408 and 429). Dead-letter immediately. We assume your server is reporting a real bug; retrying won’t fix it.
  • 5xx, 408, 429, transport errors. Retry until the budget runs out.

Dead deliveries stay in your dashboard. You can manually re-enqueue any of them with the Redeliver button.