# Reviewing a Finding

Source: https://docs.pitchpointsolutions.com/developer_guides/findings/reviewing/

**Beta**

## Overview

You review a finding with one call, [Edit a Finding](https://docs.pitchpointsolutions.com/api/findings/edit_workflow_finding). It changes any of three things: the review note, whether the finding is reviewed, and a corrected result. This guide covers how to read a finding's review state, how to change it, the permissions behind each change, and the audit trail each change leaves.

## reviewed and reviewRequired

Every finding carries two booleans, both always present and never null:

- `reviewRequired`: does this finding need someone to look at it? It is set when the finding is produced and never changes afterwards. Nothing you do through this API changes it.
- `reviewed`: has it been looked at, by a person or by an automated process such as a match against a pre-approved list? This is the field review changes.

| reviewRequired | reviewed | Meaning |
|---|---|---|
| `true` | `false` | **Outstanding.** Needs review and hasn't had it. Build your work queue from these. |
| `true` | `true` | **Review done**, by a person or automatically. |
| `false` | `true` | **Cleared, though no review was needed.** Typical of an automated check that passed, or a finding someone reviewed anyway. |
| `false` | `false` | **No review needed.** Informational. |

To find the work still to do, test `reviewRequired` is `true` **and** `reviewed` is `false`. To tell whether a finding has been cleared, read `reviewed` on its own.

`reviewer` names who or what last changed the finding's review status, as a display name. While `reviewed` is `true`, that is who reviewed it; after a review is set back to unreviewed, it is who did that. It is absent when no change to the review status has been recorded, and when the identity can't be resolved to a display name. This API doesn't tell a person's review apart from an automated one.

## result and resultOrOverriddenResult

`result` is the check's own outcome, exactly as the check produced it. Reviewing or overriding a finding never changes it.

`resultOrOverriddenResult` is the outcome to act on: a reviewer's override when one has been recorded, and otherwise the same as `result`. Keep both if you want to show what the check said next to what the reviewer decided.

Neither is a closed set of values: they are defined per check. Keep a default branch for a value you don't recognize.

## The edit call

Every review change goes to the finding's own URL, with `POST`:

```bash
curl -X POST "https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/findings/fndg_0000000000006051384" \
  -H "Authorization: Bearer your_access_token_here" \
  -H "Content-Type: application/json" \
  -d '{"reviewNote": "Confirmed with borrower via phone on 8/7; income supported by attached paystub.", "reviewed": true}'
```

It is a partial update. Send only the fields you want to change:

| Field | What it does |
|---|---|
| `reviewNote` | Replaces the current note. An empty or blank string clears it. |
| `reviewed` | `true` marks the finding reviewed; `false` returns it to unreviewed. |
| `overrideResult` | Records a corrected outcome, published as `resultOrOverriddenResult`. |

A field you leave out, or send as `null`, is left as it is. A body with none of the three changes nothing and returns the finding unchanged. The response is always the whole finding after the edit, the same as a GET made right afterwards except that `category` is left out, so you don't need a second read to see the result unless you need the categories.

## Setting a review note

The note explains the decision. `reviewNote` **replaces** the current note: it is a single value, not a list you append to. Leading and trailing whitespace is trimmed.

```bash
curl -X POST "https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/findings/fndg_0000000000006051384" \
  -H "Authorization: Bearer your_access_token_here" \
  -H "Content-Type: application/json" \
  -d '{"reviewNote": "Income re-verified against the September paystub."}'
```

To clear the note, send an empty string: `{"reviewNote": ""}`. Afterwards the finding has no note, and its `reviewNote` is absent or `null`: treat the two the same. A replaced or cleared note isn't lost; it stays on the finding's history (see below).

Setting or clearing the note doesn't change `reviewed`.

## Marking a finding reviewed, or unreviewed

Send `{"reviewed": true}` to mark a finding reviewed. There is no precondition: you can mark a finding reviewed with or without a note, though a note explaining the decision is good practice. Sending the note and `reviewed` together, as in the first example above, does both in one call.

Send `{"reviewed": false}` to return a finding to unreviewed. `reviewer` then names who did that, and a finding that requires review is outstanding again, because `reviewRequired` doesn't change. Setting `reviewed` to `false` doesn't clear the note.

To undo a review completely, clear both in one call:

```bash
curl -X POST "https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/findings/fndg_0000000000006051384" \
  -H "Authorization: Bearer your_access_token_here" \
  -H "Content-Type: application/json" \
  -d '{"reviewed": false, "reviewNote": ""}'
```

## Overriding the result

When a reviewer decides the check's outcome was wrong, record the corrected outcome with `overrideResult`:

```bash
curl -X POST "https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/findings/fndg_0000000000006051384" \
  -H "Authorization: Bearer your_access_token_here" \
  -H "Content-Type: application/json" \
  -d '{"overrideResult": "Pass", "reviewNote": "Second income source confirmed; the mismatch is explained.", "reviewed": true}'
```

Afterwards `resultOrOverriddenResult` reads `Pass`, and `result` still reads the check's original outcome.

> **Warning:** **An override can be replaced, but not removed.** Send another `overrideResult` to change it. There is no way through this API to go back to "no override". An `overrideResult` that is empty or only whitespace is a 400, and nothing is changed.

## Permissions

`authorization.allow` on each finding lists the changes you may make to it, one token per permission you hold:

| Token | Needed for |
|---|---|
| `riskinsight:JournalResolvedValueReview` | `reviewed` and `overrideResult` |
| `riskinsight:JournalResolvedValueUpdateNote` | `reviewNote` |
| `riskinsight:JournalResolvedValueUpdateAttachment` | Adding and removing attachments (see [Attachments](https://docs.pitchpointsolutions.com/developer_guides/findings/attachments)) |

A body needs every permission its fields need. If any is missing, the whole call is refused with a 403 and nothing is changed: a note and `reviewed` sent together are applied together or not at all.

> **Warning:** **`authorization.allow` is for deciding what to offer, not a guarantee.** It is worked out for whoever is asking, on every request, so two users can see different tokens on the same finding. Every edit checks permission again and can still be refused with a 403: for example, when you may not update the workflow. Handle the 403 even when the token was present. The list isn't a closed set; ignore a token you don't recognize.

## When two edits collide

If another request changes the finding while yours is in flight, yours is refused with a 409 of type `https://pointservices.com/problems/concurrent-modification`, and **nothing** from your request is applied. The service doesn't retry it for you. Read the finding again, check that your change still makes sense against what you now see, and resubmit only if it does. See [Edit a Finding](https://docs.pitchpointsolutions.com/api/findings/edit_workflow_finding#responses) for every error the call can return.

## The audit trail

Every event on the finding is recorded, from its creation through each edit and attachment change. Read it back with [Get a Finding's History](https://docs.pitchpointsolutions.com/api/findings/get_workflow_finding_history):

```bash
curl -X GET "https://api.pointservices.com/riskinsight-services-ws/resources/v1/findings/workflows/wfpop_0000000000002082611/findings/fndg_0000000000006051384/history" \
  -H "Authorization: Bearer your_access_token_here"
```

```json
{
  "workflowId": "wfpop_0000000000002082611",
  "findingId": "fndg_0000000000006051384",
  "history": [
    {
      "eventType": "resultChanged",
      "field": "resultOrOverriddenResult",
      "previousValue": "Fail",
      "newValue": "Pass",
      "reviewer": "Reviewer, Jane",
      "changedAt": "2026-08-07T15:10:31Z"
    },
    {
      "eventType": "edited",
      "reviewer": "Reviewer, Jane",
      "changedAt": "2026-08-07T15:10:31Z"
    },
    {
      "eventType": "reviewedChanged",
      "field": "reviewed",
      "newValue": "true",
      "reviewer": "Reviewer, Jane",
      "changedAt": "2026-08-07T15:04:09Z"
    },
    {
      "eventType": "noteChanged",
      "field": "reviewedNotes",
      "newValue": "Confirmed with borrower via phone on 8/7; income supported by attached paystub.",
      "reviewer": "Reviewer, Jane",
      "changedAt": "2026-08-07T15:04:09Z"
    },
    {
      "eventType": "edited",
      "reviewer": "Reviewer, Jane",
      "changedAt": "2026-08-07T15:04:09Z"
    },
    {
      "eventType": "created",
      "reviewer": "Orderer, Sam",
      "changedAt": "2026-08-07T14:52:18Z"
    }
  ]
}
```

`eventType` says what kind of event each entry records. An event that changed fields gives **one entry per field**: the edit at 15:04:09 that set the note and marked the finding reviewed gave a `noteChanged` and a `reviewedChanged` entry, plus an `edited` entry for the save itself, all sharing `reviewer` and `changedAt`. The newest entries record an override. `field` names what changed: `reviewedNotes` for the note, `reviewed` for the reviewed state, and `resultOrOverriddenResult` for an override. Events that changed no field, such as `created` and `edited`, have no `field`. Marking a finding reviewed or unreviewed can also add entries recording the reviewer of record, which the example leaves out. Don't assume `eventType` or `field` comes from a fixed list.

`previousValue` is omitted when the field had no value before the change. A cleared note shows as a `reviewedNotes` entry with no `newValue`. Earlier notes and reviews stay here after they are replaced or undone.

> **Warning:** **The trail is capped at the 500 newest entries and isn't paged.** Anything older than that isn't returned, and there's no next page to ask for.

## Categories

`category` on a finding, and the grouped view at [Get a Workflow's Findings by Category](https://docs.pitchpointsolutions.com/api/findings/get_workflow_findings_by_category), both use the workflow owner's own configured category names.

> **Warning:** **Category names are labels for a person, not a stable key.** Two workflows can legitimately use different category names for the same kind of finding, and a workflow owner can reword or add categories over time without that being a breaking change to this API. If you need something stable to switch on, use the finding's `code` instead: that's the machine-readable identifier for what was checked.
