Webhooks
Webhooks Overview
Register an HTTPS endpoint, choose events, and receive signed deliveries instead of polling.
Grout POSTs a signed JSON envelope to your endpoint whenever a subscribed event happens. Respond 2xx within 10 seconds and process asynchronously.
Register an endpoint#
From the portal (Developers → Webhooks → Add endpoint) or the API:
curl -X POST $API/webhooks/endpoints -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{
"url": "https://lms.example.edu/hooks/grout",
"description": "Gradebook sync",
"events": ["exam.*", "student.created", "license.expired"]
}'The response includes secret (whsec_…) once. Subscriptions accept "*", a prefix such as "exam.*", or exact types. Endpoints must be public HTTPS; private hosts and credentials in the URL are rejected. Up to 20 endpoints per institution.
The envelope#
POST /hooks/grout HTTP/1.1
Content-Type: application/json
User-Agent: Grout-Webhooks/1.0
X-Grout-Event: exam.graded
X-Grout-Delivery-Id: whd_…
X-Grout-Signature: t=1789300000,v1=5f1c…
{ "id": "evt_…", "type": "exam.graded", "created_at": "2026-09-14T10:00:00.000Z", "institution_id": "…",
"data": { "submission_id": "sub_…", "exam_id": "ex_…", "student_id": "u_…", "score": 87, "max_score": 100, "resubmission_required": false } }Store id and ignore duplicates — deliveries are at-least-once.
Test it#
Send test ping in the portal (or POST /webhooks/endpoints/{id}/test) delivers a ping event synchronously and shows you the response code and latency.
Manage#
curl $API/webhooks/endpoints -H "Authorization: Bearer $KEY"
curl -X PATCH $API/webhooks/endpoints/we_… -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{ "status": "paused" }'
curl -X POST $API/webhooks/endpoints/we_…/rotate-secret -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{ "grace_hours": 24 }'
curl -X DELETE $API/webhooks/endpoints/we_… -H "Authorization: Bearer $KEY"