# Get a Finding's History

Source: https://docs.pitchpointsolutions.com/api/findings/get_workflow_finding_history/

**Beta**

The finding's audit trail, newest first, up to 500 entries. Not paged: entries beyond the 500 newest are not returned.

Every event recorded on the finding appears here, and `eventType` says what kind it is:

* **Events that changed fields** (`resultChanged`, `reviewedChanged`, `noteChanged`) produce **one entry per field changed**, all sharing the event's `eventType`, `reviewer` and `changedAt`. `field` names what changed: the review note (`reviewedNotes`), the reviewed state (`reviewed`) or the result override (`resultOrOverriddenResult`). A change to the reviewed state can bring further entries recording who is now the reviewer of record.
* **Events that changed no field** produce one entry each, with no `field`, `previousValue` or `newValue`:
  * `created`: the finding was produced.
  * `edited`: the finding was [edited](https://docs.pitchpointsolutions.com/api/findings/edit_workflow_finding), or an attachment was [added](https://docs.pitchpointsolutions.com/api/findings/create_workflow_finding_attachment), changed or [removed](https://docs.pitchpointsolutions.com/api/findings/delete_workflow_finding_attachment).
  * `read`: the finding's details were opened in Pitchpoint's own application. Reading a finding through this API records nothing.
  * `empowerExportSuccess` and `empowerExportFailed`: an export of the finding to Empower succeeded or failed.

One save can record several events. An [edit](https://docs.pitchpointsolutions.com/api/findings/edit_workflow_finding) that changes the note and marks the finding reviewed records a `noteChanged` event, a `reviewedChanged` event and an `edited` event.

Don't assume `eventType` or `field` comes from a fixed list: show or skip a value you don't recognize, rather than failing.

### Sample

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

#### Header Properties

| Property | Value | Required? |
|----------|-------|-----------|
| Authorization | Bearer *your token* | true |

#### Path Parameters

| Property | Description | Type |
|----------|-------------|------|
| workflowId | The workflow's id, exactly as this API returned it. | string |
| findingId | The finding's id, exactly as published in `findingId`. | string |

> **Warning:** `workflowId`, `findingId` and `attachmentId` are opaque. Send each one back exactly as this API returned it: don't parse it, build one yourself, or add or remove its prefix. A `findingId` or `attachmentId` that isn't exactly as published, including one with its prefix removed, returns a 404 as if it didn't exist.

### Responses

**200**

| Property | Description | Type |
|----------|-------------|------|
| workflowId | The workflow's id. | string |
| findingId | The finding's id, echoed so a stored payload still says which finding it describes. | string |
| history | Up to 500 entries, newest first. Never null: `[]` when the finding has no recorded events, in which case its `hasHistory` is `false`. | array |

##### history entry

| Property | Description | Type |
|----------|-------------|------|
| eventType | What kind of event recorded this entry: `created`, `read`, `edited`, `resultChanged`, `reviewedChanged`, `noteChanged`, `empowerExportSuccess` or `empowerExportFailed`. Treat the list as open and tolerate values not listed here. Omitted when the event's type isn't recognized. | string |
| field | The name of the field this entry changed, such as `reviewed`, `reviewedNotes` or `resultOrOverriddenResult`. Omitted on an entry for an event that changed no field, and when none was recorded. | string |
| previousValue | The value before the change, rendered as text. Omitted when the field had no value before the change, and on an entry for an event that changed no field. | string |
| newValue | The value after the change, rendered as text. A stored non-string value arrives as its JSON form, so don't assume this always parses as a bare scalar. Omitted when the change recorded none, as when a note is cleared, and on an entry for an event that changed no field. | string |
| reviewer | Who recorded the event, as a display name. | string |
| changedAt | When the event was recorded. RFC 3339 UTC, trailing `Z`. Omitted when none was recorded; such entries sort last. | string |

```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"
    }
  ]
}
```

Read from the bottom up: the finding was created, then one [edit](https://docs.pitchpointsolutions.com/api/findings/edit_workflow_finding) set the note and marked it reviewed (a `noteChanged`, a `reviewedChanged` and an `edited` entry sharing `reviewer` and `changedAt`), and a later edit overrode the result from `Fail` to `Pass`. Entries that share a `changedAt` can appear in either order.

Marking a finding reviewed or unreviewed can also add entries recording the reviewer of record; the example leaves them out. A finding that had never been reviewed has no previous `reviewed` value, so that entry has no `previousValue`, as above.

A cleared note appears as a `reviewedNotes` entry with no `newValue`. Earlier notes stay here after they are replaced or cleared.

**401**

No credential the service could accept reached it. The body is an RFC 9457 problem document, served as `application/problem+json`, and the response carries a `WWW-Authenticate` challenge. The request body is never read, so a 401 says nothing about whether the rest of your request would have been accepted.

Two problem types tell the cases apart:

| `type` | Meaning | `WWW-Authenticate` |
|--------|---------|--------------------|
| `about:blank` | No credential was presented. | `Bearer realm="Helix"` |
| `https://pointservices.com/problems/invalid-token` | A credential was presented and rejected. The response doesn't say why: an expired, revoked, badly signed and malformed token all look the same. | `Bearer realm="Helix", error="invalid_token"` |

```json
{
  "type": "https://pointservices.com/problems/invalid-token",
  "title": "The access token was not accepted",
  "status": 401,
  "detail": "The access token was rejected.",
  "instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
```

> **Warning:** Refresh your token on a 401, and only on a 401. An expiring token moves a call from 200 to 401, never to 403, so a fresh token is the fix here and never the fix for a 403.

**403**

You may not read this workflow.

You are authenticated, and the answer is still no. This is an authorization decision, not a statement about your token, so refreshing the token won't turn it into a 200. 

The body is an RFC 9457 problem document, served as `application/problem+json`. Two problem types tell the cases apart:

| `type` | Meaning |
|--------|---------|
| `about:blank` | The request was refused before the operation ran. |
| `https://pointservices.com/problems/not-authorized` | The operation ran, and policy won't let you act on the workflow or finding you named. |

```json
{
  "type": "https://pointservices.com/problems/not-authorized",
  "title": "Not authorized",
  "status": 403,
  "detail": "The authenticated identity is not permitted to perform this action.",
  "instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
```

A 403 can also come from the edge, before the service is reached: for example, when a request value resembles SQL injection or cross-site scripting. Those refusals carry no problem document. Write your client to handle an error response it can't parse, rather than assuming every failure has a JSON body.

**404**

Unknown `workflowId` or unknown `findingId`. A finding with no recorded events is a 200 with an empty `history` array, never a 404.

The body is an RFC 9457 problem document, served as `application/problem+json`. Two problem types tell the cases apart:

| `type` | Meaning |
|--------|---------|
| `https://pointservices.com/problems/not-found` | An id in the path isn't one this API knows. Check that you sent it exactly as the API returned it. |
| `about:blank` | The URL or method isn't one this API serves at all. Check the path. |

| Property | Description | Type |
|----------|-------------|------|
| type | An absolute URI identifying the problem type. This is the stable value to match on; compare it as a string. | string |
| title | A short summary, written for a person. | string |
| status | The HTTP status code, repeated in the body. | number |
| detail | An explanation of this occurrence, written for your logs. Never match on it. | string |
| instance | A URI identifying this occurrence, written as `urn:pps:request:<id>`. The id is the same value as the `x-pps-request-id` response header. Quote it when you report a problem to PPS. | string |

```json
{
  "type": "https://pointservices.com/problems/not-found",
  "title": "No such resource",
  "status": 404,
  "detail": "Finding[fndg_0000000000006051384] not found",
  "instance": "urn:pps:request:8d3a1f56-6c94-4e20-b7f8-0a5e9c2d4b73"
}
```

> **Warning:** Branch on `type`, never on the text of `title` or `detail`.
