Webhooks

Webhooks let you receive real-time notifications when an import, metadata, or transcription job completes. Instead of polling status endpoints repeatedly, your system is notified as soon as a job finishes successfully.

Webhooks fire only on successful completion. Failed jobs do not trigger a webhook. If you need to detect failures, poll the relevant status endpoint.

Configuring Webhooks

Include a webhookUrl in your API request (or set a default in your Importly dashboard). When the job completes successfully, Importly sends a single POST request to that URL with the result payload. Exactly one delivery attempt is made per job — there is no automatic retry.

Payload Structure

Every webhook has the same top-level shape:

json
1{
2 "success": true,
3 "data": {
4 "jobId": "abc123",
5 "type": "import",
6 "status": "completed",
7 "...": "result fields flattened here"
8 }
9}
  • success: Always true (webhooks are only sent for successful jobs).
  • data.jobId: Match this with your internal tracking.
  • data.type: The job type — import, metadata, basic-metadata, or transcribe.
  • data.status: Always completed.
  • The job's result fields are flattened directly into data — they are not nested under a result object.

Route your handler on data.type and data.status. There is no combined event string like import.completed.

Import Webhook

json
1{
2 "success": true,
3 "data": {
4 "jobId": "abc123",
5 "type": "import",
6 "status": "completed",
7 "mediaUrl": "https://cdn.importly.io/abc123/video.mp4",
8 "title": "Sample Video",
9 "duration": 314,
10 "thumbnailUrl": "https://cdn.importly.io/abc123/thumbnail.jpg",
11 "costInDollars": 0.078,
12 "fileSizeBytes": 52428800,
13 "filename": "video.mp4"
14 }
15}

Import Webhook with S3 Storage

When S3 storage is enabled, the payload also includes an s3Storage object:

json
1{
2 "success": true,
3 "data": {
4 "jobId": "abc123",
5 "type": "import",
6 "status": "completed",
7 "mediaUrl": "https://your-bucket.s3.us-east-1.amazonaws.com/videos/2024/my-video.mp4",
8 "title": "Sample Video",
9 "duration": 314,
10 "thumbnailUrl": "https://cdn.importly.io/abc123/thumbnail.jpg",
11 "costInDollars": 0.078,
12 "fileSizeBytes": 52428800,
13 "filename": "my-video.mp4",
14 "s3Storage": {
15 "url": "https://your-bucket.s3.us-east-1.amazonaws.com/videos/2024/my-video.mp4",
16 "bucket": "your-bucket",
17 "key": "videos/2024/my-video.mp4"
18 }
19 }
20}

Import Payload Fields

  • mediaUrl: Download location (S3 URL if S3 storage is enabled).
  • title: Media title.
  • duration: Duration in seconds.
  • thumbnailUrl: URL to the thumbnail image.
  • costInDollars: The final cost of the job in US dollars.
  • fileSizeBytes: File size in bytes.
  • filename: Downloaded file name.
  • s3Storage: S3 storage information (only present when S3 storage is enabled).
    • url: Full S3 URL to the uploaded file.
    • bucket: S3 bucket name.
    • key: S3 object key (path within the bucket).

Metadata Webhook

For full metadata jobs, data.type is metadata and the raw yt-dlp metadata (snake_case) is flattened into data:

json
1{
2 "success": true,
3 "data": {
4 "jobId": "xyz789",
5 "type": "metadata",
6 "status": "completed",
7 "id": "UF8uR6Z6KLc",
8 "title": "Sample Video Title",
9 "duration": 300,
10 "thumbnail": "https://i.ytimg.com/vi/xyz789/maxresdefault.jpg",
11 "description": "Video description...",
12 "uploader": "Channel Name",
13 "upload_date": "20240115",
14 "view_count": 1000000,
15 "formats": []
16 }
17}

Basic Metadata Webhook

For basic metadata jobs, data.type is basic-metadata and only title, duration, and thumbnail are included:

json
1{
2 "success": true,
3 "data": {
4 "jobId": "xyz789",
5 "type": "basic-metadata",
6 "status": "completed",
7 "title": "Sample Video Title",
8 "duration": 300,
9 "thumbnail": "https://i.ytimg.com/vi/xyz789/maxresdefault.jpg"
10 }
11}

Transcribe Webhook

For transcription jobs, data.type is transcribe and the transcript fields are flattened into data:

json
1{
2 "success": true,
3 "data": {
4 "jobId": "b2f7c9e4",
5 "type": "transcribe",
6 "status": "completed",
7 "text": "Full transcript text…",
8 "source": "platform_captions",
9 "language": "en",
10 "duration": 212,
11 "data": {
12 "segments": [
13 { "start": 0.0, "end": 4.2, "text": "First segment…" }
14 ]
15 },
16 "costInDollars": 0.01
17 }
18}

Recommendations

  • HTTPS: Serve your webhook handler over TLS.
  • Idempotency: Only a single delivery attempt is made, so design your handler to be idempotent in case you also process the same job via status polling.
  • Return quickly: Respond with a 2xx status promptly and do heavy processing asynchronously.