Webhook Events

Our Webhooks allow you to extend the Vagaro platform beyond the built-in feature set through detailed payloads when key events occur on the platform.

Webhook Event Triggers

When a webhook trigger is triggered, a POST request will be made to the URL configured in your webhook object along with a JSON payload specific for the event type.

Event TypeDescriptionActions
appointment When an appointment is created, updated, or deletedcreated, updated, deleted
customer When an customer is updated, attached to a new business, or removed from a businessupdated
formResponseWhen a form response submission has been madecreated
transactionWhen a transaction is createdcreated

event object

Each webhook event trigger will contain a standard event body

Field nameDescriptionJSON TypeData Type
idThe unique ID of the event. May be used to ensure that an event is not processed twice in the case of a webhook that is re-tried due to an error or timeout.string
createdDateA timestamp signifying when the event was generated.
Format: YYYY-MM-DDThh:mm:ss[.SSS]Z
Note: millisecond is denoted as optional [.SSS]
stringdatetime
typeEvent type:
appointment
customer
formResponse
transaction
string
actionEvent action:
created
updated
deleted
string
payloadThe payload of the event. The contents of this object depend on the type of event.objectpayload

Example

{
    "id": "254FA623-D2B0-4785-A07D-A1A7059C74FF",
    "createdAt": "2024-02-15T00:00:00Z",
    "type": "appointment",
    "action": "created",
    "payload": {
        . . .
        . . .
        . . .      
    }
}

payload object

Each event will contain a payload object. The contents of the payload object will depend on the type of event.

Examples

{
	"id": "254FA623-D2B0-4785-A07D-A1A7059C74FF",
	"createdDate": "2024-02-15T00:00:00Z",
	"type": "appointment",
	"action": "created",
	"payload": {
		"appointmentId": "2dwfErtmMAFxe6hoCnQStw==",
		"startTime": "2024-02-15T05:25:00Z",
		"endTime": "2024-02-15T06:25:00Z",
		"bookingStatus": "Confirmed",
		"serviceTitle": "Color & Haircut",
		"serviceId": "PqiJDBWJ4tHFpnSHPZpy~w==",
		"calendarEventId": null,
		"appointmentCount": 1,
		"amount": 0.0,
		"customerId": "2dwfErtmMAFxe6hoCnQStw==",
		"eventType": "Service",
		"onlineVsInhouse": "Online",
		"appointmentTypeCode": "NR",
		"appointmentTypeName": "New Request",
		"bookingSource": "Vagaro Marketplace",
		"serviceProviderId": "2dwfErtmMAFxe6hoCnQStw==",
		"businessId": "U2FsdGVkX18zRbwyUxRZaHNTYGwjKCpDdAkKP4eUDsE=",
		"businessAlias": "Vagaro Salon Studios",
		"businessGroupId": "tYKEZF-L445YEDnCx0TIfA==",
		"serviceCategory": "Hair Care",
		"createdDate": "2023-07-10T08:50:00Z",
		"createdBy": "GVkX18zRbwyUxRZaHNTYGwjK",
		"modifiedDate": null,
		"modifiedBy": null,
		"formResponseIds": [
			"Tkhj89234jadkjal23rnjlasfdsakjlewtewt234fw4="
		]
	}
}
{
    "id": "254FA623-D2B0-4785-A07D-A1A7059C74FF",
    "createdDate": "2024-03-15T00:00:00Z",
    "type": "customer",
    "action": "updated",
    "payload": {
        "customerId": "4CB231BAD3B26B7DE53FE5832A54A7B1",
        "businessIds": ["U2FsdGVkX18zRbwyUxRZaHNTYGwjKCpDdAkKP4eUDsE="],
        "customerFirstName": "Johnny",
        "customerLastName": "Smith",
        "businessGroupId": "tYKEZF-L445YEDnCx0TIfA==",
        "email": "[email protected]",
        "mobilePhone": "9145551212",
        "dayPhone": "",
        "nightPhone": "",
        "streetAddress": "498 Edgecombe Avenue Manhattan",
        "city": "New York",
        "regionCode": "NY",
        "regionName": "New York",
        "countryCode": "US",      
        "countryName": "United States of America",      
        "postalCode": "10030",
        "createdDate": "2023-07-10T08:50:00Z",
        "createdBy": "GVkX18zRbwyUxRZaHNTYGwjK",
        "modifiedDate": "2023-08-10T08:50:00Z",
        "modifiedBy": "GVkX18zRbwyUxRZaHNTYGwjK"
    }
}
{
	"id": "254FA623-D2B0-4785-A07D-A1A7059C74FF",
	"createdDate": "2024-02-15T00:00:00Z",
	"type": "transaction",
	"action": "created",
	"payload": {
		"transactionDate": "2024-02-12T14:37:43.5Z",
		"businessId": "U2FsdGVkX18zRbwyUxRZaHNTYGwjKCpDdAkKP4eUDsE=",
		"transactionId": "a--PdjdyYWJSkudXA2BFK0TkRV7gN2yxC=",
		"userPaymentId": "ZOpfSwCHhVSl1UZJ2p3Pfw==",
		"userPaymentMstId": "ZOpfSwCHhVSl1UZJ2p3Pfw==",
		"brandName": "",
		"itemSold": "Color & Haircut",
		"purchaseType": "Service",
		"quantity": 1,
		"ccAmount": 0.0,
		"cashAmount": 0.0,
		"checkAmount": 0.0,
		"achAmount": 0.0,
		"bankAccountAmount": 0.0,
		"vagaroPayLaterAmount": 0.0,
		"otherAmount": 0.0,
		"pointsAmount": 0,
		"packageRedemption": 0.0,
		"gcRedemption": 0.0,
		"tax": 0.0,
		"tip": 0.0,
		"discount": 0.0,
		"memberShipAmount": 0.0,
		"productDiscount": 0.0,
		"ccType": "",
		"ccMode": "",
		"customerId": "681550E7A9CDA57700B419E351D50D80",
		"serviceProviderId": "D5532D70624D433AD5EA6B5B7A2E5D31",
		"businessGroupId": "tYKEZF-L445YEDnCx0TIfA==",
		"amountDue": 0.0,
		"appointmentId": "2dwfErtmMAFxe6hoCnQStw==",
		"serviceCategory": "Hair Care",
		"createdBy": "GVkX18zRbwyUxRZaHNTYGwjK"
	}
}
{
	"id": "254FA623-D2B0-4785-A07D-A1A7059C74FF",
	"createdDate": "2024-02-15T00:00:00Z",
	"type": "formResponse",
	"action": "created",
	"payload": {
		"responseId": "Tkhj89234jadkjal23rnjlasfdsakjlewtewt234fw4=",
		"formId": "U2FsdGVkX18zRbwyUxRZaHNTYGwjKCpDdAkKP4eUDsE=",
		"customerId": "681550E7A9CDA57700B419E351D50D80",
		"businessId": "U2FsdGVkX18zRbwyUxRZaHNTYGwjKCpDdAkKP4eUDsE=",
		"businessGroupId": "tYKEZF-L445YEDnCx0TIfA==",
		"appointmentId": "2dwfErtmMAFxe6hoCnQStw==",
		"membershipId": "344sdSGDE837Hhhs==",
		"formTitle": "Intake form",
		"formPublishedDate": "2023-02-15T00:00:00Z",
		"questionsAndAnswers": [
			{
				"id": 3341,
				"order": 1,
				"questionType": "short_answer",
				"question": "Are you allergic to any hair products?",
				"answer": [
					"No"
				]
			},	
			{
				"id": 5478,
				"order": 2,
				"questionType": "multiple_choice",
				"question": "How would you describe your hair?",
				"answer": [
					"long",
					"curly",
					"oily"
				]
			},
			{
				"id": 5478,
				"order": 3,
				"questionType": "scale",
				"question": "How would you rate your previous appointment?",
				"answer": [
					"8"
				]
			},
			{
				"id": 5478,
				"order": 4,
				"questionType": "contact_information",
				"question": "Please provide your contact information.",
				"answer":[
					"John",
					"",
					"4430 Rosewood Drive, Dublin, CA 94568",
					"[email protected]",
					"+1(123)456-7890",
					"male",
					"",
					""			
				]
			}	
		]
	}
}

1. Set up an HTTP endpoint in your application that can accept webhook requests via a POST method

Configure an HTTPS endpoint in your application to receive webhook request via the POST method.

Ensure that your endpoint can process POST request containing a JSON payload and promptly return a 2xx success response within 20 seconds.

If a 2xx response is not received within 20 seconds, our system will assume a delivery failure and will retry up 5 times over a period of 15 minutes using an exponential backoff strategy.


2. Create a webhook subscription

To create a webhook subscription, login to your Vagaro account and go to Settings -> Developers -> APIs & Webhooks. If this is the first time you are viewing this page, you will need to click Contact Us to fill out the request form so our team can reach out to you. Someone on our team will contact you within 2 business days.

Note that Developer Configuration Access Level is required to view and modify the webhook subscription configuration.


3. Securing webhook endpoint

Verification Token

We recommend that your application verifies the source of incoming webhook requests before processing events. This is optional but recommended to prevent bad actors from engaging in unauthorized activities on your server.

When you subscribe to a webhook in Vagaro, we will provide you with a verification token. This verification token will be included in the X-Vagaro-Signature request header.

Whitelist Outbound IP Address Range

Additionally, you can whitelist the following outbound IP address range to prevent bad actors from engaging in unauthorized activities on your server.

  • 20.220.12.83
  • 13.67.143.68
  • 13.70.105.4
  • 20.62.123.184
  • 51.140.65.108
  • 51.143.95.2

4. Retry Policy

A webhook call will be attempted up to 5 times over a 15 minute window. The attempts will happen at an exponentially increasing interval if the target responds with anything but a success (2XX) or a non-recoverable error. If no response is received within 20 seconds, the call will be considered a failure and will also be reattempted.

Non-recoverable Errors

The following status codes are deemed to be non-recoverable and Vagaro Webhook Events will not reattempt a call when receiving a response with them:

  • 400: The target exists, but can’t process the payload.
  • 401: The target is behind authentication or doesn’t recognize the webhook secret.
  • 403: Vagaro Webhook events should not be calling the target.
  • 404: The target doesn’t exist.
  • 406: The target exists, and rejected the webhook intentionally.

Best practices

Only subscribe to webhooks events that your application needs

This will help reduce the amount of webhook events that your server needs to process

Ensure that your event handlers are idempotent

Because our system processes events concurrently, duplicate events may occur. Each webhook event is sent with a unique id property, by storing these unique ID's your application can determine whether an event has already been processes.

Return a 2xx response promptly

Your server should respond with a 2xx status code to confirm the successful receipt of a webhook event. If it does not, Vagaro will continue retrying to send the webhook to your application. This may affect future webhook deliveries and Vagaro may deactivate your webhook subscription.

Handle events asynchronously

Delivery order of events is not guaranteed, we recommend to use the event payload's createdDate property, which indicates when the event occurred.


Webhooks Changelog

This changelog lists only significant changes, not all changes, to the Vagaro developer platform. It includes changes made to the Webhook Events platform

📘

Webhooks Changelog


What’s Next