---
title: "Report what actually happened after a Scout scan"
method: POST
path: "/api/records/{record_id}/outcome"
tags: ["Outcome Feedback"]
---

# Report what actually happened after a Scout scan

`POST /api/records/{record_id}/outcome`

## Request

- Base URL: `https://flint.network`
- URL: `https://flint.network/api/records/{record_id}/outcome`
- Auth: one of:
  - none
  - API key in cookie `flint_session`
  - HTTP bearer
  - HTTP bearer

FLINT cannot stop a wallet; this is the enforce-or-attest half of the contract. Reports whether the scanned transaction executed, was held, or was cancelled. Auth is one of: a bearer or cookie session whose account owns the passport presented on the record, the anonymous caller_binding_token issued with the scan (open security, no scheme), or a partner service credential. Idempotent: the first write wins and a later write returns 409 with the existing outcome. Reporting executed or executed_despite_block after a BLOCK verdict is stored as an override, appended to the passport ledger, and alerts the passport owner through Sentinel.

## Path parameters

- `record_id` string, required

## Request body

- OutcomeReportRequest
  - `outcome` 'executed' | 'held' | 'executed_despite_block' | 'cancelled', required
  - `tx_hash` string: Required when outcome starts with executed.
  - `chain` string
  - `note` string
  - `caller_binding_token` string: Required to report anonymously as the caller instead of via session or partner credential.

## Response `200`

Outcome recorded.

- OutcomeReportResponse
  - `ok` boolean, required
  - `record_id` string, required
  - `outcome` RecordOutcome, required: What actually happened after a scan, as reported through POST /api/records/{record_id}/outcome. GET /api/records/{id} and GET /api/counterparty/{address} strip reporter.ref from this shape before returning it publicly; reporter.type is always kept.
    - `outcome` 'executed' | 'held' | 'executed_despite_block' | 'cancelled', required
    - `tx_hash` string, nullable
    - `chain` string, nullable
    - `reported_at` string, date-time, required
    - `reporter` object, required
      - `type` 'owner_session' | 'caller' | 'partner', required
      - `ref` string, nullable: Stripped from every public projection of this shape; present only in the reporter's own POST response.
    - `verdict_at_scan` string, nullable
    - `override` boolean, required: True when verdict_at_scan was block and outcome starts with executed.
    - `tx_verified` boolean, nullable: Best-effort etherscan check of tx_hash against the scanned counterparty and amount. null when Etherscan is not configured or the check was inconclusive; a definitive non-match is rejected 400 tx_hash_mismatch instead of being stored.
    - `ledger_recorded` boolean: True only when an override was actually written to the passport's Scout ledger and Sentinel was notified: requires the override to be reported while the record's passport binding was credited, or by the passport owner's own session.
    - `reason` 'passport_not_credited' | 'null', nullable: Set to passport_not_credited when an override could not be written to the passport's Scout ledger because the binding was not credited and the reporter was not the owner's session.

## Other responses

- `400`: Invalid request
- `401`: No session, caller_binding_token, or partner credential was presented.
- `403`: The presented session does not own the passport bound to this record, or the caller_binding_token does not match.
- `404`: Resource not found
- `409`: An outcome was already reported for this record. The existing outcome is returned unchanged.

---

[API](https://skmtc.dev/flint/apis/flint-agent-transaction-control-api.md) · [All operations](https://skmtc.dev/flint/apis/flint-agent-transaction-control-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flint/apis/flint-agent-transaction-control-api/revisions/eb5052b7b5dc?raw)
