What does the write-back webhook POST contain, and does it ever include my keys?
Tares POSTs each finding to your write-back webhook as JSON with the finding text and run metadata, and the body never contains a key or token. The only credential involved is the optional bearer token you set, which Tares sends as an Authorization header and never in the body. The key field in the body is the name of the entity the finding is about, such as api-server, not a secret.
How it works
When an agent has Write-back webhook switched on under Deliver findings, Tares POSTs every finding as JSON to your own automation. The finding is also stored on the entity’s timeline, so it is kept whatever happens to the delivery. This page covers the finding event body, the optional bearer token and the skipped event. The full option list is on Deliver findings, and the wider picture is in AI SRE.
The finding body has these fields:
event: alwaysfindingfor a finding.agent: the name of the agent that produced it, such asincident-first-look.trigger: the trigger that dispatched the run, such asincident.key: the entity the finding is about, such asapi-server.finding: the text of the finding, for example the incident note.run_idanddispatch_id: identifiers for the run and for the dispatch that started it.model: the model the run used, such asclaude-sonnet-4-6.roundsandtool_calls: how many rounds the run took and how many tool calls it made.started_atandfinished_at: ISO 8601 timestamps with a UTC offset.duration_s: the run length in seconds.prompt_hash: a short hash,1c9f2din the example.
The body carries the finding and its run metadata, never a key or token. No API key, model provider credential or bearer token appears in any field.
The bearer token. If you set one, Tares sends it as an Authorization header on the request, so your receiver can check who is calling. Leave it empty and Tares sends no such header. The token travels in the header only.
Failures. Transient failures are retried. A delivery that fails never loses the finding, because it is already stored.
Set it up
- Open the agent’s form and find Deliver findings.
- Switch on the Write-back webhook row and enter the URL of your own automation.
- If your receiver checks credentials, enter a bearer token. Tares sends it as the
Authorizationheader. - Make your receiver accept a JSON POST and read the
eventfield first, because the webhook sends two kinds of event. - Handle the
findingbody below. This is the shape your receiver gets for each finding:
{
"event": "finding",
"agent": "incident-first-look",
"trigger": "incident",
"key": "api-server",
"finding": "…the incident note…",
"run_id": "run_9f2c81d4a6b3",
"dispatch_id": "c0f35f8210…",
"model": "claude-sonnet-4-6",
"rounds": 2,
"tool_calls": 3,
"started_at": "2026-08-14T12:01:03+00:00",
"finished_at": "2026-08-14T12:01:35+00:00",
"duration_s": 32.6,
"prompt_hash": "1c9f2d"
}- Also handle the
skippedevent. It tells your receiver that a run a trigger dispatched was refused before it started, so a receiver that files findings by the firing does not wait for a finding that never comes:
{
"event": "skipped",
"reason": "in_flight",
"message": "a run of this agent for the same key is already in flight",
"agent": "incident-first-look",
"trigger": "incident",
"key": "api-server",
"labels": {},
"run_id": null,
"dispatch_id": "c0f35f8210…",
"in_flight_run_id": "run_9f2c81d4a6b3"
}The reason field is one of these:
daily_cap: the agent already ran its daily cap of runs in 24 hours.budget_exhausted: the agent used up itsbudget_usd.in_flight: a run of the agent for the samekeyis already going, andin_flight_run_idnames it.
message carries the text the run records, and key and labels name the firing the way a finding would. A rerun, a bootstrap run or a hand-off sends no skipped event.
What you get
- A JSON body per finding with the finding text, the agent and trigger that produced it, and the entity key.
- Run metadata on every finding: run and dispatch identifiers, model, rounds, tool calls, start and finish times, duration and prompt hash. Your automation can log or correlate runs without calling back into Tares.
- A body that is safe to store or forward, because it never holds a key or token.
- An optional bearer token in the
Authorizationheader, so your receiver can reject callers it does not trust. - A
skippedevent whenever a dispatched run is refused, with the reason and the name of the run already in flight when that is the cause. - Retries on transient failures, and a finding that stays on the entity’s timeline even if delivery fails.
When something else fits
- To post the full finding to a person or team, use the Slack channel option. The workspace bot posts to a channel chosen from its own membership list, and those deliveries are retried and recorded in the delivery ledger.
- The older per-agent Slack incoming webhook URL still works, but it is neither retried nor logged and is used only when no channel is set, so prefer the channel.
Related
Still stuck? Get help