Configure Webhooks via API
Overview
The webhook configuration API allows you to programmatically define where your application will receive PIX event notifications. This eliminates the need to contact support to configure webhooks.
Changes to webhook configuration are applied immediately. Subsequent transactions will use the newly configured URL.
Endpoint
POST /api/webhooks
Authentication
Requires an Account Bearer token in the Authorization header.
Authorization: Bearer {account_token}The token must be obtained through the authentication endpoint using your client certificate.
Parameters
stringobrigatorioHTTPS URL of your webhook endpoint.
Requirements:
- Must use HTTPS protocol (HTTP is not accepted)
- Must be a valid and accessible URL
Example: https://api.example.com/webhooks/pix
stringobrigatorioEvent type to receive notifications for.
Possible values:
cash_in- PIX receivedcash_out- PIX sentrefund_in- Received payment refund (refund requested)refund_out- Refund received
arrayCustom headers for your endpoint authentication (maximum 5).
Each item must have:
key: Header namevalue: Header value
Blocked headers (not allowed):
- host
- content-length
- connection
- transfer-encoding
- content-type
- user-agent
Request Example
curl -X POST https://api.safirapay.com/api/webhooks \
-H "Authorization: Bearer {account_token}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhooks/pix",
"eventType": "cash_in",
"headers": [
{
"key": "Authorization",
"value": "Bearer my-secret-token"
},
{
"key": "X-Webhook-Secret",
"value": "abc123"
}
]
}'const response = await fetch('https://api.safirapay.com/api/webhooks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accountToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://api.example.com/webhooks/pix',
eventType: 'cash_in',
headers: [
{ key: 'Authorization', value: 'Bearer my-secret-token' },
{ key: 'X-Webhook-Secret', value: 'abc123' },
],
}),
});
const data = await response.json();
console.log(data);import requests
response = requests.post(
'https://api.safirapay.com/api/webhooks',
headers={
'Authorization': f'Bearer {account_token}',
'Content-Type': 'application/json',
},
json={
'url': 'https://api.example.com/webhooks/pix',
'eventType': 'cash_in',
'headers': [
{'key': 'Authorization', 'value': 'Bearer my-secret-token'},
{'key': 'X-Webhook-Secret', 'value': 'abc123'},
],
},
)
print(response.json())Response Example
{
"success": true,
"message": "Webhook configured successfully"
}Upsert Behavior
If a webhook is already configured for the same eventType, it will be updated with the new URL and headers. No duplicate webhook is created.
When updating an existing webhook, previous headers are replaced with the new ones. If you don't send headers, previous headers will be removed.
Error Codes
| Code | Description |
|---|---|
| 400 | Invalid URL (not HTTPS), invalid event type, or more than 5 headers |
| 401 | Token not provided or invalid |
| 404 | Account not found |
| 500 | Internal error configuring webhook |
Configuring Multiple Events
To receive notifications for multiple event types, make a call for each type:
const eventTypes = ['cash_in', 'cash_out', 'refund_in', 'refund_out'];
for (const eventType of eventTypes) {
await fetch('https://api.safirapay.com/api/webhooks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accountToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://api.example.com/webhooks/pix',
eventType,
headers: [
{ key: 'X-Webhook-Secret', value: 'abc123' },
],
}),
});
}You can use the same URL for all event types and differentiate by the type field in the webhook payload.