Webhooks
Receive real-time HTTP notifications when billing events happen in Paid
Paid can send HTTP POST requests to your system whenever important billing events happen. You configure webhooks in the Paid app under Settings > Webhooks, or manage them programmatically through the API.
This page covers:
- Which webhook events Paid supports today
- What the webhook payloads look like
- How to configure and manage webhooks
- How to test deliveries
Supported events
Envelope format
Every webhook uses the same top-level envelope:
eventidentifies which webhook firedtimestampis the time Paid created the delivery in RFC 3339 formatisTestistruefor test deliveries sent from the UIdatacontains the event-specific payload, keyed by the primary payload key listed above
How delivery works
Each webhook event is configured independently. In the Paid UI you can:
- Open Settings > Webhooks
- Choose the event you want to receive
- Enter the receiver URL in your system
- Enable the webhook
- Use the Test button to send a sample payload
Paid sends webhook requests as HTTP POST calls. Your endpoint should:
- Accept JSON request bodies with
Content-Type: application/json - Return a
2xxresponse quickly after validating and enqueueing work - Treat deliveries as retriable and idempotent on your side
- Deduplicate using the business identifiers in the payload, not the delivery timestamp
Managing webhooks through the API
You can manage webhooks programmatically through the v2 API with an organization API key.
List all webhooks
Configure a webhook
Send a test delivery
Test deliveries only work after the webhook has a valid URL configured and
enabled is set to true.
Event payload examples
Payment succeeded
Field notes:
payment.statusis currentlypostedpayment.invoiceIdandpayment.invoiceNumbercan benullwhen the payment is not linked to an invoicepayment.externalPaymentIdcan benullwhen there is no upstream processor referencepaymentDateis the effective payment timestamp in RFC 3339 format
Payment failed
Field notes:
payment.statusis currentlyfailedfailureReasonis a human-readable failure message when one is availablefailureDateis when Paid recorded the failed attempt in RFC 3339 formatinvoiceId,invoiceNumber, andexternalPaymentIdcan benull
Credits depleted
Field notes:
remainingCreditsis0when this event firescreditsCurrencyIdcan benullif the depleted balance is not scoped to a credits currencysignalIdis the Paid signal that pushed the balance to zeroeventNameis the original signal event name that consumed the final credits
Overage incurred
Field notes:
eventTypeis one ofOverageUsageorOverageCreditthresholdis the included usage limit that was crossedcurrentUsageis the usage value observed when the overage condition was detectedcustomerId,customerName,planName,threshold, andcurrentUsagecan benullin edge cases
Implementation checklist
Before you enable a webhook in Paid, make sure your receiver:
- Accepts unauthenticated HTTPS
POSTrequests from Paid at a stable public URL - Parses the top-level envelope first, then branches on
event - Handles
nullvalues for optional fields likeinvoiceId,invoiceNumber,externalPaymentId,customerName,planName,threshold, andcurrentUsage - Returns a
2xxafter persisting or queueing the event - Ignores or separately labels
isTest: truedeliveries in your downstream systems - Safely ignores unknown
eventvalues for forward compatibility as new events are added
Testing from the Paid UI
Use the Test button in Settings > Webhooks to send a synthetic event to your receiver.
- Test deliveries use the same envelope shape as production deliveries
isTestis set totrue- IDs in the nested payload are synthetic test IDs such as
pay_test_*,cust_test_*,ola_test_*, orplan_test_* - Test payloads are intended to validate parsing and routing, not to represent real billing records in your system