Dictation and vocabulary
Desktop dictation runs on your own OpenAI or Gemini key with hint vocabularies per project. Phones transcribe through PlanToCode services. The error classes tell you which layer failed.
Checked against the source on 17 September 2026
On this page
Set up dictation
- Your keytranscribe_with_provider
The desktop calls OpenAI or Gemini directly with the key saved under Settings → API Keys. PlanToCode’s servers see neither the audio nor the key.
- PlanToCode’s key/api/audio/transcriptions
Phones upload with their PlanToCode JWT and ask for openai/gpt-4o-transcribe. The server refuses the upload without a positive credit balance and charges the transcription to your account.
- Borrowed vocabularysystem.voiceTranscriptionContext
Before uploading, the phone asks the desktop over the relay for its vocabulary prompt. Without an answer it uploads without one, and the server builds its own default prompt.
- Open Settings → API Keys and save a personal OpenAI or Gemini API key.
- Open Settings → Voice, pick OpenAI or Gemini as the dictation service, and save.
- Allow microphone access when the operating system asks.
Dictation uses your own API key and is separate from the ChatGPT sign-in that runs the agent. The only accepted model IDs are gpt-4o-transcribe and gemini-flash-latest. Before the first recording the desktop sends a synthetic preflight WAV to the real provider endpoint and caches the result per provider and model for 15 minutes after a success and 5 minutes after a failure, or until you save settings again. OpenAI requests time out after 120 seconds.
Review Mode recordings go through the regional server to Gemini with POST /api/llm/video/analyze. On iPhone each capture’s narration is transcribed first. Review Mode in the iOS and Android media chapters has the details.
Teach the transcriber your words
- Rulestranscription_system_prompt
The compact rules for OpenAI take 622 bytes after XML escaping and 683 with their tags. The budget lets them use up to 720 bytes and keeps 280 for vocabulary.
- Your vocabularypersonal_vocabulary_kb
After the rules, a newline and 51 bytes of tags leave 265 bytes of text. The global list goes first, then the project list, both XML-escaped and cut at the limit, mid-word if need be. The split drawn here is an example.
- Geminitranscription_prompt_max_bytes
Gemini gets the full rules, 1,836 bytes with tags, and room for about a megabyte of vocabulary, so nothing you are likely to type is cut.
Voice settings hold a global vocabulary and a per-project vocabulary. Put terms you use everywhere in the global list and repository-specific names in the project list. They travel as an XML-escaped spelling reference inside the transcription prompt with an explicit rule never to insert them. On OpenAI they get 265 bytes of text after the rules and tags, global list first.
Error classes
| Visible problem | Check |
|---|---|
| Microphone unavailable | The operating system permission. Readiness also requires usable audio input. |
| Provider not configured | Settings → API Keys and the saved dictation service under Settings → Voice. |
| Quota or rate limit | OpenAI only, classified from its 429 code and never from free text. Quota codes such as insufficient_quota, credit_balance_exhausted, and the spend or usage limits link to billing. Any other 429, such as rate_limit_exceeded or slow_down, is a rate limit that passes with time. A Gemini failure reads as a key problem and blocks Gemini dictation for 5 minutes, or until you save Voice settings. |
| Recording too large | The desktop refuses more than 25,000,000 bytes before an OpenAI upload. Record a shorter clip or switch to Gemini. |