AI Insights Webhooks
Subscribe a webhook to AI Insights events and react the moment a run finishes or someone actions a recommendation, instead of polling the Insights API on a timer.
Typical uses: post high-severity recommendations to Slack or PagerDuty, open a ticket for every finding above a severity threshold, or keep your own system in sync when anyone rates a recommendation or marks it as implemented.
The four events
insight_run.completed
Run completed
A run finished and every investigator succeeded. Carries the finding and recommendation counts.
insight_run.partial
Run partial
A run finished with results, but at least one investigator failed. Names which succeeded and which did not.
insight_run.failed
Run failed
A run reached a terminal failed state. Carries a failure_reason.
recommendation_feedback.created
Feedback recorded
Feedback was recorded on a recommendation, whether from the dashboard or the API.
A run reports itself through exactly one of the three run events, and under normal delivery a single run is not reported as both finished and failed. Two silences are expected and worth designing around: a cancelled run emits nothing at all, and re-running an analysis that Revenium recognises as identical to a recent one emits nothing either, because it reuses that result instead of producing a new one. Treat the absence of an event as "no new result", never as "the run succeeded". "Delivery semantics" below covers the one case where two run events can arrive for the same run_id.
Subscribing
Subscriptions are per channel and per event, so one webhook can take everything while another takes failures only.
Create the webhook. Open Guardrails under Spend Management in the sidebar, then the Channels tab, and use Add Webhook in the Webhooks section. Fill in Name and URL, and pick HMAC signing under Authentication. The signing secret is shown once — copy it. Signing is not a one-time decision: each webhook shows a Signing enabled or Signing disabled badge, and the Enable Signing button turns it on later (Rotate Secret once it is on).
Pick the events. Open AI Insights and press the bell button, Notification settings, in the toolbar above the run. Every active webhook in the team appears as a row with a checkbox per event type. Check what that channel should receive and save.
Verify. See "Testing" below.
Unchecking an event stops delivery for that channel immediately; other channels are unaffected. Deleting a webhook removes its subscriptions with it.
The envelope
Every event shares the same seven top-level fields.
event_type
One of the four tokens above.
run_id
The insights run the event belongs to. Feedback events carry the run the recommendation came from.
event_id
Unique per event, stable across retries of the same event.
schema_version
v1 today. A breaking payload change ships a new version.
occurred_at
ISO-8601 UTC timestamp of the event, not of the delivery attempt. Unchanged across retries.
livemode
false for non-production environments, true in production.
data
Event-specific payload, described below.
Payloads
insight_run.completed
team_id
number
The team the run belongs to.
status
string
Always completed.
triggered_by
string
user, api, system or schedule.
period_start, period_end
string
The analysed window, ISO-8601 UTC.
findings_count
number
Findings produced. 0 is normal: findings below the economic-value floor are filtered out.
recommendations_count
number
Recommendations produced. Can be 0 on a successful run with findings, when the recommendation step degraded and the findings were preserved on their own.
failed_investigators
string[]
Always empty here: a run is only completed when every investigator succeeded.
severity_histogram
object
Counts by critical, high, medium, low, info.
total_monthly_impact_usd
number
Estimated monthly impact across the findings.
findings_truncated
boolean
true when the finding list was capped.
total_duration_ms
number
Wall-clock duration of the run.
dashboard_url
string
Deep link to this run in the dashboard.
insight_run.partial
Same fields as completed, with status set to partial, failed_investigators non-empty, and one addition:
succeeded_investigators
string[]
Which investigators did produce results. The histogram covers only these.
insight_run.failed
Carries team_id, triggered_by, period_start, period_end, total_duration_ms and dashboard_url in the same positions as completed, plus:
status
string
Always failed.
failure_reason
string
analysis_failed, dispatch_failed, missing_config, invalid_payload or timed_out.
error_summary
string
Short cause, safe to show to a human.
failed_investigators
string[]
Always empty on this event. A failed run reports its cause through failure_reason, not per investigator.
severity_histogram
object
All zeros.
total_monthly_impact_usd
number
0.
Two shapes to expect on this event and not on the others: total_duration_ms is 0 when the run failed before it could be timed, and period_start / period_end fall back to the epoch sentinel 1970-01-01T00:00:00.000Z when the failure happened before the requested window was validated. Guard against that before rendering the window to a person.
recommendation_feedback.created
team_id
number
The team the recommendation belongs to.
recommendation_id
string
The recommendation the feedback is about.
action
string
One of acknowledged, dismissed, implemented, already_aware, not_applicable. See the mapping below.
confidence_rating
number
1, 0 or -1. Derived from the action, not entered by the person.
dismissal_reason
string
Free text, only ever populated by the thumbs-down path, and optional there.
realized_savings
number
Reported savings. The dashboard never sets it, so it is 0 unless the feedback came through the API.
realized_savings_currency
string
ISO currency code, USD by default.
realized_savings_measured_at
string | null
When the savings were measured, null unless reported through the API.
actor_type
string
user for the dashboard, api for an API caller.
Feedback events are not deduplicated: two pieces of feedback on the same run produce two events, which is what keeps multiple recommendations distinguishable.
What each dashboard control sends. A recommendation card carries two independent controls: an accuracy vote (the thumbs) and a status note (the overflow menu). A recommendation can therefore have both, recorded as separate events.
Control on the recommendation
action
confidence_rating
Thumbs up, under "Accurate?"
acknowledged
1
Thumbs down, with an optional "why" note
dismissed
-1
Overflow menu, "Mark as implemented"
implemented
0
Overflow menu, "Already aware"
already_aware
0
Overflow menu, "Not applicable"
not_applicable
-1
Read action rather than the rating when you care about intent: -1 covers both "this was inaccurate" and "this does not apply to us", and 0 covers a recommendation that was implemented as well as one that was already known.
Delivery semantics
Best effort, not guaranteed. Revenium retries a transient failure and then stops, so an event can be lost.
Retries. A
5xxor a network error is retried up to three attempts, roughly 10s then 20s apart. A4xxis terminal and is not retried.Retries are the same event.
event_id,occurred_atand the signature headers are identical across attempts, so an endpoint that received an attempt without answering in time will see the same event again.Terminal run events are deduplicated per run and event type, so a re-processed run does not fire the same terminal event twice.
If a run is ever retried at the infrastructure level, you can receive both a success and a failure for one
run_id. Treatcompletedorpartialas authoritative overfailed.Ordering is not guaranteed across channels or events. Use
occurred_at.
Verifying deliveries
Enable HMAC on the webhook and verify the X-Revenium-Signature-256 header on every request. The algorithm, the 24-hour rotation overlap, the 300-second replay window and ready-to-use verifiers in Node, Python and Go are documented in Webhook Signing.
Testing
Two ways, both useful:
Synthetic delivery. Press Test on the webhook, on the Channels tab. It sends a test payload through the same signing and delivery path as a real event, so it exercises your endpoint and your verifier without waiting for a run. The API equivalent, and what a correct verifier looks like, are in Webhook Signing.
A real run. Subscribe one channel to
insight_run.completedonly, trigger a run from the Insights page, and confirm that exactly one delivery arrives and that no other event type does.
Recommended consumer behavior
Answer
2xxbefore you do the work. Acknowledge the delivery, then process asynchronously. A slow handler burns the retry budget, and a4xxfrom your side is never retried.Deduplicate on
event_id. A retry is the same event, not a new one, so keep a short window of processed identifiers rather than trusting one-shot arrival.Treat the event as a trigger, not as the record. Read the run back through the Insights API when you need the full findings or recommendations; the payload is a summary by design.
Subscribe the narrowest set of events per channel. An on-call destination usually wants
insight_run.failedalone, while a dashboard integration wants the terminal events but not feedback.Handle
partialexplicitly. It carries results and a list of investigators that failed, so a consumer that treats it as a plain success will report numbers built from an incomplete analysis.
If you need an event type that is not listed here, or delivery guarantees beyond at-most-once, contact support.
Last updated
Was this helpful?