Use Cases Pricing Docs About
Get Started
Ready to start creating map animations? Get Started Free →

Webhooks

Receive real-time notifications when your renders complete instead of polling the status endpoint.

How It Works

  1. Include a webhook_url in your render request
  2. Georender sends a POST request to your URL when the job completes
  3. Your server receives the video URL and job details

Setting Up Webhooks

POST /v1/render

{
  "waypoints": [...],
  "webhook_url": "https://your-server.com/webhooks/georender"
}

Webhook Payload

When a render completes, you'll receive a POST request with this JSON body:

Success Payload

{
  "event": "render.complete",
  "job_id": "job_8f3k2m9x",
  "status": "complete",
  "video_url": "https://cdn.georender.io/renders/job_8f3k2m9x.mp4",
  "thumbnail_url": "https://cdn.georender.io/renders/job_8f3k2m9x_thumb.jpg",
  "duration_seconds": 12,
  "resolution": "1920x1080",
  "file_size_bytes": 18432000,
  "expires_at": "2026-04-01T12:00:00Z",
  "created_at": "2026-03-26T10:00:00Z",
  "completed_at": "2026-03-26T10:01:30Z"
}

Failure Payload

{
  "event": "render.failed",
  "job_id": "job_8f3k2m9x",
  "status": "failed",
  "error": "MARITIME_ROUTE_ERROR",
  "message": "Could not calculate sea route between points. Land mass in the way.",
  "created_at": "2026-03-26T10:00:00Z",
  "failed_at": "2026-03-26T10:00:15Z"
}

Batch Webhooks

For batch render jobs, you receive a single webhook when all jobs complete:

{
  "event": "batch.complete",
  "batch_id": "batch_xyz123",
  "jobs": [
    {
      "job_id": "job_1",
      "status": "complete",
      "video_url": "https://cdn.georender.io/renders/job_1.mp4"
    },
    {
      "job_id": "job_2",
      "status": "complete",
      "video_url": "https://cdn.georender.io/renders/job_2.mp4"
    },
    {
      "job_id": "job_3",
      "status": "failed",
      "error": "ROAD_ROUTE_ERROR",
      "message": "No road found between waypoints"
    }
  ],
  "completed": 2,
  "failed": 1,
  "total": 3
}

Webhook Security

Verify that webhooks are genuinely from Georender by checking the signature header:

X-Georender-Signature: sha256=abc123...

Verifying Signatures (Node.js)

import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  );
}

// In your webhook handler
app.post('/webhooks/georender', (req, res) => {
  const signature = req.headers['x-georender-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.GEORENDER_WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process the webhook
  const { event, job_id, video_url } = req.body;
  // ...
});

Retry Policy

If your webhook endpoint returns a non-2xx status code, Georender will retry:

Important: Your webhook endpoint should respond within 30 seconds. Process the video asynchronously and return a 200 immediately.

Testing Webhooks

Use tools like webhook.site or ngrok to test webhooks locally.

# Using ngrok
ngrok http 3000

# Then use the ngrok URL as your webhook_url
{
  "waypoints": [...],
  "webhook_url": "https://abc123.ngrok.io/webhooks/georender"
}

Webhook Events

EventDescription
render.completeSingle render job completed successfully
render.failedSingle render job failed
batch.completeAll jobs in a batch finished (success or failure)