APINotifications Endpoint

Notifications Endpoint

The POST /api/notify endpoint accepts a structured notification event and fans it out to one or more configured external targets: a generic HTTP webhook,...

Notifications Endpoint

The POST /api/notify endpoint accepts a structured notification event and fans it out to one or more configured external targets: a generic HTTP webhook, Sentry, and/or Datadog. The response reports delivery success for each target independently so callers can handle partial failures.

This endpoint does not require an Authorization header; it is protected via payload validation, size limits, and rate limiting.


Request

POST /api/notify

Body

{
    "event": "compilation.failed",       // required — machine-readable event name
    "message": "Worker timed out",       // required — human-readable description
    "level": "error",                    // optional — info | warn | error | debug  (default: "info")
    "source": "bloqr-backend",        // optional — originating service/component
    "timestamp": "2026-03-10T12:00:00Z", // optional — ISO 8601 (defaults to now)
    "metadata": {                        // optional — arbitrary key/value pairs
        "requestId": "req-abc123",
        "sourceCount": 5
    }
}
FieldTypeRequiredDescription
eventstring✅Machine-readable event identifier (e.g., compilation.failed)
messagestring✅Human-readable description of the event
levelstring❌Severity level: "info", "warn", "error", or "debug". Default: "info"
sourcestring❌Originating service or component name
timestampstring❌ISO 8601 timestamp. Defaults to the time of the request
metadataobject❌Arbitrary key/value pairs forwarded to all targets

Responses

All targets delivered — 200

{
    "success": true,
    "event": "compilation.completed",
    "deliveries": [
        { "target": "generic", "success": true, "statusCode": 200 },
        { "target": "sentry",  "success": true, "statusCode": 200 }
    ],
    "duration": "42ms"
}

Partial failure — 200

The HTTP response is 200 even when some targets fail. Inspect deliveries to determine which targets succeeded.

{
    "success": true,
    "event": "compilation.completed",
    "deliveries": [
        { "target": "generic", "success": false, "error": "Connection refused" },
        { "target": "datadog", "success": true,  "statusCode": 202 }
    ],
    "duration": "38ms"
}

All targets failed — 502

{
    "success": false,
    "event": "compilation.completed",
    "deliveries": [
        { "target": "generic", "success": false, "error": "Connection refused" }
    ],
    "duration": "15ms"
}

No targets configured — 503

{
    "success": false,
    "error": "No notification targets are configured. Set WEBHOOK_URL, SENTRY_DSN, or DATADOG_API_KEY."
}

Target Configuration

Configure one or more of the following environment variables / Worker secrets. The endpoint is a no-op (returns 503) when none are set.

VariableTypeDescription
WEBHOOK_URLstringGeneric HTTP webhook endpoint. Receives the raw request body as JSON via POST.
SENTRY_DSNstringSentry DSN (https://<key>@<host>/<project>). Events are submitted to the Sentry Store API.
DATADOG_API_KEYstringDatadog API key. Events are submitted to the Datadog Events v1 API.

Setting secrets

wrangler secret put WEBHOOK_URL
wrangler secret put SENTRY_DSN
wrangler secret put DATADOG_API_KEY

Target Behaviour

Generic webhook (WEBHOOK_URL)

The request body is forwarded verbatim as a JSON POST to WEBHOOK_URL. Use this for Slack incoming webhooks, PagerDuty, or any custom HTTP endpoint.

Sentry (SENTRY_DSN)

The event is mapped to a Sentry store submission:

Notify fieldSentry field
messagemessage
level (warn → warning)level
sourcelogger
metadataextra
eventtags.event
timestamptimestamp

Datadog (DATADOG_API_KEY)

The event is submitted to the Datadog Events v1 API (/api/v1/events):

Notify fieldDatadog field
eventtitle
messagetext
levelalert_type (warn → warning)
sourcesource_type_name
metadata keystags (key:value)
timestampdate_happened (Unix epoch)

Examples

cURL

curl -X POST https://api.bloqr.dev/api/notify \
  -H "Content-Type: application/json" \
  -d '{
    "event": "compilation.completed",
    "message": "Compiled 12,500 rules from 5 sources",
    "level": "info",
    "source": "bloqr-backend",
    "metadata": { "ruleCount": 12500, "sourceCount": 5, "durationMs": 1240 }
  }'

TypeScript

await fetch('/api/notify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        event: 'compilation.failed',
        message: 'Source download timed out after 30s',
        level: 'error',
        metadata: { sourceUrl: 'https://example.com/list.txt' },
    }),
});

Notes

  • Delivery to each target is attempted in parallel.
  • Failed deliveries are reported in the response but do not affect other targets.
  • The endpoint always returns 200 when at least one target succeeds. Use the deliveries array to detect partial failures.