Webhooks
The Wellhub webhooks will notify you when specific events are triggered. This notification is an HTTP POST request to your registered URL.
This document describes both the events that are triggered along with the data they send and the API resources available for the webhooks.
General Information
Data format
Every API resource and push event uses JSON as its standard data format.
Security
When Wellhub sends an event notification to a registered webhook, we include a signature header so you know the request was sent from our servers. The header name is X-Gympass-Signature. We strongly recommend that you verify this signature when you receive a request at your webhook endpoint. This allows you to verify that the events were sent by Wellhub, not by a third party.
Before you can verify signatures, you need to provide your secret key to Wellhub Tech Sales.
Please note that the secret key has a max character limit of 100 characters
- Wellhub generates the signature by encoding the HTTP request body using your secret key.
- The encryption is done by HMAC-SHA-1 algorithm, and the body of the request will need to be stringified.
- Compare the signature string with the Wellhub header value. If they match, the message came from Wellhub servers.
- The signature string will always be Upper.
Below you will find several templates you can use to generate the hash script.
JavaScript || Java || C# || GO || PHP || Python
Retry
The response time is 1s. After that, if we have no response, we retry 3 times immediately after the missed response.
Booking Events
POST - booking.Requested
localhost:8080/gym-webhook-url/booking/requested
Triggered whenever a new booking request is made.
Request example1curl --location --request POST 'localhost:8080/gym-webhook-url/booking/requested' \2--header 'Content-Type: application/json' \3--header 'X-Gympass-Signature: 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D' \4--data-raw '{5 "event_type": "booking-requested",6 "event_data": {7 "user": {8 "unique_token": "123456789012",9 "name": "Firstname Lastname",10 "email": "user@email.com"11 },12 "slot": {13 "id": 01234567,14 "gym_id": 012345,15 "class_id": 654321,16 "booking_number": "BK_A1B2C3"17 },18 "timestamp": 1560983373378,19 "event_id": "7e8cbb0f-9681-4d3e-8c36-2b3dd6ecbadb"20 }21}'
Request Params
Name | Type | Description |
---|---|---|
event_type | String | Type of the event. For a booking request event, it defaults to "booking-requested" |
event_data.user.unique_token | String | The Wellhub ID for the user |
event_data.user.name | String | Name of the user who has originated the booking request. |
event_data.user.email | String | Email of the user who has originated the booking request. |
event_data.slot.id | Int | Id for the slot. |
event_data.slot.gym_id | Int | ID for the gym in which the booking is requested to. |
event_data.slot.booking_number | String | Identifier for the booking event. |
event_data._event_time | Long | Time when the event was generated. |
_event_id | String | ID for the event. |
Headers
Field | Description |
---|---|
Content-Type | application/json |
X-Gympass-Signature | 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D - This is an example |
Response
Response example1{2 "event_type": "booking-requested",3 "event_data": {4 "user": {5 "unique_token": "123456789012",6 "name": "Firstname Lastname",7 "email": "user@email.com"8 },9 "slot": {10 "id": 01234567,11 "gym_id": 012345,12 "class_id": 654321,13 "booking_number": "BK_A1B2C3"14 },15 "timestamp": 1560983373378,16 "event_id": "7e8cbb0f-9681-4d3e-8c36-2b3dd6ecbadb"17 }18}
POST - booking.Cancelation
localhost:8080/gym-webhook-url/booking/cancelation
Triggered whenever a user cancels a previously booked class.
Request Example1curl --location --request POST 'localhost:8080/gym-webhook-url/booking/cancelation' \2--header 'Content-Type: application/json' \3--header 'X-Gympass-Signature: 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D' \4--data-raw '{5 "event_type": "booking-canceled",6 "event_data": {7 "user": {8 "unique_token": "123456789012"9 },10 "slot": {11 "id": 01234567,12 "gym_id": 012345,13 "class_id": 654321,14 "booking_number": "BK_A1B2C3"15 },16 "timestamp": 1560983373378,17 "event_id": "7e8cab0f-9981-4d3e-8c36-2b3dd6ecbadb"18 }19}'
Event payload:
Name | Type | Description |
---|---|---|
event_type | String | Type of the event. For a booking cancellation event, it defaults to "booking-canceled" |
event_data.user.unique_token | String | The Wellhub ID for the user |
event_data.slot.id | Int | Id for the slot. |
event_data.slot.gym_id | Int | ID for the gym to which the booking is requested. |
event_data.slot.booking_number | String | Identifier for the booking event. |
_event_id String | ID | for the event. |
Headers
Field | Description |
---|---|
Content-Type | application/json |
X-Gympass-Signature | 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D - This is an example |
Response
Response example1{2 "event_type": "booking-canceled",3 "event_data": {4 "user": {5 "unique_token": "123456789012"6 },7 "slot": {8 "id": 01234567,9 "gym_id": 012345,10 "class_id": 654321,11 "booking_number": "BK_A1B2C3"12 },13 "timestamp": 1560983373378,14 "event_id": "7e8cab0f-9981-4d3e-8c36-2b3dd6ecbadb"15 }16}
POST - booking.LateCancelation
localhost:8080/gym-webhook-url/booking/lateCancelation
Triggered whenever a user cancels a previously booked class.
Request example1curl --location --request POST 'localhost:8080/gym-webhook-url/booking/lateCancelation' \2--header 'Content-Type: application/json' \3--header 'X-Gympass-Signature: 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D' \4--data-raw '{5 "event_type": "booking-late-canceled",6 "event_data": {7 "user": {8 "unique_token": "123456789012"9 },10 "slot": {11 "id": 01234567,12 "gym_id": 012345,13 "class_id": 654321,14 "booking_number": "BK_A1B2C3"15 },16 "timestamp": 1560983373378,17 "event_id": "7e8cab0f-9981-4d3e-8c36-2b3dd6ecbadb"18 }19}'
Event payload:
Name | Type | Description |
---|---|---|
event_type | String | Type of the event. For a booking cancellation event, it defaults to "booking-late-cancelled" |
event_data.user.unique_token | String | The Wellhub ID for the user |
event_data.slot.id | Int | Id for the slot. |
event_data.slot.gym_id | Int | ID for the gym to which the booking is requested. |
event_data.slot.booking_number | String | Identifier for the booking event. |
_event_id | String | ID for the event. |
Headers
Field | Description |
---|---|
Content-Type | application/json |
X-Gympass-Signature | 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D - This is an example |
Response
Response example1{2 "event_type": "booking-late-canceled",3 "event_data": {4 "user": {5 "unique_token": "123456789012"6 },7 "slot": {8 "id": 01234567,9 "gym_id": 012345,10 "class_id": 654321,11 "booking_number": "BK_A1B2C3"12 },13 "timestamp": 1560983373378,14 "event_id": "7e8cab0f-9981-4d3e-8c36-2b3dd6ecbadb"15 }16}
POST - checkin-booking-occurred
localhost:8080/gym-webhook-url/booking/checkin-booking-occurred
Triggered whenever a user checks in to a gym partner with a pending booked class.
Request example1curl --location --request POST 'localhost:8080/gym-webhook-url/booking/checkin-booking-occurred \2--header 'Content-Type: application/json' \3--header 'X-Gympass-Signature: 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D' \4--data-raw {5 "event_data": {6 "booking": {7 "booking_number": "BK_LRNLABC"8 },9 "user": {10 "unique_token": "1234567890123"11 },12 "location": {13 "lat": 33.9976708,14 "lon": -118.459719715 },16 "gym": {17 "id": 123456,18 "title": "Gym Name",19 "product": {20 "description": "Classes - Unlimited",21 "pass_type_number": 122 }23 },24 "timestamp": 1668090666,25 "expires_at": 166809606626 },27 "event_type": "checkin-booking-occurred"28}
Event payload:
Name | Type | Description |
---|---|---|
event_data.booking.booking_number | String | Identifier for the booking event. |
event_data.user.unique_token | String | The Wellhub ID for the user |
event_data.coordinates | Object | Contains the lat and long information for the gym where the check-in is being made. |
event_data.coordinates.lat | Double | Latitude for the gym where the check-in has taken place. |
event_data.coordinates.lon | Double | Longitude for the gym where the check-in has taken place. |
event_data.gym.id | Int | The gym ID for which the check-in refers. |
event_data.gym.title | String | The gym name for which the check-in refers. |
event_data.product | Object | Product details for which the check-in refers |
event_data.product.description | String | Product description |
pass_type_number | Int | Specifies what product the check-in is for |
timestamp | Long | Timestamp for the creation date of the event |
event_type | String | Type of the event. For check-ins with a corresponding booking. |
Headers
Field | Description |
---|---|
Content-Type | application/json |
X-Gympass-Signature | 0XFBDB1D1B18AA6C08324B7D64B71FB76370690E1D - This is an example |
Response
Response example1{2 "event_type": "booking-late-canceled",3 "event_data": {4 "user": {5 "unique_token": "123456789012"6 },7 "slot": {8 "id": 01234567,9 "gym_id": 012345,10 "class_id": 654321,11 "booking_number": "BK_A1B2C3"12 },13 "timestamp": 1560983373378,14 "event_id": "7e8cab0f-9981-4d3e-8c36-2b3dd6ecbadb"15 }16}
X-Gympass-Signature Scripts
JavaScript
SHA 1 HASH1const crypto = require('crypto');23// Your secret key provided by you4const secretKey = '*Secret Key*';56// Function to generate the x-gympass-signature7function generateGympassSignature(requestBody) {8 const hmac = crypto.createHmac('sha1', secretKey);9 hmac.update(requestBody);10 const signature = hmac.digest('hex');11 return signature.toUpperCase();12}1314// Example usage15const requestBody = JSON.stringify({ **Webhook event Body Payload** });1617const gympassSignature = generateGympassSignature(requestBody);1819console.log('Generated x-gympass-signature:', gympassSignature);
Java
SHA1 HASH1import javax.crypto.Mac;2import javax.crypto.spec.SecretKeySpec;3import java.nio.charset.StandardCharsets;4import java.security.InvalidKeyException;5import java.security.NoSuchAlgorithmException;67public class GympassSignatureGenerator {8 public static void main(String[] args) {9 // Your secret key provided by you10 String secretKey = "";1112 // Example request body13 String requestBody = "Webhook request body";1415 String gympassSignature = generateGympassSignature(requestBody, secretKey);1617 System.out.println("Generated x-gympass-signature: " + gympassSignature);18 }1920 public static String generateGympassSignature(String requestBody, String secretKey) {21 try {22 Mac hmacSha1 = Mac.getInstance("HmacSHA1");23 SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");24 hmacSha1.init(keySpec);25 byte[] hash = hmacSha1.doFinal(requestBody.getBytes(StandardCharsets.UTF_8));26 StringBuilder hexString = new StringBuilder();27 for (byte b : hash) {28 String hex = Integer.toHexString(0xFF & b);29 if (hex.length() == 1) {30 hexString.append('0');31 }32 hexString.append(hex);33 }34 return hexString.toString().toUpperCase();35 } catch (NoSuchAlgorithmException | InvalidKeyException e) {36 e.printStackTrace();37 }38 return null;39 }40}
C#
SHA 1 HASH1using System;2using System.Security.Cryptography;3using System.Text;45class Program6{7 static string GenerateGympassSignature(string requestBody, string secretKey)8 {9 using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey)))10 {11 byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(requestBody));12 return BitConverter.ToString(hash).Replace("-", "").ToUpper();13 }14 }1516 static void Main()17 {18 string secretKey = "*Secret Key*";19 string requestBody = "{**Webhook event Body Payload** }";2021 string gympassSignature = GenerateGympassSignature(requestBody, secretKey);2223 Console.WriteLine("Generated x-gympass-signature: " + gympassSignature);24 }25}
Go
SHA 1 HASH1package main23import (4 "crypto/hmac"5 "crypto/sha1"6 "encoding/hex"7 "fmt"8)910func generateGympassSignature(requestBody string, secretKey string) string {11 hmacSha1 := hmac.New(sha1.New, []byte(secretKey))12 hmacSha1.Write([]byte(requestBody))13 signature := hex.EncodeToString(hmacSha1.Sum(nil))14 return fmt.Sprintf("%s", signature)15}1617func main() {18 secretKey := "*Secret Key*"19 requestBody := `{**Webhook event Body Payload** }`2021 gympassSignature := generateGympassSignature(requestBody, secretKey)2223 fmt.Println("Generated x-gympass-signature:", gympassSignature)24}
PHP
SHA 1 HASH1<?php23function generateGympassSignature($requestBody, $secretKey) {4 $signature = hash_hmac('sha1', $requestBody, $secretKey);5 return strtoupper($signature);6}78$secretKey = '*Secret Key*';9$requestBody = '{**Webhook event Body Payload** }';1011$gympassSignature = generateGympassSignature($requestBody, $secretKey);1213echo 'Generated x-gympass-signature: ' . $gympassSignature;14?>
Python
SHA 1 HASH1import hmac2import hashlib34def generate_gympass_signature(request_body, secret_key):5 signature = hmac.new(secret_key.encode('utf-8'), request_body.encode('utf-8'), hashlib.sha1).hexdigest()6 return signature.upper()78secret_key = '*Secret Key*'9request_body = '{**Webhook event Body Payload** }'1011gympass_signature = generate_gympass_signature(request_body, secret_key)1213print('Generated x-gympass-signature:', gympass_signature)