Eventlayer / API & operations

Webhooks

Receive real-time notifications for API events.

Eventlayer publishes webhook events whenever resources change. Use them to keep your CRM, lifecycle email, analytics, and internal services aligned with what is happening at an event.

Why use webhooks?

Webhooks let your application react to events in real time without polling the API. Common use cases include:

  • Creating or enriching a CRM contact when a ticket is assigned
  • Triggering confirmation, reminder, or post-event email flows
  • Sending ticket and check-in activity to your analytics pipeline
  • Updating your own product when an attendee arrives

How it works

When a lifecycle event occurs—for example, a ticket is assigned or checked in—Eventlayer creates an independent signed delivery for every matching endpoint. Delivery happens separately from the API request, so an unavailable CRM or analytics service does not make your Eventlayer API call fail.

Event types

EventTriggered when
event.createdA new event is created.
event.updatedAn event is updated.
event.deletedAn event is deleted.
attendee.createdA new attendee is added to an event.
attendee.updatedAn attendee is updated.
attendee.deletedAn attendee is removed.
ticket_type.createdA new ticket type is created.
ticket_type.updatedA ticket type is updated.
ticket_type.deletedA ticket type is deleted.
ticket.createdA new ticket is issued.
ticket.updatedA ticket is updated.
ticket.deletedA ticket is deleted.
ticket.assignedA ticket is assigned to an attendee.
ticket.checked_inAn attendee checks in.

Webhook payload

Each webhook delivery includes a JSON body with the event type and the resource data:

{
  "id": "whk_35d400aab1a52a2f",
  "event_type": "ticket.checked_in",
  "timestamp": "2026-09-15T08:55:01Z",
  "attempt": 1,
  "data": {
    "id": "tkt_35d400aab1a52a2f",
    "ticket_type_id": "tt_35d400aab1a52a2f",
    "attendee_id": "atd_35d400aab1a52a2f",
    "status": "checked_in",
    "checked_in_at": "2026-09-15T08:55:00Z",
    "created_at": "2026-07-21T12:00:00Z",
    "updated_at": "2026-09-15T08:55:00Z"
  }
}

The data field contains the full response object for the affected resource — the same shape as the corresponding API response. Events are delivered independently, so consumers must not rely on delivery order.

Every request also includes Webhook-Id, Webhook-Delivery-Id, Idempotency-Key, and Webhook-Attempt headers. The webhook and delivery IDs remain unchanged across automatic retries.

Retry behavior

Network failures, timeouts, rate limits, and server errors are retried with backoff. Redirects and most other client errors are treated as permanent failures. Retryable HTTP responses are 408, 425, 429, and 5xx. Retries are scheduled after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, and 10 hours, for up to seven attempts in total. Worker availability may delay an attempt beyond its scheduled time. After the retry schedule is exhausted, the delivery is marked failed.

Your endpoint should return a 2xx status code to acknowledge receipt. Retryable failures may cause the same delivery to be sent more than once.

Delivery guarantees

Webhook delivery can happen more than once. Store the Idempotency-Key header (which equals Webhook-Delivery-Id) to avoid repeating side effects when a delivery is retried. Successful receipt is not guaranteed if the endpoint keeps failing or the delivery is cancelled.

Verify signatures

Each request includes Webhook-Timestamp (Unix seconds) and Webhook-Signature (v1=<hex HMAC>). Verify the HMAC-SHA256 using your endpoint's signing secret over Webhook-Timestamp + "." + raw_request_body. Use the exact request bytes before parsing JSON, compare signatures in constant time, and reject timestamps more than five minutes from the current time.

During the 24-hour secret-rotation overlap, the signature header contains multiple comma-separated v1 values. Accept the request if any value matches a trusted secret. The signing secret is returned only when the endpoint is created or its secret is rotated; store it securely.

View deliveries in the dashboard

Open Dashboard → Webhooks → Delivery log to see deliveries newest first. Filter by status or endpoint, use Older and Newer to page through history, and select View for a delivery's details. The log and open detail view refresh every five seconds while the page is active; the log also has a manual Refresh button.

StatusMeaning
queuedWaiting for its first attempt or a scheduled retry
deliveringA worker has claimed the delivery
succeededThe endpoint returned a 2xx response
failedA permanent failure occurred or retries were exhausted
cancelledThe endpoint was deleted before delivery completed

The log shows attempt counts, the last HTTP response or error, the next queued attempt time, and creation time. View includes IDs, timestamps, the event payload, and each recorded attempt's target URL, HTTP status, duration, error, and response body. Response bodies are limited to the first 500 bytes. An unattempted delivery has no attempt history; a network failure may have no HTTP status or response body.

Deleting an endpoint cancels its pending deliveries. Its history remains available through the All endpoints (including deleted) filter.

Delivery API and SDK

These routes require a dashboard access token from an authenticated, email-verified user session. API keys cannot access them.

GET  /v1/webhook-deliveries
GET  /v1/webhook-deliveries/{delivery_id}
POST /v1/webhook-deliveries/{delivery_id}/replay

The TypeScript SDK exposes webhookDeliveries.list(filters) and webhookDeliveries.get({ deliveryId: deliveryId }); webhookDeliveries.replay({ deliveryId: deliveryId }) queues a new delivery. See the SDK package README for authentication and examples.

The list accepts status, endpoint_id, limit (1–100, default 50), and either after or before. Its result contains items and meta.has_more, ordered newest first. Pass the last item's ID as after to fetch older deliveries with the same filters. Omit endpoint_id to include history from deleted endpoints.

List items include attempt_count, response_status, error, next_attempt_at, last_attempted_at, completed_at, and created_at, but their attempts arrays are empty. Fetch an individual delivery to load its attempt history. For queued deliveries, next_attempt_at is the scheduled attempt time; for delivering records, it is the worker lease deadline.

A replay uses the original event ID and resource payload with the endpoint's current URL, but creates a new delivery ID. The original outcome remains unchanged. Replays require an endpoint that has not been deleted.

Choose Retry for a failed delivery or Resend for another completed delivery, from the log or detail view. The new delivery opens automatically so you can follow its progress. These buttons are disabled while a delivery is queued or in progress, while a resend request is pending, or when its endpoint is unavailable. The SDK's replay() request does not automatically retry; after an uncertain network result, check history before sending again.

Select View response in the log to open the last recorded response. The Last response panel shows the body directly, along with the HTTP status, error, duration, and timestamp. Attempt history is ordered newest first.

FAQ

Next steps