Changelog

Updates to the Holofin API, newest first. Entries marked Behaviour change can affect existing integrations.

November 2026 Latest

  • Fraud factors say where their evidence comes fromEach entry of risk_factors and trust_factors now has sources: forensic, template, content or seal. The field is new, so nothing breaks; read it to route a finding to the right reviewer. See Fraud analysis.
  • Bank statement validation codes referenceThe codes now have their own table, grouped by what to do about them. The codes are unchanged. Their description in GET /agents/{id} is shorter, so branch on the code, never on that text.
  • Runs are no longer refused over a daily page volumePOST /workflow-runs/ no longer answers 429 RATE_LIMIT_EXCEEDED once an organization has processed a set number of pages in 24 hours. The code is retired; you can drop its handling. The per-key request rate and the sandbox credit allowance still answer 429. Docs.

October 2026

  • Behaviour change: fraud analysis checks for pages redrawn by AIScans and image uploads can now raise the risk factor ai_page_redrawn (severity high), so a scan that read normal can now read warning. Docs.
  • Bank statements: a misread transaction date now raises a warningA block of transactions out of date order with its neighbours, where swapping day and month or moving the month by one restores the order (10/09 returned as 2026-10-10), now raises the warning TRANSACTION_DATE_OUT_OF_SEQUENCE, or is corrected and carries the informational TRANSACTION_DATE_CORRECTED_FROM_PAGE_IMAGE. A part that was OK can now carry this warning. Docs.
  • Bank statements: an account without a statement now says soA part that names an account but has no balances and no transactions, typically a line of the bank’s account summary, now carries the informational code ACCOUNT_WITHOUT_STATEMENT. Its validation_status stays null. Docs.
  • Fraud analysis can be limited to native PDFs or bank statementsOn request, Holofin can restrict an organization’s fraud analysis to native PDFs, bank statements, or both. A document left out is not billed for fraud and reads "status": "skipped" with a skip_reason; treat it as not analysed, not as clean. Docs.
  • Bank statements: why the opening balance is missingA current-account part with no opening balance now also carries the informational code STATEMENT_LIKELY_MISSING_PAGE: the first page is probably missing. validation_status is unchanged. Branch on it to ask for the missing page. Docs.

September 2026

  • Bank statements: a closing balance its next statement contradictsWhen a closing balance is the exact negative of the next statement’s opening balance on the same account, both parts now raise the warning CLOSING_BALANCE_CONTRADICTED_BY_SIBLING: one read lost a sign. A part that was OK can now carry this warning. Docs.
  • Bank statements: more misread IBANs correctedMore IBANs failing their MOD-97 check are now corrected. Such parts carry the informational code ACCOUNT_NUMBER_CORRECTED_FROM_SEGMENTER instead of INVALID_IBAN_CHECKSUM; treat it like ACCOUNT_NUMBER_CORRECTED_FROM_SIBLING. Docs.
  • Arithmetic checks: tolerance per formulaTotals checks on built-in extractors now allow 1 € per non-zero amount in the formula (10 € minimum) instead of a flat 10 €, so long totals rounded line by line now pass. Each check returns the tolerance it applied.
  • Cases APIRun a dossier end to end without the Holofin UI. New endpoints: POST /cases, GET /cases/{case_id}, GET /cases/{case_id}/activities and GET /case-configs. To attach a document, pass case_id and party_refs when creating the workflow run. Dossier webhooks send the same body as GET /cases/{case_id}. Docs.
  • HoloLang: arrays and quantifiersRules can now work on arrays: per-element aggregates, ALL(), ANY(), IN, indexed paths and ARRAY_* functions, and @document passes the whole payload to a rule. Note that ALL() on an empty array is false. Docs.
  • Health endpointGET /api/v1.1/health reports whether Holofin is accepting and processing work, overall and for api, document_intake, processing and webhooks. It needs no API key. It returns 503 only during an outage; degraded returns 200. Docs.
  • Volumes and throughput in one callGET /api/v1.1/metrics returns both blocks for a window; add include=volumes or include=throughput for one. /metrics/volumes and /metrics/throughput are unchanged. Docs.

August 2026

  • Behaviour change: timestamps normalizedEvery API timestamp now ends in Z. Workflow-run timestamps previously carried an invalid +00:00Z suffix.
  • Behaviour change: 2D-Doc address enrichment movedThe address resolved from a 2D-Doc seal is now under enrichments.<seal field>.<group> (status, normalized, ban_id, granularity). enrichments.ddoc_<group> is no longer written: if you read it, switch to the new path. Stored rules were migrated automatically. Docs.
  • 2D-Doc schema fieldType a schema property "x-holofin-type": "2ddoc" to capture only 2D-Doc seals instead of every barcode on the page. Records and seal verification are the same as for barcode fields, which are unchanged. One per schema, at root level, with JSON type "array". Docs.
  • Identity documents: in-house verification optionIdentity-document agents can use an in-house read of the document instead of the external provider. It is opt-in per agent and returns the same checks[] with type: "id_verification".
  • Identity documents: recapture and specimen detectionTwo new warnings in checks[] (type: "id_verification"): ID_SPECIMEN_MATCH when the document matches a published specimen card, and ID_RECAPTURE_SUSPECTED when the image metadata points to a photo of a screen. Neither raises ERROR.
  • Behaviour change: in-house identity document checksAn identity document now reports validation_status: "ERROR" instead of OK when its printed zone disagrees with the MRZ, or when the CEV seal on a 2021 French CNI fails signature verification or its sealed MRZ differs from the document. Holofin also checks that issue and expiry dates are coherent. Results appear in checks[] with type: "id_verification". New validation_codes: ID_CROSS_*_MISMATCH, ID_CROSS_CHECKS_VALID, ID_CROSS_NOT_CHECKED, ID_CEV_SIGNATURE_VALID, ID_CEV_SIGNATURE_INVALID, ID_CEV_MRZ_MISMATCH, ID_CEV_MISSING, ID_CEV_UNRESOLVED, ID_CEV_NOT_CHECKED, ID_DATES_INCOHERENT, ID_VALIDITY_WINDOW_UNUSUAL.
  • Runs with no matching routeA run that completes without extraction because no workflow route matched the detected document type now says so: no_route_matched is true and unmatched_classifications lists the detected types. Both fields are on GET /workflow-runs/{run_id} and the workflow-run.completed webhook. Before, such a run looked like any other completed run. Docs.
  • Company registry check on siren fieldsProperties typed siren in the Schema Builder are looked up in the French company registry before validation rules run (a printed SIRET is accepted). New business codes: SIREN_RESOLVED, SIREN_NOT_FOUND, SIREN_ENRICHMENT_UNAVAILABLE. Code registry.
  • Behaviour change:siren failures raise ERRORA part carrying a siren field can now report validation_status: "ERROR" when the registry does not recognise the number, or when the lookup could not run. Schemas without a siren field are unaffected.
  • PDF downloadsGET /workflow-runs/{run_id}/pdf returns the uploaded document; GET /workflow-runs/{run_id}/parts/{part_key}/pdf returns one part's pages merged. Both redirect (302) to a signed URL valid ~10 minutes, or return url and expires_at with ?format=json. Run details and webhooks also carry document_pdf_url and a per-part pdf_url.
  • New checks_summary objectOne rolled-up verdict per rule category (extraction, business, id_verification): OK, WARNING, ERROR, or null when the category ran no checks. validation_status stays the combined verdict to gate on.
  • Full rule inventory in checksEach part's checks now lists every rule that ran (passed, failed and skipped) with type, code, label, status, severity and a failure message. Codes join directly to validation_codes, which is unchanged. Opt-in details add formula, values, expected, actual and tolerance.
  • Identity document typeIdentity-document parts carry a flat document_type in data (the verification provider's classification, for example "Passport"). Omitted when verification did not run or could not classify; a document_type you define yourself wins.
  • Behaviour change: declined identity checks raise ERRORIdentity verification results carry real severities under type: id_verification. A Declined document now reports validation_status: "ERROR" instead of OK. The same ID_* tokens appear in validation_codes.

July 2026

  • Rule categories in checksEvery checks entry declares a type: extraction rules judge whether the document was read correctly (formats, arithmetic, checksums), business rules whether it is acceptable under your policy (freshness, name matching). validation_status and validation_codes keep their meaning, so no integration needs to change.
  • TIFF upload supportdocument_b64 and document_pages_b64 accept TIFF alongside PNG and JPG. Each frame of a multi-page TIFF becomes one document page.
  • New <CHECK_ID>_NOT_PERFORMED codesFinancial statement rules whose source data is absent no longer fail validation. The segment stays OK and traces the skip in validation_codes. Code registry.
  • OCR confidence scores (opt-in)Per-field ocr_confidence (min, mean, engine) on document properties and transactions. Off by default, contact us to enable. Details.

June 2026

  • PNG / JPG upload supportdocument_b64 accepts a PNG or JPG image in addition to PDF. Images are converted to PDF server-side.
  • New document_pages_b64 fieldSend several images as an array to combine them into the pages of one document, in order. Provide either document_b64 or document_pages_b64, not both.

May 2026

  • New validation_codes fieldEach document_parts entry carries stable upper-snake tokens describing decisions taken during validation, whether they fired an error, a warning or a neutral note. Additive and always present, possibly empty. Code registry.
  • Opening-balance waiversSavings and securities statements (compte titres, PEA, CTO) with no opening balance are accepted as OK and traced with SAVING_ACCOUNT_WO_START_BALANCE_IS_EXPECTED or SECURITIES_ACCOUNT_WO_START_BALANCE_IS_EXPECTED.

April 2026

  • New bank account fieldsBank statements expose advisor_name (conseiller) and branch_name (agence). Both nullable, defaulting to null.

February 2026

Fraud Analysis

A new Fraud Analyzer workflow node checks each document for tampering, metadata anomalies and edits. It returns risk factors and trust factors in the workflow run response and in webhooks.

Read the documentation
  • MCP ServerThe holofin-mcp package lets AI coding assistants (Claude Code, Cursor, Windsurf) query workflow runs, extraction results and fraud analysis over the Model Context Protocol.
  • Fraud Analysis APINew documentation page covering the fraud analysis schema, risk levels, risk factors and trust factors. GET /workflow-runs/{run_id} returns a root-level fraud_analysis_result, and node-run.completed events for fraudAnalyzer nodes carry risk level, score, signal count and triggered categories.
  • Per-key IP allowlistingRestrict an API key to specific IPv4/IPv6 addresses or CIDR ranges. Requests from unlisted IPs are rejected with 403.
  • API key expirationSet an expiry when creating a key (presets or a custom date). Expired keys return 403.

January 2026

The Workflows API: custom document pipelines combining classification, segmentation and extraction, built in a visual editor.

New Endpoints

Removed

  • Behaviour change: extraction endpoints retiredPOST /extract, GET /jobs/{job_id}, GET /documents and GET /documents/{document_id} are gone from v1 and v1.1. Send documents with POST /workflow-runs/ and read results with GET /workflow-runs/{run_id}. Docs.

Version 1.1 November 12, 2025

  • List DocumentsNew GET /api/v1.1/documents endpoint, paginated, returning a document_parts array so sub-documents are directly accessible. Removed in January 2026.
  • Flat document partsEach part carries part_type directly (for example "CERFA-2033-A"), replacing the previous wrapper pattern. Support added for many CERFA forms across simplified and normal tax regimes.
  • Field renamescoherence_check_status becomes validation_status (OK / WARNING / ERROR). Document-level review fields become review_status, reviewed_by_user, reviewed_at, rejected_by_user, rejected_at, with values REVIEWED / NOT_REVIEWED / REJECTED.

Version 1.0.1 September 26, 2025

  • Financial statements (FR)French financial statement extraction, including CERFA 2033-A. Responses and webhooks carry activity logs for a full audit trail of document changes.
  • Usage statsTrack API usage and extraction consumption.

Version 1.0.0 January 10, 2025Initial Release

First release: core document extraction with webhook support.

  • POST
    Extract DocumentUpload a document for extraction. Removed in January 2026.
  • GET
    Check Job StatusMonitor extraction progress. Removed in January 2026.
  • GET
    Get ResultsRetrieve extracted, structured data. Removed in January 2026.
  • EVENT
    Webhook notificationsReal-time updates when processing completes.