How it works
Your users should never have to read a bank's shorthand
Send us the line your feed gives you. Get back a name a person recognises, a category you can group by, and a number saying how sure we are. One call. No SDK, no model to train, no rules to maintain.
One television subscription, on a Nigerian feed, arriving through a different rail each time. Every rail writes it differently.
One name, so it groups. One category, so it budgets. The channel is kept, because how they paid is real information rather than noise.
Grouped by the raw string, every one of those is a separate merchant and a separate category. Your user just sees their TV bill, again and again.
The call
Three things happen, and they take about as long as this sentence
We read it
The line comes apart into the part that names something and the part that is plumbing: references, terminal ids, phone numbers, branch and city tags.
So two payments to the same person stop looking like two different people.
We name it
What is left is resolved against a directory of 662 merchants, billers and counterparty organisations. When there is no merchant, because the payment is a transfer, we name the counterparty and what the sender said it was for.
Most of what arrives on a Nigerian feed is that second case.
We explain it
Category and MCC, country and currency, the channel it arrived through, whether it repeats, and a confidence score.
Enough to group, budget, reconcile or flag without ever touching the raw string again.
Nothing is a black box
Every answer shows its working
A label on its own cannot be checked: when one is wrong there is nothing to look at. Every result we return carries the full list of decisions that produced it, in the order they happened, so a wrong answer is something you can diagnose rather than only report.
The third line is where a wrong answer usually starts. If the noise we stripped took part of the merchant name with it, you can see that in the same response, without asking anyone.
This is the whole trace, not a summary. It comes back on every result, including the ones we could not resolve, which is where you need it most. See it documented.
When we are not sure
A blank field is a better answer than a confident wrong one
Every answer says how sure it is
A confidence score comes back with each result, and it means the same thing across every kind of transaction. Anything we are not confident about is marked, so you can decide whether to show it, hold it, or ask the user.
A wrong answer is one you can fix
Send us the correction. It is reviewed, folds into the
directory, and is added to the benchmark, so the next feed carrying that
string gets the right answer and the mistake cannot come back unnoticed.
GET /feedback shows you what became of it.
We would rather say nothing than guess. Returning a merchant we cannot stand behind is the failure that costs you a support ticket and your user their trust, so precision is measured separately from recall: a separate set of 106 narrations must resolve to no merchant at all.
Why there is no accuracy percentage on this site
Most vendors quote a score on their own test set. That score says how well an engine reads the banks it was built with, and it is not the number you need.
The one you need is how it reads your feed. Every bank writes its narrations a little differently, so check a bank that is not on our coverage page on your own feed before you rely on it.
So this site gives the size of our test sets and no scores. Ask us and you get the numbers and the method, in writing. Better still, the playground runs the real engine on whatever you paste into it, and the API will run a batch of your own narrations. A number you produced from your own feed settles the question; ours cannot.
If you have Nigerian statements and are willing to share a handful of narrations, that is the single most useful thing anyone can give us. How to send one.
Contributing a statement
What we need is formats, not volume
Five to twenty narration lines from one bank is enough. Not a full statement, not a year of history, and never a file from an account that is not yours to share. What makes a bank readable is the shape its narrations take, and a handful of lines shows that as well as a thousand do.
Most useful, in order: a Nigerian bank we have not listed on coverage, then a wallet or neobank, then anywhere else in Africa. If you are not sure whether yours helps, it probably does.
What happens to it
Account numbers, phone numbers and references are scrambled before anything is stored, and the result is never committed to a repository, never published, and never sent to another vendor. It is used to check whether the engine reads that bank, and to fix it where it does not. If you would rather redact the amounts before sending, the formats still work without them.
We will tell you what it said about your bank, which is usually the interesting part for the person who sent it.
How to send one
Paste the lines into the contact form, or ask us there and we will send the consent wording first. Pasted text is easier for both of us than a PDF, and it means you can see exactly what you are sending.
Only send narrations from an account you hold, or one whose holder has agreed. We do not accept statements found online: whoever they belong to did not agree to anything, and a set collected that way is not one we would publish a number from.
Then it gets more useful
Send an account's history and different questions get answered
One string can only be enriched. A history has patterns in it.
What repeats
Subscriptions and bills, what they cost a month, which one has quietly gone up, and which has stopped being paid.
What was charged twice
The same payment, twice, minutes apart. Told apart from two genuine payments that merely look alike.
What is coming
A cash-flow view of the month ahead, as a range rather than a single number, saying how much of it is known and how much is estimated.
Evaluating it
Answer “how good is it on my feed” without writing code
Sign up and drop a statement on the console. It is the fastest honest answer to the only question that matters, and it is the same API this page describes: there is nothing on the console the API cannot do.
The file never leaves your machine
Your browser reads the statement and posts the parsed rows to the enrichment endpoint, naming no account. There is no upload endpoint, because there is nothing to upload to.
Every panel names its call
Each one says which report produced it, and opens a log of the requests your browser actually made. What you are reading is the API’s answer, rendered.
It is a console, not an app
It is where you evaluate the API and manage your keys. We do not sell a personal finance product, and your users never see this: they see yours.
Try it on a line from your own feed
The playground calls the same API this page describes, with no key and no account, and shows you exactly what comes back.