App reference

Webhook events

EagraΓ­ Clainne can send signed HTTP POST requests to endpoints that an admin registers. Each webhook record holds a name, a URL, an HMAC secret and a list of event patterns. When an event occurs, the server delivers it to every webhook whose patterns match. ADR-0024 records the design: envelope shape, signature scheme, retry schedule and ordering guarantees.

This page lists every event the server can send.

Event families

Event names have three families:

Family Shape Source
Notification notify.<kind> The in-app notification seam
Mutation mutation.<entity>.<action> The audit log
Test webhook.test The TestWebhook RPC

Notification events

These seven events fire when the server emits the matching in-app notification. Each carries the same context fields as the notification.

  • notify.job_completed β€” a member completed a job.
  • notify.job_up_for_grabs β€” a job became available to claim.
  • notify.job_assigned β€” a job was assigned to a member.
  • notify.reward_granted β€” a member received a reward.
  • notify.reward_claimed β€” a member claimed a reward.
  • notify.meal_assigned β€” a member was assigned to cook a meal.
  • notify.meal_reminder β€” a reminder for an upcoming meal duty.

Mutation events

Every audited create, update or delete becomes a mutation.<entity>.<action> event. Coverage is structural: the dispatcher taps the audit sink, so any entity that mutates through the service layer produces events without extra wiring. A new entity type joins this list automatically.

The <action> segment is create, update or delete. Audit entries that record other activity, such as data exports, do not become webhook events.

The <entity> segment is the lowercase protobuf message name. The current entity types:

  • user
  • event
  • item
  • itemlist
  • reward
  • meal
  • mealrota
  • mealdayoverride
  • mealweek
  • apikey
  • pushsubscription
  • webhook

The notification entity is excluded. Notification rows churn on every fan-out and mark-read, and would flood consumers without information.

Test event

webhook.test fires only when an admin presses the test button or calls the TestWebhook RPC. The server sends it synchronously to that one webhook and reports the delivery result in the response.

Pattern matching

A webhook's patterns match event names in two ways:

  • An exact name: notify.job_completed.
  • A prefix that ends in *: notify.*, mutation.item.*, or a bare * for everything.

Delivery headers

Each delivery carries these headers:

  • X-Eagrai-Clainne-Event β€” the event name.
  • X-Eagrai-Clainne-Timestamp β€” the send time, in unix seconds.
  • X-Eagrai-Clainne-Signature β€” sha256= plus the hex HMAC-SHA256 of <timestamp>.<body>, keyed with the webhook's secret.

Consumers must verify the signature before they trust the body. The timestamp is inside the signed content, so a captured delivery cannot replay outside the receiver's tolerance window.

Delivery body

The body is a JSON envelope of hand-picked scalars. It never contains entity payloads β€” a consumer that needs the full record reads it back through the API. A notify.job_completed delivery looks like this:

{
  "event": "notify.job_completed",
  "timestamp": "2026-08-09T20:14:03Z",
  "actor": {
    "uid": "0198a2f4-6c1e-7d3a-b2c8-9f41e5d0a7b3",
    "name": "Fiadh"
  },
  "entity_type": "item",
  "entity_uid": "0198a2f4-8b2d-7e4f-a1c9-3d57b6e2f8c4",
  "entity_label": "Empty the dishwasher",
  "context": { "points": 5 }
}
Field Meaning
event The event name, exactly as in X-Eagrai-Clainne-Event.
timestamp When the event was built, RFC3339 UTC.
actor Who did it: uid and display name. Zero-valued ("" for both) when nobody did, such as a board reminder.
entity_type What kind of thing it happened to, in the audit log's vocabulary.
entity_uid The uid of that thing. Empty when the event has no stored record, such as a meal reminder.
entity_label A human-readable label for that thing. May be empty.
context The event family's extra scalars. Omitted when the event has none.

Context fields per event

Event Context fields
notify.job_completed points
notify.job_up_for_grabs none
notify.job_assigned target_uid
notify.reward_granted target_uid, value
notify.reward_claimed cost
notify.meal_assigned target_uid, date
notify.meal_reminder cook_uid
mutation.<entity>.<action> none
webhook.test none

For notify.meal_assigned the actor is the assigner and the target is the cook. For notify.meal_reminder no member acted, so the actor is zero-valued and cook_uid names the cook. Mutation events carry the audit entry's actor and entity fields with no context map. The test event carries only the admin who pressed the button.