Skip to main content
Webhooks send signed payloads to your endpoints whenever specific lifecycle events occur. This reference documents the available event types, their payload structures, and how to verify webhook signatures.
New to webhooks? Start with the Webhooks guide to understand use cases, best practices, and when webhooks are the right choice for your workflow.

Setup

  1. Sign in to the Renderjuice platform and make sure to be in the right workspace.
  2. Navigate to Profile & Settings → Webhooks.
  3. Add the HTTPS endpoint you’d like us to call.
  4. Choose the event types you care about.
Always return 200 OK as quickly as possible—Renderjuice considers non-2xx responses or timeouts to be failures and will retry a limited number of times.

Available events

Renderjuice currently files webhooks for the following events:
  • Job completed (onRenderComplete) – Fired when a render job finishes successfully
  • Job failed (onRenderFail) – Planned, not yet emitted

Delivery format

  • Method: POST
  • Body: JSON
  • Headers: Content-Type: application/json, plus signing headers below
  • Timeout: 7s request timeout on our side; respond with 2xx quickly and offload heavy work

Payload schema (onRenderComplete)

type WebhookPayload = {
  event: "onRenderComplete";
  status: "completed";
  jobId: string;        // Render job ID (UUID)
  workspaceId: string;  // Workspace that owns the job
  completedAt: string;  // ISO 8601 timestamp
  outputs?: {
    frames: string[];   // Signed URLs for rendered frames (may be empty)
  };
};

Example payload

{
  "event": "onRenderComplete",
  "status": "completed",
  "jobId": "465d7fed-dba7-4c49-8ca7-5bac5e4c4075",
  "workspaceId": "f61c980c-fbbe-472d-a047-d64c5b97c4ba",
  "completedAt": "2025-11-23T22:30:29.020Z",
  "outputs": {
    "frames": [
      "https://conduit.utxld.com/download/0001.jpg?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    ]
  }
}
Notes:
  • outputs is omitted when no frames are available.
  • Frame URLs are signed and expire; fetch or cache what you need when the webhook arrives.

Verifying webhook signatures

All webhook requests include cryptographic signatures so you can verify they originated from Renderjuice and haven’t been tampered with. You can view or regenerate your webhook secret in the dashboard under Profile & Settings → Webhooks.

Signature headers

Each webhook request includes two headers:
  • X-Renderjuice-Signature – HMAC-SHA256 signature of the request body
  • X-Renderjuice-Timestamp – Unix timestamp (seconds since epoch) when the request was signed

Verification process

  1. Extract the signature and timestamp from the headers
  2. Construct the signed payload: {timestamp}.{requestBody}
  3. Compute HMAC-SHA256 using your webhook secret
  4. Compare the computed signature with the header signature
  5. Optionally verify the timestamp is recent (within 5 minutes) to prevent replay attacks

Verification examples

verify-signature.js
const crypto = require('crypto');

function verifyWebhookSignature(secret, signature, timestamp, body) {
  const signedPayload = `${timestamp}.${body}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Usage
const isValid = verifyWebhookSignature(
  process.env.WEBHOOK_SECRET,
  req.headers['x-renderjuice-signature'],
  req.headers['x-renderjuice-timestamp'],
  req.body
);
Security best practices:
  • Although not required, it is highly recommended to verify signatures before processing webhook payloads
  • Use constant-time comparison (e.g., crypto.timingSafeEqual in Node.js, hmac.compare_digest in Python) to prevent timing attacks
  • Verify timestamps to prevent replay attacks (reject requests older than 5 minutes)
  • Store webhook secrets securely (environment variables, secret managers)

Retry behavior and error handling

  • Non-2xx HTTP responses are considered failures
  • Request timeouts are considered failures
  • Renderjuice will retry failed deliveries a limited number of times
  • After repeated failures, webhooks may be automatically disabled

Best practices for webhook handlers

  1. Return 200 OK quickly – Acknowledge receipt immediately, then process asynchronously
  2. Make handlers idempotent – Use eventId or domainIdempotencyKey to deduplicate events
  3. Handle duplicate events – The same event may be delivered multiple times due to retries
  4. Log all events – Keep a record of received events for debugging and auditing
  5. Validate event structure – Verify required fields are present before processing

Next steps

If you need webhook integration support before these docs are finalized, reach out to [email protected]