Webhooks
Webhooks deliver event notifications from Floatless to your application when billing state changes.
Webhook documentation belongs in the website docs. Webhook endpoints and signing secrets can be managed in the product console or through the Public API.
Endpoint management API
| Method | Endpoint | Description |
|---|---|---|
| POST | /webhook-endpoints |
Create a webhook endpoint |
| GET | /webhook-endpoints |
List webhook endpoints |
| GET | /webhook-endpoints/{endpoint_id} |
Retrieve a webhook endpoint |
| PATCH | /webhook-endpoints/{endpoint_id} |
Update URL, event subscriptions, status, or description |
| DELETE | /webhook-endpoints/{endpoint_id} |
Delete a webhook endpoint |
Delivery history API
| Method | Endpoint | Description |
|---|---|---|
| GET | /webhook-events |
List webhook delivery events |
| GET | /webhook-events/{event_id} |
Retrieve one webhook delivery event |
| POST | /webhook-events/{event_id}/retry |
Retry a failed or retrying webhook event |
Create a webhook endpoint
curl https://api.floatless.com/api/public/v1/webhook-endpoints \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/floatless",
"events": ["invoice.paid", "subscription.*"],
"description": "Production billing events"
}'
The creation response includes the signing secret once:
{
"data": {
"id": "0d75f867-0f90-4d32-aeb6-2df8136bdfc2",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/floatless",
"events": ["invoice.paid", "subscription.*"],
"status": "ACTIVE",
"description": "Production billing events",
"created_at": "2026-07-07T10:00:00Z",
"updated_at": "2026-07-07T10:00:00Z",
"secret": "whsec_..."
}
}
Store the secret securely. It is not returned by list, retrieve, or update responses.
URL requirements
Production webhook URLs must use HTTPS.
Local development URLs using http://localhost or http://127.0.0.1 are allowed for testing.
Event subscriptions
You can subscribe to specific events or family wildcards.
| Event | Description |
|---|---|
invoice.created |
Invoice created |
invoice.posted |
Invoice issued |
invoice.paid |
Invoice paid |
invoice.overdue |
Invoice moved overdue |
invoice.payment_failed |
Invoice payment failed |
subscription.created |
Subscription created |
subscription.updated |
Subscription changed |
subscription.canceled |
Subscription canceled |
subscription.activated |
Subscription activated |
payment.succeeded |
Payment succeeded |
payment.failed |
Payment failed |
customer.created |
Customer created |
customer.updated |
Customer updated |
Supported wildcards:
invoice.*subscription.*order.*payment.*customer.*
List webhook events
curl "https://api.floatless.com/api/public/v1/webhook-events?status=FAILED&limit=25" \
-H "Authorization: Bearer sk_live_..."
Query parameters
| Parameter | Type | Description |
|---|---|---|
endpoint_id |
UUID | Filter by endpoint |
status |
string | PENDING, SUCCESS, FAILED, or RETRYING |
event_type |
string | Filter by event type |
limit |
integer | Number of results, 1 to 100 |
offset |
integer | Pagination offset |
Retry a webhook event
curl https://api.floatless.com/api/public/v1/webhook-events/64d63c4a-3817-4d5d-bd38-bad334be58aa/retry \
-H "Authorization: Bearer sk_live_..." \
-X POST
Successful events cannot be retried.
Payload shape
{
"id": "evt_abc123",
"type": "invoice.paid",
"created_at": "2026-07-07T10:30:00Z",
"data": {
"id": "5b4c33b4-6a86-4e5d-9fd9-2d3a7f09d874",
"object": "invoice",
"customer_id": 123,
"status": "PAID"
}
}
Delivery headers
Webhook deliveries include:
| Header | Description |
|---|---|
X-Floatless-Signature |
HMAC SHA-256 signature |
X-Floatless-Event |
Event type |
X-Floatless-Delivery |
Delivery event ID |
User-Agent |
Floatless-Webhooks/1.0 |
Endpoint requirements
- Use HTTPS in production.
- Return a 2xx response after receiving and validating the event.
- Process expensive work asynchronously.
- Store processed event IDs to handle duplicate delivery.
- Treat webhook delivery as at-least-once.
Signature verification
Every endpoint has a signing secret. Use it to verify incoming webhook requests before trusting the payload.
The signature value is generated with HMAC SHA-256 over the raw JSON payload and formatted as sha256=<hex_digest>.