Check an invoice
{"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
readinesstells 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.
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 markedoutdated. 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.