Given a correct transcript of what the visitor said, TypelessForm puts the right value in the right field 98.5% of the time — 195 field observations across 27 spoken utterances, three forms and three languages, measured 2026-09-21 on a corpus we froze and publish. Speech recognition is not inside that number. We have not measured it, so we do not quote a figure for it.
Until 16 September 2026 this site and our npm package said "96% accuracy". That number was a speech-model vendor's published benchmark, quoted as if it were our measurement, for a model we had already stopped calling. We removed it, and then spent two days building the thing that should have been there instead. This page is the method, the raw runs, and the parts that did not flatter us.
What does "accuracy" mean for a voice form filler?
It means field-level accuracy: of the fields a speaker actually named, how many end up holding the right value. That is the term used for this class of system — Salesforce Engineering reports the same metric for speech-driven work-order forms, and it is the one we adopted rather than inventing our own.
The phrase hides a fork that decides everything. A voice form filler is two systems in a row: speech becomes text, then text becomes field values. They fail for different reasons, they are fixed by different work, and averaging them produces a number that describes neither. Salesforce's write-up on the same class of system categorises its failures by exactly that origin — transcription, semantic interpretation, field mapping — without publishing a split between them, which is itself the point: the two halves are tracked apart because they are not the same problem.
We measure the second stage. Our number answers: assuming the words were heard correctly, does each value land in the right box? It does not answer will the words be heard correctly — that depends on the microphone, the room, the accent and the network, none of which we control and none of which we have measured.
What is the measured figure, exactly?
98.5% of named discrete fields filled correctly, identical across all three passes, with zero invented values in 48 opportunities.
| What | Value |
|---|---|
| Field-level exact match, named fields | 98.5% (98.5 / 98.5 / 98.5 across three passes) |
| Observations | 195 discrete field cells |
| Corpus | 27 utterances, 3 forms, English / Russian / German |
| Binomial interval | ±1.73 percentage points |
| Invented values on fields nobody mentioned | 0 of 48 |
| Forms with zero errors | 24 of 27 |
| Date · corpus version | 2026-09-21 · v2 |
| Extraction model | gpt-5.4-mini |
| Speech recognition | not measured, not included |
Two denominators, not one. A field the speaker named is scored on whether it holds the right value. A field nobody mentioned is scored on whether it stayed empty — and filling it is the worst failure a form filler has, because an invented phone number looks exactly like a real one. Merging the two into a single percentage hides that failure completely, which is why we publish them apart.
There is a third bucket, and it is three cells wide, and it deserves saying out loud because it makes the second number look better than its earlier version did. In the scattered contact utterance the speaker never names a subject line, but dictates a message that plainly has one. Filling that in is not invention, and leaving it empty is not an error, so corpus v2 marks those three cells derivable and counts them in neither figure. In corpus v1 they were ordinary unspoken cells — and the model filled one to two of them per pass. Scored by the older rule, these same runs read 1–2 invented of 51 rather than 0 of 48. We think the newer rule is the right one, and we are not going to make you diff two JSON files to find out that it changed.
What is the corpus, and why a frozen one?
Twenty-seven written utterances with the expected field values recorded before anything was run, frozen so the same measurement can be repeated after any model change. Each of the three demo forms — contact, hotel booking, dental appointment — is spoken three ways: everything in one dense sentence, everything in a rambling paragraph, and a scattered version where the speaker changes their mind mid-sentence and leaves some fields unmentioned.
That third variant is where the interesting failures live, and it does two jobs. It carries exactly one self-correction per utterance — "we're coming in on Tuesday, no, hang on, Wednesday" — and the expected value is the corrected one. And it deliberately leaves roughly 40% of fields unspoken, which is what gives the invention counter a denominator: 48 chances to fill something nobody asked for.
Difficulty is matched across languages rather than translated. The same fields are named and unnamed in each language, the same self-correction sits in the same place, the same relative date and the same spelled-out email address appear. The data itself is local — a German name in the German utterance — so that a difference between languages comes from the language and not from one version being easier.
Relative dates forced one more decision. "This Friday" and "two weeks from today on the Tuesday" resolve differently depending on what day it is, so the corpus freezes today as 2026-10-05 and passes it explicitly. Without that, the expected answers drift on their own and the drift looks like a regression.
Both files are on this site, so none of this has to be taken on trust: the corpus — every utterance and every expected value — and the run summary, with the per-pass results, the error counts by field, the model, the prompt-file hashes and the frozen date context. What is not in them is the per-cell verdicts and the raw model responses; the totals are computed from those, under the scoring rules the corpus states. The corpus reads in Russian because that is the language it was written and is used in — the utterances themselves are English, Russian and German.
Both files are published under CC BY 4.0: use them, quote them, run your own scoring against them, publish what you find — the one condition is attribution to TypelessForm / Webappski with a link back to this page. Benchmark a competitor against them if you like. A corpus nobody may re-run is the same closed claim in a different costume.
What does the number deliberately not cover?
Speech recognition, end-to-end accuracy, latency, and free-text fields. Each omission is a decision, not an oversight.
Speech recognition is absent because measuring it honestly needs recordings of real people with a human transcript of what they actually said — and a transcript taken from the recogniser's own output would make its errors invisible by construction. We have no such corpus, so there is no figure.
End-to-end accuracy is absent for the same reason: it is the two stages multiplied, and we only have one of them.
Latency is absent because our own timings come from extraction on a developer machine with no audio in the path. A number from our hardware would not describe a visitor's phone on a hotel's wifi.
Free-text fields — a message body, a description of a symptom — are measured separately and by hand. Comparing a paragraph to an expected paragraph is not the same operation as comparing a phone number, and folding the two together would make the headline look more precise than it is. Forty-five such cells sit in the corpus awaiting human review, and they are not in the 98.5%.
What did the first run actually find?
The first run scored 63.2%, and almost none of it was about extraction quality: three whole field types were failing every single time. Date, time and checkbox fields were wrong in 198 of 198 observations. Not often wrong — never right.
Two of the three shared one cause, a single line that converted a calendar date into an instant. A date parsed as local midnight was published through a UTC conversion, so on a machine ahead of UTC "this Friday" arrived as the Thursday. Times lost the same offset. The third was unrelated and simpler: a lone checkbox was described to the model as a value to return, the model returned the field's name, and the widget only ticks a box for a boolean or for the element's own value — so no box was ever ticked, in any timezone.
The timezone defect has an honest asterisk, and it is the kind that usually gets quietly dropped. It depends on the timezone of the server process, not the visitor's, and the hosting default is UTC — where it does not reproduce at all. It failed consistently on every developer machine in Europe and in the local emulator, and passed in production. That is why it survived unnoticed for months, and it is why the 63.2% is labelled as a bench figure everywhere we mention it.
With both defects fixed the same corpus scored 97.1%. Then the remaining failures were read one by one, which is where the least comfortable finding came from.
Which failures turned out to be our own measurement's fault?
Three of them. The corpus was wrong, not the product. The Russian utterances dictated an email domain one way and the expected answer spelled it another — the model faithfully reproduced what had been said, and our own gold disagreed with it.
The cheap fix was to change the expected answer to match the output and collect three free percentage points. We changed the utterance instead, so the corpus says what the expected answer claims, and re-measured the affected scripts. Fitting expected answers to results is how a measurement becomes decoration.
That correction is the whole distance from 97.1% to 98.5%. It is our corpus getting fixed, not our product getting better, and anyone quoting the pair should say so.
What happened when we tried to improve the number?
We wrote two prompt rules aimed at the four remaining failures, measured them, and threw them away. The result was 98.1% — slightly worse, and worse in a way the headline could not show.
| Attempt | Figure | Cells fixed | Cells broken |
|---|---|---|---|
| Before the prompt edit | 98.5% | — | — |
| After the prompt edit | 98.1% | 1 | 3 |
The −0.4 point move sits inside the ±1.73 interval, so on the headline alone the change was indistinguishable from noise. The per-cell comparison settled it: one German option-matching cell was repaired, and three that had always worked stopped working — including one where the speaker corrects themselves and the model took the value from before the correction.
That last one is why it was reverted rather than tuned. Teaching a model that "a negation rules out the option it mentions" leaked into "no, make it ten o'clock", which is not a negation at all but a person changing their mind. Self-correction is the behaviour that makes one-shot filling usable; trading it for one option-matching cell is a bad trade at any accuracy number.
What still fails?
Four cells, all outside English, in two recognisable shapes. German numbers dictated as words come back one digit too long or empty — "fünf sechs sieben acht" arriving as 56778. And a colloquial phrase that describes an option without naming it sometimes reaches no option at all: a German "it isn't constant, it comes and goes" failing to select "periodic", a Russian "it's urgent, actually" failing to select "emergency".
Both are extraction quality, not plumbing, and the failed prompt attempt above is evidence that they are not a five-minute fix. They are listed here rather than smoothed over because a method page that only reports what went well is a brochure.
How does 98.5% compare to what others report?
It is not comparable, and no accuracy figure from two different vendors ever is. Published numbers in this space are measured on different corpora, different field types, different definitions of "correct" and different halves of the pipeline.
One adjacent reference point, as context and not as confirmation: Salesforce Engineering, writing in March 2026 about speech-driven work-order forms for field service technicians, reports "85% field-level accuracy, which serves as a robust production baseline". That is the same operation as ours — speech into form fields — in a different domain, on their corpus, under their conditions, and including the speech stage that our figure excludes. It is not a number ours can be placed beside. The only honest use of another vendor's figure is as evidence that the metric exists and is taken seriously — which is precisely the line we crossed when we quoted a speech vendor's 96% as our own.
What you can compare is method. Ask any vendor quoting an accuracy figure four questions: how many observations, on what corpus, measured when, and which half of the pipeline. A number that cannot answer all four is a decoration.
Can the measurement be repeated?
Yes, and that was a design requirement — the corpus is frozen and published, and every run records what could move the number. Each result carries the extraction model as the provider returned it, the speech model even when no audio was involved, hashes of the four prompt files, the frozen date context and the corpus version.
That bookkeeping earns its keep on one specific day. The speech model we call today, gpt-4o-mini-transcribe, was deprecated on 26 August 2026 and shuts down on 26 February 2027. When its replacement arrives, a number that moves will be attributable — to the model, to a prompt edit, or to neither — instead of being a mystery to argue about.
Questions we get asked
The short answers are below; each one is expanded above.
Try it on your own form
The three forms in the corpus are the same three on our demo page, and the fastest way to judge a voice form filler is to speak into your own worst form — the long one, with the dates and the dropdowns — and count. The demo is here, and the free tier covers 200 fills with no card.