Webhooks
Webhooks let you hook into events that happen throughout the Wistia platform.
Webhooks let you know about events that happen in Wistia as they occur. Want to send an alert as soon as a prospect fills out a Turnstile? Perhaps get new stats pushed from Wistia into your custom dashboard as people watch your videos? Well then, you and webhooks will be fast friends.
Want to use webhooks, but hate the technical aspect of setting them up? Good news! Check out our Zapier section for all of the details.
Overview
When you have a webhook configured for a particular event in Wistia, we'll send a HTTP POST request to the URL of your choice anytime that event occurs, containing the data you'll want about what happened. That's it!
To configure a new webhook, head to the Webhooks section of your Account Settings. Or, read on for more information about the available event types and the structure of the data.
Request Format
Headers
The POST request to your webhooks consumer will contain the following headers:
Header | Description |
---|---|
Host | The URL of your consumer, which you provide when configuring a webhook. |
User-Agent | Wistia-Webhooks/{VERSION}. The current version is 0.0.47. |
X-Wistia-Signature | An HMAC hexdigest of the POST body, computed using the secret_key provided when configuring the webhook. You should be using a sha256 HMAC hexdigests. |
Content-Type | The output format will always be JSON, so this will always be application/json . |
Content-Length | The byte length of the request body. |
Example Signature Generation
payload_body = request.body.read
secret_key = SECRET_KEY_AS_DEFINED_IN_WISTIA
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret_key, payload_body)
Request Body
Within the body of the request, there will always be two things: a hook
(containing a uuid
for that webhook message), and an array of events
. Note that even if there's only a single event, it will always be contained in an events
array. Within that array, each event will have the following fields:
Field | Description |
---|---|
uuid | A universally-unique ID for this instance of the event. You should only pay attention to the first instance. |
type | The type of event, like media.updated |
generated_at | When the event occurred in Wistia. This is always in ISO-8601 format, and always in UTC. |
payload | These are the data you're looking for. |
The Payload
The payload for each event contains the data about what happened, and the object that it happened to. The structure for each event type is may vary to include relevant information. Check out the events list for details on each one.
Example POST
POST /to HTTP/1.1
Host: where.im.going
User-Agent: Wistia-Webhooks/{VERSION}
X-Wistia-Signature: 23948kwer9ewrkj2340981aszxcmnvie
Content-Type: application/json
Content-Length: ...
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e67f16e673a000",
"type": "media.updated",
"payload": {
"media": {
"url": "https://dave.wistia.com/medias/f5diqltruh",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/21d23d756f30711e7a5e66815d7d74900515ba29.jpg?image_crop_resized=200x120"
},
"name": "Cakes on cakes on cakes",
"id": "f5diqltruh",
"duration": 7.676
},
"project": {
"id": "some-hashed-id",
"name": "Folder Name",
},
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:53:15Z"
}]
}
NoteThe "duration" value is displayed in seconds.
Events
Tip
Webhooks are currently available for the following events in Wistia. We plan on adding more, so please let us know if you don't see the event you want listed here. Also let us know if you do see the event you want, but it doesn't provide the data you need.
List of Events
- media.created
- media.processing
- media.ready
- media.failed
- media.updated
- media.deleted
- viewing_session.play
- viewing_session.percent_watched
- viewing_session.turnstile.converted
- viewing_session.call_to_action.converted
- viewing_session.annotation.converted
media.created
The media.created
event occurs when a media is created.
Payload structure
Field | Description |
---|---|
media | The media object |
Example delivery
{
"hook": {
"uuid": "a4ab9eb6-ab82-4dae-86f2-29f744f7d031"
},
"events": [
{
"uuid": "fc53f8f78b67d04d455029813f8ec1ef",
"type": "media.created",
"payload": {
"media": {
"duration": 40.207,
"id": "vpe2p82q64",
"name": "Lenny Delivers Video!",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e96ea382701bc172657d90bf269211beddbf6f7f.jpg?image_crop_resized=200x120"
},
"url": "https://harper.wistia.com/medias/vpe2p82q64"
},
"project": {
"id": "some-hashed-id",
"name": "Folder Name",
},
},
"metadata": {
"account_id": "0sxav1wj8o"
},
"generated_at": "2024-03-31T21:56:45Z"
}
]
}
media.processing
The media.processing
event occurs when processing is started.
Payload structure
Field | Description |
---|---|
media | The media object |
Example delivery
{
"hook": {
"uuid": "a4ab9eb6-ab82-4dae-86f2-29f744f7d031"
},
"events": [
{
"uuid": "fc53f8f78b67d04d455029813f8ec1ef",
"type": "media.processing",
"payload": {
"media": {
"duration": 40.207,
"id": "vpe2p82q64",
"name": "Lenny Delivers Video!",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e96ea382701bc172657d90bf269211beddbf6f7f.jpg?image_crop_resized=200x120"
},
"url": "https://harper.wistia.com/medias/vpe2p82q64"
},
"project": {
"id": "some-hashed-id",
"name": "Folder Name",
},
},
"metadata": {
"account_id": "0sxav1wj8o"
},
"generated_at": "2024-03-31T21:56:45Z"
}
]
}
media.ready
The media.ready
event occurs when processing is complete and all dependent video and image assets have been successfully encoded. The media is ready for playback.
Payload structure
Field | Description |
---|---|
media | The media object |
Example delivery
{
"hook": {
"uuid": "a4ab9eb6-ab82-4dae-86f2-29f744f7d031"
},
"events": [
{
"uuid": "fc53f8f78b67d04d455029813f8ec1ef",
"type": "media.ready",
"payload": {
"media": {
"duration": 40.207,
"id": "vpe2p82q64",
"name": "Lenny Delivers Video!",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e96ea382701bc172657d90bf269211beddbf6f7f.jpg?image_crop_resized=200x120"
},
"url": "https://harper.wistia.com/medias/vpe2p82q64"
}
},
"metadata": {
"account_id": "0sxav1wj8o"
},
"generated_at": "2024-03-31T21:56:45Z"
}
]
}
media.failed
The media.failed
event occurs when processing has failed.
Payload structure
Field | Description |
---|---|
media | The media object |
Example delivery
{
"hook": {
"uuid": "a4ab9eb6-ab82-4dae-86f2-29f744f7d031"
},
"events": [
{
"uuid": "fc53f8f78b67d04d455029813f8ec1ef",
"type": "media.failed",
"payload": {
"media": {
"duration": 40.207,
"id": "vpe2p82q64",
"name": "Lenny Delivers Video!",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e96ea382701bc172657d90bf269211beddbf6f7f.jpg?image_crop_resized=200x120"
},
"url": "https://harper.wistia.com/medias/vpe2p82q64"
}
},
"metadata": {
"account_id": "0sxav1wj8o"
},
"generated_at": "2024-03-31T21:56:45Z"
}
]
}
media.updated
A media is updated when its title, description, or thumbnail image changes. These can all be changed through the UI on the media's page in your Wistia account, or through the Data API.
Payload structure
Field | Description |
---|---|
media | The media object |
previous_attributes | The attribute(s) that got updated, and what they were previously |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e6729eecb3a000",
"type": "media.updated",
"payload": {
"media": {
"url": "https://dave.wistia.com/medias/l9dqljgtfy",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/aa2863d2bf45cf2cc5c325d129e80bd5c0055883.jpg?image_crop_resized=200x120"
},
"name": "Lenny Eating Peanuts",
"id": "l9dqljgtfy",
"duration": 71.912
},
"project": {
"id": "some-hashed-id",
"name": "Folder Name",
},
"previous_attributes": {
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e04d7729a8b83f4fdd52e107b980f5594359bb45.jpg?image_crop_resized=200x120"
}
}
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:10:13Z"
}]
}
media.transcript_updated
A media's transcript is updated when new captions are generated - either automated or human-generated. We'll also send the language code for which caption was updated in case you'd like to grab the transcript via the Captions Show endpoint.
Payload structure
Field | Description |
---|---|
media | The media object |
transcript.language_code | The language code for the transcript that was updated |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca0142000e7"
},
"events": [{
"uuid": "09e6729eecb3a010",
"type": "media.transcript_updated",
"payload": {
"media": {
"url": "https://dave.wistia.com/medias/l9dqljgtfy",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/aa2863d2bf45cf2cc5c325d129e80bd5c0055883.jpg?image_crop_resized=200x120"
},
"name": "Lenny Eating Peanuts",
"id": "l9dqljgtfy",
"duration": 71.912
},
"project": {
"id": "some-hashed-id",
"name": "Folder Name",
},
"transcript": {
language_code: "eng",
},
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:10:13Z"
}]
}
media.deleted
Payload structure
Field | Description |
---|---|
media | The media object that was deleted |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e67f16f873a000",
"type": "media.deleted",
"payload": {
"media": {
"id": "f5diqltruh"
},
"project": {
"id": "some-hashed-id",
"name": "Folder Name",
},
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:57:05Z"
}]
}
viewing_session.play
The viewing_session.play
event occurs when a person presses play on a video for the first time per visit to a page, or the video autoplays.
Payload structure
Field | Description |
---|---|
visitor | The visitor object, containing the visitor's ID |
viewing_session | Object containing the ID of the viewing_session. |
media | The media object |
Note
In the Stats API, what's referred to as the
viewing_session
here is currently just called anevent
.viewing_session
will be the name in v2 of our API 🔮.
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e7b27100b3a000",
"type": "viewing_session.play",
"payload": {
"visitor": {
"id": "v20150227_c651bc81-8ec8-445b-b8a0-878d19278d35"
},
"viewing_session": {
"id": "v20150225_e17a7db7-da7d-4d56-b5a8-ce6a9b62a800"
},
"media": {
"url": "https://dave.wistia.com/medias/l9dqljgtfy",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e04d7729a8b83f4fdd52e107b980f5594359bb45.jpg?image_crop_resized=200x120"
},
"name": "Lenny Eating Peanuts",
"id": "l9dqljgtfy",
"duration": 71.912
}
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-31T13:59:22Z"
}]
}
viewing_session.percent_watched
As a person watches a video, the percent_watched
increases. This event will get triggered when the percent_watched
reaches each of four major thresholds: 25%, 50%, 75%, and 100%.
Payload structure
Field | Description |
---|---|
visitor | The visitor who watched the video |
viewing_session | The viewing_session object |
percent_watched | The percent_watched threshold reached |
media | The media object |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e67473ecb3a000",
"type": "viewing_session.percent_watched",
"payload": {
"visitor": {
"id": "v20150227_bee7121c-04bb-42ae-abc9-5327f536df0f"
},
"viewing_session": {
"id": "v20150225_52967e29-8196-42d8-9dc6-952c1d9ec87f"
},
"percent_watched": 25,
"media": {
"url": "https://dave.wistia.com/medias/mmgzi8h6yh",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/23c4846eecd462beab57a508dff7f052a5faf065.jpg?image_crop_resized=200x120"
},
"name": "Lenny Eating Peanuts",
"id": "mmgzi8h6yh",
"duration": 71.912
}
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:14:01Z"
}]
}
viewing_session.turnstile.converted
A visitor was tagged with an email address, and potentially their first and last name, by entering their information into Turnstile.
Payload structure
Field | Description |
---|---|
visitor | The visitor object for the visitor who submitted their information to Turnstile |
viewing_session | The viewing_session object |
name | The name of the visitor, if provided |
media | The media object for the media the Turnstile is on |
The email address of the visitor |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e7b61ae133a000",
"type": "viewing_session.turnstile.converted",
"payload": {
"visitor": {
"id": "v20150227_e38e365e-77e2-41e2-b521-0723fca11b06"
},
"viewing_session": {
"id": "v20150225_85d3bf5d-a60b-42fe-a5e6-b0e0eb1645f3"
},
"name": "Lenny Lavigne",
"media": {
"url": "https://dave.wistia.com/medias/l9dqljgtfy",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/e04d7729a8b83f4fdd52e107b980f5594359bb45.jpg?image_crop_resized=200x120"
},
"name": "Lenny Eating Peanuts",
"id": "l9dqljgtfy",
"duration": 71.912
},
"email": "[email protected]"
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-31T14:03:04Z"
}]
}
viewing_session.call_to_action.converted
If your video has a Call To Action, this event will fire when the visitor clicks on it.
Payload structure
Field | Description |
---|---|
visitor | The visitor object for the visitor who clicked the CTA |
viewing_session | The viewing_session object |
url | The URL that the CTA points to |
media | The media object for the media the CTA is on |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e67b56f1b3a000",
"type": "viewing_session.call_to_action.converted",
"payload": {
"visitor": {
"id": "v20150227_199a749f-db0c-4d0b-84b1-cabe496be192"
},
"viewing_session": {
"id": "v20150225_3783d72c-3834-4d0f-bc7b-c624c437e3a6"
},
"url": "https://wistia.com",
"media": {
"url": "https://dave.wistia.com/medias/9xa4r4b4z0",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/d01f7a9a38dd3e9308098e8fce11b2b09567935d.jpg?image_crop_resized=200x120"
},
"name": "Cakes on cakes on cakes",
"id": "9xa4r4b4z0",
"duration": 7.676
}
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:26:01Z"
}]
}
viewing_session.annotation.converted
Payload structure
Field | Description |
---|---|
visitor | The visitor who clicked the Annotation link |
viewing_session | The viewing_session in which the visitor clicked the Annotation Link |
url | The URL the Annotation Link points to |
media | The media object for the media the Annotation Link is on |
Example delivery
{
"hook": {
"uuid": "bb812395-8d23-4285-9278-9ca014209ae7"
},
"events": [{
"uuid": "09e679f29c73a000",
"type": "viewing_session.annotation.converted",
"payload": {
"visitor": {
"id": "v20150227_199a749f-db0c-4d0b-84b1-cabe496be192"
},
"viewing_session": {
"id": "v20150225_3783d72c-3834-4d0f-bc7b-c624c437e3a6"
},
"url": "https://wistia.com",
"media": {
"url": "https://dave.wistia.com/medias/9xa4r4b4z0",
"thumbnail": {
"url": "https://embed-ssl.wistia.com/deliveries/d01f7a9a38dd3e9308098e8fce11b2b09567935d.jpg?image_crop_resized=200x120"
},
"name": "Cakes on cakes on cakes",
"id": "9xa4r4b4z0",
"duration": 7.676
}
},
"metadata": {
"account_id": "8lq25o0p9c"
},
"generated_at": "2024-03-30T15:23:45Z"
}]
}
Ordering, Batching, and Uniqueness
We aim to ensure that every webhooks message is sent by Wistia and received by your consumer at least once. Since the order in which your consumer receives the messages cannot be guaranteed, and Wistia might send the same message multiple times in rare cases (say, the wait for a 200 OK response from your consumer exceeds the 10 second request timeout limit), each event
in a message's body will specify a uuid
and a generated_at
timestamp. Your consumer should use this data to determine the proper order and uniqueness of events. If multiple received events have the same uuid
, they're the same exact event, and it's safe to ignore all but one of them.
If multiple events occur within a very short timeframe, we'll batch them together into a single POST to avoid making an unreasonable amount of requests to your consumer. In such cases, the events
array in the request body will contain multiple events.
Connecting to Zapier Example
Note
Custom webhooks are not available on all Zapier Plans. Before you get started be sure that your Zapier account supports them.
One of the easiest ways to use Wistia's webhooks is to set up a zap with Zapier. You can begin by setting up your own Zapier account and selecting create zap. You'll see an option to Choose a Trigger App. Within that option, select Webhooks.
On the next screen, select the Catch Hook option.
From here, you'll need to Pick off a Child Key. For this step, you'll want to add events.payload
into the text box. Then click "Continue."
Zapier will then generate a catch URL (Your webhook URL) that you'll need to copy into your Wistia account. In the Webhooks section of your Account Settings, paste the catch URL in the box labeled POST URL. You will also need to enter a Secret Key (it can be whatever you want).
Next up, select the events you're interested in sending to your zap. Check the events section above for the full breakdown.
Hit that Submit button, and head back to Zapier.
After that, you'll get an option to test your webhook. Click "Test Trigger."
To trigger the webhook, you'll want to watch one of your videos in an incognito or private browsing window. That should prompt a message indicating that Zapier is successfully receiving the webhook. Woohoo! 🎯
Now that the webhook is working, you'll have the opportunity to set up the action Zapier takes upon receiving the webhook from Wistia, and can set it up with various apps.
In the "Set up action" section, you'll be able to choose the various information from the webhook you'd like to display.
After that, you'll be all set to receive your own custom webhooks!
Updated about 1 month ago