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 raw audio data in the request body. The API will transcribe it and deduct usage from your credits or subscription.
Headers
| Parameter | Type | Description |
|---|---|---|
Authorizationrequired | string | Bearer token or API key |
Content-Typerequired | string | Must be audio/pcm |
X-Provider | string | Provider override (e.g. 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}
With Custom Provider
curl -X POST https://dictatorflow.com/transcribe \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: audio/pcm" \-H "X-Provider: textgen" \-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 |