Appearance
Destinations
A destination is one of your own URLs that should receive forwarded events for a source. Each source can have many destinations, optionally filtered by event type.
Base URL: https://app.krafter.dev/api/v1
Create a destination
POST /webhooks/sources/:source_id/destinationsRequired scope: webhooks:write
Request body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Yes | — | HTTPS URL. HTTP is rejected in production. SSRF-checked: private/link-local/loopback addresses fail. |
secret | string | No | auto | Encrypted at rest. If omitted, a whsec_… secret is generated. |
event_filter | array of strings | No | [] | Event types to forward. Empty array = forward everything. |
enabled | boolean | No | true | Disabled destinations are skipped during fan-out. |
Response — 201 Created
json
{
"data": {
"id": "uuid",
"source_id": "uuid",
"url": "https://api.your-app.com/webhooks/stripe",
"event_filter": ["invoice.paid"],
"enabled": true,
"failure_count": 0,
"secret": "whsec_…",
"created_at": "2026-04-26T09:00:00Z",
"updated_at": "2026-04-26T09:00:00Z"
}
}WARNING
The secret field is returned only on this POST response. All read endpoints (list / get / update) omit it. Save it now or rotate by PATCHing a new secret.
List destinations
GET /webhooks/sources/:source_id/destinationsRequired scope: webhooks:read
json
{ "data": [ /* destination objects, no `secret` field */ ] }Get a destination
GET /webhooks/sources/:source_id/destinations/:idRequired scope: webhooks:read
Returns the destination object without secret.
Update a destination
PATCH /webhooks/sources/:source_id/destinations/:idRequired scope: webhooks:write
Accepts the same body as create. To rotate the secret, send a new secret value. The response does not echo the new secret back — provide a value you already have.
Delete a destination
DELETE /webhooks/sources/:source_id/destinations/:idRequired scope: webhooks:write
Returns 204 No Content. Cascades to all delivery attempts.
Test a destination
POST /webhooks/sources/:source_id/destinations/:id/testRequired scope: webhooks:write
Sends a synthetic signed POST to the destination URL with this body:
json
{
"event": "test",
"data": { "message": "Test delivery from Krafter", "timestamp": "..." },
"source_id": "uuid"
}The URL is re-checked for SSRF safety at send time.
Response — 200:
json
{ "ok": true, "status": 200 }Response on transport error or 5xx — 422:
json
{ "ok": false, "error": "..." }Auto-disable
failure_count is incremented every time a forwarding attempt exhausts retries. After 10 consecutive failures the destination is flipped to enabled: false automatically. Re-enable by sending a PATCH with enabled: true; this also resets failure_count to 0 on the first successful delivery thereafter.