Skip to main content
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. 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

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. 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. 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. 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.