curl --request GET \
--url https://api.watchdog.no/v1/invoices/metrics \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.watchdog.no/v1/invoices/metrics', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.watchdog.no/v1/invoices/metrics"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"alert_scope": {
"type": "invoice",
"agreement_ids": null
},
"total_count": 2,
"financially_invalid_count": 0,
"alert_checked_count": 0,
"alert_checkable_count": 2,
"organization_currency": {
"currency_code": "NOK",
"total_amount_excluding_vat": "2400.00",
"total_amount_including_vat": "3000.00",
"alert_checked_amount": "0",
"alert_checkable_amount": "3000.00"
},
"currencies": [
{
"currency_code": "NOK",
"invoice_count": 1,
"alert_checked_count": 0,
"alert_checkable_count": 1,
"alert_checked_amount": "0",
"alert_checkable_amount": "125.00",
"alert_checked_amount_excluding_vat": "0",
"alert_checkable_amount_excluding_vat": "100.00",
"total_amount_excluding_vat": "100.00",
"total_amount_including_vat": "125.00"
},
{
"currency_code": "EUR",
"invoice_count": 1,
"alert_checked_count": 0,
"alert_checkable_count": 1,
"alert_checked_amount": "0",
"alert_checkable_amount": "250.00",
"alert_checked_amount_excluding_vat": "0",
"alert_checkable_amount_excluding_vat": "200.00",
"total_amount_excluding_vat": "200.00",
"total_amount_including_vat": "250.00"
}
]
}{
"error": {
"code": "validation_error",
"message": "The request is invalid. details lists up to 20 field errors. Request bodies are limited to 2 MiB.",
"request_id": "req_example"
}
}{
"error": {
"code": "invalid_token",
"message": "The bearer token is missing or invalid.",
"request_id": "req_example"
}
}{
"error": {
"code": "forbidden",
"message": "Access denied. The error code says why: forbidden, token_disabled, organization_required, insufficient_role or mfa_required.",
"request_id": "req_example"
}
}{
"error": {
"code": "not_found",
"message": "The resource does not exist in the current organization.",
"request_id": "req_example"
}
}{
"error": {
"code": "conflict",
"message": "One or more selected teams have invalid saved filter rules. Update the team filters before retrying.",
"request_id": "req_example"
}
}{
"error": {
"code": "search_too_broad",
"message": "More than 1,000 invoices match search or invoice_number. Narrow the search or use other filters.",
"request_id": "req_example"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Wait for the Retry-After delay before retrying.",
"request_id": "req_example"
}
}{
"error": {
"code": "internal_error",
"message": "Unexpected server failure. Include the request ID when contacting support.",
"request_id": "req_example"
}
}{
"error": {
"code": "service_unavailable",
"message": "Temporarily unavailable. Retry after the Retry-After delay, when provided.",
"request_id": "req_example"
}
}Total invoice spend
Counts invoices and totals their amounts (spend) per currency and in the organization currency, using the same filters as listInvoices; filter by supplier_ids for one supplier’s spend. Totals are exact decimal strings and plain sums: an invoice without an amount adds nothing, and credit notes reduce spend. Use issued_from and issued_through to report a period. organization_currency converts amounts at each invoice’s date; an invoice without an exchange rate for that date adds nothing there, though the per-currency totals include it. For spend per supplier, recipient or month in one call, use listInvoiceGroups.
curl --request GET \
--url https://api.watchdog.no/v1/invoices/metrics \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.watchdog.no/v1/invoices/metrics', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.watchdog.no/v1/invoices/metrics"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"alert_scope": {
"type": "invoice",
"agreement_ids": null
},
"total_count": 2,
"financially_invalid_count": 0,
"alert_checked_count": 0,
"alert_checkable_count": 2,
"organization_currency": {
"currency_code": "NOK",
"total_amount_excluding_vat": "2400.00",
"total_amount_including_vat": "3000.00",
"alert_checked_amount": "0",
"alert_checkable_amount": "3000.00"
},
"currencies": [
{
"currency_code": "NOK",
"invoice_count": 1,
"alert_checked_count": 0,
"alert_checkable_count": 1,
"alert_checked_amount": "0",
"alert_checkable_amount": "125.00",
"alert_checked_amount_excluding_vat": "0",
"alert_checkable_amount_excluding_vat": "100.00",
"total_amount_excluding_vat": "100.00",
"total_amount_including_vat": "125.00"
},
{
"currency_code": "EUR",
"invoice_count": 1,
"alert_checked_count": 0,
"alert_checkable_count": 1,
"alert_checked_amount": "0",
"alert_checkable_amount": "250.00",
"alert_checked_amount_excluding_vat": "0",
"alert_checkable_amount_excluding_vat": "200.00",
"total_amount_excluding_vat": "200.00",
"total_amount_including_vat": "250.00"
}
]
}{
"error": {
"code": "validation_error",
"message": "The request is invalid. details lists up to 20 field errors. Request bodies are limited to 2 MiB.",
"request_id": "req_example"
}
}{
"error": {
"code": "invalid_token",
"message": "The bearer token is missing or invalid.",
"request_id": "req_example"
}
}{
"error": {
"code": "forbidden",
"message": "Access denied. The error code says why: forbidden, token_disabled, organization_required, insufficient_role or mfa_required.",
"request_id": "req_example"
}
}{
"error": {
"code": "not_found",
"message": "The resource does not exist in the current organization.",
"request_id": "req_example"
}
}{
"error": {
"code": "conflict",
"message": "One or more selected teams have invalid saved filter rules. Update the team filters before retrying.",
"request_id": "req_example"
}
}{
"error": {
"code": "search_too_broad",
"message": "More than 1,000 invoices match search or invoice_number. Narrow the search or use other filters.",
"request_id": "req_example"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Wait for the Retry-After delay before retrying.",
"request_id": "req_example"
}
}{
"error": {
"code": "internal_error",
"message": "Unexpected server failure. Include the request ID when contacting support.",
"request_id": "req_example"
}
}{
"error": {
"code": "service_unavailable",
"message": "Temporarily unavailable. Retry after the Retry-After delay, when provided.",
"request_id": "req_example"
}
}Authorizations
Personal API key sent as a bearer token, together with X-Organization-Id. The key must have at least the access level the endpoint requires (read, write or admin).
Headers
The organization to act in. Required for personal API keys; list the organizations you can access with GET /v1/organizations.
Query Parameters
Return only these fields, comma-separated; use dots for nested fields, such as alert_scope.type. Fields: alert_scope, total_count, financially_invalid_count, alert_checked_count, alert_checkable_count, organization_currency, currencies.
Only records matched by the filters of teams you belong to. Teams combine with OR; other filters combine with AND. Cannot be combined with team_ids.
true, false Only records matched by the filters of these teams: at most 50, comma-separated in a query string or an array in a JSON body. Teams combine with OR. Unknown teams return 404.
Case-insensitive match on invoice number, title, or supplier or recipient name (as printed on the invoice or as currently named). Eight or more digits, spaces ignored, also match a printed organization number. Fewer than three characters match the start of the invoice number.
1 - 200Case-insensitive match on invoice number. Fewer than three characters match its start.
1 - 200Supplier IDs, comma-separated (maximum 50). Use null for invoices without a supplier.
Recipient IDs, comma-separated (maximum 50). Use null for invoices without a recipient.
Categories, comma-separated: invoice, credit_note, self_billed_invoice.
Currency codes, comma-separated (maximum 50). Use null for unknown currency, for example NOK,EUR,null.
and requires every column filter to match; or requires at least one. Search, agreement_ids, deleted and team filters always apply.
and, or How supplier_ids applies: is matches any listed value; is_not excludes all listed values.
is, is_not How recipient_ids applies: is matches any listed value; is_not excludes all listed values.
is, is_not How categories applies: is matches any listed value; is_not excludes all listed values.
is, is_not How currency_codes applies: is matches any listed value; is_not excludes all listed values.
is, is_not How confidence_levels applies: is matches any listed value; is_not excludes all listed values.
is, is_not How check_statuses applies: is matches any listed value; is_not excludes all listed values.
is, is_not How alert_statuses applies: is matches any listed value; is_not excludes all listed values.
is, is_not How display_statuses applies: is matches any listed value; is_not excludes all listed values.
is, is_not Alert status, comma-separated: credited (covered by credit notes), checking (a check is running), has_issues (open alerts), clean (checked, no open alerts), not_checked.
Like alert_statuses, but splits credited into resolved_by_credit_note (alerts were found first) and pre_empted_by_credit_note (no alerts were found). Comma-separated: not_checked, checking, has_issues, clean, resolved_by_credit_note, pre_empted_by_credit_note.
Extraction confidence, comma-separated: high, mid, low or unknown.
Check status, comma-separated: completed (every matched agreement checked), incomplete (some checks missing, failed or outdated), checking, not_checked, or not_checkable (credit notes, invoices with a matched credit note, invoices without a document).
true selects invoices linked to a credit note, and credit notes linked to an invoice; false selects those without.
true, false invoice covers all of the invoice's checks and alerts; selected_agreements covers only the agreements in agreement_ids (required).
invoice, selected_agreements Earliest issue date (YYYY-MM-DD), inclusive.
^\d{4}-\d{2}-\d{2}$Latest issue date (YYYY-MM-DD), inclusive.
^\d{4}-\d{2}-\d{2}$Earliest due date (YYYY-MM-DD), inclusive.
^\d{4}-\d{2}-\d{2}$Latest due date (YYYY-MM-DD), inclusive.
^\d{4}-\d{2}-\d{2}$Whether the amounts add up (see amounts.valid).
true, false Whether a person has confirmed the extracted data.
true, false Whether review is recommended (see review.recommended).
true, false Agreement IDs, comma-separated (maximum 50). Selects invoices matched to any of them.
Whether the invoice is matched to at least one agreement.
true, false Whether the invoice has open (pending or claimed) alerts.
true, false true lists only soft-deleted invoices. Defaults to false.
true, false Response
Invoice counts and totals by currency.
Show child attributes
Show child attributes
Totals converted to the organization currency at each invoice's date, rounded to cents. An invoice without an amount or exchange rate adds nothing.
Show child attributes
Show child attributes
Show child attributes
Show child attributes