Appearance
Sources
A source is a single inbound webhook origin (one Stripe account, one GitHub repo, one Shopify store, one custom integration). Each source gets its own ingest URL and signing configuration.
Base URL: https://app.krafter.dev/api/v1
Create a source
POST /webhooks/sourcesRequired scope: webhooks:write
Request body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | — | Human-readable label. |
provider | string | Yes | "generic" | One of stripe, github, shopify, generic. |
signing_secret | string | No | null | Encrypted at rest. Without it, every event is stored with signature_valid: false. |
signing_algorithm | string | No | null | generic only. Currently sha256. |
signing_header | string | No | null | generic only. Header carrying the signature (raw hex, no prefix). |
event_type_source | string | No | null | generic only. body or header. |
event_type_path | string | No | null | generic only. Dot-path into JSON body, or header name. |
enabled | boolean | No | true | Disabled sources still accept ingest but skip fan-out. |
retention_days | integer | No | 30 | Event retention window. 1–365. |
Response — 201 Created
json
{
"data": {
"id": "uuid",
"name": "Stripe production",
"slug": "wh_aB3xY7q1",
"url": "https://app.krafter.dev/in/wh_aB3xY7q1",
"destinations_count": 0,
"provider": "stripe",
"signing_algorithm": null,
"signing_header": null,
"event_type_source": null,
"event_type_path": null,
"enabled": true,
"retention_days": 30,
"created_at": "2026-04-26T09:00:00Z",
"updated_at": "2026-04-26T09:00:00Z"
}
}The signing_secret is never returned by any read endpoint. To rotate it, PATCH the source with a new secret.
slug is auto-generated (wh_ + 8 url-safe chars) and used in url to form the public ingest endpoint. Slugs are immutable.
List sources
GET /webhooks/sourcesRequired scope: webhooks:read
Returns all sources owned by the authenticated team, newest first.
json
{ "data": [ /* source objects */ ] }Get a source
GET /webhooks/sources/:idRequired scope: webhooks:read
Returns the source object as shown above. Returns 404 if the source doesn't belong to the authenticated team.
Update a source
PATCH /webhooks/sources/:idRequired scope: webhooks:write
Accepts the same body as create. Only present fields are updated. Returns 200 with the updated source object. The slug and url cannot be changed.
Delete a source
DELETE /webhooks/sources/:idRequired scope: webhooks:write
Returns 204 No Content. Cascades to all destinations, events, and deliveries belonging to the source.