Agent skill
Argil Webhooks Skill
Receive and verify Argil (argil.ai) AI avatar video webhooks, signed per Standard Webhooks. Use when setting up an Argil webhook endpoint, getting the whsec_ signing secret from POST /webhooks, debugging webhook-id / webhook-timestamp / webhook-signature verification, or handling VIDEO_GENERATION_SUCCESS, VIDEO_GENERATION_FAILED, AVATAR_TRAINING_SUCCESS and AVATAR_TRAINING_FAILED events.
Install this skill
npx skills add hookdeck/webhook-skills --skill argil-webhooks
Argil is an AI avatar video generation platform. Its webhooks report video renders and avatar trainings finishing or failing. Deliveries are signed per Standard Webhooks with webhook-id, webhook-timestamp and webhook-signature headers.
When to Use This Skill
- How do I receive Argil webhooks?
- How do I verify an Argil webhook signature?
- Where do I get my Argil webhook signing secret?
- How do I handle
VIDEO_GENERATION_SUCCESSorAVATAR_TRAINING_FAILED? - Why is my Argil
webhook-signatureverification failing, or why are there no signature headers? - How do I dedupe Argil webhook retries?
Signing requirement: recreate old webhooks
Webhooks created before Argil added signing are delivered unsigned, and there is no way to retrieve a secret for them. Recreate the webhook to get a whsec_ secret (Hookdeck's alert for this source says the same: "Webhooks created before Argil added signing are unsigned. Recreate the webhook to get a whsec_ secret."). The secret is returned once, in the response of POST /webhooks, so store it then.
Verification (core)
| Header | Value |
|---|---|
webhook-id | The event ID, the same on every retry |
webhook-timestamp | Unix seconds when this attempt was sent |
webhook-signature | v1,<base64 HMAC-SHA256>, possibly several space-separated entries |
Signed content is {webhook-id}.{webhook-timestamp}.{raw body}. The key is the base64-decoded part of the secret after whsec_. Argil's docs show the standardwebhooks library (npm, PyPI). It enforces a fixed 5-minute timestamp window and compares in constant time. If webhook-id is missing, read the svix-* headers instead: same scheme, other prefix.
const { Webhook } = require('standardwebhooks');
// rawBody: exact request body string, NOT re-serialised JSON
function verifyArgilWebhook(rawBody, get, secret = process.env.ARGIL_WEBHOOK_SECRET) {
const prefix = get('webhook-id') ? 'webhook' : 'svix';
return new Webhook(secret).verify(rawBody, {
'webhook-id': get(`${prefix}-id`),
'webhook-timestamp': get(`${prefix}-timestamp`),
'webhook-signature': get(`${prefix}-signature`),
}); // returns the parsed { event, data }; throws → respond 400
}
Python: from standardwebhooks.webhooks import Webhook, then Webhook(secret).verify(await request.body(), {...same mapping...}).
Late retries. Hookdeck retries and replays resend the original timestamp, so the library rejects them after 5 minutes. A dependency-free manual verifier with no window is in references/verification.md.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Event Envelope
{ "event": "VIDEO_GENERATION_SUCCESS",
"data": { "videoId": "...", "videoName": "...", "videoUrl": "https://...",
"message": "Video generation completed successfully",
"extras": "...", "renderCost": 150, "renderCostRefunded": false } }
The event name is the top-level event string. The payload has no event ID: dedupe on the webhook-id header.
Common Event Types
| Event | Fired when | data fields |
|---|---|---|
VIDEO_GENERATION_SUCCESS | A video render succeeds | videoId, videoName, videoUrl, message, extras, renderCost, renderCostRefunded (false) |
VIDEO_GENERATION_FAILED | A video render fails | videoId, videoName, message (why), extras, renderCost, renderCostRefunded |
AVATAR_TRAINING_SUCCESS | An avatar training succeeds | avatarId, voiceId, avatarName, extras |
AVATAR_TRAINING_FAILED | An avatar training fails | avatarId, avatarName, extras |
Argil's Avatar Training Failed page calls the event
AVATAR_GENERATION_FAILEDin its prose, but its payload example and the subscription enum useAVATAR_TRAINING_FAILED. Use that.
Full payloads: references/overview.md and Argil's webhook docs.
Delivery Semantics
- Return a
2xxwithin 10 seconds, then process asynchronously. Redirects are not followed. - Failed deliveries retry after 30 s, 2 min, 10 min, 1 h, 6 h, then every 12 h for 3 days.
- Delivery is at least once and can arrive out of order.
- Answer
410 Goneto disable the webhook. Three days of failures disables it too and emails the workspace owner. Updating a disabled webhook enables it again.
Environment Variables
ARGIL_WEBHOOK_SECRET=whsec_xxxxx # full value incl. whsec_; handlers fail closed (500) without it
Local Development
# Express / Next.js (use 8000 for FastAPI). No install or account required.
npx hookdeck-cli listen 3000 argil --path /webhooks/argil
Create a webhook with the printed URL as callbackUrl (see references/setup.md), then render a video or train an avatar.
Reference Materials
- references/overview.md - Event catalog, payload fields, delivery and retries
- references/setup.md - Creating, listing, updating and deleting webhooks through the API, the one-time secret
- references/verification.md - Library and manual verification, gotchas, debugging