-
-
Notifications
You must be signed in to change notification settings - Fork 1
API Webhooks
Subscribe to real-time events for bill and transaction activity. Webhooks send HTTP POST requests to your configured URL whenever a matching event occurs. All webhook operations require an active team context.
Base path: /api/v1/webhooks
| Method | Endpoint | Description |
|---|---|---|
GET |
/webhooks/events |
List available webhook events |
GET |
/webhooks |
List webhooks for active team |
POST |
/webhooks |
Create a webhook |
GET |
/webhooks/{webhook} |
Get a single webhook |
PUT |
/webhooks/{webhook} |
Update a webhook |
DELETE |
/webhooks/{webhook} |
Delete a webhook |
GET |
/webhooks/{webhook}/deliveries |
Get delivery history |
POST |
/webhooks/{webhook}/deliveries/{delivery}/retry |
Retry a failed delivery |
| Event | Trigger |
|---|---|
bill.created |
A new bill is created |
bill.updated |
A bill is updated |
bill.paid |
A bill is marked as paid |
bill.deleted |
A bill is deleted |
transaction.created |
A new transaction is recorded |
transaction.updated |
A transaction is updated |
transaction.deleted |
A transaction is deleted |
Response 200:
{
"success": true,
"data": [
{ "name": "bill.created", "description": "Triggered when a new bill is created" },
{ "name": "bill.updated", "description": "Triggered when a bill is updated" },
{ "name": "bill.paid", "description": "Triggered when a bill is marked as paid" },
{ "name": "bill.deleted", "description": "Triggered when a bill is deleted" },
{ "name": "transaction.created","description": "Triggered when a new transaction is created" },
{ "name": "transaction.updated","description": "Triggered when a transaction is updated" },
{ "name": "transaction.deleted","description": "Triggered when a transaction is deleted" }
]
}List all webhooks configured for the active team.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
search |
string | Search name/URL |
status |
string |
active · inactive · failed
|
event |
string | Filter by specific event name |
sort_by |
string | Column to sort by |
sort_direction |
string |
asc or desc
|
per_page |
integer | Results per page (max: 100) |
Response 200:
{
"data": [
{
"id": 1,
"name": "Bill Notifications",
"url": "https://example.com/webhooks/bills",
"events": ["bill.created", "bill.paid"],
"status": "active",
"retry_count": 0,
"created_at": "2026-02-01T00:00:00.000Z"
}
],
"links": { ... },
"meta": { ... }
}Create a new webhook subscription.
Request:
{
"name": "Bill Notifications",
"url": "https://example.com/webhooks/bills",
"events": ["bill.created", "bill.paid"],
"active": true
}| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Descriptive webhook name |
url |
string | Yes | HTTPS endpoint that will receive POST requests |
events |
array | Yes | List of event names to subscribe to |
active |
boolean | No | Enable immediately (default: true) |
Response 201:
{
"success": true,
"message": "Webhook created successfully",
"data": {
"id": 1,
"name": "Bill Notifications",
"url": "https://example.com/webhooks/bills",
"events": ["bill.created", "bill.paid"],
"status": "active"
}
}Get a single webhook with full details including delivery statistics.
Response 200:
{
"success": true,
"data": {
"id": 1,
"name": "Bill Notifications",
"url": "https://example.com/webhooks/bills",
"events": ["bill.created", "bill.paid"],
"status": "active",
"retry_count": 0,
"last_triggered_at": "2026-02-05T10:30:00.000Z",
"created_at": "2026-02-01T00:00:00.000Z",
"updated_at": "2026-02-01T00:00:00.000Z"
}
}Update a webhook. All fields are optional.
Request:
{
"name": "All Bill Events",
"url": "https://example.com/webhooks/updated",
"events": ["bill.created", "bill.updated", "bill.paid", "bill.deleted"],
"active": true
}Response 200:
{
"success": true,
"message": "Webhook updated successfully",
"data": {
"id": 1,
"name": "All Bill Events",
"url": "https://example.com/webhooks/updated"
}
}Delete a webhook and all its delivery history.
Response 200:
{
"success": true,
"message": "Webhook deleted successfully"
}Get the delivery history for a webhook. Useful for debugging failed deliveries.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status |
string |
pending · delivered · failed
|
event |
string | Filter by event name |
date_from |
date | Filter from date (YYYY-MM-DD) |
date_to |
date | Filter to date (YYYY-MM-DD) |
sort_direction |
string |
asc or desc (default: desc) |
per_page |
integer | Results per page (max: 100) |
Response 200:
{
"data": [
{
"id": 1,
"webhook_id": 1,
"event": "bill.created",
"status": "delivered",
"payload": { },
"response_status_code": 200,
"response_body": "OK",
"attempts": 1,
"next_retry_at": null,
"delivered_at": "2026-02-05T10:30:00.000Z",
"created_at": "2026-02-05T10:30:00.000Z"
}
],
"links": { ... },
"meta": { ... }
}Manually queue a retry for a failed webhook delivery.
Response 200:
{
"success": true,
"message": "Delivery retry queued successfully",
"data": {
"id": 1,
"status": "pending",
"next_retry_at": "2026-02-05T10:35:00.000Z"
}
}When an event fires, the payload sent to your endpoint follows this structure:
{
"event": "bill.created",
"team_id": 1,
"timestamp": "2026-04-23T12:00:00.000Z",
"data": {
"id": 1,
"title": "Netflix Subscription",
"amount": 15.99
}
}Your endpoint should respond with a 2xx status code to acknowledge receipt.
TOKEN="YOUR_TOKEN"
BASE="https://bills.msar.me/api/v1"
# List available events
curl "$BASE/webhooks/events" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json"
# Create a webhook
curl -X POST "$BASE/webhooks" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My Webhook",
"url": "https://example.com/hook",
"events": ["bill.paid", "transaction.created"]
}'
# View delivery history (failed only)
curl "$BASE/webhooks/1/deliveries?status=failed" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json"
# Retry a failed delivery
curl -X POST "$BASE/webhooks/1/deliveries/5/retry" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json"© Bill Organizer - Free for Personal use | Need paid license for Commercial use