goAML Reporter is live: automated CTR, STR, SAR and STAR reports for Kenyan institutions. Try the demo →

Why goAML reporting is still a manual job in Kenya, and how we're automating it

Every bank, microfinance bank, SACCO, remittance provider and forex bureau in Kenya is a reporting institution under the Proceeds of Crime and Anti-Money Laundering Act. When something looks suspicious, the institution files a report with the Financial Reporting Centre (FRC), and since the FRC adopted goAML, that report is a structured XML document, not a letter.

I recently built a goAML report generator from scratch. This post is about what I learned along the way, why I think most institutions are still doing this by hand, and what an automated version looks like.

Read the original post on LinkedInThe short version of this story, and the conversation around it.

What actually goes into a goAML report

A Suspicious Transaction Report (STR) is a tree. At the top sits the reporting entity, the officer filing it, and a free-text narrative explaining the grounds for suspicion. Under that sit the transactions, and every transaction has two sides: where the money came from and where it went.

Each side has to be modelled precisely:

<transaction>
  <transactionnumber>PL26251C11</transactionnumber>
  <transmode_code>PSL</transmode_code>
  <amount_local>280000.00</amount_local>
  <t_from_my_client> … your customer's account, signatory, KYC … </t_from_my_client>
  <t_to> … the counterparty's account at another bank … </t_to>
</transaction>

A Suspicious Activity Report (SAR) has a different shape: instead of transactions it describes the parties involved and why they matter. Same schema, different branch of the tree.

Two more report types complete the set. A Cash Transaction Report (CTR) covers cash transactions at or above the USD 15,000 threshold, suspicious or not, and is usually the highest-volume report an institution files. A Suspicious Transaction and Activity Report (STAR) combines both shapes for cases that need the transactions and the wider activity behind them. The generator I built handles all four: CTR, STR, SAR and STAR.

Why uploads get rejected

goAML is strict, and that's a good thing. But it means small data problems become failed submissions. The common ones are boringly predictable:

None of these are hard to fix. They're just hard to catch when the report is being assembled by hand from screenshots of a core banking screen.

Validate first, generate second

The design decision that made the biggest difference was simple: never generate XML that you haven't validated. The same rule engine runs when a compliance officer clicks "Validate" and again immediately before the XML is built. Every rule is a pure function over the report data, so it's testable in isolation and there's exactly one definition of "valid".

Rules come in two strengths:

Every issue points at the exact row and field, so the fix takes seconds. In practice that turned a report that took a morning to assemble into one that takes a couple of minutes to review.

Try it yourself. We've published a browser-only proof of concept (see also the goAML Reporter product page). Load the sample case. It includes one deliberately broken transaction, so you can see the validator catch it. Then fix it and download the XML. Nothing you type leaves your browser.

Why this matters beyond one institution

Kenya has roughly 38 commercial banks, 14 microfinance banks, over 170 deposit-taking SACCOs, and well over a hundred remittance providers, forex bureaus and digital lenders, all filing to the same FRC, against the same schema. Most are solving the same problem independently, often with spreadsheets.

That's why I've refocused my company, formerly WaveOdooApps Consulting, now Humus Technologies, on regulatory reporting. goAML Reporter is our first product: it covers all four report types, connects to your core banking data, validates against goAML rules, generates the XML, and keeps an audit trail of everything filed.

If you're an MLRO, head of compliance or CTO at a Kenyan financial institution and this sounds familiar, I'd like to hear how you're handling it today.

See it with your own data.

Send an anonymised export and we'll show you the goAML XML it produces, with every issue flagged.