BETA
Skip to content

Webhooks

Configure webhooks to receive real-time notifications about push events. Today the dispatcher fires notification.sent after each fan-out — see the Available Events table below for reserved event names.

Base URL: https://app.krafter.dev/api/v1

Signing, retry policy, and auto-disable rules are shared across the platform — see Webhook delivery.

List Webhooks

Retrieve all webhooks configured for an app.

GET /push/apps/:app_id/webhooks

Required scope: push:read

Example Request

bash
curl https://app.krafter.dev/api/v1/push/apps/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/webhooks \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response

json
{
  "data": [
    {
      "id": "f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f9a0b1c",
      "app_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
      "url": "https://example.com/webhooks/push",
      "events": ["notification.sent"],
      "enabled": true,
      "failure_count": 0,
      "created_at": "2025-06-01T08:00:00Z",
      "updated_at": "2025-06-01T08:00:00Z"
    }
  ]
}

Create Webhook

Create a new webhook for an app. The webhook will start receiving events immediately if enabled is true (the default).

POST /push/apps/:app_id/webhooks

Required scope: push:write

Request Body

FieldTypeRequiredDescription
urlstringYesThe URL to send webhook payloads to. Must use https://lib/krafter/push/push_webhook.ex:21 rejects http://, and Krafter.UrlValidator.validate_url/2 rejects loopback, RFC 1918 / link-local, cloud-metadata, and .local / .internal hosts to prevent SSRF.
secretstringNoSecret used to sign webhook payloads. Optional — when omitted (or empty string), the dispatcher skips the x-krafter-signature header entirely (webhook_delivery_helper.ex:42-46). Without a secret your handler has no way to verify the request came from Krafter; treat this as a development-only path.
eventsstring[]NoEvents to subscribe to. Defaults to [] (no events fire) — set this to ["notification.sent"] to actually receive deliveries. See Available Events below.
enabledbooleanNoWhether the webhook is active. Defaults to true.

Available Events

Today the dispatcher emits a single event:

EventDescription
notification.sentFan-out completed for a notification. Payload includes notification_id, app_id, title, sent_count, and failed_count.

Coming soon

notification.delivered, notification.clicked, notification.failed, subscriber.registered, and subscriber.unsubscribed are reserved event names. The webhook schema accepts them in events arrays without error, but the dispatcher does not emit them yet — your handler will only see notification.sent until per-event delivery, click, and subscriber-lifecycle tracking ship.

Example Request

bash
curl -X POST https://app.krafter.dev/api/v1/push/apps/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/webhooks \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/push",
    "secret": "whsec_a1b2c3d4e5f6g7h8i9j0",
    "events": ["notification.sent"]
  }'

Example Response

json
// 201 Created
{
  "data": {
    "id": "f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f9a0b1c",
    "app_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "url": "https://example.com/webhooks/push",
    "events": ["notification.sent"],
    "enabled": true,
    "failure_count": 0,
    "created_at": "2025-06-01T08:00:00Z",
    "updated_at": "2025-06-01T08:00:00Z"
  }
}

Update Webhook

Update an existing webhook. Only provided fields are changed.

PATCH /push/apps/:app_id/webhooks/:webhook_id

Required scope: push:write

Request Body

FieldTypeRequiredDescription
urlstringNoThe URL to send webhook payloads to.
secretstringNoSecret used to sign webhook payloads.
eventsstring[]NoEvents to subscribe to.
enabledbooleanNoWhether the webhook is active.

Example Request

bash
curl -X PATCH https://app.krafter.dev/api/v1/push/apps/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/webhooks/f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f9a0b1c \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["notification.sent"],
    "enabled": false
  }'

Example Response

json
{
  "data": {
    "id": "f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f9a0b1c",
    "app_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "url": "https://example.com/webhooks/push",
    "events": ["notification.sent"],
    "enabled": false,
    "failure_count": 0,
    "created_at": "2025-06-01T08:00:00Z",
    "updated_at": "2025-06-15T11:00:00Z"
  }
}

Delete Webhook

Permanently delete a webhook. It will stop receiving events immediately.

DELETE /push/apps/:app_id/webhooks/:webhook_id

Required scope: push:write

Example Request

bash
curl -X DELETE https://app.krafter.dev/api/v1/push/apps/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/webhooks/f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f9a0b1c \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response

// 204 No Content

Built by Krafter Studio