DictatorFlow API Documentation
API Reference
The DictatorFlow API provides speech-to-text transcription and text command processing. All API requests use JSON and require authentication via JWT token or API key.
https://dictatorflow.comBearer <token | api_key>Quick Start
# 1. Sign upcurl -X POST https://dictatorflow.com/auth/signup \-H "Content-Type: application/json" \-d '{"email": "[email protected]", "password": "secret123"}'# 2. Create an API key (use the token from signup response)curl -X POST https://dictatorflow.com/auth/api-keys \-H "Authorization: Bearer YOUR_JWT_TOKEN" \-H "Content-Type: application/json" \-d '{"name": "my-app"}'# 3. Transcribe audiocurl -X POST https://dictatorflow.com/transcribe \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: audio/pcm" \--data-binary @audio.pcm
Pricing
| Plan | Price | Included |
|---|---|---|
| Pay-as-you-go | $0.004/sec | API credits, billed per second of audio |
| Pro | $9/month | 10 hours/month transcription |
| Lifetime | $99 one-time | Unlimited + $99 API credits |
Authentication
All protected endpoints require a Bearer token in the Authorization header. You can use either a JWT token (from login/signup) or an API key (prefixed with vt_).
Sign Up
/auth/signupCreate a new account| Parameter | Type | Description |
|---|---|---|
emailrequired | string | Account email address |
passwordrequired | string | Account password |
curl -X POST https://dictatorflow.com/auth/signup \-H "Content-Type: application/json" \-d '{"email": "[email protected]", "password": "secure123"}'
Response
{"token": "eyJhbGciOiJIUzI1NiIs...","user": {"id": "550e8400-e29b-41d4-a716-446655440000","created_at": "2026-02-28T12:00:00Z"}}
Log In
/auth/loginAuthenticate and get a token| Parameter | Type | Description |
|---|---|---|
emailrequired | string | Account email |
passwordrequired | string | Account password |
curl -X POST https://dictatorflow.com/auth/login \-H "Content-Type: application/json" \-d '{"email": "[email protected]", "password": "secure123"}'
Response
{"token": "eyJhbGciOiJIUzI1NiIs...","user": {"id": "550e8400-e29b-41d4-a716-446655440000","created_at": "2026-02-28T12:00:00Z"}}
JWT tokens expire after 7 days.
API Keys
/auth/api-keysCreate a new API keyRequires authentication. The full key is only returned once -- store it securely.
| Parameter | Type | Description |
|---|---|---|
name | string | Friendly name for the key |
curl -X POST https://dictatorflow.com/auth/api-keys \-H "Authorization: Bearer YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"name": "production"}'
Response
{"key": "vt_a1b2c3d4e5f6...","prefix": "vt_a1b2c3d","id": "key-uuid-here"}
/auth/api-keysList all API keyscurl https://dictatorflow.com/auth/api-keys \-H "Authorization: Bearer YOUR_TOKEN"
Response
[{"id": "key-uuid","prefix": "vt_a1b2c3d","name": "production","created_at": "2026-02-28T12:00:00Z","last_used_at": "2026-02-28T14:30:00Z"}]
Update Account
/auth/accountUpdate email or password| Parameter | Type | Description |
|---|---|---|
email | string | New email address |
password | string | New password |
old_password | string | Current password (required when changing password) |
curl -X PUT https://dictatorflow.com/auth/account \-H "Authorization: Bearer YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"email": "[email protected]"}'
Transcription
/transcribeTranscribe audio to textSend audio data in the request body. Meta Muse Voice Transcribe is the default quality path, with automatic fallback to the configured providers. Smart mode cleans disfluencies and applies readable formatting. Choose Verbatim mode when exact speech, word timing, or speaker attribution matters.
Headers
| Parameter | Type | Description |
|---|---|---|
Authorizationrequired | string | Bearer token or API key |
Content-Typerequired | string | PCM, WAV, OGG, WebM, MP3/MPEG, or another supported audio MIME type |
X-Transcription-Mode | string | smart (default) or verbatim |
X-Language-Code | string | auto (default) or a BCP-47 hint such as en-NZ, es-419, or ja-JP |
X-Word-Timestamps | boolean | Return word annotations. Requires Verbatim mode and can reduce recognition accuracy. |
X-Speaker-Diarization | boolean | Label speakers in annotations. Requires Verbatim mode; supports up to eight speakers. |
X-Provider | string | Provider override: meta, gemini, openai, or textgen |
X-Provider-Key | string | API key for the specified provider |
Audio Format
Raw PCM audio: 32-bit float, 16kHz sample rate, mono channel. Audio duration is calculated as bytes / (4 * 16000).
curl -X POST https://dictatorflow.com/transcribe \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: audio/pcm" \--data-binary @recording.pcm
Response
{"text": "Hello, this is a transcription test.","duration_seconds": 0.142,"mode": "smart","language": "auto"}
Word timestamps and speakers
curl -X POST https://dictatorflow.com/transcribe \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: audio/wav" \-H "X-Transcription-Mode: verbatim" \-H "X-Language-Code: en-NZ" \-H "X-Word-Timestamps: true" \-H "X-Speaker-Diarization: true" \--data-binary @meeting.wav
{"text": "Welcome to the meeting.","mode": "verbatim","language": "en-NZ","words": [{"text": "Welcome", "start_offset": "0.20s", "end_offset": "0.61s", "speaker": "spk_1"}]}
Smart mode is intentionally incompatible with timestamps and diarization. Use focused custom vocabulary from your DictatorFlow dictionary for names, products, acronyms, and specialist terms.
With Custom Provider
curl -X POST https://dictatorflow.com/transcribe \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: audio/pcm" \-H "X-Provider: meta" \-H "X-Provider-Key: YOUR_PROVIDER_KEY" \--data-binary @recording.pcm
Python Example
import requestswith open("recording.pcm", "rb") as f:audio = f.read()resp = requests.post("https://dictatorflow.com/transcribe",headers={"Authorization": "Bearer YOUR_API_KEY","Content-Type": "audio/pcm",},data=audio,)print(resp.json()["text"])
JavaScript Example
const resp = await fetch("https://dictatorflow.com/transcribe", {method: "POST",headers: {"Authorization": "Bearer YOUR_API_KEY","Content-Type": "audio/pcm",},body: audioBuffer, // ArrayBuffer of PCM data});const { text } = await resp.json();console.log(text);
Browser Widget
/embed/dictatorflow-stt.jsEmbeddable browser speech-to-text widgetThe browser widget gives any web app a microphone-powered speech modal with a live waveform, Enter-to-finish, and transcript insertion into inputs, textareas, or contenteditable surfaces.
Install
<script src="https://dictatorflow.com/embed/dictatorflow-stt.js"></script>
Mount Next to a Textarea
<textarea id="notes" rows="8"></textarea><script>window.DictatorFlowSTT.mount(document.getElementById("notes"), {apiKey: "YOUR_API_KEY",buttonLabel: "Speak",title: "Dictate your notes",subtitle: "Press Enter when you're done speaking."});</script>
Open the Modal from Your Own Button
const composer = document.querySelector("#composer");const trigger = document.querySelector("#voice-trigger");trigger.addEventListener("click", () => {window.DictatorFlowSTT.open({target: composer,endpoint: "/api/dictation",title: "Voice reply",subtitle: "Transcribe through your own backend proxy."});});
Auto-Mount Across a Form
window.DictatorFlowSTT.mountAll("[data-voice]", (target) => ({endpoint: "/api/dictation",target,buttonLabel: "Speak",title: "Talk to " + (target.getAttribute("placeholder") || "this field")}));
Proxy Through Go
func dictatorflowProxy(w http.ResponseWriter, r *http.Request) {req, _ := http.NewRequest(http.MethodPost,"https://dictatorflow.com/transcribe",r.Body,)req.Header.Set("Authorization", "Bearer "+os.Getenv("DICTATORFLOW_API_KEY"))req.Header.Set("Content-Type", r.Header.Get("Content-Type"))resp, _ := http.DefaultClient.Do(req)defer resp.Body.Close()w.Header().Set("Content-Type", "application/json")w.WriteHeader(resp.StatusCode)io.Copy(w, resp.Body)}
Proxy Through Python
@app.post("/api/dictation")def dictatorflow_proxy():upstream = requests.post("https://dictatorflow.com/transcribe",headers={"Authorization": f"Bearer {os.environ['DICTATORFLOW_API_KEY']}","Content-Type": request.headers.get("Content-Type", "audio/webm"),},data=request.get_data(),timeout=30,)return Response(upstream.content,status=upstream.status_code,content_type="application/json",)
Widget API
| Parameter | Type | Description |
|---|---|---|
target | HTMLElement | Input, textarea, or contenteditable element that should receive the transcript |
endpoint | string | Optional absolute or relative endpoint. Defaults to https://dictatorflow.com/demo/transcribe unless apiKey is provided. |
apiKey | string | Optional API key. When provided, the widget uses https://dictatorflow.com/transcribe. |
title | string | Custom modal heading |
subtitle | string | Custom helper copy shown under the heading |
buttonLabel | string | Label for buttons created by mount or mountAll |
buttonClassName | string | Optional class override for mounted buttons |
headers | Record<string, string> | Additional headers to send with the transcription request |
onResult | (text, payload) => void | Optional callback that runs after a successful transcription |
onError | (error) => void | Optional callback for microphone or network failures |
onCancel | () => void | Optional callback when the user cancels the speech modal |
window.DictatorFlowSTT.open(), attach(), attachAll(), mount(), mountAll(), and insertText().Command
/commandExecute a text command using AISend a voice transcription as a command to manipulate text using AI. Deducts a fixed 2.5 seconds of usage per call.
| Parameter | Type | Description |
|---|---|---|
transcriptionrequired | string | The voice command transcription |
selected_text | string | Text to apply the command to |
curl -X POST https://dictatorflow.com/command \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"transcription": "make this uppercase","selected_text": "hello world"}'
Response
{"result": "HELLO WORLD"}
Billing
Manage your subscription, credits, and billing portal. All billing endpoints require authentication.
Get Balance
/billing/balanceGet current billing statuscurl https://dictatorflow.com/billing/balance \-H "Authorization: Bearer YOUR_TOKEN"
Response
{"subscription": {"id": "sub-uuid","plan": "pro","monthly_seconds": 36000,"used_seconds": 1234.5,"status": "active","current_period_end": "2026-03-28T00:00:00Z"},"credits": {"user_id": "user-uuid","balance_cents": 5000,"total_purchased_cents": 10000},"can_transcribe": true}
Purchase Credits
/billing/creditsBuy API credits via Stripe| Parameter | Type | Description |
|---|---|---|
amount_centsrequired | integer | Amount in cents (min 100 = $1.00) |
curl -X POST https://dictatorflow.com/billing/credits \-H "Authorization: Bearer YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"amount_cents": 1000}'
Response
{"checkout_url": "https://checkout.stripe.com/c/pay/..."}
Redirect the user to the checkout URL to complete payment.
Subscribe
/billing/subscribeStart a subscription| Parameter | Type | Description |
|---|---|---|
planrequired | string | "pro" ($9/mo, 10hr) or "lifetime" ($99 one-time) |
curl -X POST https://dictatorflow.com/billing/subscribe \-H "Authorization: Bearer YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"plan": "pro"}'
Response
{"checkout_url": "https://checkout.stripe.com/c/pay/..."}
Customer Portal
/billing/portalOpen Stripe customer portalcurl -X POST https://dictatorflow.com/billing/portal \-H "Authorization: Bearer YOUR_TOKEN"
Response
{"portal_url": "https://billing.stripe.com/p/session/..."}
Usage History
/usageGet recent transaction historyReturns the last 50 transactions for the authenticated user.
curl https://dictatorflow.com/usage \-H "Authorization: Bearer YOUR_TOKEN"
Response
[{"id": "txn-uuid","user_id": "user-uuid","type": "usage","amount_cents": -40,"seconds_used": 100.0,"created_at": "2026-02-28T15:30:00Z"},{"id": "txn-uuid-2","user_id": "user-uuid","type": "purchase","amount_cents": 1000,"seconds_used": 0,"stripe_charge_id": "ch_...","created_at": "2026-02-28T12:00:00Z"}]
Transaction Types
| Type | Description |
|---|---|
| purchase | Credit purchase via Stripe |
| usage | Transcription or command usage deduction |
| subscription_reset | Monthly subscription seconds reset |
Error Handling
All errors return a JSON object with an error field.
{"error": "insufficient credits or no active subscription"}
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request -- missing or invalid parameters |
| 401 | Unauthorized -- invalid or missing auth token |
| 402 | Payment required -- insufficient credits or no subscription |
| 409 | Conflict -- email already exists |
| 429 | Rate limited -- too many demo requests |
| 500 | Internal server error |