Document-heavy processes are still handled by people reading a PDF and typing its contents into a business system. The work is slow, hard to audit, and error-prone in ways that only surface downstream. Automating the reading is the easy part; the difficulty is producing data a business is willing to act on.
Input arrives as scans, exported PDFs, photographs, and — in some cases — structured files that happen to be delivered as documents. Quality varies per source and per sender. The output has to land in systems of record, where a wrong value is more expensive than a missing one.
OCR and model calls are external, variable in latency, and occasionally fail. Model output is probabilistic and cannot be assumed correct. Documents may contain sensitive data, so storage and access have to be deliberate rather than incidental.
The platform is a pipeline of explicit stages over a persisted job. Each stage reads the job state, does one thing, and writes the next state — so any stage can fail and be resumed without repeating the ones before it.
Document
│
Ingestion idempotent key
│
OCR / Structured source
│
Extraction deterministic → AI
│
Validation rules + confidence
│
Human review approval boundary
│
Approved data
│
Business system / SalesforceThe asynchronous design adds state and operational surface: more to observe, more to reason about, and a client integration that cannot be a single blocking call. Keeping a human in the path bounds throughput deliberately. Both costs were accepted because the alternative is silently wrong data in a system of record.
Review is a state in the pipeline, not a screen bolted onto it. Fields arrive with their source location and a confidence signal, so a reviewer can go straight to what is uncertain instead of re-reading the document. Corrections are stored alongside the original extraction, which makes them useful later as evaluation data.
OCR engines and extraction configurations are compared on a fixed set of documents with known correct values, per field rather than per document, so a change that improves totals but breaks dates is visible. Reviewer corrections feed the same set. The purpose is to make configuration changes decidable by measurement instead of impression.
Consuming systems integrate over an authenticated API and signed webhooks. On the Salesforce side, approved data maps onto records through an integration boundary that owns the translation, so the document platform stays independent of any one target model.
POST /documents → 202 { job_id } idempotency key
GET /documents/{id} → { state, fields, confidence }
webhook document.approved signed · retried · replayableMaking the processing state explicit mattered more than the choice of queue or model. Once every document had a durable state, reliability became a question of moving between states correctly.
Confidence is only useful when it is attached to a field and a location in the document. Aggregate scores tell a reviewer nothing actionable.
The AI part of an AI system was not where most of the design effort went. Ingestion, state, validation, review, and delivery were.