Back to scouq.com

Webhooks

Stripe billing webhooks today. Custom deal-event webhooks on the roadmap.

Scouq exposes one inbound webhook endpoint for Stripe, which keeps user plan state in sync with billing events. Outbound webhooks for deal events (new match, score change, status change) are planned for a future release.

Stripe billing webhook

The Stripe webhook lives at POST /api/stripe-webhook. Stripe posts events here whenever a checkout completes, a subscription updates, or an invoice fails. Scouq updates the user's plan field in Supabase accordingly.

This is not an endpoint you call directly. It is the receive side of a webhook that Stripe sends. The only setup work is on the Stripe dashboard.

Endpoint URL

https://scouq.com/api/stripe-webhook

Events Scouq listens for

Stripe eventEffect
checkout.session.completedMarks the user's plan as paid based on the purchased product.
customer.subscription.updatedSyncs plan tier and active status.
customer.subscription.deletedDowngrades the user back to the free tier.
invoice.payment_failedFlags the account for retry; access is preserved through Stripe's grace window.

Setup

For self-hosted forks or for understanding how Scouq's billing is wired, see the full setup walkthrough in STRIPE.md at the repo root. The short version:

  1. In the Stripe dashboard, go to Developers, Webhooks, Add endpoint.
  2. Use the URL above as the endpoint URL.
  3. Select the four events listed above.
  4. Copy the signing secret Stripe generates and add it to Vercel as STRIPE_WEBHOOK_SECRET on both Preview and Production.
  5. Send a test event from the Stripe dashboard and confirm a 200 response.

Stripe verifies webhook authenticity with HMAC signatures. The signature header is Stripe-Signature. Scouq's endpoint rejects requests whose signature does not verify against STRIPE_WEBHOOK_SECRET.

Retry behavior

Scouq's endpoint must respond with a 2xx status within Stripe's timeout (currently 30 seconds) for the event to be considered delivered. Non-2xx responses cause Stripe to retry with exponential backoff for up to three days. The endpoint is idempotent on Stripe event id, so retries are safe.

Custom outbound webhooks Planned

Outbound webhooks let your system react to events inside Scouq without polling. The planned scope:

Each event will deliver a signed JSON payload to your endpoint, with an X-Scouq-Signature header containing an HMAC SHA-256 of the body. The shape will mirror the Stripe convention: a stable id, a type, and a data object.

If you have a concrete use case that should shape this design, file a request from the in-app feature request form so it can be prioritized.