Technical reference for integrating Trutina’s document analysis API into your loan origination system. One endpoint, base64 documents in, risk score out.
Trutina exposes a single webhook endpoint for document analysis. Submit one or more base64-encoded documents and receive a comprehensive risk assessment with individual flags, severity scores, and a recommended action.
/api/v1/webhooks/ingestAuthentication
X-Api-Key header
Content Type
application/json
Response Time
~60 seconds (full analysis)
All API requests must include your API key in the X-Api-Key header. API keys are issued when you sign up for a plan and can be rotated from your dashboard.
X-Api-Key: your-api-key-here
Content-Type: application/jsonSubmit an applicant’s details along with one or more base64-encoded documents. Each document must specify a type, filename, and content_base64.
{
"applicant_name": "John Smith",
"loan_amount": 750000,
"broker_abn": "12345678901",
"documents": [
{
"type": "payslip",
"filename": "payslip_jan2026.pdf",
"content_base64": "JVBERi0xLjQK..."
},
{
"type": "bank_statement",
"filename": "statement_dec2025.pdf",
"content_base64": "JVBERi0xLjQK..."
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
| applicant_name | string | Yes | Full name of the applicant |
| loan_amount | number | Yes | Loan amount in AUD (no decimals) |
| broker_abn | string | No | 11-digit ABN for broker risk profiling |
| documents | array | Yes | One or more documents to analyse |
| documents[].type | string | Yes | One of the supported document types |
| documents[].filename | string | Yes | Original filename (for logging) |
| documents[].content_base64 | string | Yes | Base64-encoded document content (max 20MB) |
A successful response includes a risk score (0-100), risk level, recommended action, and an array of individual flags with evidence.
{
"case_id": "uuid",
"reference": "TT-2026-00042",
"risk_score": 82,
"risk_level": "critical",
"recommended_action": "reject",
"flags": [
{
"category": "ai_content",
"code": "AI_GENERATED_HIGH",
"title": "High-confidence AI-generated content",
"description": "Document exhibits statistical patterns consistent with large language model output, including uniform sentence structure and atypical font embedding.",
"severity": "critical",
"weight": 9
}
],
"summary": "High-confidence AI-generated document detected. PDF metadata indicates creation via an online generator with no print history. Employer ABN does not match ASIC records."
}clear
0-20
low
21-40
medium
41-60
high
61-80
Critical
81-100 — reject or escalate immediately
| Action | Meaning |
|---|---|
| approve | No flags detected, proceed normally |
| review | Minor flags, manual review recommended |
| escalate | Significant flags, escalate to fraud team |
| reject | High-confidence fraud indicators detected |
Complete working examples for submitting a document and reading the result. Replace the API URL and key with your instance details.
import requests, base64, json
API_URL = "https://your-instance.trutina.com.au/api/v1/webhooks/ingest"
API_KEY = "your-api-key"
with open("payslip.pdf", "rb") as f:
doc_b64 = base64.b64encode(f.read()).decode()
response = requests.post(API_URL, json={
"applicant_name": "John Smith",
"loan_amount": 750000,
"documents": [{
"type": "payslip",
"filename": "payslip.pdf",
"content_base64": doc_b64
}]
}, headers={"X-Api-Key": API_KEY})
result = response.json()
print(f"Risk: {result['risk_score']}/100 ({result['risk_level']})")
print(f"Action: {result['recommended_action']}")import requests, base64, json
API_URL = "https://your-instance.trutina.com.au/api/v1/webhooks/ingest"
API_KEY = "your-api-key"
with open("payslip.pdf", "rb") as f:
doc_b64 = base64.b64encode(f.read()).decode()
response = requests.post(API_URL, json={
"applicant_name": "John Smith",
"loan_amount": 750000,
"documents": [{
"type": "payslip",
"filename": "payslip.pdf",
"content_base64": doc_b64
}]
}, headers={"X-Api-Key": API_KEY})
result = response.json()
print(f"Risk: {result['risk_score']}/100 ({result['risk_level']})")
print(f"Action: {result['recommended_action']}")const fs = require('fs');
const docB64 = fs.readFileSync('payslip.pdf').toString('base64');
const response = await fetch(
'https://your-instance.trutina.com.au/api/v1/webhooks/ingest',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'your-api-key'
},
body: JSON.stringify({
applicant_name: 'John Smith',
loan_amount: 750000,
documents: [{
type: 'payslip',
filename: 'payslip.pdf',
content_base64: docB64
}]
})
}
);
const result = await response.json();
console.log(`Risk: ${result.risk_score}/100 (${result.risk_level})`);using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Api-Key", "your-api-key");
var docBytes = File.ReadAllBytes("payslip.pdf");
var payload = new {
applicant_name = "John Smith",
loan_amount = 750000,
documents = new[] {
new {
type = "payslip",
filename = "payslip.pdf",
content_base64 = Convert.ToBase64String(docBytes)
}
}
};
var response = await client.PostAsync(
"https://your-instance.trutina.com.au/api/v1/webhooks/ingest",
new StringContent(
JsonSerializer.Serialize(payload),
Encoding.UTF8,
"application/json"
)
);
var result = await response.Content.ReadAsStringAsync();| Status | Meaning |
|---|---|
| 200 | Analysis complete |
| 400 | Invalid request (missing fields, invalid base64) |
| 401 | Invalid or missing API key |
| 413 | Document too large (max 20MB per document) |
| 429 | Rate limit exceeded |
| 500 | Internal error (retry with exponential backoff) |
Rate limits are enforced per API key. Exceeding limits returns a 429 status code. Contact us if you need higher limits.
| Plan | Concurrent | Monthly Limit |
|---|---|---|
| Starter | 10 | 200/month |
| Professional | 25 | 1,000/month |
| Enterprise | Custom | Custom |
Instead of polling for results, configure a webhook URL in your dashboard to receive analysis results as soon as they are ready. Trutina will send a POST request to your webhook URL with the same response payload as the synchronous API.
// Webhook configuration (set in dashboard)
{
"webhook_url": "https://your-system.com/webhooks/trutina",
"webhook_secret": "your-webhook-signing-secret"
}
// Trutina sends POST to your URL with:
// Header: X-Trutina-Signature: sha256=<HMAC of body>
// Body: Same response format as synchronous APIX-Trutina-Signature header by computing an HMAC-SHA256 of the raw request body using your webhook secret. Reject any requests with invalid signatures.Starter: response within 24 hours
Professional: response within 4 hours
Enterprise: response within 1 hour
Professional and Enterprise plans include dedicated integration support. We can join your Slack, provide sandbox environments, and assist with UAT testing against your loan origination system.
© 2026 Trutina — AI Lending Fraud Detection