Documentation Index
Fetch the complete documentation index at: https://docs.aspect.inc/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Use webhooks to receive real-time notifications when a task changes state. This lets you react to long-running media processing without polling. To set up a webhook, go to our dashboard and create a new endpoint.
- Provider: Svix
- Events:
task.progress, task.completed, task.failed
- Payload envelope: common event fields plus
data.task
Event payload
All webhooks share the same envelope. The event_type matches the event you subscribe to and the data object contains the resource payloads. For task events, only data.task is populated.
{
"timestamp": "2025-01-01T12:00:00Z",
"user_id": "3f5d7e38-8c7c-4a22-9a7d-5702a8c3a111",
"event_id": "8b7a2e8f-3a1c-4ff9-9f5e-4b8e0a9ee000",
"event_type": "task.progress",
"data": {
"task": {
"id": "2e1c7e42-4f8d-4e10-8d7a-0a6c0d3b1234",
"asset_id": "c4b6b5f1-6a2d-4d75-9a90-1f6f4a0a2222",
"features": {
"transcription": { "state": "processing" },
"visual": { "state": "queued" },
"preview": { "state": "completed" },
"proxy": { "state": "na" },
},
"user_id": "3f5d7e38-8c7c-4a22-9a7d-5702a8c3a111",
"created": "2025-01-01T11:55:00Z",
"updated": "2025-01-01T12:00:00Z"
}
}
}
Envelope schema
{
"timestamp": "string (ISO 8601)",
"user_id": "uuid",
"event_id": "uuid",
"event_type": "'task.progress'|'task.completed'|'task.failed'",
"data": {
"task": { "Task": "see schema below" }
}
}
Task schema
This matches the API response TaskGetResponse used throughout the server.
{
"id": "uuid",
"asset_id": "uuid",
"features": {
"proxy": { "state": "queued|processing|completed|failed|cancelled|na" },
"preview": { "state": "queued|processing|completed|failed|cancelled|na" },
"visual": { "state": "queued|processing|completed|failed|cancelled|na" },
"transcription": { "state": "queued|processing|completed|failed|cancelled|na" }
},
"user_id": "uuid",
"created": "string (ISO 8601)",
"updated": "string (ISO 8601)"
}
Supported events
task.progress: One or more features changed state (e.g., queued → processing)
task.completed: All user-facing features reached a terminal success state
task.failed: One or more user-facing features failed
Set up an endpoint
Create and manage webhook endpoints via API. We use Svix applications per user; your first endpoint creation will provision one if needed. The create response includes the endpoint secret.
Create endpoint
POST /webhooks/endpoints
Request
{
"url": "https://your-domain.com/webhooks/aspect",
"description": "Prod listener",
"event_types": ["task.*"],
"rate_limit": 120,
"version": 1
}
Response
{
"endpoint": {
"id": "ep_123",
"url": "https://your-domain.com/webhooks/aspect",
"description": "Prod listener",
"event_types": ["task.progress","task.completed","task.failed"],
"rate_limit": 120,
"disabled": false,
"version": 1,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
},
"secret": "whsec_xxx",
"app": { "id": "app_123", "is_new": true }
}
Update endpoint
PUT /webhooks/endpoints/{endpoint_id}
{
"url": "https://your-domain.com/webhooks/aspect",
"description": "Prod listener",
"event_types": ["task.progress","task.completed","task.failed"],
"rate_limit": 120,
"version": 1,
"disabled": false
}
Delete endpoint
DELETE /webhooks/endpoints/{endpoint_id} → { "success": true }
Inspect logs (optional)
- GET
/webhooks/messages — recent webhook messages
- GET
/webhooks/delivery-attempts?message_id=...|endpoint_id=... — delivery attempts
- GET
/webhooks/endpoints/{endpoint_id}/deliveries — legacy endpoint attempts list
Verify signatures
Svix signs requests with headers svix-id, svix-timestamp, and svix-signature. Always verify before processing. Your endpoint secret comes from the create response (keep it safe). Remove the whsec_ prefix when using verification helpers that expect the raw secret.
Node (TypeScript)
import { Webhook } from 'svix'
import express from 'express'
const app = express()
app.use(express.json({ type: '*/*' }))
app.post('/webhooks/aspect', (req, res) => {
const svixId = req.header('svix-id')
const svixTimestamp = req.header('svix-timestamp')
const svixSignature = req.header('svix-signature')
if (!svixId || !svixTimestamp || !svixSignature) return res.status(400).send('Missing Svix headers')
const secret = process.env.ASPECT_WEBHOOK_SECRET || ''
const wh = new Webhook(secret.replace(/^whsec_/, ''))
try {
const payload = wh.verify(JSON.stringify(req.body), {
'svix-id': svixId,
'svix-timestamp': svixTimestamp,
'svix-signature': svixSignature
})
// payload matches the envelope schema above
res.status(204).end()
} catch (err) {
res.status(400).send('Invalid signature')
}
})
Python (FastAPI)
from fastapi import FastAPI, Request, HTTPException
from svix.webhooks import Webhook
app = FastAPI()
@app.post('/webhooks/aspect')
async def handler(request: Request):
svix_id = request.headers.get('svix-id')
svix_timestamp = request.headers.get('svix-timestamp')
svix_signature = request.headers.get('svix-signature')
if not (svix_id and svix_timestamp and svix_signature):
raise HTTPException(status_code=400, detail='Missing Svix headers')
secret = (os.getenv('ASPECT_WEBHOOK_SECRET') or '').removeprefix('whsec_')
payload = await request.body()
try:
evt = Webhook(secret).verify(payload, {
'svix-id': svix_id,
'svix-timestamp': svix_timestamp,
'svix-signature': svix_signature,
})
return { 'ok': True }
except Exception:
raise HTTPException(status_code=400, detail='Invalid signature')
Testing
Use the Svix dashboard to send test events to your endpoint. If you need a simple echo endpoint for local testing, expose it and verify signatures using the steps above.
Notes
- Only
task.* events are currently published to webhooks
- All events are also available via SSE for live dashboards
- Delivery attempts and logs are queryable using our Webhooks API