openai/openai-python · error · ValueError

The webhook secret must either be set using the env var, OPE

Error message

The webhook secret must either be set using the env var, OPENAI_WEBHOOK_SECRET, on the client class, OpenAI(webhook_secret='123'), or passed to this function

What it means

Webhooks.verify_signature needs the shared secret used to sign incoming webhook payloads. It first uses the explicitly passed secret, then falls back to the client's webhook_secret (populated from the OPENAI_WEBHOOK_SECRET env var or the webhook_secret constructor argument); if both are unset it raises this ValueError. This is a configuration error, not a payload problem.

Source

Thrown at src/openai/resources/webhooks/webhooks.py:60

        payload: str | bytes,
        headers: HeadersLike,
        *,
        secret: str | None = None,
        tolerance: int = 300,
    ) -> None:
        """Validates whether or not the webhook payload was sent by OpenAI.

        Args:
            payload: The webhook payload
            headers: The webhook headers
            secret: The webhook secret (optional, will use client secret if not provided)
            tolerance: Maximum age of the webhook in seconds (default: 300 = 5 minutes)
        """
        if secret is None:
            secret = self._client.webhook_secret

        if secret is None:
            raise ValueError(
                "The webhook secret must either be set using the env var, OPENAI_WEBHOOK_SECRET, "
                "on the client class, OpenAI(webhook_secret='123'), or passed to this function"
            )

        if not _webhook_signature_matches(payload, headers, secret=secret, tolerance=tolerance):
            raise InvalidWebhookSignatureError(
                "The given webhook signature does not match the expected signature"
            ) from None


class AsyncWebhooks(AsyncAPIResource):
    def unwrap(
        self,
        payload: str | bytes,
        headers: HeadersLike,
        *,
        secret: str | None = None,
    ) -> UnwrapWebhookEvent:

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Set the OPENAI_WEBHOOK_SECRET environment variable where the app runs
  2. Or pass the secret when constructing the client: OpenAI(webhook_secret='...')
  3. Or pass secret=... directly to verify_signature/unwrap
  4. Verify with print(os.environ.get('OPENAI_WEBHOOK_SECRET')) that the var is visible to the process

Example fix

# before
client = OpenAI()
client.webhooks.unwrap(payload, headers)

# after
client = OpenAI(webhook_secret=os.environ["OPENAI_WEBHOOK_SECRET"])
event = client.webhooks.unwrap(payload, headers)
Defensive patterns

Strategy: validation

Validate before calling

secret = os.environ.get("OPENAI_WEBHOOK_SECRET") or getattr(client, "webhook_secret", None)
if not secret:
    raise RuntimeError("Webhook secret not configured (set OPENAI_WEBHOOK_SECRET)")

Try / catch

try:
    event = client.webhooks.unwrap(payload, headers)
except ValueError as e:
    if "webhook secret" in str(e):
        return Response("Webhook not configured", 503)
    raise

Prevention

When it happens

Trigger: Calling client.webhooks.verify_signature(payload, headers) (or unwrap, which calls it) without passing secret while OPENAI_WEBHOOK_SECRET is unset and the client was constructed without webhook_secret='...'.

Common situations: Local development where the env var is only set in production, CI runs missing the secret, deploying with a different process manager that drops the environment, or forgetting to configure it after adding webhook handling.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/f375b51c3fb47c39. Report an issue: GitHub.