EnvoyX Docs

Bank Statements — Docs Intelligence

Docs Intelligence — Bank Statement Analysis

Upload bank statements to get a comprehensive Financial Health Profile and Fraud Risk Profile. The system produces scored, reasoned, and explained assessments calibrated specifically for African financial markets.

Two Profiles, One Call: Every analysis produces both a Financial Health Profile (creditworthiness) and a Fraud Risk Profile (fraud detection), each with LLM-generated narratives that explain what the patterns mean and what to do about them.

What You Get

Financial Health Profile

  • 4 Dimension Scores (0-100): Revenue, Cash Flow, Expense and Liability, Balance Behaviour — each rated Strong / Adequate / Weak / Insufficient
  • 6 African Market Signals: Tontine Intelligence, Mobile Money Shadow Balance, Bancarization Quality, Calendar-Adjusted Stress, Social Capital, Diaspora Income
  • Credit Readiness Score (0-100) with credit limit band
  • LLM Narrative (3-5 paragraphs) explaining the financial picture
  • Recommendations: Additional documents, conditions, monitoring

Fraud Risk Profile

  • Fraud Score (0-100) with verdict: Proceed / Proceed with conditions / Refer / Decline
  • Individual flags with dimension, pattern, confidence, cross-dimensional corroboration
  • Named anomaly clusters: Pre-Application Staging, Circular Flow, Ghost Business, Debt-Driven Distress, Dangerous Payer Concentration
  • LLM Fraud Narrative explaining each significant signal

API Endpoints

MethodEndpointDescription
POST/api/v1/bank-statements/uploadUpload and analyze
GET/api/v1/bank-statementsList with pagination
GET/api/v1/bank-statements/{id}Full analysis detail
GET/api/v1/bank-statements/{id}/reportDownload PDF report
DELETE/api/v1/bank-statements/{id}Delete statement and report
GET/api/v1/bank-statements/preferencesGet analysis defaults
PUT/api/v1/bank-statements/preferencesUpdate analysis defaults

Upload and Analyze

POST https://api.tryenvoyx.com/api/v1/bank-statements/upload

Request Fields

FieldTypeRequiredDescription
fileFileYesPDF, JPEG, or PNG (max 20MB)
business_typestringNoe.g. healthcare_provider, retail, agriculture
sectorstringNoe.g. healthcare, commerce, services
account_holder_namestringNoExpected name for comparison matching

Parameter Priority: request param, then saved preference, then system default. Set defaults via the Preferences API.

Streaming

Add X-Stream-Response: true header for real-time Server-Sent Events through all 14 processing steps.

Code Examples

curl -X POST https://api.tryenvoyx.com/api/v1/bank-statements/upload \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@bank_statement.pdf" \
  -F "business_type=healthcare_provider" \
  -F "sector=healthcare"
const formData = new FormData()
formData.append('file', fs.createReadStream('bank_statement.pdf'))
formData.append('business_type', 'healthcare_provider')

const response = await fetch('https://api.tryenvoyx.com/api/v1/bank-statements/upload', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY' },
  body: formData,
})

const { data } = await response.json()
console.log('Credit Readiness:', data.bank_statement.fh_credit_readiness_score)
console.log('Fraud Verdict:', data.bank_statement.fraud_risk_verdict)
import requests

with open('bank_statement.pdf', 'rb') as f:
    response = requests.post(
        'https://api.tryenvoyx.com/api/v1/bank-statements/upload',
        headers={'X-API-Key': 'YOUR_API_KEY'},
        files={'file': f},
        data={'business_type': 'healthcare_provider'},
    )

stmt = response.json()['data']['bank_statement']
print(f"Credit Readiness: {stmt['fh_credit_readiness_score']}/100")
print(f"Fraud Verdict: {stmt['fraud_risk_verdict']}")

The Four Dimensions (0-100 each)

Each dimension is scored 0-100 and rated:

ScoreRating
80-100Strong
60-79Adequate
40-59Weak
0-39Insufficient

Revenue Analysis

Classifies every inflow by source: institutional payments, mobile money sweeps, cash deposits, tontine receipts, related-party transfers, diaspora transfers. Evaluates consistency against what this business type actually earns and on what cycle.

Cash Flow Health

Measures how the business manages gaps between major inflows. In markets where institutional payers clear every 60-90 days, the inter-cycle floor is the real stress test. Identifies mobile money and tontine liquidity bridges.

Expense and Liability Patterns

Identifies what a real operating business should be spending on and whether those expenses are present. Separates tontine from debt service, personal from operational. Assesses total visible debt load including mobile credit apps.

Balance Behaviour

Analyses balance patterns for timing manipulation (pre-application conditioning), survival behaviour between inflows, and trend over the full period.


African Market Signals

Six proprietary signals calibrated for how money actually moves in West Africa:

SignalOutputWhat It Measures
Tontine Intelligence0-100 score + ratingTontine participation consistency as credit character evidence
Mobile Money Shadow BalanceRange estimate (e.g. 400K-900K XOF)Inferred off-statement wealth from sweep patterns
Bancarization Quality Index0-100 score + confidenceWhat proportion of real financial activity the statement captures
Calendar-Adjusted StressRaw + adjusted scores + deltaNormalizes stress against WAEMU calendar (Ramadan, Tabaski, harvest)
Social Capital SignalPresent / Weak / AbsentSocial consequences for default from reciprocal networks
Diaspora Income SharePercentage + stability ratingConcentration risk from cross-border family inflows

Credit Readiness Score

The composite score (0-100) is a weighted combination:

DimensionWeight
Revenue30%
Cash Flow25%
Expense and Liability25%
Balance Behaviour20%

Adjusted by: African market signal bonus/penalty (up to 5 points), legitimacy gate (cap at 20 if document not legitimate).

The score maps to a credit limit band calibrated to the currency (e.g. "500K-2M XOF").


Fraud Risk Score and Verdict

Score RangeVerdict
0-25Proceed — no material fraud signals
26-50Proceed with conditions — signals detected but likely explainable
51-75Refer — significant signals warrant human investigation
76-100Decline — high-confidence cross-dimensional fraud pattern

Named Anomaly Clusters

When flags from multiple dimensions point to the same pattern, they are grouped into named clusters:

  • Pre-Application Staging — fabricated activity near application date
  • Circular Flow / Manufactured Inflow — coordinated deposit rings
  • Ghost Business — missing expected operating expenses
  • Debt-Driven Distress — loan stacking across multiple lenders
  • Dangerous Payer Concentration — over-reliance on single income source

Processing Pipeline (14 Steps)

StepDescription
1Starting analysis
2Downloading from storage
3Validating document format
4Running AI analysis (longest step)
5Evaluating revenue patterns
6Assessing cash flow health
7Evaluating expense and liability
8Analyzing balance behaviour
9Computing African market signals
10Generating financial health profile
11Running fraud detection
12Computing fraud risk score
13Generating reasoning narratives
14Finalizing (PDF generation, name comparison, duplicate check)

PDF Report

Every analyzed statement generates a PDF report accessible via:

GET https://api.tryenvoyx.com/api/v1/bank-statements/{id}/report

Returns a presigned URL for the PDF. The report includes both profiles, all scores, narratives, flags, anomaly clusters, and recommendations — formatted for credit committee review.


Webhook Events

EventDescription
bank_statement.uploadedStatement uploaded (async mode)
bank_statement.processingAnalysis in progress (14 steps)
bank_statement.analyzedAnalysis complete, no critical issues
bank_statement.flaggedAnalysis complete, fraud flags detected
bank_statement.failedAnalysis error

See Webhooks for setup and WebSockets for real-time streaming.


Preferences API

Set defaults so you do not pass business_type and sector with every upload.

curl -X PUT https://api.tryenvoyx.com/api/v1/bank-statements/preferences \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"default_business_type": "healthcare_provider", "default_sector": "healthcare"}'
await fetch('https://api.tryenvoyx.com/api/v1/bank-statements/preferences', {
  method: 'PUT',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ default_business_type: 'healthcare_provider', default_sector: 'healthcare' }),
})

Tip: For production, use webhooks instead of polling. Subscribe to bank_statement.analyzed and bank_statement.flagged to receive results when ready.

On this page