Skip to content

Report outcomes

An assessment is a prediction. Weeks later your platform knows the truth: the account ran up a chargeback, your team closed an abuse case, or a flagged signup turned out to be a real customer. POST /v1/assessments/{assessment_id}/outcomes records that truth against the assessment.

Outcomes are the only way NoResponse learns what happened on your platform. A confirmed abuse report links the identifiers in that assessment to abuse, so a later signup that shares them scores higher. A withdrawal clears an earlier report. Over time your outcomes make the scores your platform receives more accurate, and they give you a record of which assessments were right.

Outcome Meaning Effect
confirmed_abuse Your team confirmed the account was abusive. Reports abuse.
account_takeover The account was taken over by someone other than its owner. Reports abuse.
chargeback A payment on the account was charged back. Reports abuse.
false_positive The assessment pointed at abuse and your team found a real customer. Withdraws your platform’s earlier abuse report for this assessment.
legitimate The account proved to be a real customer. Withdraws your platform’s earlier abuse report for this assessment.
unknown You closed the case without a finding. Recorded only.

Outcomes are append-only, and the latest one recorded for an assessment wins. Send legitimate after confirmed_abuse and the abuse report is withdrawn.

Send an outcome at the moment your platform learns something, from the system that learns it.

  • When your payment processor reports a chargeback, send chargeback.
  • When your team closes a review as abuse, send confirmed_abuse with the case id as external_ref.
  • When your team clears a review, or an account that was stepped up or reviewed has been a paying customer for a while, send legitimate.
  • When your security team confirms a takeover, send account_takeover.

You need the assessment_id you stored with the decision. An outcome for an assessment that has expired, or that belongs to another platform, answers 404.

const outcome = await nr.assessments.recordOutcome(
"asm_01M5FNFQWDRBZZMWBPN0WEC40C",
{
outcome: "confirmed_abuse",
observedAt: "2026-11-04T10:15:00Z",
externalRef: "case-4821",
notes: "Credits spent on a relay within an hour of signup; closed by trust and safety.",
},
{ idempotencyKey: "outcome-case-4821-confirmed_abuse" },
);
console.log(outcome.id, outcome.receivedAt);
Field Rules
outcome Required. One of the six values above.
observed_at When your platform observed the outcome, as RFC 3339. Defaults to when NoResponse received it.
external_ref Your own reference, such as a case or ticket id, up to 128 characters of letters, digits, ., _, : and -.
notes Free text for your own records, up to 500 characters. Stored with the outcome and not scored.

The Idempotency-Key is required, and it works as it does on POST /v1/assessments: the same key and body replays the record with Idempotent-Replayed: true, and the same key with a different body answers 409 idempotency_key_reused. The key stays bound to its first body for as long as the outcome is kept. Derive it from the case and the outcome, as above, rather than from the time. A later outcome for the same case, such as a withdrawal, then uses a new key and does not answer 409.

The answer is 202 with the recorded outcome.

{
"id": "out_01JA2ZC0Q1R2S3T4V5W6X7Y8Z9",
"assessment_id": "asm_01M5FNFQWDRBZZMWBPN0WEC40C",
"outcome": "confirmed_abuse",
"received_at": "2026-11-04T10:15:02.000Z"
}

There is nothing to poll afterwards. The outcome follows its assessment’s retention: when the assessment expires, the outcome goes with it.