Skip to content

Local API

Experimental

The local HTTP API is experimental. The API design may change in future releases.

The local API allows other applications to send audio files to Murmure for transcription without using the GUI.

Quick Start

  1. Open Murmure
  2. Go to Settings > System
  3. Find Local API (Experimental) and toggle it ON
  4. The API starts on http://localhost:4800
  5. (Optional) Change the port if needed

The API runs as long as Murmure is open.

Endpoint

POST http://localhost:4800/api/transcribe

Send a multipart form with a WAV file:

curl -X POST http://127.0.0.1:4800/api/transcribe \
  -F "audio=@recording.wav" \
  | jq '.text'

Response

Success (200):

{
    "text": "Hello everyone, here is the complete transcript..."
}

Error (4xx/5xx):

{
    "error": "Error message describing what went wrong"
}

Code Examples

import requests

with open('audio.wav', 'rb') as f:
    response = requests.post(
        'http://localhost:4800/api/transcribe',
        files={'audio': f}
    )
    print(response.json()['text'])
const fs = require('fs');
const FormData = require('form-data');
const axios = require('axios');

const form = new FormData();
form.append('audio', fs.createReadStream('recording.wav'));

const response = await axios.post(
  'http://localhost:4800/api/transcribe',
  form,
  { headers: form.getHeaders() }
);
console.log(response.data.text);
curl -X POST http://localhost:4800/api/transcribe \
  -F "audio=@recording.wav" \
  | jq '.text'

Limitations

Constraint Value
Audio format WAV only
Max file size 100 MB
Audio length No limit, only the 100 MB file size applies
Cancellation Close the connection. Stops at the end of the current audio segment
Optimal sample rate 16kHz mono (others are resampled)
Real-time streaming Not supported
Concurrent requests Sequential only (queued). A cancelled request frees its slot once it has actually stopped
Network access localhost / 127.0.0.1 only
CORS Disabled

Notes

  • The custom dictionary is automatically applied to API transcriptions
  • Language is auto-detected (no way to force a language)
  • The first request is slower (model warmup)
  • The port can be configured between 1024 and 65535
  • Long audio is split into segments before transcription, the same way the keyboard shortcut and the CLI do it. There is no duration limit.
  • The response is synchronous. A long file keeps the connection open for several minutes, so disable the timeout in your HTTP client or set it well above the expected duration: a timeout that fires cancels the transcription.
  • Filler removal and formatting rules are applied to the result, so the API returns the same text as the keyboard shortcut for the same audio.