> ## Documentation Index
> Fetch the complete documentation index at: https://fdbad6a-heedeo-e1965c.manicule.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For every page in one file, fetch https://fdbad6a-heedeo-e1965c.manicule.dev/llms-full.txt (large).
> To search and read these docs as tools, connect the MCP server at https://fdbad6a-heedeo-e1965c.manicule.dev/api/mcp.
> Every agent surface: https://fdbad6a-heedeo-e1965c.manicule.dev/.well-known/llms-manifest.json

# 9. Report what you learn (/report-what-you-learn)

<!-- agent-signals: reading_time_min: 2 · est_tokens: 497 · updated: 2026-11-11 -->
Related: [Integrating Heedeo](/index.md), [Connect your app](/connect-your-app.md), [1. Quick start](/quick-start.md), [2. Serve Heedeo from your own domain (do this before you go live)](/serve-heedeo-from-your-own-domain.md), [3. One server call: evaluate or log](/one-server-call.md), [4. The fields to act on](/the-fields-to-act-on.md)

When you find out what a signup really was, tell Heedeo. An outcome changes no flag and no label: it records what really happened, and Recommend weights (Settings, Advanced, Weights) learns your weights from the events you labelled, so the more you report, the sooner your own numbers replace the defaults. A paid conversion is a cheap `legit`; a refund, a chargeback or a third free trial is `abuse`.

```sh
curl -s -H "authorization: Bearer $HEEDEO_SECRET_KEY" -H "content-type: application/json" \
  -d '{"event_id":"7504b755-…","outcome":"abuse","label":"trial_abuse","note":"third trial this month"}' \
  https://app.heedeo.com/v1/outcomes
```

Send exactly one of `event_id` (from the events response), `visitor_id` or `user_id` (hashed on arrival, as events hash it; an `abuse` by `user_id` is `confirmed_abuse` on the next event of every browser that has presented that account, or presents it then); `outcome` is `abuse` or `legit`; `label` is your own short word and `note` one line, both optional. One outcome per subject: a later report replaces the earlier one; a `visitor_id` a merge retired is reported on the visitor it joined, which the answer names with `merged_into`. An event or visitor that is not yours answers 404. Send a `request_id` with each report, the same one on a retry, as with a label (section 5, Let a real person through): a repeat in the next 72 hours gets the first answer, with `heedeo-replayed: true`, and replaces nothing, so a retry never undoes a reviewer's Confirm or Dismiss given in between; another report under it answers 409. The package sends one from 0.2.0-beta.1, and `requestId` sets your own. The answer is the stored row: `kind`, `event_id` or `visitor_id`, `outcome`, `label`, `source` (`api`, or `review` when a reviewer resolved the flag as Abuse or Legit on the review page), `note` and `created_at`. Outcomes show on the visitor page and beside resolved flags. With the package: `heedeo.outcome({ eventId, outcome: 'abuse' })`.
