Skip to content

Outbound Webhooks

NuxtBase lets each organization register its own outbound webhook endpoints.

This is separate from the Stripe inbound webhook endpoint. Here, NuxtBase is the sender.

Webhook endpoints are organization-scoped and manager-controlled.

The create, update, and delete APIs require the active user to be an organization:

  • owner
  • admin

Regular members do not get webhook management actions in the dashboard.

The shipped event list is:

  • member.added
  • member.removed
  • member.role_changed
  • team_member.added
  • team_member.removed
  • subscription.created
  • subscription.updated
  • subscription.cancelled
  • project.created
  • project.deleted

This list is validated in shared schema code, so it is not just a UI convention.

The normal management flow is:

  1. create an endpoint URL
  2. choose one or more subscribed events
  3. save the endpoint and store the generated secret
  4. toggle active state or edit event selection later
  5. delete the endpoint if it is no longer needed

Each endpoint gets its own secret in this format:

whsec_...

When an event is dispatched, the webhook service:

  1. loads endpoints for the organization
  2. filters to active endpoints that subscribed to the event
  3. signs the JSON payload with HMAC-SHA256
  4. sends a POST request with webhook headers
  5. records a delivery log row
  6. retries failures until the total attempt count reaches 3

In the current template, that means:

  • 1 initial delivery attempt
  • up to 2 retry attempts

The retry schedule is:

  • after 1 minute
  • after 5 minutes

The third slot in the retry delay array is not reached by the current MAX_RETRIES = 3 logic, because the service only schedules another delivery when attempt < MAX_RETRIES.

The outgoing request includes:

  • X-Webhook-Signature
  • X-Webhook-Event
  • X-Webhook-Timestamp

Your receiver should verify the signature against the raw JSON body using the endpoint secret.

NuxtBase stores delivery metadata locally, including:

  • endpoint ID
  • event name
  • payload
  • HTTP status code
  • truncated response text
  • attempt count
  • next retry time

That makes webhook failures observable without needing external logging first.

For quick webhook debugging, Webhook.site is a useful external receiver.

Official Webhook.site references:

Practical debugging flow:

  1. Open Webhook.site and copy the unique URL it generates for you.
  2. Create a NuxtBase outbound webhook endpoint with that URL.
  3. Subscribe the endpoint to one or more events.
  4. Trigger a real event in NuxtBase.
  5. Inspect the received request on Webhook.site, including the JSON body, headers, and response code.
  6. Compare the received X-Webhook-Event, X-Webhook-Timestamp, and X-Webhook-Signature headers with what your receiver expects.

This is especially useful when you want to confirm:

  • the payload shape is correct
  • the right event names are being sent
  • headers are present before you start debugging signature verification code
  • retries are happening after a failed response

According to the official Webhook.site FAQ, free URLs expire after 7 days and stop accepting new requests after 100 requests. That is fine for quick local debugging, but not something you should treat as your long-term customer endpoint.

If you need to forward captured requests to a local machine, Webhook.site’s docs point to three approaches:

  • fetch data through the API
  • stream requests to localhost with the Webhook.site CLI
  • use XHR Redirect if your local endpoint can answer with the required CORS headers