Webhooks API
Subscription management and delivery behavior for GridWonk event notifications.
Webhooks API
Endpoints
GET /api/v1/webhooksPOST /api/v1/webhooksGET /api/v1/webhooks/{id}PATCH /api/v1/webhooks/{id}DELETE /api/v1/webhooks/{id}
Supported Events
job.completedjob.faileddocument.classifieddocument.digitizeddocument.validateddeficiency.foundscreening.completerequirements.extractedutility.screening.determinedutility.finding.adjudicatedutility.study_requirement.setutility.package.frozenutility.notice.status_changed
deficiency.found and screening.complete are reserved event types unless a specific workflow emits them through its job completion payload.
The five utility.* families are implemented in the reviewed utility-notice stack and require
its separately approved schema activation and release. This documentation does not establish
production availability. They describe actual human screening decisions, finding decisions,
study-requirement changes, package freezes, and canonical notice status changes. A send request,
provider receipt, replay or rolled-back transaction does not create another status event.
A utility.package.frozen event can include an optional data.syntheticFeeExemption audit record for an explicitly approved synthetic test application. It identifies the exact application, form version, finding and approval, and states paymentRecorded: false. The fee finding remains in the immutable report; this record is not a payment receipt or a general fee waiver.
Only subscriptions in the application's receiving utility organization receive these events. An applicant or consultant subscription does not inherit them through its actor's application access. Registering a subscription does not backfill historical changes. Existing management-key authentication and organization scoping are unchanged.
Create Subscription
curl -X POST https://gridwonk.com/api/v1/webhooks \
-H "Authorization: Bearer $GRIDBOOST_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://partner.example/hooks/gridwonk","events":["job.completed","job.failed"]}'If secret is omitted, GridWonk generates one and returns it only at creation time.
Response shape:
{
"subscription": {
"id": "uuid",
"url": "https://partner.example/hooks/gridwonk",
"events": ["job.completed", "job.failed"],
"isActive": true,
"createdAt": "2026-05-08T12:00:00.000Z",
"secret": "whsec_..."
}
}Each organization can have up to 25 webhook subscriptions.
Update and Delete
PATCH /api/v1/webhooks/{id} accepts url, events, and isActive. Setting isActive to false records disabledAt; setting it back to true clears disabledAt and resets consecutive failure counters.
GET /api/v1/webhooks/{id} returns the subscription and its 50 most recent delivery attempts. DELETE /api/v1/webhooks/{id} returns { "success": true, "id": "..." }.
For utility events, an event-list change affects future changes, not already committed deliveries. Disabling pauses new claims; an already in-flight request can finish. Re-enabling permits pending work to resume but does not reset exhausted holds. Deleting the subscription removes its delivery rows while retaining immutable source events.
Delivery Headers
Each delivery includes:
X-GridWonk-EventX-GridWonk-Event-IdX-GridWonk-TimestampX-GridWonk-Signature
Removed aliases: deliveries previously also carried
X-GridBoost-Event,X-GridBoost-Event-Id,X-GridBoost-Timestamp, andX-GridBoost-Signaturewith identical values. Those aliases have been removed — use theX-GridWonk-*headers above.
Signature Verification
Signature input format:
<timestamp>.<raw-json-payload>Algorithm: HMAC-SHA256(secret, payload) with header value sha256=<hex>.
Retry and Reliability
- Delivery attempts are persisted in
webhook_delivery_log. - Failures are retried with increasing delay.
- Legacy job/document subscriptions auto-disable after repeated consecutive failures.
- Invalid internal or private webhook targets are rejected at configuration time. URLs must use HTTPS, cannot include credentials, and cannot resolve to localhost, private, reserved,
.local,.internal, or metadata host addresses.
Ordered utility events
The business change, immutable event and subscribed deliveries commit in one transaction.
The payload includes eventId, eventType, payloadVersion: 1, organizationId, submissionId,
sequence (a decimal string), occurredAt, originating provenance, and event-specific data.
Notice events contain notice/revision/package/run IDs and previous/new status, not recipients
or email content. See the integration guide.
Delivery is at least once: verify the signature and durably deduplicate by event ID before acknowledging. Retries retain the stored payload and ID with a fresh signature timestamp. Each subscription/application pair is ordered independently; unsubscribed events may leave sequence gaps. Up to eight attempts use delays of 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 12 hours and 24 hours. Recovery queues due stream heads every five minutes, so these are minimum delays, not a delivery-time guarantee. Exhaustion holds that pair and its later events without disabling the subscription or blocking other applications/subscribers. Operator review is required for held work; changing the subscription does not reset its budget.