webhooks.md
Webhooks
Webhooks let your integration react to MK.IO events as they happen. Rather than polling jobs, live events, or streaming locators on a timer, you register a webhook rule and receive an HTTP POST request whenever a subscribed event fires. Webhook rules belong to the Management API.
How a webhook rule works
A rule belongs to a project and defines where to deliver events, whether delivery is on, and which events trigger it:
url: the target for thePOSTrequest.enabled: whether the rule delivers.events: the event types that trigger the rule.headersandqueryParams: non-sensitive request decoration.authentication.headersandauthentication.queryParams: sensitive values, such as a shared secret.
The configuration endpoint is /api/v1/projects/{project_name}/webhook/rules. For the create, edit, and delete calls, see Webhook rules.
The events you can subscribe to
| Event | Use it to |
|---|---|
MediaKind.JobStarted |
Track when a job leaves the queue and begins processing. |
MediaKind.JobFinished |
Trigger downstream work when a job reaches a terminal state. |
MediaKind.StreamingLocatorCreated |
React when newly published content is ready. |
MediaKind.ChannelInstanceStarted |
Track live channel startup. |
MediaKind.ChannelInstanceStopped |
Track live channel shutdown. |
MediaKind.ChannelInstanceError |
Alert on live channel failures. |
MediaKind.ScheduledOperationAccepted |
Observe scheduled work entering the pipeline. |
MediaKind.ScheduledOperationOngoing |
Track scheduled work in progress. |
MediaKind.ScheduledOperationCompleted |
Trigger follow-up work after a scheduled operation finishes. |
MediaKind.ScheduledOperationError |
Alert on scheduled-operation failures. |
Scheduled operation events are available only when that feature is enabled for the organization.
The delivered payload
MK.IO delivers events in the CloudEvents format. Every payload has the same envelope:
{
"specversion": "1.0",
"id": "<unique_id>",
"type": "<event_type>",
"source": "<object_url>",
"time": "<event_time>",
"datacontenttype": "application/json",
"data": {
"projectName": "<project_name>",
"previousState": "<state before this event>",
"state": "<new state>",
"resource": {}
}
}
The data.resource object holds the full resource, exactly as a GET on source would return it. The data.previousState and data.state fields tell you which transition fired the event:
| Event | previousState |
state |
|---|---|---|
MediaKind.JobStarted |
Queued |
Processing |
MediaKind.JobFinished |
Processing |
Finished, Canceled, or Error |
MediaKind.StreamingLocatorCreated |
Creating |
Created |
What webhooks change in your design
Without webhooks, a client creates a resource, then polls a GET or /state endpoint until the resource reaches a terminal state, handling retry timing and rate limits along the way. With webhooks the flow becomes:
- Create the resource.
- Return control to the user or job runner.
- Wait for the event that reports the state change.
- Retrieve the resource only when you need fresh detail.
This is most valuable for jobs and live workflows, where the wait can be long and unpredictable.
A useful first rule
For a Video On Demand (VOD) workflow, the smallest useful subscription is MediaKind.JobStarted and MediaKind.JobFinished, which signal when a job begins and when it reaches a terminal state. For live workflows, start with MediaKind.ChannelInstanceStarted, MediaKind.ChannelInstanceStopped, and MediaKind.ChannelInstanceError.
Authentication fields are write-only
A rule separates general request decoration from sensitive values. headers and queryParams carry general fields. authentication.headers and authentication.queryParams carry secret or authentication values. Fields under authentication are write-only: when you read a saved rule back, those values appear masked rather than in clear text.
Build a handler that survives retries
If a delivery fails, MK.IO retries it. Your endpoint should therefore handle duplicate deliveries safely:
- Make event handling idempotent where possible.
- Log the event
id,type, andsource. - Return a success response as soon as you have safely accepted the event.
Treat the endpoint as a security surface. Serve it over HTTPS, pass a shared secret through the authentication fields, and verify that secret in your handler before acting on a payload.
When a direct read is still the right tool
Webhooks suit asynchronous workflows, but they do not replace every read. Use a direct GET when a user asks for the current state now, when you need to list resources on demand, or when the resource has no event coverage. The strongest integrations combine both: webhooks for change notification, and API reads for current detail.