Data warehouse integration
Documents to Snowflake tables, with the evidence attached
Holofin reads your PDFs and scans and streams every field into a Snowflake table, with how sure it is and where on the page the value came from.
| FIELD | VALUE | CONFIDENCE | PAGE | NEEDS_REVIEW | |
|---|---|---|---|---|---|
| 1 | invoice_number | F-2026-0412 | 0.99 | 1 | FALSE |
| 2 | invoice_date | 2026-10-14 | 0.98 | 1 | FALSE |
| 3 | due_date | 2026-11-13 | 0.97 | 1 | FALSE |
| 4 | supplier_name | Atelier Mécanique Durand SARL | 0.99 | 1 | FALSE |
| 5 | total_excl_tax | 4860.00 | 0.98 | 1 | FALSE |
| 6 | vat_amount | 972.00 | 0.71 | 1 | TRUE |
| 7 | total_incl_tax | 5832.00 | 0.97 | 1 | FALSE |
✓7 fields loaded
!1 flagged for review
How it works
- 1
Connect Snowflake once
Create a role with insert rights on one schema and paste its credentials into Holofin. Holofin creates the table on the first load; nothing else in Snowflake is visible to it.
- 2
Send documents the way you already do
Upload in the app, forward by email, or post to the API. Holofin classifies each file, splits bundles into documents and reads the fields of each type.
- 3
Query the rows
Each field lands as one row with its confidence, the page it came from and a needs_review flag. Join it to your own tables in Snowflake like any other source.
How the Snowflake connector writes
Holofin writes with Snowpipe Streaming, so rows arrive in seconds without a stage, a file format or a warehouse running to load them. It authenticates with key-pair authentication as a service user whose role can insert into one schema and nothing else.
The only grant Holofin needs:
CREATE ROLE HOLOFIN_LOADER; GRANT USAGE ON DATABASE HOLOFIN TO ROLE HOLOFIN_LOADER; GRANT USAGE ON SCHEMA HOLOFIN.EXTRACTED TO ROLE HOLOFIN_LOADER; GRANT INSERT, SELECT ON ALL TABLES IN SCHEMA HOLOFIN.EXTRACTED TO ROLE HOLOFIN_LOADER; ALTER USER HOLOFIN_SVC SET RSA_PUBLIC_KEY = 'MIIBIjANBgkqh...';
The table Holofin writes
One row per field, so a new document type never changes the table. The same columns exist in every warehouse; types follow Snowflake's own names.
| document_id | STRING | Holofin's identifier for the document, stable across reloads. |
|---|---|---|
| document_type | STRING | The class Holofin gave the document: supplier_invoice, payslip, bank_statement, and so on. |
| field | STRING | The field name, in snake_case, as defined in your extraction schema. |
| value | STRING | The value as normalized text: ISO dates, dot decimals, IBANs without spaces. |
| confidence | FLOAT | Between 0 and 1. How sure Holofin is of the value. |
| page | INTEGER | The page of the source file the value was read on. |
| bbox | ARRAY<FLOAT> | Where on that page: x, y, width, height, as fractions of the page. |
| needs_review | BOOLEAN | True when the confidence is low or a rule failed, such as a balance that does not add up. |
| reviewed_by | STRING | Who confirmed or corrected the value in Holofin, once someone has. |
| loaded_at | TIMESTAMP | When the row was written. Corrections write a new row; the latest wins. |
Query it in Snowflake
Find the invoices a reviewer still has to look at, with the weakest field of each, using Snowflake's QUALIFY:
-- Invoices with at least one field waiting for a reviewer, -- with the weakest field of each one SELECT document_id, field, value, confidence, loaded_at FROM HOLOFIN.EXTRACTED.DOCUMENT_FIELDS WHERE document_type = 'supplier_invoice' AND needs_review AND reviewed_by IS NULL QUALIFY ROW_NUMBER() OVER ( PARTITION BY document_id ORDER BY confidence ) = 1 ORDER BY loaded_at;
Security
- Documents are processed in Europe, on OVHcloud servers in France certified ISO 27001.
- Holofin only ever writes to the schema you grant. It cannot read your other tables.
- Retention of the source files in Holofin is set per organization, from zero data retention to indefinite. Rows in your warehouse follow your own policies.
- GDPR: Holofin acts as your processor. No document leaves the European Union.
Frequently asked questions
Does loading use my Snowflake credits?
Snowpipe Streaming is billed as serverless ingestion, not by a running virtual warehouse, and a document is only a few rows. For a few thousand documents a month the cost is small. Queries you run afterwards use your warehouses as usual.
Can I use my own database and schema names?
Yes. You choose the database, schema and table name when you connect. The examples on this page use HOLOFIN.EXTRACTED.DOCUMENT_FIELDS.
How quickly do fields appear in Snowflake?
Within seconds of the document being read. Most documents are read in under a minute, so a file sent by email is usually queryable in Snowflake a minute later.
What happens when a reviewer corrects a value?
Holofin writes a new row for that field with the corrected value, needs_review set to false and reviewed_by filled in. Keep the latest row per document and field to get the current state, or keep every row for a full audit trail.
Can I choose which fields are loaded?
Yes. Each document type has an extraction schema in Holofin. Add, rename or remove fields there and the next documents load with the new names. Nothing in the table structure changes.
Which documents does Holofin read?
Any business document sent as a PDF, a scan or a photo: invoices, payslips, bank statements, tax notices, company extracts, IDs, certificates. Holofin also checks each file for tampering and can flag a suspicious document before its fields are trusted.
Put Holofin on your own documents.
Every value linked to the page it came from, every PDF checked for tampering, rules checked across the whole file.