📘 Public beta · Endpoints are stable; OpenAPI specs and SDKs ship monthly. See changelog →
Products
Bank Statement
Analyses & transactions

Analyses & transactions

Read an analysis

GET/api/analyses/{id}
Auth · API keyScope · analyses:read

Returns the analysis + up to 1000 transactions. For statements with >1000 transactions, paginate via ?offset=0&limit=1000 (max 1000 per call).

Full response shape

{
  "data": {
    "id": "ana_01HXY...",
    "status": "completed",
    "parseMethod": "bca_native | mandiri_native | ... | gemini_vision | manual_review",
    "detectedBank": "BCA",
    "rawCustomerName": "BUDI SANTOSO",
    "accountHolder": "Budi Santoso",
    "accountNumber": "1234567890",
    "accountNumberMasked": "******7890",
    "statementPeriod": "01 May 2026 - 31 May 2026",
 
    "openingBalance": 12500000,
    "closingBalance": 18750000,
    "totalInflow": 25000000,
    "totalOutflow": 18750000,
    "netMovement": 6250000,
    "averageBalance": 14375000,
    "minBalance": 8200000,
    "maxBalance": 24500000,
    "currency": "IDR",
 
    "confidenceScore": 99,
    "confidenceLevel": "high | medium | low",
    "affordabilityScore": 78,
    "authenticityScore": 96,
    "authenticityStatus": "trusted | suspicious | unknown",
    "manualReviewRequired": false,
    "riskLevel": "low | medium | high",
 
    "transactions": [...],
    "createdAt": "...",
    "completedAt": "...",
    "customer": { "id": "cus_01HXY...", "fullName": "Budi Santoso" },
    "transactionCount": 47
  }
}

Field meanings

FieldNotes
parseMethod{bank}_native for native parsers, gemini_vision for AI parser, manual_review if analyst sign-off was the canonical extraction.
rawCustomerNameName exactly as on the statement. May be ALL CAPS or have weird punctuation.
accountHolderNormalized name; used for cross-statement reconciliation in consolidations.
accountNumberMaskedDisplay version; last 4 digits visible.
confidenceLevelhigh (>= 90) · medium (70–89) · low (< 70). Used by the analyst-review trigger.
affordabilityScore0–100 heuristic: monthly average balance / monthly outflow + stability adjustment.
authenticityScore0–100. PDF metadata consistency + transaction-balance math + sudden-row checks.
authenticityStatustrusted (>= 80) · suspicious (60–79) · unknown (< 60).
manualReviewRequiredTrue when confidence below threshold OR authenticity below threshold.
riskLevelConvenience rollup: low (auth >= 80, conf >= 90) · medium · high.

Transaction shape

{
  "id": "txn_01HXY...",
  "sequenceNo": 1,
  "occurredAt": "2026-05-02T00:00:00Z",
  "rawTxnDate": "02/05",
  "description": "SALARY PT XYZ",
  "amount": 12000000,
  "direction": "in",
  "balanceAfter": 24500000,
  "balanceMismatch": false,
  "channel": "transfer | atm | qris | card | cash | fee | interest | tax",
  "categoryId": "cat_salary",
  "categoryConfidence": 0.98
}
FieldNotes
sequenceNo1-based position in the statement (preserved from source).
occurredAtISO-8601 with timezone. Inferred from rawTxnDate + statementPeriod.
rawTxnDateAs printed: "02/05" or "15/05/2026". Some banks omit the year.
descriptionNormalized: trimmed, repeated spaces collapsed.
amountAbsolute value (always positive). Use direction to know sign.
directionin (credit) · out (debit).
balanceAfterRunning balance. null if not extractable.
balanceMismatchtrue when prev.balanceAfter + signedAmount !== this.balanceAfter.
channelInferred from description heuristics. transfer is the default catch-all.
categoryIdPre-categorized — see categories below.
categoryConfidence0–1 confidence of the categorisation.

Categories

Built-in categories (each has a stable categoryId):

CategoryExamples
salaryPayroll credits, contractor invoices paid
transfer_internalSelf-transfer between own accounts
transfer_externalTransfers to/from third parties
foodRestaurants, food delivery (GoFood, GrabFood, Shopee Food)
transportGojek, Grab, taxi, parking
ecommerceTokopedia, Shopee, Lazada
bills_utilitiesPLN, PDAM, Indihome, Telkomsel postpaid
loan_repaymentKKB, KPR, KTA, BNPL repayments
cash_withdrawalATM cash, cardless withdrawal
cash_depositATM/CRM cash deposits
interest_creditBank-paid interest
fee_debitAdmin fees, transfer fees, RTGS fees
tax_debitPPh23, BPHTB withholding
investmentReksadana, saham, deposito
insurancePremi (life, health, motor)
otherCatch-all

Total of 38 categories. Full list available via the dashboard's Category Library page.

Correcting a category

PATCH/api/transactions/{id}/category
Auth · API keyScope · categorization:write
{
  "categoryId": "cat_loan_repayment",
  "createRule": true,
  "applyToSimilar": true
}
  • createRule: true — turns this correction into a permanent rule for your org. Description-pattern-based.
  • applyToSimilar: true — applies the rule retrospectively to all matching transactions in your org. Returns bulkAffected count.

Common pattern: analyst sees a string of "PEMBAYARAN KKB BCA" transactions categorized as transfer_external. They correct one with createRule: true, applyToSimilar: true, and all of them flip to loan_repayment.

List analyses

GET/api/analyses
Auth · API keyScope · analyses:read

Filters: status, bank (code), customerId, externalRef, from, to, page, limit. Default page size 50, max 200.

{
  "data": [{ /* analysis row, no transactions */ }],
  "total": 1287,
  "page": 1,
  "limit": 50
}

The list endpoint returns analysis metadata + summary fields (totalInflow, confidenceScore, etc.) but not transactions — fetch the detail endpoint per analysis when you need transaction-level data.

Delete

DELETE/api/analyses
Auth · API keyScope · write

Bulk delete by query string:

curl -X DELETE ".../api/analyses?ids=ana_1,ana_2,ana_3" \
  -H "Authorization: Bearer $QE_API_KEY"

Response:

{
  "data": {
    "deleted": ["ana_1", "ana_2"],
    "skipped": [{ "id": "ana_3", "reason": "currently parsing — cancel job first" }],
    "missing": []
  }
}

Delete is destructive but auditable

Deletions are logged with actor + timestamp. The original PDF (if still in retention window) and the analysis row are both removed. To purge just the PDF but keep the analysis (for audit), use the dashboard's "Strip PDF" action instead.