---
title: "Compare a CSV or PDF invoice with a record CSV"
method: POST
path: "/api/v1/invoice-audit"
---

# Compare a CSV or PDF invoice with a record CSV

`POST /api/v1/invoice-audit`

## Request

- Base URL: `https://spoolis.com`
- URL: `https://spoolis.com/api/v1/invoice-audit`
- Auth: HTTP bearer

Compares mapped invoice rows with mapped record rows and returns measured differences, totals, and a period statement. Send exactly one of invoice_csv or invoice_pdf_base64. A PDF is read in server memory for the request and is not stored. The operation is deterministic, does not decide which source is correct, and requires a full-scope key.

## Request body

- InvoiceAuditRequest
  - `invoice_csv` string: CSV invoice input. Send exactly one of invoice_csv or invoice_pdf_base64.
  - `invoice_pdf_base64` string: Bare standard base64 PDF input. Send exactly one of invoice_pdf_base64 or invoice_csv.
  - `record_csv` string, required
  - `mapping` object, required
    - `invoice` object, required
      - `key` string[], required
      - `amount` string, required
      - `date` string
      - `quantity` string
    - `record` object, required
      - `key` string[], required
      - `amount` string
      - `date` string
  - `options` object
    - `currency` string
    - `key_normalization` 'exact' | 'trim_casefold'
    - `amount_tolerance_cents` number
    - `period` object
      - `start` string, required
      - `end` string, required
  - `vendor_label` string

## Response `200`

Invoice audit report and period statement

- InvoiceAuditResponse
  - `run_id` string, required
  - `report` object, required
    - `as_of` string, date-time, required
    - `currency` string, required
    - `period` object
      - `start` string, required
      - `end` string, required
    - `totals` object, required
      - `billed_cents` integer, required
      - `supported_cents` integer, required
      - `questioned_cents` integer, required
      - `by_kind` object, required
        - `not_in_record` object, required
          - `lines` integer, required
          - `cents` integer, required
        - `duplicate_line` object, required
          - `lines` integer, required
          - `cents` integer, required
        - `ambiguous_match` object, required
          - `lines` integer, required
          - `cents` integer, required
        - `amount_mismatch` object, required
          - `lines` integer, required
          - `cents` integer, required
        - `outside_period` object, required
          - `lines` integer, required
          - `cents` integer, required
        - `unreadable_date` object
          - `lines` integer, required
          - `cents` integer, required
        - `unreadable_amount` object, required
          - `lines` integer, required
          - `cents` integer, required
        - `in_record_not_billed` object, required
          - `lines` integer, required
          - `cents` integer, required
      - `invoice_lines` integer, required
      - `record_rows` integer, required
      - `matched_lines` integer, required
      - `unreadable_lines` integer, required
      - `unreadable_date_lines` integer
      - `credit_lines` integer, required
    - `findings` object[], required
      - `kind` 'not_in_record' | 'duplicate_line' | 'ambiguous_match' | 'amount_mismatch' | 'outside_period' | 'unreadable_date' | 'unreadable_amount' | 'in_record_not_billed', required
      - `discrepancy_kind` 'count' | 'duplicate' | 'evidence' | 'amount' | 'timing' | 'other', required
      - `invoice_row` integer
      - `record_rows` integer[], required
      - `key` string[], required
      - `expected` object, required
      - `observed` object, required
      - `explanation` string, required
    - `discrepancy_drafts` object[], required
      - `kind` string, required
      - `expected` object, required
      - `observed` object, required
      - `explanation` string, required
      - `unit` integer, required
    - `digest` string, required
  - `statement` object, required
    - `vendor_label` string
    - `period` object
      - `start` string, required
      - `end` string, required
    - `currency` string, required
    - `invoice_lines` integer, required
    - `record_rows` integer, required
    - `matched_lines` integer, required
    - `unreadable_lines` integer, required
    - `unreadable_date_lines` integer
    - `credit_lines` integer, required
    - `billed_cents` integer, required
    - `supported_cents` integer, required
    - `questioned_cents` integer, required
    - `findings` object[], required
      - `kind` 'not_in_record' | 'duplicate_line' | 'ambiguous_match' | 'amount_mismatch' | 'outside_period' | 'unreadable_date' | 'unreadable_amount' | 'in_record_not_billed', required
      - `lines` integer, required
      - `cents` integer, required
    - `report_digest` string, required
  - `pdf` object
    - `pages` integer, required
    - `lines` integer, required
    - `headers` string[], required
    - `dropped_ungrounded` integer, required
    - `reconciliation` object, required
      - `status` 'matches' | 'differs' | 'no_total', required
      - `lines_cents` integer, nullable, required
      - `stated_cents` integer, nullable, required

## Other responses

- `400`: Machine-readable invoice audit error
- `401`: Machine-readable invoice audit error
- `403`: Machine-readable invoice audit error
- `413`: Machine-readable invoice audit error
- `429`: Machine-readable invoice audit error
- `500`: Machine-readable invoice audit error

---

[API](https://skmtc.dev/spoolis/apis/spoolis-public-api.md) · [All operations](https://skmtc.dev/spoolis/apis/spoolis-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/spoolis/apis/spoolis-public-api/revisions/e438bfc05c01?raw)
