---
title: "Apply a review tip"
method: POST
path: "/reports/{id}/versions/{versionId}/review/findings/{findingId}/apply"
tags: ["Reports"]
---

# Apply a review tip

`POST /reports/{id}/versions/{versionId}/review/findings/{findingId}/apply`

## Request

- Base URL: `https://api.greentally.ai/v1`
- URL: `https://api.greentally.ai/v1/reports/{id}/versions/{versionId}/review/findings/{findingId}/apply`
- Auth: HTTP bearer

Report review spec §11. P1 applies a completeness tip whose fix is an answer: the body's answer is validated and written exactly as PATCH /reporting-profile/{year} writes it (for fix.year, in the request's workspace, source user), and the tip is marked applied in the same transaction. The version itself is frozen: updateOffered is true and the client offers "Update report". Applying an applied tip answers 200 unchanged. 409 REPORT_REVIEW_APPLY_REJECTED for a tip whose fix is a link, REPORT_REVIEW_FINDING_CLOSED for a dismissed tip, WORKSPACE_SCOPE_UNSUPPORTED in a workspace that keeps no answers of its own, PROFILE_CHANGED when the answer kept changing while it was being saved (retry); 400 VALIDATION_ERROR for an answer the question does not take. A wording tip is applied with no body (or `{}`): its sentence is replaced by the stored rewrite (or removed, for an empty rewrite, with the paragraph's other open tips re-anchored to their sentences) through the manual edit's own save (a published version is copied into a new draft version, its tips carried), and the response's report is the version written. 409 REPORT_REVIEW_VERSION_SUPERSEDED when the version is no longer the report's current draft version, REPORT_REVIEW_FINDING_OUT_OF_DATE when its sentence changed, REPORT_REVIEW_APPLY_REJECTED when the edit is refused; 400 VALIDATION_ERROR for an answer on a wording tip or no answer on a completeness tip. Needs report.edit_draft, and report.create when an answer is sent.

## Path parameters

- `id` string, required
- `versionId` string, required
- `findingId` string, required

## Request body

- ReportReviewApplyRequest: P1 requires answer (a completeness tip's answer fix); P2's wording apply sends none.
  - `answer` ReportingProfileAnswerChange
    - `reason` string
    - `status` 'reported' | 'not_applicable' | 'omitted_sensitive' | 'not_estimated' | 'missing', required
    - `unit` string
    - `value` unknown

## Response `200`

The tip, applied

- ReportReviewApplyResponse
  - `data` ReportReviewApplyResult, required
    - `finding` ReportReviewFinding, required
      - `anchor` ReportReviewAnchor, required: Where a tip sits. blockId is the block its marker sits beside (absent when no block holds it); completeness adds datapointId, checkId or rowKey (the row's first cell); wording (P2) adds sentenceIndex, sentenceHash and span (UTF-16 code units, [start, end)).
        - `blockId` string
        - `checkId` string
        - `datapointId` string
        - `rowKey` string
        - `sentenceHash` string
        - `sentenceIndex` integer
        - `span` object
          - `end` integer, required
          - `start` integer, required
      - `appliedVersionId` string: The version a wording apply wrote (P2); absent for completeness.
      - `category` 'share_as_predicate' | 'missing_subject' | 'omitted_key_fact' | 'unclear' | 'redundancy' | 'tone' | 'missing_item' | 'failed_check' | 'month_without_data' | 'site_without_data' | 'scope3_unassessed', required
      - `fix` ReportReviewFix, required: How the tip is fixed; type says which fields are set. none: nothing to apply or follow (dismiss only). rewrite (P2): original, rewrite (display texts); rewrite absent or empty (redundancy, tone or unclear only) means remove the sentence. answer: datapointId, year, item (as readiness shows it, pre-filled only from its stored suggestion), focusRow (a Scope 3 category), answeredSince (answered after this version was made: update the report). link: target, a place the client routes to.
        - `answeredSince` boolean
        - `datapointId` string
        - `focusRow` integer
        - `item` ReportReadinessItem
          - `answerable` boolean, required
          - `applicable` boolean, required
          - `choices` object[]
            - `label` string, required
            - `value` string, required
          - `citation` string
          - `columns` object[]
          - `display` string, required
          - `help` string
          - `id` string, required
          - `label` string, required
          - `origin` object
          - `question` string
          - `reason` string
          - `requirement` 'required' | 'if_applicable' | 'optional', required
          - `source` 'ledger' | 'profile' | 'derived' | 'user', required
          - `status` 'reported' | 'not_applicable' | 'omitted_sensitive' | 'not_estimated' | 'missing', required
          - `suggestion` ReportingProfileAnswer
            - `answeredAt` string, date-time, required
            - `answeredBy` string, required
            - `reason` string
            - `source` 'user' | 'tally', required
            - `status` 'reported' | 'not_applicable' | 'omitted_sensitive' | 'not_estimated', required
            - `unit` string
            - `value` unknown
          - `suggestionOrigin` 'override_last_year' | 'default_last_year': Where suggestion came from (last year's override row or last year's Default workspace row). Set only with suggestion.
          - `type` 'number' | 'integer' | 'money_eur' | 'percent' | 'tonnes' | 'text' | 'bool' | 'enum' | 'year' | 'date' | 'list' | 'table', required
          - `unit` string
        - `original` string
        - `rewrite` string
        - `target` 'emissions_data' | 'sites' | 'organization_profile' | 'answer_sheet'
        - `type` 'rewrite' | 'answer' | 'link' | 'none', required
        - `year` integer
      - `id` string, required
      - `kind` 'wording' | 'completeness', required: Template issues are stored for a central fix and never returned.
      - `originFindingId` string: Wording tips only: the tip's first row before any copy on write (its own id when not carried). Clients match a tip across versions by it.
      - `reason` string, required: Core's sentence; never model text.
      - `severity` 'high' | 'medium' | 'low': A fixed map by category
      - `state` 'current' | 'out_of_date', required: Completeness tips are always current.
      - `status` 'open' | 'applied' | 'dismissed', required
      - `statusAt` string, date-time
      - `statusBy` string
      - `title` string, required: Core's label of the tip (the item's label
    - `report` ReportDetail
      - `accessReason` 'owned_by_me' | 'shared_with_me' | 'organization_access'
      - `createdAt` string, date-time, required
      - `draftVersionId` string
      - `framework` 'ghg_protocol' | 'csrd_esrs' | 'management' | 'vsme', required: csrd_esrs is retired: existing reports stay readable, editable and exportable, and no new one can be created (400 FRAMEWORK_RETIRED). vsme reports are made only by the report engine.
      - `id` string, required
      - `latestPublishedAt` string, date-time
      - `latestPublishedVersionId` string
      - `periodEnd` string: Last day the current draft covers (inclusive), YYYY-MM-DD; absent on earlier reports. Only in the list, and only while REPORTS_V2_ENABLED is on.
      - `periodStart` string: First day the current draft covers, YYYY-MM-DD; absent on earlier reports. Only in the list, and only while REPORTS_V2_ENABLED is on.
      - `sourceOrganizationName` string
      - `status` string: draft, incomplete or published (the list's Status column). Only in the list, and only while REPORTS_V2_ENABLED is on.
      - `template` 'executive_carbon_summary' | 'dashboard_snapshot_report'
      - `templateId` string: The report engine's template (ghg, vsme or management); absent on earlier reports. Only in the list, and only while REPORTS_V2_ENABLED is on.
      - `title` string, required
      - `tone` 'conservative' | 'consultant' | 'executive_narrative'
      - `updatedAt` string, date-time, required
      - `draft` object
      - `evidencePack` object: Report evidence pack. reportContext.emissionsUnit ("tCO2e") is the unit of every emissions value in the pack (metric values, chart/table "emissions" fields); packs without it predate the unit fix and hold kgCO2e sums labelled tCO2e. reportContext.period uses month granularity: startDate is the first day of the first month and endDate the first day of the LAST INCLUDED month; startMonth/endMonth ("YYYY-MM", inclusive) and endDateInclusive ("YYYY-MM-DD", the last covered day) spell that out on packs generated after they were added. A report-evidence-pack/v2 pack (report engine) freezes every resolved datapoint in datapoints[]: id, label, type, requirement, applicable, status, value, unit, source, quality, reason, display, origin and citation, plus caveat, which qualifies a reported figure (for example "excludes 2 energy bills with no kWh recorded"); figures derived from it carry the same caveat, and its display already includes it. A datapoint may also carry proseDisplay (optional): the text that model-written prose substitutes for the datapoint's token ("24.0 tCO2e of Scope 1 emissions"), which names the figure's subject where display, shown next to its own label in tables, does not; it may leave the caveat out to fit the prose fact limit. Absent when prose uses display, and on packs generated before it was added. A v2 pack's reportContext.emissionBasis (absent: calculated) records what its totals counted: basis ("calculated" or "supplier_figures/v1"), supplierProvidedT, replacedEstimateT, their prior-period twins, figures[] (figureId, supplierId, period start/end inclusive, basis, figureT, estimateT, factor, appliedT, replacedT, status applied|not_applied, and withheldByClose: true when a period closed on calculated figures withholds the figure, omitted otherwise) and, on an update, previousVersion (versionNumber, basis, figuresIncluded: whether that version's totals counted an applied figure, and figuresChanged: whether the applied figures differ, set only when both versions count figures). A v2 pack's reportContext.periodClose (period close A6; absent when a month of the effective period was open at generation) records locks[] (lockId, from, to, closedAt, snapshotSha256), priorPeriodClosed (true also when the report shows no prior comparison) and snapshotTotalT, the covering locks' snapshot tonnes over the period, present only for a whole-organization, whole-month report whose basis equals every lock's snapshot basis. When the snapshot reconciles it matches the report's total within 0.0005 t; it is never compared for equality.
      - `organizationName` string: Display name of the organization the report was prepared by, resolved when the report is read (organization name, else its account name, else its slug). Prefer it over evidencePack.reportContext.organizationName, which reports generated before it was recorded do not carry.
      - `recipientLabel` string: Set only on the shared-link view (GET /shared/report): the recipient label the link was created with, e.g. "Acme Hotels (verifier)". Absent when the link has none.
      - `reviewAvailable` boolean: Report review (spec 2026-10-06 §12): present, and true, only when REPORT_REVIEW_ENABLED is on, the version is the report engine's and the caller may edit the draft (report.edit_draft). Absent otherwise, so earlier responses are unchanged byte for byte.
      - `validation` object
      - `versionId` string
      - `versionStatus` 'draft' | 'published' | 'archived'
    - `updateOffered` boolean, required

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found
- `409`: Conflict

## Changes

- **2026-10-09** `840a458f7a4d`: 1 info
  - added the optional property `data/finding/originFindingId` to the response with the `200` status
- **2026-10-08** `adccfaee8514`: 1 info
  - request body became optional
- **2026-10-07** `5c524454c847`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/greentally/apis/esgai-api/changes/reports/:id/versions/:versionId/review/findings/:findingId/apply/post.md)

---

[API](https://skmtc.dev/greentally/apis/esgai-api.md) · [All operations](https://skmtc.dev/greentally/apis/esgai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/greentally/apis/esgai-api/revisions/7eab940f1dd0?raw)
