FluidVoice API Endpoints: Complete Guide to the Local HTTP Interface
FluidVoice provides a local-only HTTP API running on 127.0.0.1:47733 with six JSON endpoints for transcription, dictionary management, and post-processing.
The FluidVoice API is a built-in, opt-in feature of the macOS dictation app that exposes programmatic access to core functionality without requiring any external network calls. When enabled in Settings → "Enable Local API", the app launches an internal server bound exclusively to the loopback interface, making it safe for automation scripts and third-party tools on the same machine.
How the FluidVoice API Server Works
The local API architecture centers on three Swift components in Sources/Fluid/Services/LocalAPI/:
- LocalAPIServer – Creates the TCP listener in
LocalAPIServer.swift, validates loop-back origins, and manages connection lifecycles - LocalAPIRouter – Registers route handlers and dispatches
LocalAPI.Requestobjects to the appropriate controller - LocalAPIModels – Defines request/response structs, the default port (47733), and shared JSON coders
Server startup reads from LocalAPI.Configuration.current, which respects the user-defaults key LocalAPIPort for custom port overrides.
All FluidVoice API Endpoints Reference
| Method | Path | Handler File | Purpose |
|---|---|---|---|
| GET | /v1/health |
Inline in LocalAPIRouter.swift |
Health check with version info |
| GET | /v1/history |
HistoryAPIController.swift |
Query transcription history |
| GET/POST | /v1/dictionary/replacements |
DictionaryAPIController.swift |
Manage text replacement rules |
| GET/POST | /v1/dictionary/custom-words |
DictionaryAPIController.swift |
Manage custom vocabulary |
| POST | /v1/transcribe |
InferenceAPIController.swift |
On-device audio transcription |
| POST | /v1/postprocess |
InferenceAPIController.swift |
Text refinement via Fluid Intelligence |
Every endpoint returns JSON and rejects non-local connections at the socket level.
FluidVoice API Examples
Health Check
Verify the server is running and retrieve the app version:
curl http://127.0.0.1:47733/v1/health
Response:
{"status":"ok","version":"1.6.0"}
Query Transcription History
Retrieve recent entries with an optional limit parameter:
curl "http://127.0.0.1:47733/v1/history?limit=5"
Response structure:
{
"count": 5,
"items": [
{"text": "example transcription", "timestamp": "2024-01-15T09:30:00Z", ...}
]
}
Manage Dictionary Replacements
The mode parameter accepts "append" or "replace":
curl -X POST http://127.0.0.1:47733/v1/dictionary/replacements \
-H "Content-Type: application/json" \
-d '{
"mode": "append",
"entries": [
{"triggers": ["brb"], "replacement": "be right back"},
{"triggers": ["imo", "imho"], "replacement": "in my opinion"}
]
}'
Add Custom Vocabulary Words
Custom words improve recognition accuracy for specialized terms:
curl -X POST http://127.0.0.1:47733/v1/dictionary/custom-words \
-H "Content-Type: application/json" \
-d '{
"mode": "append",
"entries": [
{"word": "Kubernetes", "pronunciationHint": "koo-ber-net-ees"},
{"word": "React", "pronunciationHint": "ree-akt"}
]
}'
Transcribe Audio Files
Submit a local file path, base64 audio, or raw bytes:
curl -X POST http://127.0.0.1:47733/v1/transcribe \
-H "Content-Type: application/json" \
-d '{"path": "/Users/me/Audio/sample.wav"}'
Response includes text, confidence (0.0-1.0), sampleCount, and provider.
Post-Process Text with Fluid Intelligence
Send raw transcribed text for AI-powered refinement:
curl -X POST http://127.0.0.1:47733/v1/postprocess \
-H "Content-Type: application/json" \
-d '{"text": "i went to the market tho it was raining"}'
Response:
{
"text": "I went to the market, though it was raining.",
"provider": "Fluid Intelligence",
"model": "v1"
}
Programmatic Server Control
Enable and start the FluidVoice API from Swift code:
import Fluid
LocalAPI.Configuration.current = LocalAPI.Configuration(
enabled: true,
port: 47733 // or custom port
)
LocalAPIServer.shared.start()
To stop the server:
LocalAPIServer.shared.stop()
Security and Network Boundaries
The FluidVoice API is strictly local-only. The LocalAPIServer implementation in LocalAPIServer.swift validates that every incoming connection originates from 127.0.0.1 or localhost before accepting data. Remote connections are rejected at the TCP level, ensuring no external network exposure regardless of firewall configuration.
Key Source Files
| File Path | Responsibility |
|---|---|
Sources/Fluid/Services/LocalAPI/LocalAPIServer.swift |
TCP listener, connection validation, lifecycle management |
Sources/Fluid/Services/LocalAPI/LocalAPIRouter.swift |
Route registration and request dispatch |
Sources/Fluid/Services/LocalAPI/LocalAPIModels.swift |
Shared types, defaults, JSON encoding |
Sources/Fluid/Services/LocalAPI/HistoryAPIController.swift |
/v1/history implementation |
Sources/Fluid/Services/LocalAPI/DictionaryAPIController.swift |
Dictionary replacement and custom-words endpoints |
Sources/Fluid/Services/LocalAPI/InferenceAPIController.swift |
/v1/transcribe and /v1/postprocess |
Summary
- FluidVoice API endpoints are available at
http://127.0.0.1:47733when the local API is enabled in preferences - Six endpoints cover health checks, history queries, dictionary management, transcription, and AI post-processing
- All traffic is restricted to the loopback interface for security
- Default port 47733 can be customized via
LocalAPIPortuser defaults - Request/response models and routing logic are fully contained in
Sources/Fluid/Services/LocalAPI/
Frequently Asked Questions
How do I enable the FluidVoice API?
Open FluidVoice Settings and check "Enable Local API". The server starts automatically on port 47733. You can verify it's running with curl http://127.0.0.1:47733/v1/health.
Can I access the FluidVoice API from another computer on my network?
No. The server explicitly binds to 127.0.0.1 and rejects any connection not originating from the local machine. This is hardcoded in LocalAPIServer.swift and cannot be overridden through configuration.
What audio formats does the /v1/transcribe endpoint accept?
The endpoint accepts three input methods: a local file path (string), base64-encoded audio data, or raw audio bytes in the request body. Supported formats depend on the underlying macOS speech recognition framework—typically WAV and CAF work reliably.
How do I change the default API port?
Set the LocalAPIPort value in user defaults before starting the server, or programmatically configure LocalAPI.Configuration.current with your preferred port number before calling LocalAPIServer.shared.start().
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →