Skip to content

Webhooks

Receive real-time notifications when events occur in your Nur account.

Overview

Webhooks allow your application to receive real-time HTTP callbacks when specific events happen in your Nur account. Instead of polling the API to check the status of long-running tasks, you can register a webhook URL and Nur will send a POST request to that URL whenever an event occurs.

Common use cases for webhooks include:

Dubbing job completed

Get notified when an AI dubbing job finishes processing so you can deliver the dubbed content immediately.

Voice clone ready

Receive an alert as soon as a custom voice clone has been trained and is ready for use.

Agent session ended

Track when a voice agent session concludes to log analytics or trigger follow-up workflows.

Music generation finished

Know the moment a music track has been generated and is available for download.

Setup

To start receiving webhooks, register a webhook endpoint by sending a POST request to /v1/webhooks/create. Your endpoint must be a publicly accessible HTTPS URL that returns a 2xx status code.

1curl -X POST https://api.nur.ai/v1/webhooks/create \
2 -H "Authorization: Bearer nur_your_api_key" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "url": "https://your-app.com/webhooks/nur",
6 "events": [
7 "dubbing.completed",
8 "voice.clone.completed",
9 "agent.session.ended"
10 ],
11 "secret": "whsec_your_signing_secret"
12 }'

Tip: Signing Secret

The secret parameter is optional but strongly recommended. When provided, Nur will sign every webhook payload with this secret so you can verify the request originated from Nur.

Events

Subscribe to specific events to only receive the notifications you need. The following events are available:

EventDescription
dubbing.completedA dubbing job has finished processing successfully.
dubbing.failedA dubbing job has failed due to an error.
voice.clone.completedA voice clone has been trained and is ready for use.
voice.clone.failedA voice cloning request has failed.
agent.session.startedA voice agent session has begun with a user.
agent.session.endedA voice agent session has concluded.
music.generation.completedA music generation task has finished and the track is available.

Payload Format

Every webhook delivery sends a JSON POST request to your registered URL. The payload follows a consistent structure across all event types:

1{
2 "id": "evt_abc123def456",
3 "event": "dubbing.completed",
4 "data": {
5 "job_id": "dub_789xyz",
6 "source_language": "en",
7 "target_language": "es",
8 "duration_seconds": 342,
9 "output_url": "https://cdn.nur.ai/dubbing/dub_789xyz/output.mp4",
10 "status": "completed"
11 },
12 "timestamp": "2026-01-15T14:30:00.000Z",
13 "webhook_id": "wh_abc123"
14}

Payload Fields

The id is a unique identifier for the delivery event. The data object contains event-specific fields that vary by event type. Use the webhook_id to correlate deliveries with your registered webhook.

Signature Verification

When you provide a signing secret during webhook creation, Nur includes a X-Nur-Signature header with each delivery. This header contains an HMAC-SHA256 signature of the raw request body, allowing you to verify the webhook was sent by Nur and has not been tampered with.

1import hmac
2import hashlib
3
4def verify_webhook(payload_body, signature_header, secret):
5 """Verify that a webhook payload was sent by Nur."""
6 expected = hmac.new(
7 secret.encode("utf-8"),
8 payload_body,
9 hashlib.sha256,
10 ).hexdigest()
11
12 signature = signature_header.replace("sha256=", "")
13
14 if not hmac.compare_digest(expected, signature):
15 raise ValueError("Invalid webhook signature")
16
17 return True
18
19# Usage in a Flask route
20from flask import request
21
22@app.route("/webhooks/nur", methods=["POST"])
23def handle_webhook():
24 signature = request.headers.get("X-Nur-Signature")
25 verify_webhook(request.data, signature, "whsec_your_secret")
26
27 event = request.json
28 print(f"Received event: {event['event']}")
29 return "", 200

Retry Policy

If your endpoint does not return a 2xx status code within 30 seconds, Nur will retry the delivery using exponential backoff. A maximum of 5 retry attempts will be made before the delivery is marked as failed.

AttemptDelayCumulative Time
1st retry1 minute1 minute
2nd retry5 minutes6 minutes
3rd retry30 minutes36 minutes
4th retry2 hours2 hours 36 minutes
5th retry24 hours26 hours 36 minutes

Important

Your endpoint must respond with a 2xx HTTP status code within 30 seconds. Any other response code or a timeout will be treated as a failure and trigger a retry. Ensure your endpoint processes webhooks asynchronously if the handling logic takes longer than a few seconds.

Managing Webhooks

Use the following endpoints to list and delete your registered webhooks.

1# GET /v1/webhooks - List all registered webhooks
2curl https://api.nur.ai/v1/webhooks \
3 -H "Authorization: Bearer nur_your_api_key"
4
5# Response
6{
7 "webhooks": [
8 {
9 "id": "wh_abc123",
10 "url": "https://your-app.com/webhooks/nur",
11 "events": ["dubbing.completed", "voice.clone.completed"],
12 "created_at": "2026-01-10T08:00:00.000Z",
13 "status": "active"
14 }
15 ]
16}