Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Openai Openai node Webhooks Resource

From Leeroopedia
Knowledge Sources
Domains SDK, Webhooks, Security
Last Updated 2026-02-15 12:00 GMT

Overview

The Webhooks resource class provides methods for verifying OpenAI webhook signatures and securely parsing webhook event payloads.

Description

The Webhooks class extends APIResource and implements webhook signature verification using HMAC-SHA256 via the Web Crypto API. It protects against replay attacks by validating the webhook-timestamp header against a configurable tolerance window (default: 300 seconds / 5 minutes), and it supports multiple signature formats in the webhook-signature header, accepting any valid v1,<base64> signature.

The class provides two main methods: verifySignature performs pure validation and throws InvalidWebhookSignatureError on failure, while unwrap verifies and then parses the payload into a typed UnwrapWebhookEvent discriminated union. The webhook secret can be provided directly, configured on the client via webhookSecret, or set through the OPENAI_WEBHOOK_SECRET environment variable. Secrets prefixed with whsec_ are automatically base64-decoded.

The module also exports a comprehensive set of webhook event type interfaces covering batch operations (BatchCancelledWebhookEvent, BatchCompletedWebhookEvent, BatchExpiredWebhookEvent, BatchFailedWebhookEvent), eval runs (EvalRunCanceledWebhookEvent, EvalRunFailedWebhookEvent, EvalRunSucceededWebhookEvent), fine-tuning jobs (FineTuningJobCancelledWebhookEvent, FineTuningJobFailedWebhookEvent, FineTuningJobSucceededWebhookEvent), realtime calls (RealtimeCallIncomingWebhookEvent), and background responses (ResponseCancelledWebhookEvent, ResponseCompletedWebhookEvent, ResponseFailedWebhookEvent, ResponseIncompleteWebhookEvent).

Usage

Use this resource in server-side webhook handlers to verify that incoming HTTP requests genuinely originated from OpenAI. Call unwrap for a single verify-and-parse step, or verifySignature if you only need validation without automatic parsing. The Web Crypto API (crypto.subtle) must be available in the runtime environment.

Code Reference

Source Location

Signature

class Webhooks extends APIResource {
  unwrap(
    payload: string,
    headers: HeadersLike,
    secret?: string | undefined | null,
    tolerance?: number,
  ): Promise<UnwrapWebhookEvent>;

  verifySignature(
    payload: string,
    headers: HeadersLike,
    secret?: string | undefined | null,
    tolerance?: number,
  ): Promise<void>;
}

Import

import OpenAI from 'openai';

I/O Contract

Inputs

Name Type Required Description
payload string Yes The raw webhook request body as a string.
headers HeadersLike Yes The request headers, must include webhook-id, webhook-timestamp, and webhook-signature.
secret undefined | null No The webhook secret. Falls back to client.webhookSecret or OPENAI_WEBHOOK_SECRET env var.
tolerance number No Maximum age of the webhook in seconds (default: 300).

Outputs

Name Type Description
UnwrapWebhookEvent Discriminated union A typed event object. Discriminated by the type field (e.g., 'batch.completed', 'fine_tuning.job.succeeded').
event.id string The unique event ID.
event.created_at number Unix timestamp (seconds) when the event was created.
event.type string The event type string (e.g., 'batch.completed').
event.data { id: string; ... } Event-specific data payload containing the resource ID.
event.object 'event' Always 'event'.

Usage Examples

import OpenAI from 'openai';

const client = new OpenAI({ webhookSecret: 'whsec_myBase64Secret==' });

// In an Express webhook handler
app.post('/webhooks/openai', async (req, res) => {
  try {
    const event = await client.webhooks.unwrap(
      req.body,       // raw string body
      req.headers,     // request headers
    );

    switch (event.type) {
      case 'batch.completed':
        console.log('Batch completed:', event.data.id);
        break;
      case 'fine_tuning.job.succeeded':
        console.log('Fine-tuning job succeeded:', event.data.id);
        break;
      case 'response.completed':
        console.log('Background response completed:', event.data.id);
        break;
    }

    res.status(200).send('OK');
  } catch (err) {
    console.error('Webhook verification failed:', err);
    res.status(400).send('Invalid signature');
  }
});

// Verify signature only (without parsing)
await client.webhooks.verifySignature(rawBody, headers, 'whsec_mySecret');

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment