Back to Overview

Webhook Events Reference

Full reference for Tymeslot webhook events — payloads, headers, retry behaviour, and security verification.

Luka Breitig — Technical Product Builder & AI Developer
Luka Breitig

Technical Product Builder & AI Developer

Before You Begin

You will need:

  • A running Tymeslot instance with at least one event type configured
  • A publicly accessible HTTPS endpoint to receive webhook deliveries — plain HTTP endpoints are rejected
  • A secret token you choose — you will configure it in Tymeslot and verify it on your endpoint to authenticate deliveries

By the end of this guide, you will know how to configure, verify, and consume Tymeslot webhook events in your own application.

How Webhooks Work

Tymeslot sends an HTTP POST request to your configured endpoint URL whenever a scheduling event occurs. Your endpoint receives a JSON payload describing what happened. Key behaviours to understand before you begin:

  • Your endpoint must respond with a 2xx status code within 10 seconds. For slow operations, respond immediately with 200 OK and process the payload asynchronously.
  • Failed deliveries are retried up to 5 times with exponential backoff — your endpoint may receive the same event multiple times.
  • Every delivery carries a unique X-Delivery-ID header — use it to deduplicate retries.
  • Full delivery history is visible in Dashboard → Settings → Webhooks → Delivery Logs with manual retry support.

1 Add a Webhook

  1. In Tymeslot, go to [Dashboard][Settings][Webhooks] and click [Add Webhook].
  2. Enter your HTTPS endpoint URL in the [Endpoint URL] field.
  3. Enter a secret token in the [Secret Token] field. Choose a long random string — this is how your endpoint authenticates that deliveries genuinely come from Tymeslot.
  4. Click [Save]. Tymeslot immediately sends a test event to verify your endpoint is reachable. Check the [Delivery Logs] tab to see if it was received successfully.

Event Types

meeting.created

Meeting Created

Fired when an attendee completes a booking. This is the primary event for triggering downstream automation — CRM updates, calendar invites, Slack notifications, and similar. The payload includes full attendee details, meeting time, and the video conference URL if one was generated.

meeting.cancelled

Meeting Cancelled

Fired when a meeting is cancelled — by the host or by the attendee. The payload includes a cancelled_by field indicating which party initiated the cancellation (host or attendee). Use this to decide whether to send an apology email, update a CRM record, or free up a resource.

meeting.rescheduled

Meeting Rescheduled

Fired when a meeting is moved to a new date or time. The payload includes both the original scheduled time (under previous_start_time) and the new time (under start_time), so you can update downstream records correctly.

Request Headers

Every webhook delivery includes these headers:

X-Tymeslot-Token: <your-configured-secret-token>
Content-Type: application/json
User-Agent: Tymeslot-Webhook/1.0
X-Webhook-ID: <webhook-configuration-id>
X-Delivery-ID: <unique-per-delivery-attempt-id>
X-Tymeslot-Token

Your configured secret token. Verify this on every request before processing the payload — reject anything that does not match.

Content-Type

Always application/json. Parse the body as JSON.

User-Agent

Always Tymeslot-Webhook/1.0. Useful for filtering in access logs but not a security mechanism.

X-Webhook-ID

The ID of the webhook configuration that triggered this delivery. Useful when you have multiple webhooks configured and want to route deliveries differently.

X-Delivery-ID

A unique identifier for this delivery attempt. Different on each retry of the same event. Use this for idempotency — store delivery IDs you have successfully processed and skip reprocessing if the same ID arrives again.

Payload Structure

All events use the same envelope. The event field identifies the type; the data field carries the event-specific payload:

{
  "event": "meeting.created",
  "timestamp": "2026-03-01T10:00:00Z",
  "webhook_id": "wh_abc123",
  "data": {
    "meeting": {
      "id": "mtg_xyz789",
      "title": "30-Minute Consultation",
      "start_time": "2026-03-05T14:00:00Z",
      "end_time": "2026-03-05T14:30:00Z",
      "timezone": "Europe/Berlin",
      "status": "confirmed",
      "cancelled_by": null,
      "previous_start_time": null,
      "attendee": {
        "name": "Jane Smith",
        "email": "jane@example.com"
      },
      "host": {
        "name": "Alex Johnson",
        "username": "alex"
      },
      "location": {
        "type": "video",
        "url": "https://meet.google.com/abc-defg-hij"
      },
      "urls": {
        "view": "https://tymeslot.yourdomain.com/dashboard/meetings/mtg_xyz789"
      }
    }
  }
}

cancelled_by"host" or "attendee" for meeting.cancelled events; null otherwise.

previous_start_time — the original time before rescheduling for meeting.rescheduled events; null otherwise.

location.url — present only when a video conference link was generated; omitted for in-person or custom locations.

All timestamps are ISO 8601 in UTC. Apply the timezone field when displaying times to users.

Verifying the Token

Always compare the X-Tymeslot-Token header against your expected secret before processing any payload. Use a constant-time string comparison — a naive equality check (===) is vulnerable to timing attacks that could allow an attacker to guess your token one character at a time.

Examples in common languages:

// Node.js
const crypto = require('crypto');

function isValidToken(received, expected) {
  const a = Buffer.from(received);
  const b = Buffer.from(expected);
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}
# Python
import hmac

def is_valid_token(received: str, expected: str) -> bool:
    return hmac.compare_digest(received, expected)
<?php
// PHP
function is_valid_token(string $received, string $expected): bool {
    return hash_equals($expected, $received);
}

Reject Requests With a Missing or Invalid Token

Return a 401 response immediately if the X-Tymeslot-Token header is absent or does not match. Do not process the payload at all. Without this check, anyone who discovers your webhook URL can inject arbitrary events into your system.

Handling Retries — Idempotency

Because Tymeslot retries failed deliveries, your endpoint may receive the same event more than once. Design your handler to be idempotent — processing the same delivery twice should produce the same result as processing it once.

The simplest approach: store every X-Delivery-ID you successfully process in a database or cache with a short TTL (72 hours covers the full retry window). On each incoming request, check whether the delivery ID was already processed. If it was, return 200 immediately without re-executing the handler logic.

Delivery ID Is Per Attempt, Not Per Event

The X-Delivery-ID changes with each retry attempt. Store it after successfully processing, not before — if your handler fails partway through, the same ID will arrive again on retry and you should reprocess it.

Retry Schedule

A delivery is considered failed when your endpoint returns a non-2xx status code, returns a 3xx redirect, or does not respond within 10 seconds. Failed deliveries are retried on this schedule:

Attempt 1 Immediate
Attempt 2 1 minute after the previous failure
Attempt 3 5 minutes after the previous failure
Attempt 4 30 minutes after the previous failure
Attempt 5 2 hours after the previous failure

After 5 failed attempts, the delivery is marked as permanently failed. You can manually retry individual deliveries from [Dashboard][Settings][Webhooks][Delivery Logs].

Delivery Log Retention

Webhook delivery logs are retained for 60 days and then automatically purged. If you need a permanent audit trail, store the event payloads in your own database when your endpoint processes them.

Delivery Logs

The delivery log is your primary debugging tool. To access it:

  1. Go to [Dashboard][Settings][Webhooks].
  2. Click [Delivery Logs] next to the webhook you want to inspect.
  3. Each row shows the event type, delivery time, HTTP status code your endpoint returned, and the full response body.
  4. Click any row to see the complete request payload that was sent.
  5. Click [Retry] on a failed delivery to resend it immediately.

When debugging a failed integration, start here — the response body column often shows the exact error your endpoint returned.

Troubleshooting

Endpoint returns 200 but deliveries keep retrying

Your endpoint may be returning a redirect (3xx). Tymeslot does not follow redirects — a 301 or 302 is treated as a failure. Ensure your endpoint URL is the final destination URL, not one that redirects. Check the [Delivery Logs] — the status code column will show the 3xx your endpoint returned.

All deliveries show as failed immediately

Check your endpoint's SSL certificate. Tymeslot rejects self-signed certificates and certificates from untrusted CAs. Use a certificate from a public CA (Let's Encrypt, ZeroSSL, or your cloud provider's managed certificate). The [Delivery Logs] response body will typically show an SSL error message.

Deliveries succeed but events are being processed twice

Implement idempotency using the X-Delivery-ID header as described in the "Handling Retries" section above. Store processed delivery IDs and skip reprocessing on duplicates.

Test event delivered successfully but real events do not arrive

The test event is sent immediately when you save the webhook. Real events are queued and delivered asynchronously. If real events are not arriving, check whether your Tymeslot instance's background job worker (Oban) is running. Also confirm the webhook is still active — navigate to [Dashboard][Settings][Webhooks] and verify the webhook shows as Active.

Frequently Asked Questions

How do I verify that a webhook request is genuinely from Tymeslot?

Tymeslot sends your configured secret token verbatim in the X-Tymeslot-Token header on every delivery. On your endpoint, read that header and compare it to the secret you configured — if the values do not match, reject the request with a 401 and do not process the payload.

Always use a constant-time comparison rather than a plain equality check. A timing-safe comparison prevents attackers from inferring your token character by character by measuring how long the comparison takes:

// Node.js
const received = req.headers['x-tymeslot-token'];
const expected = process.env.WEBHOOK_SECRET;
const a = Buffer.from(received ?? '');
const b = Buffer.from(expected);
const valid = a.length === b.length && crypto.timingSafeEqual(a, b);
My webhook endpoint receives events but the token check always fails — why?

The most common cause is a mismatch between the secret you saved in Tymeslot and the value your endpoint is comparing against. Check for:

  • Leading or trailing whitespace in the secret — copy it from your environment variable or secrets manager carefully, not by hand.
  • A stale environment variable — if you recently rotated the secret in Tymeslot, make sure the new value is also deployed to your endpoint's environment.
  • URL-encoding artefacts — if the token contains special characters, ensure it is stored and compared as the raw string, not a URL-encoded form.

To rule out configuration issues quickly, use Tymeslot's [Delivery Logs] to send a test delivery and inspect the exact headers that were sent.

Tymeslot is retrying webhook deliveries — how do I make it stop?

Tymeslot retries a delivery whenever your endpoint does not return a 2xx HTTP status code, or does not respond within 10 seconds. To stop retries, ensure your endpoint:

  • Returns a 200 OK (or any other 2xx status) as the final HTTP response — not a 3xx redirect, which Tymeslot treats as a failure.
  • Responds within 10 seconds — if your processing is slow, acknowledge the delivery immediately with 200 and process the payload in a background job.
  • Does not crash before it flushes the response — unhandled exceptions that close the connection before a status code is sent will be treated as a timeout.
I need to process webhooks asynchronously — how should I handle this?

Acknowledge the webhook immediately, then process the event in a background job. The pattern is:

  1. Receive the request and verify the X-Tymeslot-Token header.
  2. Persist the raw payload to a queue or database table.
  3. Return 200 OK immediately — before any slow work begins.
  4. Process the payload in a background worker at your own pace.

This prevents Tymeslot from treating your endpoint as slow or unresponsive while still giving you time to handle complex operations like CRM updates or outbound API calls.

Are webhook payloads guaranteed to be delivered in order?

No. Tymeslot delivers events as they occur, but retries on failure can cause earlier events to arrive after later ones. For example, a meeting.rescheduled event that was retried three times may arrive after a meeting.cancelled event for the same meeting.

To handle out-of-order delivery correctly:

  • Use the timestamp field in the payload envelope to determine which event is more recent.
  • Use the X-Delivery-ID header to detect and skip duplicate deliveries of the same attempt.
  • Model your data so that applying an older event on top of a newer state is a safe no-op rather than a destructive overwrite.

Verification Checklist

Confirm each item before considering your webhook integration live:
  • Webhook added in [Dashboard][Settings][Webhooks] with an HTTPS endpoint URL and a secret token
  • Test event appeared in [Delivery Logs] with a 200 status code
  • Your endpoint verifies X-Tymeslot-Token using a constant-time comparison before processing
  • Your endpoint stores X-Delivery-ID values and skips reprocessing duplicates
  • Your endpoint responds with 200 within 10 seconds (processes slow work asynchronously)
  • A real test booking was placed and the meeting.created event arrived at your endpoint with the correct payload
  • Your endpoint's SSL certificate is from a public CA (not self-signed)

🔗 Related Articles

Read n8n Automation

n8n Automation

Connect Tymeslot to n8n via webhooks. Automate your scheduling workflows, sync CRM data, and send notifications.

Read Google Calendar Integration

Google Calendar Integration

Sync Tymeslot with Google Calendar. Availability checks, booking creation, and conflict detection — all automatic.

Read Outlook Calendar Integration

Outlook Calendar Integration

Sync Tymeslot with Outlook Calendar. Works with personal Outlook.com accounts and Microsoft 365 work accounts.