Supplier Invoice Speech-to-Text: EU Startup Validation Beyond Per-Minute Pricing A developer outlines a method for EU startups to select a speech-to-text API for supplier invoice transcription, emphasizing cost per accepted invoice over per-minute pricing. The approach involves building a TypeScript adapter, testing candidates against a fixed corpus, and enforcing EU data-handling requirements. The developer advises that provider names alone do not determine the winner and that acceptance gates and billing units must be measured. Short answer: the cheapest speech-to-text API for an EU startup is the candidate that passes your invoice-field accuracy gate at the lowest normalized cost for your actual audio. Don't choose from a public per-minute headline alone. Put every provider behind one small TypeScript interface, replay the same supplier recordings, reject transcripts that fail schema checks, and compare the cost of accepted results. For an edtech SaaS, this is a weekly-shipping decision, not a research project. The concrete job here is awkward but real: a school administrator reads fields from a supplier invoice into a voice note, and the application turns that audio into structured invoice data. A cheap transcript that changes a VAT identifier, currency, date, or total creates review work. That failed result has no useful price per minute. I would time-box the first pass to an afternoon. OpenAI, Deepgram, AssemblyAI, and Google Cloud can all enter the candidate set named in the question, but their names don't determine the winner. A current quote, the exact billing unit, EU processing requirements, and a fixed acceptance corpus do. I'm not sure which one will win for your microphones and supplier vocabulary until those inputs are measured; anyone certain without them is guessing. Start with the denominator. A provider may quote audio duration, rounded units, model-specific units, or another billing basis. Do not translate those into a common number by intuition. Record each candidate's current commercial terms as data, then calculate one metric: cost per accepted invoice. This keeps a changing quote outside application code and makes the decision reproducible. The acceptance gate matters more than the spreadsheet. Build a small corpus that represents the input you will actually receive: quiet office recordings, phone microphones, supplier names, invoice numbers, dates, decimal totals, currency codes, and VAT identifiers. Keep the source invoice beside each recording so expected fields are explicit. Twenty carefully chosen clips can expose more decision-relevant failures than hundreds of generic sentences, though that count is a starting point rather than a universal benchmark. Your mileage may vary. Use a table with blanks, not invented precision: | Candidate | Current billing unit | EU requirement met? | Accepted clips | Quoted corpus cost | Cost per accepted invoice | |---|---|---|---|---|---| | Candidate A | Verify from current terms | Yes / No | Test result | Test result | Derived | | Candidate B | Verify from current terms | Yes / No | Test result | Test result | Derived | | Candidate C | Verify from current terms | Yes / No | Test result | Test result | Derived | | Candidate D | Verify from current terms | Yes / No | Test result | Test result | Derived | That Yes / No column is deliberately strict. "Available in Europe" and "meets this application's EU data-handling requirement" are different questions, and a candidate's name establishes neither. Write down the requirement your counsel or customer contract gives you, request evidence, and make a failed requirement disqualifying rather than assigning it a soft score. There is another trap. Audio length is only the input to the bill; accepted structured fields are the output that earns revenue. If one transcript needs a person to reopen the invoice while another passes automatically, their nominal per-minute numbers are not comparable. Count human review time separately, but don't manufacture an hourly saving claim. Your own support and operations data should supply that value. The adapter needs fewer concepts than most SDK examples suggest. Accept bytes plus a MIME type. Return transcript text and provider usage in the provider's native unit. Keep invoice extraction and validation downstream, because coupling those steps to one transcription response makes the exit test much harder. type AudioInput = { bytes: Uint8Array; mimeType: string; }; type Transcript = { text: string; billedQuantity: number; billedUnit: string; }; interface SpeechToText { transcribe input: AudioInput : Promise