Skip to main content

Anomaly Detection

Anomaly detection surfaces cross-document data quality issues at the case level. Five structural detectors compare values across the documents in a case to find contradictions, divergences, and missing patterns that no single-document check can catch, for example an invoice and a purchase order that share the same po_number but name different suppliers. Anomalies are computed from the case's field occurrences with deterministic rules: no LLM is involved in the detectors.

The five detectors

Anomaly detectors

ParameterTypeDescription
Validation ClusterD1Multiple validation failures concentrated in the same document.
Field ConflictD2An identifier-style field has too many different values across documents in a case.
Duplicate Key DivergenceD3Documents share a key value but differ on fields that should match.
Missing Document TypeD4A case template expects a document type that is absent from this case.
Value ReuseD5Identical values appear across unrelated fields, suggesting copy-paste or extraction errors.
  • D1 — Validation Cluster (validation_cluster, warning): more than 30% of a document's evidence entries fail validation, counted only when the document has at least 3 entries
  • D2 — Field Conflict (field_conflict, warning): a field whose name ends in _number, _id, _name, or _code has more distinct values than the larger of 2 and the square root of the case's document count
  • D3 — Duplicate Key Divergence (duplicate_key_divergence): two or more documents share a value in a field ending in _number, _id, or _code, yet disagree on another field; critical when that field ends in _name or _id, warning otherwise
  • D4 — Missing Document Type (missing_document_type): the matched case template expects a type the case lacks; warning for a required type, info for an optional one
  • D5 — Value Reuse (value_reuse_suspicious, info): a value longer than 5 characters appears in fields from 3 or more unrelated field groups; pure numbers and placeholders such as n/a, none, yes, or no are ignored

The thresholds explain some behaviour that can look surprising at first. D2 tolerates some variation by design, so a two-document case needs at least three distinct values on the same identifier field before it is flagged; a plain two-way disagreement between related documents is what D3 is for. D2, D3, and D5 only consider values that passed evidence validation, so noise that validation already rejected does not produce a second alert, while D1 is exactly the signal that a document has a lot of that noise. D4 only fires when the case matches a template, so a workspace without templates never sees it.

Triage workflow

Anomalies appear in the Anomalies tab of the case detail page (Advanced mode). Each anomaly card shows severity, the affected documents, and a dismiss button, and the list is ordered critical first, then warning, then info. Dismissed anomalies are hidden by default but visible via the show dismissed toggle, and a dismissal can be undone. Dismissing requires the Member role (Contract Management) or above. A typical workflow starts on the cases list page, where anomaly count badges show which cases need attention: click into a case, switch to the Anomalies tab, and use the severity filter pills to focus on critical issues first.

When detection runs again for a case, open anomalies are replaced with the new results while dismissed ones are kept, so a dismissal is not lost when membership changes. Each detector operates independently, so a single case can trigger multiple anomaly types simultaneously, and the badge counts only anomalies that are not dismissed. Configure case templates so the D4 detector can flag incomplete cases.

Reading anomalies through the API

The public endpoint GET /v1/cases/{key}/anomalies computes anomalies on read from the case's current members and persists nothing, so it always reflects the live document set. It runs the field conflict, duplicate key divergence, missing document type, and value reuse detectors; the validation cluster detector is left out on this route because it measures per-document extraction noise rather than whether the case itself is consistent. For cases with more than 120 member documents the detectors are skipped and only the findings are returned, which keeps the call fast on very large cases. Anomalies that cite a document hidden from the caller by access rules are dropped whole, never partially redacted.

List anomalies for a specific case
curl -s https://api.talonic.com/v1/cases/CASE_UUID/anomalies \
  -H "Authorization: Bearer $TALONIC_API_KEY"

# Response:
# {
#   "data": [
#     {
#       "type": "duplicate_key_divergence",
#       "severity": "critical",
#       "title": "Divergent supplier_name for shared key",
#       "description": "Documents sharing the same key have different values for supplier_name: acme corp vs acme logistics ltd",
#       "document_ids": ["…", "…"],
#       "targets": [
#         { "document_id": "…", "field": "supplier_name", "value": "ACME Corp" },
#         { "document_id": "…", "field": "supplier_name", "value": "Acme Logistics Ltd" }
#       ]
#     },
#     {
#       "type": "missing_document_type",
#       "severity": "warning",
#       "title": "Missing required: Contract",
#       "description": "Workflow template \"Invoice + PO + Contract\" expects a Contract document, but none was found in this case.",
#       "document_ids": [],
#       "targets": []
#     }
#   ],
#   "findings": [ ... ],   # open dangling-reference findings
#   "template": { "name": "Invoice + PO + Contract",
#                 "required_types": ["Invoice", "Purchase Order", "Contract"],
#                 "optional_types": [] }
# }
# severity is one of: critical, warning, info
Triage: only critical anomalies, with their targets
# Requires jq. Print each critical anomaly with the values to inspect:
curl -s https://api.talonic.com/v1/cases/CASE_UUID/anomalies \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  | jq '.data[] | select(.severity == "critical")
        | { title, values: [ .targets[] | "\(.field)=\(.value)" ] }'

# -> { "title": "Divergent supplier_name for shared key",
#      "values": [ "supplier_name=ACME Corp", "supplier_name=Acme Logistics Ltd" ] }

Each anomaly carries targets, the document, field, and value triples behind it (up to 40), so a client can open the document and highlight the offending value. Field conflicts, duplicate key divergences, and value reuse carry targets; a missing document type has none because it describes something absent. findings are a separate list of open dangling references, such as a contract number a document cites that no member carries, and template is the matched template or null.

Anomaly detection is designed for high-throughput triage. Across a large number of cases, the anomaly count badges on the cases list page give you an instant heat map of where problems are concentrated. A case with zero anomalies typically needs only a quick spot-check, while a case with critical duplicate key divergences warrants detailed investigation. This severity-based prioritization lets your team focus review effort where it has the highest impact, rather than reviewing every case with equal depth.

The Anomalies tab requires Advanced mode. In Simple mode, anomalies are still computed but not displayed in the case detail page. Toggle Advanced mode from the sidebar to access the full anomaly workflow, or read the same signals through GET /v1/cases/{key}/anomalies.

Frequently asked questions

What anomalies does Talonic detect?+
Five structural patterns: validation clusters (D1), field conflicts (D2), duplicate key divergence (D3), missing document types (D4), and value reuse (D5). Each is surfaced as a dismissable card on the case detail page. D3 is the only detector that can raise a critical anomaly, when documents sharing a key disagree on a name or ID field.
Do anomalies update automatically when cases change?+
Yes. The public API computes them on read from the case's current members, and in the app re-detection replaces open anomalies while keeping the ones you dismissed. Each detector operates independently, so a single case can trigger multiple anomaly types simultaneously.
Can I dismiss anomalies?+
Yes, with the Member role (Contract Management) or above. Each anomaly card includes a dismiss button; dismissed anomalies are hidden by default, revealed with the show dismissed toggle, and can be restored. Dismissing is an in-app action; the public API is read-only for anomalies.
What is the difference between anomaly detection and validation checks?+
Validation checks operate on individual documents — they flag issues within a single record like date inconsistencies or format mismatches. Anomaly detection operates at the case level — it compares values across multiple documents within a case to find conflicts, divergences, and missing patterns. Both are complementary: validation catches per-document issues while anomaly detection catches cross-document issues.
Does anomaly detection use an LLM?+
No. The five detectors are deterministic structural rules computed from the case's field occurrences. Nothing is sent to a language model, and the public endpoint persists nothing; it recomputes on every read so results always reflect the current document set.
Why does the API return no anomalies for a very large case?+
For cases with more than 120 member documents the public endpoint skips the detectors to keep the call fast and returns only the open findings and template. Splitting an over-connected case into smaller ones brings detection back.