Notifications & webhooks
Use webhooks to customize your customers experience or integrate Timekit with your own organization.
What is a webhook?
You can use webhooks to be notified about changes that happens to a booking. If there are any changes to a booking Timekit will let you know about that change.
How to set up a webhook?
You can setup and configure your webhooks from the Admin Dashboard under API settings.
When to use webhooks?
Webhooks are great when you want to control the customer experience and flow by implementing other services or processes in your customer experience. For example if you have payments as part of your service setup.
You can hook into any state change in a booking on Timekit, so if you want to be notified when a booking is created, confirmed or cancelled by customer you should use webhooks. Lets say you want to post to Slack every time you get a new booking for your project "Sales Demo", you can setup a webhook on Timekit to notify Zapier and you will tell Zapier to post something in Slack.
We have an article about setting up Timekit + Zapier here: http://help.timekit.io/working-with-the-api/send-custom-emails-and-other-notifications-with-webhooks-via-zapier
Webhook payload
The webhook you'll receive will contain most of the relevant booking associated info you need. If there's anything else you need, you have to make a subsequent API call to retrieve it.
Here's the included payload data:
Native fields:
- id
- state (the state the webhook is configured for, which is the state the booking entered when the webhook fired)
- graph
- completed
- created_at
- updated_at
- action (the name of the action that moved the booking into this state, for example
confirm) - what, where, description, start, end, rsvp and allDay (once the booking has a calendar event)
Related models (included by default):
- event
- calendar
- customers
- attributes
- user
- project
- location
- meta
- available_actions
- customer_action_links
- owner_booking
The set of related models can be changed per webhook with its include setting, which takes a comma-separated list like the include query parameter on the bookings endpoints.
An example
Let's look over an example webhook from Timekit. This is the data that you get from Timekit about a single booking:
json{
"id": "b3c99d95-6a46-4957-b30e-bfc929efabc3",
"state": "confirmed",
"graph": "instant",
"completed": false,
"created_at": "2017-12-05T10:13:17+0000",
"updated_at": "2017-12-05T10:13:18+0000",
"rsvp": "accepted",
"what": "Doc. Emmett Brown x Marty McFly",
"where": "TBD",
"description": "Comment: If my calculations are correct, when this baby hits 88 miles per hour...",
"allDay": false,
"end": "2017-12-05T15:00:00+0000",
"start": "2017-12-05T14:00:00+0000",
"action": "confirm",
"customers": [{
"id": "de64b2f7-cdbd-4929-94e8-5813e5a44367",
"name": "Marty McFly",
"email": "mcfly@timekit.io",
"phone": "",
"voip": "",
"timezone": "America/Los_Angeles",
"meta": "{}"
}],
"event": {
"id": "18b9d750-7ca7-4275-afed-15f7a6a3c54b",
"what": "Doc. Emmett Brown x Marty McFly",
"where": "TBD",
"description": "Comment: If my calculations are correct, when this baby hits 88 miles per hour...",
"rsvp": "accepted",
"allDay": false,
"start": "2017-12-05T14:00:00+0000",
"end": "2017-12-05T15:00:00+0000",
"created_at": "2017-12-05T10:13:17+0000",
"updated_at": "2017-12-05T10:13:24+0000"
},
"calendar": {
"id": "f30c9c39-317c-4a28-915e-66a0abeabf09",
"provider_id": "doc@timekit.io",
"provider_access": "owner",
"provider_primary": true,
"provider_sync": true,
"name": "doc@timekit.io",
"description": null,
"foregroundcolor": "#1d1d1d",
"backgroundcolor": "#4986e7",
"created_at": "2015-05-12T03:49:11+0000",
"updated_at": "2017-12-05T10:13:24+0000",
"provider": "google"
},
"attributes": {
"customer": {
"comment": "If my calculations are correct, when this baby hits 88 miles per hour...",
"email": "mcfly@timekit.io",
"name": "Marty McFly",
"timezone": "Europe\/Madrid"
},
"event": {
"calendar_id": "f30c9c39-317c-4a28-915e-66a0abeabf09",
"description": "Comment: If my calculations are correct, when this baby hits 88 miles per hour...",
"end": "2017-12-05T16:00:00+01:00",
"invite": true,
"my_rsvp": "accepted",
"participants": ["mcfly@timekit.io"],
"start": "2017-12-05T15:00:00+01:00",
"sync_provider": true,
"what": "Doc. Emmett Brown x Marty McFly",
"where": "Hill Valley"
},
"event_info": {
"calendar_id": "f30c9c39-317c-4a28-915e-66a0abeabf09",
"description": "Comment: If my calculations are correct, when this baby hits 88 miles per hour...",
"end": "2017-12-05T15:00:00+0000",
"participants": ["doc@timekit.io"],
"start": "2017-12-05T14:00:00+0000",
"what": "Doc. Emmett Brown x Marty McFly",
"where": "Hill Valley"
}
},
"user": {
"id": "14ac45d1-5e38-4d1c-9cb9-4fcaa447fa97",
"first_name": "Doc. Emmett",
"last_name": "Brown",
"name": "Doc. Emmett Brown",
"email": "doc@timekit.io",
"image": "https:\/\/lh5.googleusercontent.com\/-9gtmiFGk5Q4\/AAAAAAAAAAI\/AAAAAAAAABk\/-qnPdiM7I2M\/photo.jpg",
"timezone": "America/Los_Angeles",
"created_at": "2015-05-12T03:48:59+0000",
"updated_at": "2017-07-05T16:19:45+0000"
}
}
This data contains info about the booking (current state, created_at, etc), the customer (name, email etc), the event (start, end etc).
Best practices
When you receive a webhook you need to respond with a 200, 201 or 204 HTTP status code to acknowledge that you have successfully received the webhook. Any other status code, including other 2xx codes, counts as a failure.
Failed webhooks are not retried automatically. If your endpoint returns an unexpected status code or cannot be reached, the webhook is recorded as failed straight away and the app owner is notified by email (at the app's webhook notification email address if one is set, otherwise at the app creator's email address). Make sure your endpoint responds quickly and reliably, and use the API to fetch the booking if you need to recover from a missed webhook.