CreditAI has an integrated OCR (Optical Character Recognition) and intelligent document parsing system that allows analysts to upload PDF or image documents and automatically extract structured data to fill manual entry forms.
-
DocumentsController (
/api/documents)- REST endpoints for document upload and processing
- File format and size validation
-
TesseractOcrService (
IDocumentOcrService)- Text extraction from PDFs and images using Tesseract OCR
- Support for multiple formats: PDF, PNG, JPG, JPEG, TIFF, BMP
- Image preprocessing for better accuracy
-
LlmDocumentParsingService (
IDocumentParsingService)- Intelligent parsing via OpenAI-compatible LLM (
INarrativeLlmClient→POST /v1/chat/completions) - Structured field extraction based on
ManualDataEntryPolicydefinitions - On-premise LLM host or ContextMemory gateway
- Intelligent parsing via OpenAI-compatible LLM (
Document Upload (PDF/Image)
↓
[TesseractOcrService]
- Text extraction (OCR)
- Image preprocessing
↓
Raw text
↓
[LlmDocumentParsingService]
- Local LLM analyzes text
- Identifies relevant fields
- Extracts structured values
↓
Structured Fields (JSON)
↓
Integration with manual entry
Path: /requests/{requestId}/upload-document
Features:
-
Data source selection
- BDP CRC (Central Credit Register)
- Citius (Portugal judicial data)
- World-Check (AML sanctions)
- Moody's EDF (Default risk)
- ESG Ratings (Environmental/social ratings)
-
Document upload
- Supported formats: PDF, JPG, PNG, TIFF
- Maximum size: 10MB
- Real-time progress (OCR → Parsing → Review)
-
Extracted data review
- Extracted text visualization (OCR)
- AI-extracted field editing
- Mandatory justification
- Submission to manual entry
-
Manual Data Entry Integration
- Direct access button on manual data page
- Link in main navigation menu
- Via Menu: Operations → Upload documents
- Via Manual Data: "Upload document (OCR + AI)" button on manual entry page
Processes a complete document (OCR + Parsing).
Request:
requestId: Credit request GUIDfile: File (PDF or image)sourceKey: Data source (e.g., "CRC", "Citius", "WorldCheck")segment: Applicant segment (e.g., "Sme", "Corporate", "Consumer")
Response:
{
"success": true,
"sourceKey": "Citius",
"extractedText": "Portal CITIUS - Process Query...",
"extractedFields": {
"insolvency_proceedings_count": "0",
"active_enforcement_count": "1",
"total_debt_amount_eur": "15000",
"has_criminal_records": "false"
},
"errorMessage": null,
"ocrConfidence": 0.95,
"parsingConfidence": 1.0
}Example cURL:
curl -X POST "https://api.creditai.pt/api/documents/12345678-1234-1234-1234-123456789012/process" \
-H "Authorization: Bearer <token>" \
-F "file=@citius_consulta.pdf" \
-F "sourceKey=Citius" \
-F "segment=Sme"Extracts only text from document (OCR without parsing).
Request:
file: File (PDF or image)
Response:
{
"success": true,
"extractedText": "Central Credit Register\nDate: 04/06/2026...",
"errorMessage": null,
"confidence": 0.92
}| Format | Extension | Notes |
|---|---|---|
.pdf |
Recommended for official documents | |
| PNG | .png |
Good quality for screenshots |
| JPEG | .jpg, .jpeg |
Compressed, may reduce OCR accuracy |
| TIFF | .tiff, .tif |
High quality, ideal for scans |
| BMP | .bmp |
Uncompressed, large file size |
Limits:
- Maximum size: 10 MB per file
- Recommended resolution: minimum 300 DPI for best OCR
The system can extract fields from any source configured in ManualDataEntryPolicy:
has_active_incidents: Active incidentsactive_contracts: Active contracts
insolvency_proceedings_count: Insolvency proceedingsactive_enforcement_count: Active enforcementstotal_debt_amount_eur: Total debt amounthas_criminal_records: Criminal records
sanctions_hit: Sanctions list matchpep_flag: Politically exposed person
monthly_net_income: Monthly net incomeincome_stability_index: Stability indexavg_balance_90d: 90-day average balance
turnover_meur: Turnoverebitda_margin: EBITDA marginnet_worth_ratio: Net worth ratiocurrent_ratio: Current ratio
probability_of_default: EDFlgd_estimate: Estimated LGD
esg_risk_score: ESG risk scoreclimate_risk_score: Climate risk
Tesseract requires language data files (tessdata).
Windows Installation:
# Via Chocolatey
choco install tesseract
# Or manual download from: https://github.com/UB-Mannheim/tesseract/wikiLinux Installation:
sudo apt-get install tesseract-ocr
sudo apt-get install tesseract-ocr-por # PortugueseDocker:
FROM mcr.microsoft.com/dotnet/aspnet:9.0
RUN apt-get update && apt-get install -y \
tesseract-ocr \
tesseract-ocr-por \
&& rm -rf /var/lib/apt/lists/*Tesseract data path:
By default, the service searches in tessdata/. To change:
// DependencyInjection.cs
services.AddScoped<IDocumentOcrService>(_ => new TesseractOcrService("/usr/share/tesseract-ocr/5/tessdata"));Parsing uses the same Llm:* / ContextMemory client as narrative AI:
{
"Llm": {
"Enabled": true,
"BaseUrl": "http://localhost:8000",
"Model": "qwen3.5:9b",
"Temperature": 0.1
}
}Extracted data can be submitted directly to the manual entry system:
# 1. Upload and process document
curl -X POST "/api/documents/{requestId}/process" \
-F "file=@document.pdf" \
-F "sourceKey=Citius" \
-F "segment=Sme"
# 2. Review extracted fields (UI/analyst)
# 3. Submit to system
curl -X POST "/api/manual-data/{requestId}/submit" \
-H "Content-Type: application/json" \
-d '{
"sourceKey": "Citius",
"enteredBy": "analyst@example.pt",
"justification": "Automatically extracted via OCR - manual review completed",
"values": {
"insolvency_proceedings_count": "0",
"active_enforcement_count": "1",
"total_debt_amount_eur": "15000"
}
}'- Minimum resolution: 300 DPI for scanned documents
- Contrast: Dark text on light background
- Orientation: Documents in correct position (not rotated)
- Format: Prefer native PDF over scanned PDFs
- Always review: Extracted data should be reviewed by analyst
- Low confidence: If
ocrConfidence < 0.7orparsingConfidence < 0.5, review carefully - Critical fields: Regulatory incidents and monetary values must always be manually validated
- Size: Documents < 5 MB process faster
- Pages: PDFs with < 10 pages are ideal
- Concurrency: Recommended concurrent upload limit: 5
All document processing is audited:
-
Captured metadata:
- Original file (name, size, hash)
- Upload timestamp
- Responsible analyst
- OCR and parsing confidence
-
Traceability:
- Extracted text is stored
- LLM-identified fields are logged
- Mandatory manual entry justification
-
Compliance:
- On-premise OCR + OpenAI-compatible LLM (Tesseract +
Llm:*/ CM) - No data sent to cloud
- GDPR and banking regulation compliance
- On-premise OCR + OpenAI-compatible LLM (Tesseract +
-
OCR:
- Accuracy depends on document quality
- Handwritten documents have low success rate
- Complex tables may not be extracted correctly
-
Parsing:
- Local LLM may not recognize very specific formats
- Non-Portuguese documents may have lower accuracy
- Very long documents (>10 pages) may exceed LLM context
-
Unsupported formats:
- Word/Excel (convert to PDF first)
- Images with heavy watermarks
- Encrypted/protected documents
Solution: Install Tesseract and ensure tessdata/ is accessible.
Possible causes:
- Encrypted PDF
- Low quality image
- Blank document
Solution: Check document quality, try converting to high-resolution PNG.
Possible causes:
- Unknown document format
- Fields missing in document
- LLM did not recognize patterns
Solution: Review extracted text, adjust LLM prompt if necessary, direct manual entry.
- Azure Document Intelligence support (advanced OCR)
- Structured table extraction
- Signature and stamp recognition
- Automatic document type classification
- Multi-language support (ES, EN, FR)
- Blazor drag-and-drop upload interface with preview