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:

StatusEventDescription
succeededcompletedThe prediction has been completed.
failedfailedThe prediction has failed.
canceledcanceledThe 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

POST
/v1/predict
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"]
    }
  }'

NOTIFY/your-webhook-url

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.

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

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

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

php
if (hash_equals($expected_signature, $signature)) {
    // The signature is valid
}

Was this page helpful?