Webhooks
Receive real-time HTTP POST notifications when events happen in your schedules.
Overview
Webhooks let you receive automatic POST notifications to your server when key events occur, such as ticket sales, event changes, or check-ins. Instead of polling the API, your application is notified in real time.
Each webhook delivery includes an HMAC-SHA256 signature so you can verify the payload came from Event Schedule. Delivery logs are available in your account settings for debugging.
Setup
- Go to Settings in the admin panel and select the Webhooks section.
- Enter your endpoint URL (must be HTTPS in production).
- Select which event types you want to receive.
- Click Add Webhook. Your signing secret will be displayed once. Copy and store it securely.
- Use the Test button to send a test ping and verify your endpoint responds with a 2xx status.
Event Types
| Event | Description |
|---|---|
| sale.created | A new ticket sale is created (status: unpaid) |
| sale.paid | A sale is confirmed as paid (Stripe, Invoice Ninja, manual, or free) |
| sale.refunded | A sale is refunded |
| sale.cancelled | A sale is cancelled |
| event.created | A new event is created |
| event.updated | An event is updated |
| event.deleted | An event is deleted |
| ticket.scanned | A ticket QR code is scanned at check-in |
| feedback.submitted | An attendee submits feedback for an event |
Payload Format
All webhook payloads are JSON with this structure:
{
"event": "sale.paid",
"timestamp": "2026-03-01T12:00:00+00:00",
"data": {
"id": "abc123",
"event_id": "def456",
"event_name": "Summer Concert",
"name": "Jane Doe",
"email": "[email protected]",
"status": "paid",
"payment_amount": 25.00,
"tickets": [
{ "ticket_id": "ghi789", "quantity": 2, "price": 12.50, "type": "General" }
]
}
}
The data object matches the corresponding API response format. Sale webhooks include the same fields as the
Sales API
, and event webhooks match the Events API.
Request Headers
| Header | Description |
|---|---|
| X-Webhook-Signature | HMAC-SHA256 signature: sha256=<hex> |
| X-Webhook-Event | The event type (e.g. sale.paid) |
| X-Webhook-Timestamp | ISO 8601 timestamp of when the webhook was sent |
| Content-Type | application/json |
| User-Agent | EventSchedule-Webhook/1.0 |
Signature Verification
Every webhook includes an X-Webhook-Signature header containing an HMAC-SHA256 hash of the raw request body, signed with your webhook secret. Always verify this signature before processing the payload.
PHP
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $webhookSecret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$data = json_decode($payload, true);
Node.js
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret).update(body).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(signature)
);
}
Python
import hmac, hashlib
def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Best Practices
- Respond quickly. Return a 2xx status within 5 seconds. Do heavy processing asynchronously after acknowledging receipt.
- Verify signatures. Always validate the
X-Webhook-Signatureheader before processing any webhook payload. - Handle duplicates. Use the
data.idfield as an idempotency key. In rare cases, the same event may be delivered more than once. - Use HTTPS. Always use an HTTPS endpoint to protect webhook payloads in transit.
- Monitor deliveries. Check the delivery log in your Webhook settings to debug failed deliveries and verify payloads.
Testing
Use the Test button in your webhook settings to send a test payload. The test event uses the type webhook.test with an empty data object:
{
"event": "webhook.test",
"timestamp": "2026-03-01T12:00:00+00:00",
"data": {}
}
See Also
- REST API Reference - Full API documentation for managing schedules and events
- Account Settings - Configure webhooks in your account
- Selling Tickets - Learn about the ticketing system that generates sale events