> ## Documentation Index
> Fetch the complete documentation index at: https://docs.watchdog.no/llms.txt
> Use this file to discover all available pages before exploring further.

# Compliance checks

> Check invoices against their agreements and read the results.

A compliance check reads an invoice and compares it with the terms and prices of an agreement it is
matched to. Anything that doesn't follow the agreement becomes an [alert](/api-reference/alerts).

New invoices are checked automatically when they arrive. Use the commands on this page to check
invoices that were missed, or to check again after an agreement has changed.

## Check an invoice

```bash theme={null}
curl -X POST "$API_URL/v1/invoices/$INVOICE_ID/check" \
  -H "Authorization: Bearer $API_KEY" -H "X-Organization-Id: $ORGANIZATION_ID"
```

This checks the invoice against every agreement it can be checked against. To check only some of
them, send `{"agreement_ids": [...]}`. The response has a `workflow_run_id` that you can
[follow until it finishes](/api-reference/workflow-runs). When it has, the invoice's `alerts` show the
result.

## Check an agreement

`POST /v1/agreements/{id}/check` checks every invoice matched to the agreement that hasn't been
checked yet, or whose last check failed. When the response says `has_more`, there were more
invoices than one request takes: send it again after the run has finished.

`POST /v1/agreements/check` does the same for all your agreements.

## Choose a scope before running

`POST /v1/check-selections/preview` previews a selection without starting checks.
Use an agreement filter, explicit agreement IDs, a topic, or a previous run's unfinished items as the
scope. Agreement filters in this JSON body use arrays and booleans, not comma-separated query values.
The full matching scope is resolved server-side, independently of the current page.

Choose `outstanding` for eligible unchecked or failed pairs, or `again` to include completed pairs.
Invoices can be selected explicitly, filtered by inclusive invoice dates, or sampled with a stable
seed. A sample contains up to ten distinct invoices across the scope, not ten per agreement. Keep
the returned `sample_invoice_ids` as the sample's `invoice_ids` on subsequent requests to freeze it.
`POST /v1/check-selections/invoices` pages through candidate invoices; its search only
filters the displayed rows, not the execution scope.

The preview includes exclusions, replacement impact and a fingerprint. Submit the same selection
and fingerprint to `POST /v1/check-selections`, preferably with a fresh `Idempotency-Key`
so a timeout can be retried safely. Without one, the server generates a receipt key returned in `Location`.
Reuse that key only when retrying the same request. A changed selection returns `409`; preview and
confirm again. Selections are limited to 5,000 checks and 50 agreement runs. The response's `workflow_run_ids`
can be followed through the [workflow runs API](/api-reference/workflow-runs).

The app opens Run with the page's active-agreement filters. Once the request succeeds, the sheet
closes and progress is available in Background work. Failed requests stay open for correction or safe retry.
Reset remains a separate agreement-menu action: it invalidates eligible alerts and clears check
state without starting a new check. Claimed pairs remain protected.

## When an invoice can't be checked

A check only runs when both sides are ready:

* **The invoice** has been imported, has its original document, and isn't a credit note or
  credited by one.
* **The agreement** is active, has a title, a supplier and usable terms, and its documents have
  finished processing. Each agreement's `readiness` tells you what is missing.
* **No claim holds the pair.** While alerts from an invoice and agreement are part of an open claim,
  Watchdog doesn't check that pair again, so the claim keeps the alerts it was made from.

If nothing can be checked, you get `409` and nothing starts.

## Check again

A new check replaces the earlier alerts for that invoice and agreement, including alerts you
[created yourself](/api-reference/alerts#record-your-own-alert). Alerts you dismissed come back if the
check finds the same problem again. Only an alert accepted in a claim that is not cancelled is kept,
and the check then skips that invoice.

When an agreement or invoice changes after it was checked, the check is marked `outdated`. To check
again, check the invoice, or recheck a whole topic with `POST /v1/agreements/{id}/check` with `topic_id` and `include_checked: true`.

## Read the results

Most integrations only need the alerts. If you want the checks themselves,
`GET /v1/compliance-checks` lists them with filters for invoice and agreement, and
`GET /v1/compliance-checks/{id}/findings` returns what a check found. A check never changes after it
is done, so it shows exactly what Watchdog saw at the time.

Prices in another currency are converted to the invoice currency, using the invoice's own exchange
rate or otherwise the Norges Bank rate for the invoice date.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.