Skip to main content

Webhooks

Event-driven integrations for async operations

2 min read


Webhooks are currently in beta. The webhook URL parameter is available on async fetch operations. A dedicated client.webhooks namespace for registration and management is planned for a future SDK release.

KLOAKD can push events to your server as async operations complete by passing a webhook_url when starting an async job.

Receive fetch completion via webhook

Pass a webhook_url to evadr.fetch_async() — KLOAKD will POST the result to your endpoint when the fetch completes:

job_id = client.evadr.fetch_async(
    "https://example.com",
    webhook_url="https://your-server.com/webhooks/kloakd",
)
const jobId = await client.evadr.fetchAsync('https://example.com', {
  webhookUrl: 'https://your-server.com/webhooks/kloakd',
});

Webhook payload

When an async operation completes, KLOAKD sends a POST request to your webhook URL with a JSON body:

{
  "job_id": "evadr-fetch-abc123",
  "status": "completed",
  "url": "https://example.com",
  "success": true,
  "artifact_id": "art_xyz789",
  "tier_used": 2,
  "timestamp": "2026-08-29T06:00:00Z"
}

Event types

| Event | Trigger | Method | |-------|---------|--------| | fetch.complete | Async fetch finished | evadr.fetch_async(webhook_url=...) | | fetch.failed | Async fetch failed | evadr.fetch_async(webhook_url=...) |

For crawl operations, use client.crawl_stream() or client.webgrph.crawl_stream() for real-time SSE progress instead of webhooks. Streaming gives you per-page events as they happen.

Verify signatures

Webhook requests include an X-Kloakd-Signature header. Verify it with HMAC-SHA256:

import hmac, hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Responding to webhooks

Return HTTP 200 OK within 30 seconds. KLOAKD retries failed deliveries with exponential backoff (up to 3 attempts).

# FastAPI example
from fastapi import FastAPI, Request, Header

app = FastAPI()

@app.post("/webhooks/kloakd")
async def kloakd_webhook(request: Request, x_kloakd_signature: str = Header(None)):
    body = await request.body()
    # verify_webhook(body, x_kloakd_signature, "your-signing-secret")
    event = await request.json()
    if event["status"] == "completed":
        print(f"Fetch done: {event['url']} (tier {event['tier_used']})")
    return {"ok": True}
Was this page helpful?