Webhooks
In this guide, we will look at how to register and consume webhooks to integrate your app with Skytells. With webhooks, your app can know when something happens in Skytells, such as a video generation is completed or when an async task is completed.
By default, Skytells will send webhooks to the webhook URL you provided when you create a Prediction and specify the webhook URL in the webhook
object within your request.
Schema
The webhook request schema can be attached to the Prediction request body.
- Name
webhook.url
- Description
The URL to send the webhook to.
- Name
webhook.events
- Description
The events to listen for.
Webhook Object
{
"webhook": {
"url": "https://your-webhook-url.com/webhook",
"events": ["completed", "failed", "started"]
}
}
Events
By having the webhook object in the request body, Skytells triggers the webhook events when the prediction status changes.
Webhook events are triggered when the prediction status changes to the following statuses:
Status | Event | Description |
---|---|---|
succeeded | completed | The prediction has been completed. |
failed | failed | The prediction has failed. |
canceled | canceled | The prediction has been canceled. |
Prediction with Webhook
Here's an example of a prediction with the webhook object attached:
- Name
webhook.url
- Type
- string
- Description
The URL to send the webhook to.
- Name
webhook.events
- Type
- array
- Description
The events to listen for.
- Name
model
- Type
- string
- Description
The model to use for the prediction.
- Name
safety_checker
- Type
- boolean
- Description
Whether to use the safety checker.
- Name
stream
- Type
- boolean
- Description
Whether to stream the prediction.
- Name
gpu
- Type
- string
- Description
The GPU to use for the prediction.
- Name
input
- Type
- object
- Description
The input to the prediction.
Request
curl -X POST "https://api.skytells.ai/v1/predict" \
-H "x-api-key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"model": "truefusion",
"safety_checker": true,
"stream": false,
"gpu": "H100",
"input": {
"prompt": "A man sitting on a computer",
"aspect_ratio": "1:1"
},
"webhook": {
"url": "https://example.com/webhook",
"events": ["succeeded", "failed"]
}
}'
Notifications
The webhook is required
for video generation.
For each prediction status change, your server will receive the complete Prediction via the URL you provided. The webhook payload will contain the same structure as the prediction response, including output URLs to the generated video.
Configure your webhook endpoint to properly handle and process these notifications, Store your videos in a secure location as soon as you receive the webhook notification. Skytells does not retain data more than 5 minutes after a prediction is completed. Implementing proper error handling and retry logic is recommended.
Your webhook receives the updated prediction object even when the prediction status changes.
Security
For security reasons, we recommend you to use a secure webhook URL that is not publicly accessible.
However, Skytells attaches a verification signature to the webhook notification to ensure that the notification is authenticly sent from Skytells and not intercepted by a third party.
You may verify the signature by comparing the X-Skytells-Signature
header with the expected signature.
The expected signature is calculated using the HMAC-SHA256
algorithm and the secret key SKYTELLS_WEBHOOK_SECRET
provided in your dashboard if you're using our Enterprise API.
Enterprise Signature Verification
function verify_signature($payload, $signature) {
$secret = 'your_skytells_webhook_secret';
$expected_signature = hash_hmac('sha256', $payload, $secret);
// Use hash_equals to prevent timing attacks
return hash_equals($expected_signature, $signature);
}
Otherwise, if you're using our General API, the signature is calculated using the HMAC-SHA256
hash with salted x-api-key.
General Signature Verification
$payload = json_encode($payload);
$signature = hash_hmac('sha256', $payload, $x_api_key);
// Replace $x_api_key with your API key
Important Security Practices
- Never expose it in frontend code, public repos, or browser logs.
- Always use
hash_equals()
to compare the signatures instead of==
or===
to avoid timing attacks.
Hash Comparison
if (hash_equals($expected_signature, $signature)) {
// The signature is valid
}