---
title: "Write findings for an exception's lines"
method: PUT
path: "/reconciliation_exceptions/{id}/findings"
---

# Write findings for an exception's lines

`PUT /reconciliation_exceptions/{id}/findings`

## Request

- Base URL: `https://api.endclose.com/v1`
- URL: `https://api.endclose.com/v1/reconciliation_exceptions/{id}/findings`
- Auth: API key in header `X-API-KEY`

Upserts one finding per record of the exception — the note, status and suggested action your reviewers see on each open line. Findings are keyed on (exception, record), so sending the same record again replaces its finding. Up to 1,000 findings per request; each is validated independently and the response lists the rejected ones, so a partial batch still writes. Records already matched by rules do not need findings — write them for the lines that are left.

## Path parameters

- `id` string, required

## Headers

- `Idempotency-Key` string

## Request body

- FindingsUpsertRequest
  - `findings` FindingInput[], required
    - `record_id` string: The record's id. Required unless `external_id` is given.
    - `external_id` string: The record's external id within the exception's data stream. Rejected when it matches more than one record.
    - `looks_right` boolean: `true` when the line is correct as it stands and only needs the note. These lines can be confirmed in bulk.
    - `note` string, required: One or two plain sentences: what happened to this line and what was checked.
    - `category` string, nullable: A short label for the kind of line, in your own words (e.g. `back-billing`, `monthly minimum`).
    - `suggestion` object: What Approve applies. Omit, or use kind `none`, when there is nothing to apply.
      - `kind` 'match' | 'adjust' | 'none': `match`: pair the line with `record_ids` (must balance). `adjust`: pair them and plug the remaining gap with an adjustment carrying `reason`. `none`: nothing to apply.
      - `record_ids` string[]: Every other record of the proposed match, either side, as record ids or external ids.
      - `reason` string: For `adjust`: why a gap remains. Becomes the adjustment's description.
      - `text` string: The sentence shown next to the Approve button.
      - `difference_cents` integer: Informational. Recomputed from the records as |side A| − |side B| whenever `record_ids` is given; only kept as sent for a one-sided `adjust`.
    - `evidence` object[]: Quotes that back the note. A quote with a `url` marks the line as checked against a document in the review.
      - `quote` string, required
      - `source` string, nullable: Where the quote is from, e.g. `Services Agreement, Exhibit B p.19`.
      - `url` string, nullable: An http(s) link to the document — for a file in End Close, the file's `url`. End `#page=N` to open a PDF at that page: the review drawer labels the link “Open p.N” and shows the document inline. Other schemes are dropped.
    - `precedent` string, nullable: How the same line was handled before, in one sentence.
    - `labels` object: Free-form markers your reviewers care about, e.g. `{"carried_forward": true, "colour": "peach"}`. The review page reads `colour`, `colour_cell` and `carried_forward`; anything else is stored and returned untouched.

## Response `200`

Findings written (possibly with per-finding errors)

- FindingsUpsertResult: Each finding is validated on its own, so a batch succeeds partially: `upserted` counts the rows written and `errors` names the rejected ones by position.
  - `upserted` integer
  - `errors` object[]
    - `index` integer: Position of the rejected finding in the request's `findings`.
    - `record_id` string
    - `external_id` string
    - `message` string

## Other responses

- `401`: Unauthorized
- `404`: Exception not found
- `422`: `findings` is not a list, or has more than 1,000 items

## Changes

- **2026-10-29** `159f9ed3dbf4`: 1 info
  - added the new optional `header` request parameter `Idempotency-Key`
- **2026-10-07** `e4a47982742a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/endclose/apis/end-close-api/changes/reconciliation_exceptions/:id/findings/put.md)

---

[API](https://skmtc.dev/endclose/apis/end-close-api.md) - [All operations](https://skmtc.dev/endclose/apis/end-close-api/llms.txt) - [OpenAPI document](https://skmtc.dev/endclose/apis/end-close-api/revisions/dfe0fde00f12?raw)
