Transcription is the top of the pipeline and it fails soft: any exception logs a WARNING, returns None, and upload.py carries on. That is the right behaviour for a network blip and exactly the wrong behaviour for an unpayable account, because with no transcript there is no extraction, no correlation and no incident -- the system keeps accepting calls and quietly stores empty ones, which looks like quiet radio traffic rather than an outage. This is the third instance of the same failure mode today. The Gemini correlator was down first on a retired model ID and then on a depleted balance, and in both cases the only signal was a per-call WARNING that read as noise. The OpenAI balance is low enough that this one is a matter of when. Billing-shaped errors (insufficient_quota, billing, credit, quota exceeded) now log once at ERROR, name what is dead downstream, and link the top-up page. Everything else keeps the existing per-call WARNING. No new environment variables, so CI deploys this without an ansible run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>