Skip to main content
Webhooks allow you to receive real-time HTTP notifications when your asynchronous processing jobs complete. Instead of polling the predictions endpoint, VLM Run will automatically send the results to your specified callback URL.

Overview

When you submit a request with batch=True and provide a callback_url, VLM Run will:
  1. Process your request asynchronously
  2. Generate the results
  3. Send an HTTP POST request to your callback URL with the complete response
  4. Include an HMAC signature for verification (if you’ve configured a webhook secret)

Setting Up Webhooks

1. Configure Your Webhook Secret

To ensure webhook requests are authentic, you should configure a webhook secret in your account settings. This secret is used to generate HMAC signatures that you can verify on your server. Setting your webhook secret:
  1. Log in to your VLM Run Dashboard
  2. Navigate to Settings → API Keys
  3. Set your webhook secret (keep this secure and never share it)

2. Create a Webhook Endpoint

Create an endpoint on your server to receive webhook notifications. The endpoint should:
  • Accept POST requests
  • Verify the HMAC signature (recommended)
  • Process the webhook payload
  • Return a 2xx status code to acknowledge receipt

3. Submit Requests with Callback URL

When making API requests, include the callback_url parameter:
from vlmrun.client import VLMRun

# Initialize the client
client = VLMRun()

response = client.document.generate(
    file_id="file_abc123",
    domain="document.invoice",
    batch=True,
    callback_url="https://your-domain.com/webhooks/vlmrun"
)

print(f"Request ID: {response.id}")
# Your webhook endpoint will receive the results when processing completes

Verifying Webhook Signatures

VLM Run signs all webhook requests with an HMAC signature using your webhook secret. The signature is included in the X-VLMRun-Signature header. Important: Always verify webhook signatures to ensure requests are authentic and haven’t been tampered with. The VLM Run SDKs provide built-in webhook verification utilities that handle signature validation securely.
import os
import json
from vlmrun.common.webhook import verify_webhook

# In your webhook handler, obtain the raw request body (bytes),
# signature header, and webhook secret
raw_body = request.body()  # Must be bytes, not parsed JSON
signature = request.headers.get("X-VLMRun-Signature")
secret = os.environ["VLMRUN_WEBHOOK_SECRET"]

# Verify signature using SDK
if not verify_webhook(raw_body, signature, secret):
    return {"error": "Invalid signature"}, 401

# Parse and process webhook
data = json.loads(raw_body)
print(f"Received webhook for prediction: {data['id']}")

# Handle the completed prediction
if data["status"] == "completed":
    response_data = data["response"]
    # ... your business logic here

return {"status": "success"}
Important: Always verify the raw request body before any JSON parsing. For Express, use express.raw({ type: 'application/json' }) middleware on your webhook route to ensure the body is available as a Buffer.

Manual Verification (Alternative)

If you prefer not to use the SDK, you can implement signature verification manually:
import hmac
import hashlib

def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
    if not signature_header or not signature_header.startswith("sha256="):
        return False

    received_sig = signature_header[len("sha256="):]
    expected_sig = hmac.new(
        secret.encode("utf-8"),
        raw_body,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(received_sig, expected_sig)

# Usage in your webhook handler
raw_body = request.body()
signature = request.headers.get("X-VLMRun-Signature")
secret = os.environ["VLMRUN_WEBHOOK_SECRET"]

if not verify_webhook(raw_body, signature, secret):
    return {"error": "Invalid signature"}, 401

Webhook Delivery

Retry Logic

VLM Run automatically retries failed webhook deliveries with exponential backoff:
  • Maximum retries: 2 attempts
  • Timeout: 30 seconds per request
  • Backoff: Exponential (1s, 2s, 4s, etc.)
A webhook delivery is considered failed if:
  • The endpoint returns a non-2xx status code
  • The request times out after 30 seconds
  • A network connection error occurs

Testing Webhooks Locally

To test webhooks from a local server, use a tunneling tool such as ngrok, Cloudflare Tunnel, or localtunnel to expose your endpoint and use the public URL as your callback_url.