Webhook Endpoints API
The Webhook Endpoints API allows you to manage webhook endpoints that receive real-time notifications when events occur in your TreasuryPath account.
Endpoints
- List Webhook Endpoints -
GET /api/v1/companies/{company_id}/webhook_endpoints - Create Webhook Endpoint -
POST /api/v1/companies/{company_id}/webhook_endpoints - Get Webhook Endpoint -
GET /api/v1/companies/{company_id}/webhook_endpoints/{id} - Update Webhook Endpoint -
PATCH /api/v1/companies/{company_id}/webhook_endpoints/{id} - Delete Webhook Endpoint -
DELETE /api/v1/companies/{company_id}/webhook_endpoints/{id} - Toggle Webhook Endpoint -
PATCH /api/v1/companies/{company_id}/webhook_endpoints/{id}/toggle
List Webhook Endpoints
Retrieve all webhook endpoints for a company.
Endpoint
Headers
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
active |
boolean | No | Filter by active status |
Example Request
curl -X GET "https://api.treasurypath.com/api/v1/companies/{company_id}/webhook_endpoints" \
-H "Authorization: Bearer {jwt_token}"
Success Response (200 OK)
{
"data": [
{
"id": "Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ",
"url": "https://your-app.com/webhooks/treasurypath",
"active": true,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z",
"subscribed_events_count": 3,
"webhook_subscribed_events": [
{
"id": "Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rU3Vic2NyaWJlZEV2ZW50LzE",
"event_name": "PaymentEvents::CompletedEvent",
"display_name": "Payment Completed",
"event_category": "payment",
"event_action": "completed"
}
]
}
],
"meta": {
"current_page": 1,
"total_pages": 1,
"total_count": 1,
"per_page": 25
}
}
Create Webhook Endpoint
Create a new webhook endpoint to receive event notifications.
Endpoint
Headers
Request Body
{
"url": "https://your-app.com/webhooks/treasurypath",
"active": true,
"company_id": "Z2lkOi8vd2FsbGV0LWFwcC9Db21wYW55LzE",
"event_names": [
"PaymentEvents::CompletedEvent",
"PaymentEvents::FailedEvent",
"BankAccountEvents::UpdatedEvent",
"PaymentProfileEvents::CreatedEvent"
]
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | HTTPS URL to receive webhook events |
active |
boolean | No | Whether endpoint is active (default: true) |
event_names |
array | Yes | Array of event names to subscribe to |
Example Request
curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/webhook_endpoints" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/treasurypath",
"event_names": ["PaymentEvents::CompletedEvent", "PaymentEvents::FailedEvent", "BankAccountEvents::CreatedEvent"]
}'
Success Response (201 Created)
{
"data": {
"id": "Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ",
"url": "https://your-app.com/webhooks/treasurypath",
"active": true,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z",
"subscribed_events_count": 3,
"webhook_secret": "whsec_1234567890abcdef"
}
}
Note: The webhook_secret is only returned once during creation. Store it securely to verify webhook signatures.
Get Webhook Endpoint
Retrieve details of a specific webhook endpoint.
Endpoint
Headers
Example Request
curl -X GET "https://api.treasurypath.com/api/v1/webhook_endpoints/Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ" \
-H "Authorization: Bearer {jwt_token}"
Success Response (200 OK)
{
"data": {
"id": "Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ",
"url": "https://your-app.com/webhooks/treasurypath",
"active": true,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z",
"subscribed_events_count": 3,
"webhook_subscribed_events": [
{
"event_name": "PaymentEvents::CompletedEvent",
"display_name": "Payment Completed"
}
]
}
}
Update Webhook Endpoint
Update an existing webhook endpoint.
Endpoint
Headers
Request Body
{
"url": "https://your-app.com/webhooks/treasurypath/v2",
"active": false,
"event_names": [
"PaymentEvents::CompletedEvent",
"PaymentEvents::FailedEvent",
"BankAccountEvents::CreatedEvent",
"PaymentProfileEvents::FailedEvent"
]
}
Example Request
curl -X PATCH "https://api.treasurypath.com/api/v1/webhook_endpoints/Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"active": false
}'
Success Response (200 OK)
{
"data": {
"id": "Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ",
"uuid": "webhook_123e4567-e89b-12d3-a456-426614174000",
"url": "https://your-app.com/webhooks/treasurypath/v2",
"active": false,
"updated_at": "2025-01-15T11:00:00Z"
}
}
Delete Webhook Endpoint
Delete a webhook endpoint.
Endpoint
Headers
Example Request
curl -X DELETE "https://api.treasurypath.com/api/v1/webhook_endpoints/Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ" \
-H "Authorization: Bearer {jwt_token}"
Success Response (204 No Content)
Toggle Webhook Endpoint
Toggle the active status of a webhook endpoint.
Endpoint
Headers
Example Request
curl -X PATCH "https://api.treasurypath.com/api/v1/webhook_endpoints/Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ/toggle" \
-H "Authorization: Bearer {jwt_token}"
Success Response (200 OK)
{
"data": {
"id": "Z2lkOi8vd2FsbGV0LWFwcC9XZWJob29rRW5kcG9pbnQvMQ",
"active": true,
"updated_at": "2025-01-15T11:15:00Z"
}
}
Available Events
To see all available webhook events, use the Available Events endpoint:
Endpoint
Example Response
{
"data": [
{
"category_name": "payment",
"display_name": "Payment Events",
"description": "Events related to payment processing",
"event_count": 4,
"events": [
{
"event_name": "PaymentEvents::CompletedEvent",
"display_name": "Payment Completed",
"action": "completed",
"description": "Triggered when a payment is completed"
},
{
"event_name": "PaymentEvents::FailedEvent",
"display_name": "Payment Failed",
"action": "failed",
"description": "Triggered when a payment is failed"
},
{
"event_name": "PaymentEvents::CancelledEvent",
"display_name": "Payment Cancelled",
"action": "cancelled",
"description": "Triggered when a payment is cancelled"
},
{
"event_name": "PaymentEvents::DebitInitiatedEvent",
"display_name": "Payment Debit Initiated",
"action": "debit_initiated",
"description": "If payment has a payment order with direction debit, this event is triggered"
}
]
},
{
"category_name": "bank_account",
"display_name": "Bank Account Events",
"description": "Events related to bank account management",
"event_count": 3,
"events": [
{
"event_name": "BankAccountEvents::CreatedEvent",
"display_name": "Bank Account Created",
"action": "created",
"description": "Triggered when a bank account is created"
},
{
"event_name": "BankAccountEvents::UpdatedEvent",
"display_name": "Bank Account Updated",
"action": "updated",
"description": "Triggered when a bank account is updated"
},
{
"event_name": "BankAccountEvents::DeletedEvent",
"display_name": "Bank Account Deleted",
"action": "deleted",
"description": "Triggered when a bank account is deleted"
}
]
},
{
"category_name": "payment_profile",
"display_name": "Payment Profile Events",
"description": "Events related to payment profile management",
"event_count": 2,
"events": [
{
"event_name": "PaymentProfileEvents::CreatedEvent",
"display_name": "Payment Profile Created",
"action": "created",
"description": "Triggered when a payment profile is created"
},
{
"event_name": "PaymentProfileEvents::FailedEvent",
"display_name": "Payment Profile Failed",
"action": "failed",
"description": "Triggered when a payment profile becomes unable to be used for payments"
}
]
}
]
}
Error Responses
400 Bad Request
{
"error": {
"code": "validation_error",
"message": "Invalid webhook URL format",
"details": [
{
"field": "url",
"message": "URL must use HTTPS"
}
]
}
}
404 Not Found
Webhook Security
Signature Verification
All webhook requests include a TreasuryPath-Signature header containing an HMAC-SHA256 signature of the request payload. This signature is generated using your webhook endpoint's unique secret key.
Header Format:
Verification Process:
1. Extract the signature from the header (remove the sha256= prefix)
2. Generate the expected signature using HMAC-SHA256 with your webhook secret and the raw request body
3. Compare the signatures using a secure comparison function to prevent timing attacks
Example Implementation:
import hmac
import hashlib
def verify_webhook_signature(payload, signature_header, webhook_secret):
# Extract signature from header
signature = signature_header.replace('sha256=', '')
# Generate expected signature
expected = hmac.new(
webhook_secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
# Use secure comparison
return hmac.compare_digest(expected, signature)
# Usage
if verify_webhook_signature(request_body, signature_header, webhook_secret):
# Process webhook
process_webhook_event(request_body)
else:
# Invalid signature - reject request
return 401
Important Notes: - Always use the raw request body for signature verification (before JSON parsing) - Use secure comparison functions to prevent timing attacks - The webhook secret is only provided once during endpoint creation - store it securely
Retry Mechanism
TreasuryPath automatically retries failed webhook deliveries: - Retry Schedule: 1 minute, 5 minutes, 25 minutes, 125 minutes (up to 5 total attempts) - Signature Consistency: Each retry uses the same signature as the original request - Failure Conditions: Non-200 HTTP status codes or request timeouts (30 seconds)
Best Practices
- Use HTTPS: Only HTTPS URLs are accepted for webhook endpoints
- Verify signatures: Always verify webhook signatures before processing events
- Handle retries: Implement idempotent processing using event IDs to handle duplicate events
- Respond quickly: Return 200 status within 30 seconds to avoid timeouts
- Handle failures: Monitor webhook delivery logs and implement alerting for failed deliveries
- Test thoroughly: Use webhook testing tools during development to verify signature verification
- Secure secrets: Store webhook secrets securely and never log them