Get Video Results with Webhooks
Use this guide when you need to add webhook-based video completion handling instead of polling from a client or worker.
By the end, your implementation should submit a video job with callback_url
and verify the webhook signature.
For reusable agent knowledge across projects, install the openrouter-video skill.
Before you start
You need:
- An OpenRouter API key available as
OPENROUTER_API_KEY - Node.js 20 or newer
- A public HTTPS endpoint for your webhook receiver
- A webhook signing secret configured in your OpenRouter workspace settings
- A video model slug for the job you submit with
callback_url
If you have not chosen a model yet, read Choose a Video Generation Model so you can select one based on your clip duration, output shape, input type, audio, provider controls, and cost requirements.
Use the API reference pages as the source of truth for exact fields:
- Create video generation request
- List video generation models
- TypeScript SDK video generation reference
If you adapt the Express examples below in a local test project, use these dependencies:
Submitting POST /api/v1/videos starts a real video generation job and may
spend OpenRouter credits.
Step 1: Implement a webhook receiver
Add a webhook receiver that preserves the raw request body before parsing JSON. Signature verification must use the exact bytes OpenRouter sent, not a re-serialized payload.
Example Express receiver:
Step 2: Validate signature handling before using real jobs
Before connecting a real callback_url, exercise the receiver with the same
signing secret your test sender uses:
Actual local receiver startup output:
Expose the receiver with a public HTTPS URL before using it as a real
callback_url. A local tunnel or deployed preview URL works as long as
OpenRouter can reach it over HTTPS.
Step 3: Send a signed test event
Before spending credits on a real video job, test the receiver with a locally signed event. This verifies that raw-body handling, timestamp parsing, HMAC comparison, and idempotency headers are wired correctly.
Example local sender:
Exercise the local sender while the receiver is listening:
A valid signed event should return 204. Change the secret or signature to
confirm the receiver returns 401 for invalid requests.
Actual local signature-test output:
You can also use a temporary Webhook.site URL as CALLBACK_URL to confirm
OpenRouter delivers the webhook and includes the expected headers and envelope.
Webhook.site does not run your signature verifier; use your own public receiver
with the workspace signing secret for end-to-end signature verification.
Example Webhook.site delivery:
Step 4: Submit a video job with callback_url
Once the receiver is reachable over public HTTPS, submit the video job with
callback_url. The callback URL can be set per request, which is useful for
preview environments or tenant-specific receivers.
Example submit logic:
The submit call returns the initial job fields. In a completed run, that job later completed and delivered a webhook with this final summary:
After the receiver is deployed or exposed through a tunnel, run the submit logic
with CALLBACK_URL set to that public endpoint:
The per-request callback_url takes priority over a workspace-level default callback URL.
Step 5: Handle the completed job
Handle webhook delivery as a terminal job update. The payload is an event
envelope with the job fields inside data; the data object includes fields
such as id, status, generation_id, model, unsigned_urls, usage, and
error, depending on the terminal state. Store the job state in your database,
deduplicate retries with X-OpenRouter-Idempotency-Key, then download the
video from the first unsigned_urls entry or from the content endpoint. If the
URL points to the OpenRouter API, include the bearer token when downloading it.
For a complete polling and download helper, see Generate and Download a Video from Text.
Actual local receiver log shape from the signature test:
Check your work
Your receiver should return 204 for a valid OpenRouter webhook and 401 for
a request with a missing or invalid signature. A real callback delivery should
produce a terminal job update that your app can store and use to download the
generated video.