Notifications and streams have different jobs
Webhooks let a backend react without holding a stream open. Session notifications include created, action_required, in_progress, idle, and failed. For action_required, retrieve the session to obtain current required_actions; the notification does not contain all function arguments or connection details.
Verify before trusting the event
Create an endpoint in the OpenAI dashboard and store its signing secret server-side. Verify the original request body and headers with the OpenAI SDK before parsing or processing. JSON parsing and re-serialization can change signed bytes. The webhook signing secret is separate from the application API key and executor environment key.
// Server-side verification boundary; call before accepting work.
// Install openai and set OPENAI_API_KEY + OPENAI_WEBHOOK_SECRET.
import OpenAI from "openai";
const client = new OpenAI({
webhookSecret: process.env.OPENAI_WEBHOOK_SECRET,
});
export async function verifyNotification(rawBody, headers) {
await client.webhooks.verifySignature(rawBody, headers);
return JSON.parse(rawBody);
}
// Your HTTP handler must then durably store the verified event.
// Return success only after that write commits.
// Verification alone does not queue or execute the work.Use a durable inbox
Application architecture: insert the verified event into a database inbox with a unique event ID. Acknowledge only after the insert commits. A worker can poll this inbox, avoiding a gap between saving an event and publishing to a separate queue. For an external queue, use a transactional outbox or equivalent durable delivery design. An in-memory Set does not survive restarts.
Make the worker safe to repeat
Retrieve current session state before acting: a notification may refer to an already-resolved action. Route environment_connection to the compute controller and function_call to an authorized tool handler. Deduplicate business effects using a stable operation key as well as deduplicating webhook delivery. A crash after a side effect but before marking completion must not charge a customer twice.
Test delivery failures
Exercise invalid signatures, duplicate delivery, unavailable storage, stale actions, and a worker crash. Return a non-success status if durable acceptance fails. Record event and session IDs for correlation without logging secrets or unrestricted tool payloads. Show pending, failed, and completed job states separately in the UI.
Read the official reference
Check the source for current API fields, account requirements, and service limits.
OpenAI: webhooks