Outcomes and the feedback loop
An outcome says what happened after a decision. Reporting outcomes is free, unlimited and idempotent. It is the one thing that makes Verdict better for you specifically.
Report an outcome
Section titled “Report an outcome”POST /v1/outcomes. Free. Scope outcomes:write.
curl -X POST 'https://api.askverdict.io/v1/outcomes' \ -H "Authorization: Bearer $VERDICT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ -d '{ "decision_id": "dec_01JC3Z4Y8R9K2M5N7P1Q3S5T7V", "outcome": "meeting_booked", "observed_at": "2026-11-09T16:30:00Z", "meta": { "channel": "email" }}'{ "id": "out_01JC3Z4Y8R9K2M5N7P1Q3S5T7V", "decision_id": "dec_01JC3Z4Y8R9K2M5N7P1Q3S5T7V", "outcome": "meeting_booked", "observed_at": "2026-11-09T16:30:00Z", "meta": { "channel": "email" }, "created_at": "2026-11-09T16:30:02Z"}The call is idempotent on (decision_id, outcome, observed_at): the same triple twice records one outcome. Use custom:<slug> for outcomes of your own.
outcome |
Meaning |
|---|---|
bounced |
The message bounced. |
delivered |
The message was delivered. |
replied |
The prospect replied. |
interested |
The prospect showed interest. |
not_interested |
The prospect declined. |
meeting_booked |
A meeting was booked. |
meeting_held |
A booked meeting took place. |
approved |
A human approved the agent’s proposed action. |
skipped |
A human skipped (rejected) the agent’s proposed action. |
reopened |
A closed thread or deal reopened. |
converted |
The prospect became a customer. |
What the loop does
Section titled “What the loop does”- Every decision stores
p_rawfrom the model, the calibratedp, the threshold applied and a hash of its structured features. Never your text. - Your outcomes are joined to those decisions.
- Once your org has 50 outcomes for a decision and question-set version, Verdict fits a calibration map for your org (isotonic from 200 outcomes, Platt scaling below) and a threshold that maximizes F1 on the positive outcome. Below 50, it uses the map for your ICP’s segment (industry group and size band), built from all orgs that opt in. Below that, the global map.
calibrationon every response says which map answered:org,segmentorglobal, and how many outcomes it rests on.
Maps are refit nightly and when your org crosses an outcome threshold.
What is pooled, and what is not
Section titled “What is pooled, and what is not”Only outcomes and feature hashes enter the segment and global maps. No name, email, domain, roster or thread text is ever an input to a pooled map. No customer’s records train anything another customer sees. You can opt out of contributing; your own calibration keeps working.
Outcomes without code
Section titled “Outcomes without code”Point your sending and booking tools at Verdict and outcomes arrive on their own. Each receiver verifies the vendor’s signature and maps the vendor’s event to an outcome on the decision you tagged.
| Tool | Receiver |
|---|---|
| Instantly | POST /v1/webhooks/instantly/{receiver_token} |
| Smartlead | POST /v1/webhooks/smartlead/{receiver_token} |
| Cal.com | POST /v1/webhooks/calcom/{receiver_token} |
| Calendly | POST /v1/webhooks/calendly/{receiver_token} |
The receiver_token in the path identifies your org. Treat the full URL as a secret. To tag a send, put the decision id in the vendor’s custom field verdict_decision_id (the SDK helper withDecision(decisionId) does it) or in the email header X-Verdict-Decision; Closing the loop has the whole convention. Verdict never holds your vendor credentials.
Your own approval step
Section titled “Your own approval step”If a human or a rule approves each action before it happens, report approved or skipped. The SDKs ship approve(decisionId) and skip(decisionId) helpers for exactly this.