GPT-5.5 & Codex API access - $19/week, $76/month, or $59 first month with UNLIMITED59 when configuredSee packagesvs OpenAI API

Webhooks

Prepare your product for webhook events.

Create and manage customer webhook endpoints for usage, billing, and API key lifecycle events, then prepare receivers for signed delivery, retries, and redacted observability.

Last updated: July 6, 2026. Examples use safe placeholders and do not include real secrets, API keys, or customer payloads.

Receiver rule

Prepare receivers to verify the raw payload signature first, record each event ID once, and return 2xx only after your app can safely process or ignore the event.

Setup path

Five steps from endpoint URL to delivery readiness.

Step 1

Create a receiver endpoint

Expose an HTTPS URL that accepts POST requests and can read the raw request body before JSON parsing.

Open

Step 2

Select events

Choose the usage, subscription, invoice, or API key lifecycle event types your receiver should be ready for.

Open

Step 3

Store the signing secret

Copy the endpoint secret once and save it in a secret manager so receivers are ready for signed webhook delivery.

Open

Step 4

Plan retry handling

Design idempotent receivers so repeated delivery attempts are safe when webhook sending is enabled.

Open

Step 5

Plan observability

Track endpoint status now and define the delivery records your team will need for future webhook sending.

Open

Endpoint URL

Register one endpoint per environment.

Use separate URLs for development, staging, and production so future test deliveries never trigger production side effects.

{
  "name": "Production usage events",
  "url": "https://example.com/api/unlimitedcodex/webhook",
  "events": [
    "usage.threshold_reached",
    "subscription.updated",
    "invoice.payment_failed"
  ]
}

Event selection

Select event types your receiver should be ready for.

Keep each receiver narrow while delivery is being prepared. A billing service may only need invoice events, while a usage guardrail may only need threshold-event fixtures.

Webhook events, trigger context, and receiver use cases.
EventTrigger contextReceiver use case
usage.threshold_reachedA workspace crosses a configured usage threshold.Prepare account-owner messaging, pause expensive jobs, or ask billing owners to review package fit.
subscription.updatedThe subscription state, package, or billing period changes.Refresh local entitlements and access details.
api_key.revokedAn API key is revoked.Invalidate cached credentials and prepare an owning-team notification.
invoice.paidAn invoice is marked paid.Unlock paid access, reconcile billing state, or update account records.
invoice.payment_failedAn invoice payment fails.Prepare a dunning flow, account-owner messaging, or limits for risky background usage.

Signing secret

Verify the raw body before processing.

Webhook signing secrets are shown once. Store the secret in an environment variable or secret manager, then use it to validate timestamped HMAC SHA-256 signatures when webhook sending is enabled.

The signature value uses t=timestamp,v1=signature. This example names the header x-ucx-signature; use the signature header shown for your delivery.

import { createHmac, timingSafeEqual } from "crypto";

function verifySignature(rawBody, signatureHeader, secret) {
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((part) => part.split("="))
  );
  const timestamp = Number(parts.t);
  const signature = parts.v1;

  if (!Number.isInteger(timestamp) || !signature) {
    return false;
  }

  const signedPayload = `${timestamp}.${rawBody}`;
  const expected = createHmac("sha256", secret)
    .update(signedPayload)
    .digest("hex");
  const left = Buffer.from(expected, "hex");
  const right = Buffer.from(signature, "hex");

  return left.length === right.length && timingSafeEqual(left, right);
}

Receiver example

Keep handlers small and idempotent.

Use this receiver pattern once outbound delivery is enabled: parse the event after signature verification, record the event ID, then hand off slow work to your own queue.

export async function POST(request) {
  const rawBody = await request.text();
  const signature = request.headers.get("x-ucx-signature") ?? "";
  const secret = process.env.UCX_WEBHOOK_SECRET;

  if (!secret || !verifySignature(rawBody, signature, secret)) {
    return new Response("Invalid signature", { status: 400 });
  }

  const event = JSON.parse(rawBody);

  // Store event.id before doing side effects so retries stay idempotent.
  await recordWebhookEvent(event.id, event.type);

  return Response.json({ received: true });
}

Safe payload shape

Event payloads should be treated as operational metadata. Do not put prompts, raw API keys, payment card data, or customer secrets in webhook fixtures or logs.

{
  "id": "evt_example_123",
  "type": "usage.threshold_reached",
  "created": "2026-07-06T12:00:00.000Z",
  "data": {
    "workspaceId": "workspace_example",
    "metric": "requests",
    "thresholdPercent": 80
  }
}

Retries

Design for repeated delivery attempts.

When webhook sending is enabled, network failures, timeouts, and non-2xx responses can lead to retry attempts. Build handlers that can receive the same event more than once without duplicating side effects.

Return 2xx after durable work

Write the event ID or enqueue the work before returning success.

Use event IDs for idempotency

Ignore duplicates that have already been recorded or processed.

Keep handlers fast

Move email, billing sync, and long jobs to an internal queue.

Do not depend on exact ordering

Use current resource state when possible instead of assuming events arrive in sequence.

Observability

Plan for redacted endpoint context.

Plan delivery records around redacted operational context such as event type, endpoint, status, attempt count, response status, response body, next retry time, and delivery time.

Require HTTPS for production endpoint URLs.

Verify the timestamped HMAC signature before trusting the payload.

Store signing secrets in a secret manager, not source code.

Treat event handlers as idempotent because delivery attempts can repeat.

Return 2xx only after the event is safely recorded or intentionally ignored.

Do not log raw signing secrets, API keys, payment details, prompts, or customer payloads.

Local testing

Test with a tunnel before production.

Point a development webhook endpoint at a temporary tunnel, prepare a safe event fixture, verify the signature helper, and confirm your handler stores a single event record.

# Use a local tunnel URL as the endpoint while testing.
https://your-tunnel.example/api/unlimitedcodex/webhook

# Keep the signing secret out of source code.
UCX_WEBHOOK_SECRET=whsec_ucx_placeholder_value

FAQ

Webhook setup questions.

Which events can I subscribe to?

Customer webhook endpoint management supports selecting usage.threshold_reached, subscription.updated, api_key.revoked, invoice.paid, and invoice.payment_failed so receivers can be configured before webhook sending is enabled.

How are webhook deliveries signed?

Prepare receivers for a timestamped HMAC SHA-256 signature. The signature value follows the t=timestamp,v1=signature format, and receivers should verify it against the raw request body and signing secret.

What delivery assumptions should my handler make?

When webhook sending is enabled, do not assume a single delivery, strict ordering, or a successful final attempt. Build idempotent handlers and record event IDs before side effects.

Can I rotate a webhook signing secret?

Yes. Rotating an endpoint creates a new signing secret that is shown once. Store the new value securely and update the receiver before depending on it in production.

Ready to prepare event receivers?

Pair webhooks with usage and billing controls.

Review package fit, rate-limit behavior, and error handling before customer-event workflows affect customer-facing systems.