Skip to main content
Webhooks

Using webhooks to keep track of events that happen inside of your Zenbooker account

Updated over a year ago

Overview

Note: Webhooks are an advanced feature used for connecting multiple apps together. Webhooks are mainly for developers, so don't worry if you're not using them.

Webhooks are notifications sent over the web containing data about your jobs and recurring bookings. These notifications are sent to your HTTP endpoints. You define a URL and the type of event that Zenbooker should send notifications for. When an event that you've created a webhook for happens, Zenbooker will make a POST request with relevant data attached in a JSON payload. 

To get started with webhooks, go to Settings > Webhooks from your Zenbooker admin. 

Events

When configuring a webhook, you select the type of event you would like to receive payloads for. You can only specify one event type per webhook, but you can create multiple webhooks for the same endpoint URL for each event type you need.

Job created  job.created  
Triggered whenever a new job is created. Including jobs created from the Zenbooker admin, booked by customers, and jobs created as part of a recurring booking.

Job rescheduled  job.rescheduled  
Triggered whenever a customer or a staff member reschedules a job. Also triggered when a recurring booking's frequency is edited, and upcoming jobs in the recurring series are automatically rescheduled.

Job canceled  job.canceled  
Triggered whenever a customer or a staff member cancels a job. Also triggered when an upcoming job is canceled due to a recurring booking being canceled.

Job assigned job.service_providers.assigned
Triggered whenever service providers are assigned or unassigned to an existing job. The trigger does not activate when service providers are assigned while creating a new job in the Zenbooker admin.

Job marked en-route job.enroute
Triggered whenever a job is marked as en-route.

Job started job.started
Triggered whenever a job is marked as In Progress or when the Start Job button is clicked.

Job completed job.completed
Triggered whenever a job is marked as Complete

Recurring booking created  recurring_booking.created  
Triggered whenever a new recurring booking is created.

Recurring booking canceled  recurring_booking.canceled
Triggered whenever a recurring booking is canceled.

Quote request created quote_request.created
Triggered whenever a customer submits a quote request form.

Payloads

Each event type has a specific payload format with the relevant event information in the data field of the body. In addition to the data object, all webhooks contain the following fields:

  • event  The event type that triggered this notification.

  • account  The Zenbooker account ID of the business where the event occurred.

  • webhook_id  The ID of the webhook configuration that this notification belongs to.

  • retry_count The number of times Zenbooker has tried to resend this webhook if the first attempt failed.

To learn more about the data attributes for different events, review these API references:

Job object ↗

Recurring booking object (documentation coming soon)

Responding to a webhook payload

Your webhook endpoint must return a 2xx status code to acknowledge the receipt of a webhook event. Any other status code as a response will be treated as a delivery failure and Zenbooker will attempt to resend the webhook.

Webhook retries

If an attempt to deliver a webhook fails, Zenbooker will make up to 4 more attempts to send the webhook payload (at increasing intervals). If all of these attempts fail, Zenbooker will disable the webhook, and send you an email to inform you of it.


Example delivery for job events

{{
  "type": "notification_event",
  "event": "job.canceled",
  "account": "1571029397034x364427806567301100",
  "webhook_id": "1571081549517x624940525773914100",
  "data": {
    "start_date": "2019-11-13T00:00:00.000Z",
    "end_date": "2019-11-13T02:45:00.000Z",
    "time_slot": {
      "type": "arrival_window",
      "name": "11:00 AM - 1:00 PM",
      "start_time": "11:00",
      "end_time": "13:00",
      "arrival_window_length": 2
    },
    "rescheduled": false,
    "canceled": true,
    "status": "scheduled",
    "created_by": "staff",
    "timezone": "Australia/Melbourne",
    "location": {
      "address": "434 Lygon St, Brunswick East VIC 3057, Australia",
      "unit": "B2",
      "lat": -37.764464,
      "lng": 144.973149
    },
    "duration_seconds": 9900,
    "service_name": "Handyman Services",
    "job_fields": [
      {
        "field_type": "service_modifier",
        "field_name": "Hanging things",
        "field_id": "1571070716577x396825217377501200",
        "input_method": "checkboxes",
        "order": 1,
        "editable_quantity": true,
        "selected_options": [
          {
            "text": "TV Mounting",
            "id": "1571070716577x494955286296789000",
            "parent_section_id": "1571070716577x396825217377501200",
            "metadata_value": null,
            "price": 100,
            "quantity": 2,
            "total_price": 200,
            "duration": 2700,
            "total_duration": 5400
          },
          {
            "text": "Picture/fine art hanging",
            "id": "1571070803683x735663189819129900",
            "parent_section_id": "1571070716577x396825217377501200",
            "metadata_value": null,
            "price": 119,
            "quantity": 1,
            "total_price": 119,
            "duration": 2700,
            "total_duration": 2700
          }
        ]
      },
      {
        "field_type": "service_modifier",
        "field_name": "Interior",
        "field_id": "1571070924929x295284963700637700",
        "input_method": "radio_buttons",
        "order": 3,
        "editable_quantity": false,
        "selected_options": [
          {
            "text": "Interior Door Repair: hinges, closing, etc",
            "id": "1571071022450x346495445726658560",
            "parent_section_id": "1571070924929x295284963700637700",
            "comments": null,
            "price": 125,
            "quantity": 1,
            "total_price": 125,
            "duration": 0,
            "total_duration": 0
          }
        ]
      },
      {
        "field_type": "intake",
        "field_name": "Pictures?",
        "field_id": "1571071048844x786265051788214300",
        "input_method": "image_upload",
        "order": 4,
        "editable_quantity": false,
        "selected_options": [
          {
            "image": "https://s3.amazonaws.com/...png",
            "parent_section_id": "1571071048844x786265051788214300",
            "comments": "This is a photo of the broken thing"
          }
        ]
      },
      {
        "field_type": "service_modifier",
        "field_name": "Custom Line items",
        "input_method": "custom_line_item",
        "order": 99,
        "editable_quantity": false,
        "selected_options": [
          {
            "text": "early bird service fee",
            "id": "1571382447070x565300114523422700",
            "price": 19,
            "quantity": 1,
            "total_price": 19,
            "duration": 0,
            "total_duration": 0
          }
        ]
      }
    ],
    "job_notes": "Call when on the way. First time customer",
    "job_number": "#002202-4",
    "service_territory": "1571029455936x927426070375515900",
    "id": "1571382643450x202948477110764130",
    "customer": {
      "name": "Fiona Apple",
      "phone": "+6134343434",
      "email": "[email protected]",
      "accepts_sms": false,
      "accepts_email": true,
      "notes": "no relation to the computer company"
    },
    "recurring_booking": {
      "is_recurring": true,
      "recurring_frequency_name": "Weekly",
      "recurring_interval_days": 7,
      "job_instance": 4,
      "recurring_booking_id": "1571382547065x870725811325131500"
    },
    "service_providers": [
      "1571029440829x796978779967228800"
    ],
    "invoice": {
      "subtotal": 528,
      "discount_amount": 52.8,
      "coupon_amount": null,
      "total_tax": 0,
      "total_price": 475.2,
      "stripe_customer_id": null,
      "paid": false
    }
  }
}


Did this answer your question?