Skip to main content

Overview

Instead of polling for task status, configure a webhook to receive notifications when events occur. ModelHunter.AI will POST a JSON payload to your URL.

Register a Webhook

curl -X POST https://api.modelhunter.ai/api/v1/webhooks \
  -H "Authorization: Bearer river_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/modelhunter",
    "events": ["task.completed", "task.failed"]
  }'

Event Types

EventDescription
task.completedA generation task finished successfully
task.failedA generation task failed

Webhook Payload

Headers

Content-Type: application/json
X-Webhook-ID: evt_abc123
X-Webhook-Timestamp: 1705312800
X-Webhook-Signature: sha256=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Body

{
  "id": "evt_abc123",
  "type": "task.completed",
  "created_at": "2025-01-15T10:00:45Z",
  "data": {
    "task": {
      "id": "task_abc123",
      "type": "video",
      "status": "succeeded",
      "provider": "vidu",
      "model": "viduq2-pro-fast",
      "result": [
        {
          "url": "https://cdn.modelhunter.ai/results/task_abc123.mp4?signature=xxx",
          "duration": 4,
          "format": "mp4",
          "size_bytes": 12582912
        }
      ],
      "created_at": "2025-01-15T10:00:00Z",
      "completed_at": "2025-01-15T10:00:45Z",
      "metadata": { "user_id": "u_123" }
    }
  }
}

Per-Job Webhooks vs Configured Webhooks

There are two types of webhook delivery:
  • Configured webhooks (registered via POST /api/v1/webhooks) include X-Webhook-Signature for verification and support automatic retries.
  • Per-job webhooks (via webhookUrl in a generation request) do not include X-Webhook-Signature (no shared secret), but include additional headers: X-Webhook-Event (e.g. task.completed) and X-Job-ID.

Signature Verification

Configured webhooks include an X-Webhook-Signature header. Verify it to ensure the request is authentic. The signature is computed as HMAC-SHA256(timestamp + "." + body, secret).
import crypto from "crypto";

function verifyWebhookSignature(req, secret) {
  const timestamp = req.headers["x-webhook-timestamp"];
  const signature = req.headers["x-webhook-signature"];
  const body = JSON.stringify(req.body);

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${body}`)
    .digest("hex");

  const expectedSignature = `sha256=${expected}`;

  if (signature !== expectedSignature) {
    throw new Error("Invalid webhook signature");
  }

  // Reject timestamps older than 5 minutes
  const age = Math.floor(Date.now() / 1000) - parseInt(timestamp, 10);
  if (age > 300) {
    throw new Error("Webhook timestamp too old");
  }

  return true;
}

Retry Policy

If your endpoint does not return a 2xx status, ModelHunter.AI retries with exponential backoff:
AttemptDelay
11 minute
25 minutes
330 minutes
After 3 failed attempts, the delivery is marked as failed. You can replay it from the Dashboard.

Test a Webhook

Send a test event to verify your endpoint:
curl -X POST https://api.modelhunter.ai/api/v1/webhooks/{webhook_id}/test \
  -H "Authorization: Bearer river_live_xxx"

Manage Webhooks

# List webhooks
curl https://api.modelhunter.ai/api/v1/webhooks \
  -H "Authorization: Bearer river_live_xxx"

# Delete a webhook
curl -X DELETE https://api.modelhunter.ai/api/v1/webhooks/{webhook_id} \
  -H "Authorization: Bearer river_live_xxx"