Creating a webhook
Introduction
💡Webhook service integration allows Spir to send POST requests to specified URLs upon specific events.
- Integrating with applications like Zapier, IFTTT, etc.
It enables integrating various services through APIs.
- Example: Integrating with Salesforce upon event confirmation
While Spir defaults to sending email notifications to the organizer and attendees upon event confirmation, leveraging webhook enables integration with external services.
- Example: Integrating with Salesforce upon event confirmation
Configuration
💡
Event Types
- Event Confirmation (event.confirmed)
- Event Cancellation (event.canceled)
- Form Answer (form.answered)
Preparation of Webhook URL
- HTTPS communication
- localhost URLs not supported
- IP addresses not supported
- https://example.com/callback-confirmed
Limit on the Number of Webhook URL Settings
Request
Response
💡When the configured Webhook URL receives a request from Spir, please return a response with status code 200.
- When the Webhook URL returns HTTP responses with status codes 3xx, 4xx, or 5xx
- When there's a timeout connecting to the system (requests time out after 30 seconds)
- Retry every 10 seconds up to 4 times
- Notify errors after the final unsuccessful request
Error Notification Content
- Notification Method: Email notification
- Recipients: All team administrators
- Email Title
【Spir】Webhook Transmission Failed
- Email Notification Content
Title for managing availability URLWebhook URLTime of transmissionTransmission logs including HTTP responses(Transmission logs will be included as attachments.)
Request Body
Event Confirmation (event.confirmed)
Response Body
| Property Name | Data Type | Required | Description |
webhookEventName |
string | true | Event type of the webhook. |
webhookEventId |
string | ture | Unique id for each webhook event. |
payload |
Object | true |
Payload Object
| Property Name | Data Type | Required | Description |
originalUrl |
string | true | Availability URL used for confirmation. Can be used to uniquely identify the availability URL. |
privateTitle |
string | true | Title used for managing the availability URL used for confirmation. |
confirmedAt |
string | true | Date and time when the schedule was confirmed (not the date and time of the confirmed schedule). |
title |
string | true | Title of the schedule. |
startDateTime |
string | true | Start date and time of the schedule. |
endDateTime |
string | true | End date and time of the schedule. |
timeZone |
string | true | Timezone of the schedule confirmant. |
organizer |
Object | true | Organizer of the schedule (organizer set in the availability URL). |
attendeesFromOrganizerSide |
Array | true | Attendees from the organizer's side of the schedule. |
invitee |
Object | true | Confirmer of the schedule (individual who received the availability URL and selected the schedule). |
attendeesFromInviteeSide |
Array | true | Attendees from the confirmer's side of the schedule. |
onlineMeeting |
Object | true | Schedule's video call details. |
formAnswers |
Array | true | Responses to forms set in the availability URL. |
utmParameters |
Object | false | UTM Parameters If the schedule was confirmed with UTM parameters, the payload will contain their values. |
source |
Object | false | Stores the environment data captured upon schedule confirmation. |
Payload.source Object
| Property Name | Data Type | Required | Description |
url |
Object | false | Contains URL-related information. |
Payload.source.url Object
| Property Name | Data Type | Required | Description |
query |
String | true | Query parameters from the URL at confirmation. Max 2000 characters. |
Json Sample
{
"webhookEventName": "event.confirmed",
"webhookEventId": "tp7mPJVl0oOULa9hOIM80",
"payload": {
"originalUrl": "https://app.spirinc.com/t/xxx/as/xxx/confirm",
"privateTitle": "URL for Sales Discussion",
"confirmedAt": "2023-07-01T12:00:00Z",
"startDateTime": "2023-07-05T12:00:00Z",
"endDateTime": "2023-07-05T13:00:00Z",
"timeZone": "Asia/Tokyo",
"title": "Sales Discussion",
"organizer": {
"name": "Hiroki Ito",
"email": "hiroki.ito@example.com"
},
"attendeesFromOrganizerSide": [
{
"name": "Go Yamada",
"email": "go.yamadaa@example.com"
}
],
"invitee": {
"name": "Shohei Nakazima",
"email": "syohei.nakazima@example.com",
"language": "JA"
},
"attendeesFromInviteeSide": [
{
"name": "Mitsuru Sawada",
"email": "mitsuru.sawada@example.com"
}
],
"onlineMeeting": {
"type": "zoom",
"url": "https://zoom~",
"password": "abcd1234"
},
"formAnswers": [
{
"questionId": "xxx1",
"question": "name",
"answer": "Shohei Nakazima"
},
{
"questionId": "xxx2",
"question": "email",
"answer": "syohei.nakazima@example.com"
},
{
"questionId": "xxx3",
"question": "Company Name",
"answer": "Acme Inc."
},
{
"questionId": "xxx4",
"question": "Phone Number",
"answer": "08012345678"
}
],
"utmParameters": {
"utmSource": "test",
"utmCampaign": "campaign test",
"utmMedium": "medium test",
"utmTerm": "term test",
"utmContent": "test content"
},
"source": {
"url": {
"query": "?utm_source=test&utm_campaign&utm_medium=medium%20test&utm_term=term%20test&utm_content=test%20content"
}
}
}
}
Event Cancellation (event.canceled)
Response Body
| Property Name | Data Type | Required | Description |
webhookEventName |
string | true | Event type of the webhook. |
webhookEventId |
string | ture | Unique id for each webhook event. |
payload |
Object | true |
Payload Object
| Property Name | Data Type | Required | Description |
originalUrl |
string | true | Availability URL used for confirmation. Can be used to uniquely identify the availability URL. |
privateTitle |
string | true | Title used for managing the availability URL used for confirmation. |
confirmedAt |
string | true | Date and time when the schedule was confirmed (not the date and time of the confirmed schedule). |
title |
string | true | Title of the schedule. |
startDateTime |
string | true | Start date and time of the schedule. |
endDateTime |
string | true | End date and time of the schedule. |
timeZone |
string | true | Timezone of the schedule. |
organizer |
Object | true | Organizer of the schedule (organizer set in the availability URL). |
attendeesFromOrganizerSide |
Array | true | Attendees from the organizer's side of the schedule. |
invitee |
Object | true | Confirmer of the schedule (individual who received the availability URL and selected the schedule). |
attendeesFromInviteeSide |
Array | true | Attendees from the confirmer's side of the schedule. |
formAnswers |
Array | true | Responses to forms set in the availability URL. |
cancelReason |
string | true | Reason for schedule cancellation. |
canceledAt |
string | true | Date and time when the schedule was canceled. |
JSON Sample
jsonCopy code
{
"webhookEventName": "event.canceled",
"webhookEventId": "tp7mPJVl0oOULa9hOIM80",
"payload": {
"originalUrl": "https://app.spirinc.com/t/xxx/as/xxx/confirm",
"privateTitle": "Sales Discussion URL",
"confirmedAt": "2023-07-01T12:00:00Z"
"startDateTime": "2023-07-05T12:00:00Z",
"endDateTime": "2023-07-05T13:00:00Z",
"timeZone": "Asia/Tokyo",
"title": "Sales Discussion",
"organizer": {
"name": "Hiroki Ito",
"email": "hiroki.ito@example.com"
},
"attendeesFromOrganizerSide": [
{
"name": "Go Yamada",
"email": "go.yamadaa@example.com"
}
],
"invitee": {
"name": "Shohei Nakajima"
"email": "syohei.nakazima@example.com",
"language": "JA"
},
"attendeesFromInviteeSide": [
{
"name": "Mitsuru Sawada",
"email": "mitsuru.sawada@example.com"
}
],
"formAnswers": [
{
"questionId": "xxx1",
"question": "name",
"answer": "Shohei Nakajima"
},
{
"questionId": "xxx2",
"question": "email",
"answer": "syohei.nakazima@example.com"
},
{
"questionId": "xxx3",
"question": "Company Name",
"answer": "Acme Inc."
},
{
"questionId": "xxx4",
"question": "Phone Number",
"answer": "08012345678"
}
],
"cancelReason": "Had an urgent external meeting.",
"canceledAt": "2023-07-01T18:00:00Z"
}
}
Form Answer (form.answered)
This event is sent when a respondent submits a form with rules and the routing result has been determined.
Response Body
| Property Name | Data Type | Required | Description |
webhookEventName |
string | true | Event type of the webhook. |
webhookEventId |
string | ture | Unique id for each webhook event. |
payload |
Object | true |
Payload Object
| Property Name | Data Type | Required | Description |
originalUrl |
string | true | URL of the form with rules that was answered. Can be used to uniquely identify the form. |
privateTitle |
string | ture | Title used for managing the form with rules. |
answeredAt |
string | true | Date and time when the form was answered (ISO 8601). |
action |
Object |
true |
The next action determined by the routing result based on the answers. |
|
|
Object |
true |
The form respondent. |
|
|
Array |
true |
Form answers submitted by the respondent. |
Payload.action Object
The next action depends on the routing result. The properties included vary depending on the value of `type`.
| Property Name | Data Type | Required | Description |
|
|
string |
true |
Type of the routing destination. Either `team_availability_sharing` (redirect to an availability URL) or `message` (display a message). |
|
|
string |
false |
Set when `type` is `team_availability_sharing`. The public availability URL to redirect to. |
|
|
string |
false |
Set when `type` is `team_availability_sharing`. The management title of the destination availability URL. |
|
|
string |
false |
Message shown to the respondent. Required when `type` is `message`; optional when `type` is `team_availability_sharing`. |
Payload.respondent Object
| Property Name | Data Type | Required | Description |
name |
string | true | Name of the respondent. |
email |
string | ture |
Email address of the respondent. |
language |
string | true | Language setting of the respondent (e.g., `ja`). |
Payload.formAnswers Object (array element)
| Property Name | Data Type | Required | Description |
questionId |
string | true | Unique identifier of the question. |
question |
string | ture | Label of the question. `name` and `email` are fixed items; others are question texts set by the form creator. |
answer |
string | true | Answer to the question. |
Json Sample
{
"webhookEventName": "form.answered",
"webhookEventId": "tp7mPJVl0oOULa9hOIM80",
"payload": {
"originalUrl": "https://app.spirinc.com/t/xxx/r/xxx/answer",
"privateTitle": "Sales Discussion Routing Form",
"answeredAt": "2023-07-01T12:00:00Z",
"action": {
"type": "team_availability_sharing",
"url": "https://app.spirinc.com/t/xxx/as/xxx/confirm",
"privateTitle": "URL for Sales Discussion"
},
"respondent": {
"name": "Shohei Nakazima",
"email": "syohei.nakazima@example.com",
"language": "JA"
},
"formAnswers": [
{
"questionId": "xxx1",
"question": "name",
"answer": "Shohei Nakazima"
},
{
"questionId": "xxx2",
"question": "email",
"answer": "syohei.nakazima@example.com"
},
{
"questionId": "xxx3",
"question": "Company Name",
"answer": "Acme Inc."
},
{
"questionId": "xxx4",
"question": "Industry",
"answer": "Marketing"
},
{
"questionId": "xxx5",
"question": "Company Size",
"answer": "100-200 employees"
},
{
"questionId": "xxx6",
"question": "Inquiry Details",
"answer": "Inquiry about product introduction"
}
]
}
}