Webhooks and Events Reference
LockMyCal can send HTTP POST requests to URL endpoints you define, in real time, whenever an event occurs in the booking system.
Supported event types (Event Types)
| Event | Trigger |
|---|---|
meeting.created |
A client successfully created a new booking (or the time was approved by the organizer). |
meeting.cancelled |
The meeting was cancelled by the client or the host. |
meeting.rescheduled |
The date or time of an existing booking changed (also after a rescheduling is approved again). |
meeting.requested |
A new booking is awaiting approval by the organizer. |
meeting.declined |
The organizer rejected the booking request. |
meeting.request_expired |
The booking request expired without a decision. |
HTTP request headers
Every webhook request contains the following HTTP headers:
Content-Type: application/json
User-Agent: Lockmycal-Webhooks/1.0
X-Lockmycal-Timestamp: 2026-08-30T14:00:00Z
X-Lockmycal-Token: your_configured_security_token
X-Lockmycal-Delivery-Id: 1234
Verifying authenticity (Security Token)
LockMyCal does not use an HMAC signature scheme — verification is done by simply comparing a shared secret token:
- When creating a webhook in the dashboard (Automation → Webhooks), enter your own Security Token (any sufficiently strong string).
- On your server, when you receive a request, compare the value of the
X-Lockmycal-Tokenheader with the token you set. - If the values don't match (or the header is missing), reject the request — it is not a valid call from LockMyCal.
JSON payload structure (meeting.created)
{
"event": "meeting.created",
"timestamp": "2026-08-30T14:00:00Z",
"webhook_id": "42",
"data": {
"meeting": {
"id": 1234,
"uid": "a1b2c3d4-...",
"title": "Strategy consultation",
"summary": "Strategy consultation",
"description": null,
"start_time": "2026-09-01T10:00:00+02:00",
"end_time": "2026-09-01T11:00:00+02:00",
"duration": 60,
"status": "confirmed",
"meeting_type": "Strategy consultation",
"location": "Google Meet",
"organizer": {
"name": "Jan Novák",
"email": "jan.novak@yourdomain.com",
"title": null,
"user_id": 7
},
"attendee": {
"name": "Petr Svoboda",
"email": "petr.svoboda@client.com",
"phone": "+420777123456",
"company": "ACME s.r.o.",
"timezone": "Europe/Prague",
"message": null,
"attachments": [
{
"filename": "zadani.pdf",
"content_type": "application/pdf",
"byte_size": 183204
}
]
},
"guests": [
{
"email": "jana.dvorakova@client.com",
"name": "Jana Dvořáková",
"status": "accepted",
"responded_at": "2026-08-30T15:10:00Z"
}
],
"urls": {
"view": "https://yourdomain.com/.../view",
"reschedule": "https://yourdomain.com/.../reschedule",
"cancel": "https://yourdomain.com/.../cancel",
"meeting": "https://meet.google.com/abc-defg-hij"
},
"video": {
"enabled": true,
"room_id": "abc-defg-hij",
"organizer_url": "https://meet.google.com/abc-defg-hij",
"attendee_url": "https://meet.google.com/abc-defg-hij",
"created_at": "2026-08-30T14:00:01Z",
"expires_at": null
},
"created_at": "2026-08-30T14:00:00Z",
"updated_at": "2026-08-30T14:00:00Z"
}
}
}
Note
For the client's attachments, the attendee.attachments field contains only the file name, type and size – no download link. The files are private and the organiser downloads them from the dashboard.
Note
Answers to custom form questions (Intake Questions) and payment details are not part of the webhook payload — for this information, use the booking detail in the dashboard.
Handling retries and idempotency
If your endpoint server returns a status code other than 2xx (or doesn't respond within 10 seconds), LockMyCal automatically retries the delivery with an exponential delay (up to 5 attempts).
We recommend using the X-Lockmycal-Delivery-Id header (the delivery ID: the same for all retry attempts of one delivery and different for every other delivery) to ensure idempotent processing in your systems – a receiver that stores it can discard a second copy.
LockMyCal follows at most 5 redirects and verifies each of them; the token is not sent when redirecting to a different domain.