Skip to content

Preview a correction without saving it (signed-in ANALYST+, not API keys)

POST
/invoices/{invoiceId}/correction-preview
curl --request POST \
--url https://api.invogi.com/v1/invoices/example/correction-preview \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "reason": "example", "expected_revision": 1, "verified_against_document": true, "fields": { "invoice_number": "example", "issue_date": "2026-04-15", "due_date": "2026-04-15", "currency": "example", "net_amount": "example", "tax_amount": "example", "gross_amount": "example", "purchase_order_ref": "example", "buyer": { "name": "example", "tax_id": "example" }, "supplier": { "name": "example", "tax_id": "example", "company_number": "example", "bank_account": { "iban": "example", "sort_code": "example", "account_number": "example" } }, "lines": [ { "description": "example", "quantity": "example", "unit_price": "example", "tax_rate": "example", "line_net_amount": "example" } ] } }'

Runs the correction in a transaction that is rolled back. Same body and result as PATCH, with preview true; nothing is stored. Where saving would be refused because the caller needs an Admin or Owner, or has not set verified_against_document, the preview still succeeds and lists the reasons in blockers.

invoiceId
required
string
Media typeapplication/json
object
reason
required
string
>= 1 characters <= 1000 characters
expected_revision

The revision the caller was looking at; a different current revision is a CONFLICT

integer
>= 1
verified_against_document

The person compared the corrected values with the invoice’s source document. Required for an analyst to clear data-quality findings; recorded on the revision

boolean
fields
required
object
>= 1 properties
invoice_number
string
issue_date
string format: date
due_date
string | null format: date
currency

ISO 4217

string
net_amount

Decimal string

string | null
tax_amount

Decimal string

string | null
gross_amount

Decimal string

string
purchase_order_ref
string | null
buyer
object
name
string
tax_id
string
supplier
object
name
string
tax_id
string
company_number

UK Companies House number. Setting it re-checks the corrected number against the register.

string
bank_account
object
iban
string
sort_code
string
account_number
string
lines

Replaces the whole line list

Array<object>
object
description
string
quantity
string
unit_price
string
tax_rate
string
line_net_amount
string

Example generated

{
"reason": "example",
"expected_revision": 1,
"verified_against_document": true,
"fields": {
"invoice_number": "example",
"issue_date": "2026-04-15",
"due_date": "2026-04-15",
"currency": "example",
"net_amount": "example",
"tax_amount": "example",
"gross_amount": "example",
"purchase_order_ref": "example",
"buyer": {
"name": "example",
"tax_id": "example"
},
"supplier": {
"name": "example",
"tax_id": "example",
"company_number": "example",
"bank_account": {
"iban": "example",
"sort_code": "example",
"account_number": "example"
}
},
"lines": [
{
"description": "example",
"quantity": "example",
"unit_price": "example",
"tax_rate": "example",
"line_net_amount": "example"
}
]
}
}

The decision and findings the correction would produce

Media typeapplication/json
object
id
required
string format: uuid
revision
required
integer
>= 2
decision
required
string
Allowed values: PASS REVIEW BLOCK
previous_decision
required
string | null
Allowed values: PASS REVIEW BLOCK
risk_score
required
integer
<= 100
changed_fields
required
Array<string>
superseded_finding_ids
required

Findings of earlier analyses that this correction replaced

Array<string>
cleared_findings
required

Findings the correction clears, as TYPE or TYPE (of N invoices) for findings that point at other invoices

Array<string>
added_findings
required

Findings the corrected data raises that the invoice did not have

Array<string>
blockers
required

What stops the caller from saving this correction. Only a preview returns blockers (saving refuses with the first one instead). Empty when saving would succeed.

Array<object>
object
kind
required
string
Allowed values: ADMIN_REQUIRED ATTESTATION_REQUIRED SOURCE_DOCUMENT_REQUIRED
message
required
string
findings
required
Array<object>
object
versions
required
object

Example

{
"decision": "PASS",
"previous_decision": "PASS",
"blockers": [
{
"kind": "ADMIN_REQUIRED"
}
]
}

Invalid request

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: NOT_FOUND UNAUTHORIZED FORBIDDEN INVALID_REQUEST CONFLICT RATE_LIMITED USAGE_LIMIT_EXCEEDED PROCESSING_FAILED
message
required
string
request_id
required
string

Example

{
"error": {
"code": "NOT_FOUND"
}
}

Missing or invalid API key

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: NOT_FOUND UNAUTHORIZED FORBIDDEN INVALID_REQUEST CONFLICT RATE_LIMITED USAGE_LIMIT_EXCEEDED PROCESSING_FAILED
message
required
string
request_id
required
string

Example

{
"error": {
"code": "NOT_FOUND"
}
}

API key lacks required scope/role

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: NOT_FOUND UNAUTHORIZED FORBIDDEN INVALID_REQUEST CONFLICT RATE_LIMITED USAGE_LIMIT_EXCEEDED PROCESSING_FAILED
message
required
string
request_id
required
string

Example

{
"error": {
"code": "NOT_FOUND"
}
}

Resource not found

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: NOT_FOUND UNAUTHORIZED FORBIDDEN INVALID_REQUEST CONFLICT RATE_LIMITED USAGE_LIMIT_EXCEEDED PROCESSING_FAILED
message
required
string
request_id
required
string

Example

{
"error": {
"code": "NOT_FOUND"
}
}

Conflicting idempotency key or resource processing state

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: NOT_FOUND UNAUTHORIZED FORBIDDEN INVALID_REQUEST CONFLICT RATE_LIMITED USAGE_LIMIT_EXCEEDED PROCESSING_FAILED
message
required
string
request_id
required
string

Example

{
"error": {
"code": "NOT_FOUND"
}
}