Webhooks
Configure webhooks to receive real-time notifications when events occur in your Logproof account. Webhooks are HTTP callbacks that Logproof will POST to your specified URL.
Webhook Payload Format
All webhook deliveries use the following JSON structure:
{
"id": "wh_evt_1a2b3c4d5e6f",
"event": "event.created",
"data": {
// Event-specific data
},
"timestamp": "2026-02-10T14:30:00Z"
}
Signature Verification
Each webhook request includes an X-Logproof-Signature header containing an HMAC-SHA256
signature of the request body. Use your webhook secret to verify the signature and ensure the request
came from Logproof.
const crypto = require('crypto');
function verifySignature(body, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
function verifySignature($body, $signature, $secret) {
$expectedSignature = hash_hmac('sha256', $body, $secret);
return hash_equals($expectedSignature, $signature);
}
import hmac
import hashlib
def verify_signature(body, signature, secret):
expected_signature = hmac.new(
secret.encode(),
body.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected_signature, signature)
Retry Policy
If your webhook endpoint returns a non-2xx status code or times out, Logproof will retry the delivery up to 3 times with exponential backoff:
- 1st retry: after 1 minute
- 2nd retry: after 5 minutes
- 3rd retry: after 15 minutes
Create Webhook
https://logproof.de/v1/webhooks
Creates a new webhook endpoint to receive event notifications.
Required Scope: keys:manage
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | The HTTPS URL to send webhook payloads to |
events |
array | Yes | Array of event patterns to subscribe to (e.g., event.created, *) |
active |
boolean | No | Whether the webhook is active (default: true) |
Example Request
curl -X POST https://logproof.de/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/logproof",
"events": ["event.created", "event.verified"],
"active": true
}'
const response = await fetch('https://logproof.de/v1/webhooks', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://example.com/webhooks/logproof',
events: ['event.created', 'event.verified'],
active: true
})
});
const data = await response.json();
$client = new \GuzzleHttp\Client();
$response = $client->post('https://logproof.de/v1/webhooks', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
'Content-Type' => 'application/json'
],
'json' => [
'url' => 'https://example.com/webhooks/logproof',
'events' => ['event.created', 'event.verified'],
'active' => true
]
]);
$data = json_decode($response->getBody(), true);
import requests
response = requests.post(
'https://logproof.de/v1/webhooks',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'url': 'https://example.com/webhooks/logproof',
'events': ['event.created', 'event.verified'],
'active': True
}
)
data = response.json()
Response (201 Created)
{
"data": {
"id": "wh_1a2b3c4d5e6f",
"url": "https://example.com/webhooks/logproof",
"events": ["event.created", "event.verified"],
"active": true,
"secret": "whsec_1a2b3c4d5e6f7g8h9i0j",
"created_at": "2026-02-10T14:30:00Z"
}
}
secret is only returned once during creation. Store it securely
to verify webhook signatures. You cannot retrieve it later.
List Webhooks
https://logproof.de/v1/webhooks
Retrieves a list of all configured webhooks for your account.
Required Scope: keys:manage
Example Request
curl -X GET https://logproof.de/v1/webhooks \ -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch('https://logproof.de/v1/webhooks', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const data = await response.json();
$client = new \GuzzleHttp\Client();
$response = $client->get('https://logproof.de/v1/webhooks', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY'
]
]);
$data = json_decode($response->getBody(), true);
import requests
response = requests.get(
'https://logproof.de/v1/webhooks',
headers={
'Authorization': 'Bearer YOUR_API_KEY'
}
)
data = response.json()
Response Body
{
"data": [
{
"id": "wh_1a2b3c4d5e6f",
"url": "https://example.com/webhooks/logproof",
"events": ["event.created", "event.verified"],
"active": true,
"created_at": "2026-02-10T14:30:00Z"
},
{
"id": "wh_9z8y7x6w5v4u",
"url": "https://backup.example.com/hooks",
"events": ["*"],
"active": false,
"created_at": "2026-02-08T10:15:00Z"
}
]
}
Update Webhook
https://logproof.de/v1/webhooks/{id}
Updates the configuration of an existing webhook.
Required Scope: keys:manage
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | No | The new URL for the webhook |
events |
array | No | Updated array of event patterns |
active |
boolean | No | Enable or disable the webhook |
Example Request
curl -X PATCH https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": ["*"],
"active": false
}'
const response = await fetch('https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
events: ['*'],
active: false
})
});
const data = await response.json();
$client = new \GuzzleHttp\Client();
$response = $client->patch('https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
'Content-Type' => 'application/json'
],
'json' => [
'events' => ['*'],
'active' => false
]
]);
$data = json_decode($response->getBody(), true);
import requests
response = requests.patch(
'https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'events': ['*'],
'active': False
}
)
data = response.json()
Response Body
{
"data": {
"id": "wh_1a2b3c4d5e6f",
"url": "https://example.com/webhooks/logproof",
"events": ["*"],
"active": false,
"created_at": "2026-02-10T14:30:00Z"
}
}
Delete Webhook
https://logproof.de/v1/webhooks/{id}
Permanently deletes a webhook. This action cannot be undone.
Required Scope: keys:manage
Example Request
curl -X DELETE https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f \ -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch('https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
// Response status: 204 No Content
$client = new \GuzzleHttp\Client();
$response = $client->delete('https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY'
]
]);
// Response status: 204 No Content
import requests
response = requests.delete(
'https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f',
headers={
'Authorization': 'Bearer YOUR_API_KEY'
}
)
# Response status: 204 No Content
Response
Returns 204 No Content on successful deletion.
Get Delivery History
https://logproof.de/v1/webhooks/{id}/deliveries
Retrieves the delivery history for a specific webhook, including success and failure information.
Required Scope: keys:manage
Example Request
curl -X GET https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f/deliveries \ -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch('https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f/deliveries', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const data = await response.json();
$client = new \GuzzleHttp\Client();
$response = $client->get('https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f/deliveries', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY'
]
]);
$data = json_decode($response->getBody(), true);
import requests
response = requests.get(
'https://logproof.de/v1/webhooks/wh_1a2b3c4d5e6f/deliveries',
headers={
'Authorization': 'Bearer YOUR_API_KEY'
}
)
data = response.json()
Response Body
{
"data": [
{
"id": "wh_del_1a2b3c4d",
"event": "event.created",
"status": "success",
"status_code": 200,
"attempts": 1,
"delivered_at": "2026-02-10T14:30:00Z"
},
{
"id": "wh_del_5e6f7g8h",
"event": "event.verified",
"status": "failed",
"status_code": 500,
"attempts": 3,
"last_attempt_at": "2026-02-10T14:45:00Z",
"next_retry_at": null
}
]
}