AML Platform · Quickstart
End-to-end: screen a new customer, evaluate a transaction, work the alert, file the SAR.
Time: ~25 minutes against sandbox.
Prerequisites
Sandbox API key with scopes: read, write, screen.run, case.write, sar.write.
1. Create a customer
/api/customerscurl -X POST https://sandbox.quantumelixir.tech/aml/api/customers \
-H "Authorization: Bearer $QE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fullName": "Umar Patek",
"nik": "3201234567890099",
"customerType": "individual",
"nationality": "ID",
"dateOfBirth": "1970-07-20",
"occupation": "Trader",
"reportedIncomeIdr": 800000000,
"kycLevel": 2
}'We use "Umar Patek" because the sandbox watchlist is seeded with the real UN-SC QDi.007 entry — you'll get a guaranteed sanctions hit on the name. (For a NIK-driven PEP hit, use Bambang Setiawan Hartono with NIK 3171010101710001, which matches PPATK PEP entry PEP-DOM-001.) In production this customer would be a real person.
Response:
{
"ok": true,
"data": {
"id": "cus_01HXY...",
"fullName": "Umar Patek",
"nik": "3201234567890099",
"riskRating": "medium",
"isPep": false,
"isSanctioned": false,
"createdAt": "..."
}
}2. Run onboarding screening
/api/screeningscurl -X POST https://sandbox.quantumelixir.tech/aml/api/screenings \
-H "Authorization: Bearer $QE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"lane": "onboarding",
"customerId": "cus_01HXY...",
"subjectType": "individual",
"fullName": "Umar Patek",
"nik": "3201234567890099",
"dateOfBirth": "1970-07-20",
"nationality": "ID"
}'Response:
{
"ok": true,
"data": {
"screeningId": "scr_01HXY...",
"customerId": "cus_01HXY...",
"status": "confirmed",
"topMatchScore": 0.95,
"startedAt": "...",
"completedAt": "...",
"matches": [
{
"id": "mat_01HXY...",
"score": 0.95,
"watchlistEntry": {
"fullName": "Umar Patek",
"category": "sanctions",
"watchlistId": "wl_un_sc",
"sourceListSlug": "QDi.007",
"remarks": "JI — Bali bombing 2002"
}
}
]
}
}Confirmed hit → an alert was auto-created. Look for the alert.created webhook arriving on your endpoint, or poll:
curl "https://sandbox.quantumelixir.tech/aml/api/alerts?customerId=cus_01HXY..." \
-H "Authorization: Bearer $QE_API_KEY"3. Evaluate a transaction
/api/transactions/evaluateThis is the high-volume, real-time endpoint. Use it inline on every transaction:
curl -X POST https://sandbox.quantumelixir.tech/aml/api/transactions/evaluate \
-H "Authorization: Bearer $QE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "cus_01HXY...",
"direction": "credit",
"amountIdr": 550000000,
"currency": "IDR",
"channel": "transfer",
"counterpartyName": "PT Foo",
"isCrossBorder": false,
"city": "Jakarta",
"country": "ID"
}'Response (this one trips the IDR 500M cash threshold rule):
{
"ok": true,
"data": {
"decision": "review",
"riskScore": 65,
"alertId": "alt_01HXY...",
"hits": [
{
"ruleId": "rul_01HXY...",
"ruleName": "High Transaction Amount",
"severity": "medium",
"scoreContribution": 35
}
]
}
}Use data.decision to gate the transaction in your core banking system.
4. Work the case
The screening hit + transaction hit are both alerts on the same customer. Promote the screening alert to a case:
curl -X POST .../api/alerts/alt_01HXY.../escalate \
-H "Authorization: Bearer $QE_API_KEY"Response includes the new (or existing) case ID. Add notes, assign it:
curl -X PATCH .../api/cases/cas_01HXY... \
-H "Authorization: Bearer $QE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "in_review",
"priority": "high",
"assignedToId": "usr_01HXY..."
}'
curl -X POST .../api/cases/cas_01HXY.../notes \
-H "Authorization: Bearer $QE_API_KEY" \
-d '{ "body": "Counterparty PT Foo also under separate watchlist hit." }'5. File the SAR (four-eyes)
Drafting a SAR happens in the dashboard (it's a form-heavy step that doesn't fit raw API ergonomics). When the maker has drafted, the MLRO submits:
/api/sar-filings/{id}/submitcurl -X POST .../api/sar-filings/sar_01HXY.../submit \
-H "Authorization: Bearer $QE_API_KEY"Response:
{
"ok": true,
"data": {
"filing": {
"id": "sar_01HXY...",
"caseId": "cas_01HXY...",
"status": "submitted",
"filedById": "usr_drafter...",
"submittedById": "usr_mlro...",
"submittedAt": "..."
},
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<goAML>...</goAML>",
"next": "Forward XML to PPATK goAML gateway via the configured connector."
}
}The xml field is your PPATK-ready goAML envelope. Forward it through your existing PPATK channel.
Four-eyes rule
submittedById must differ from filedById. Same user attempting both → HTTP 409 four-eyes violation: drafter cannot submit. No exceptions, configurable per-org policy.
Next steps
- Screening → — bulk screening, fuzzy match tuning
- Transaction monitoring → — at-scale ingestion patterns
- Rules → — write your own rules
- SAR filing → — goAML format reference
- Webhooks → — replace polling with push