Hinweis
Nur lokal: Der Server ist standardmäßig deaktiviert und bindet ausschließlich an 127.0.0.1. Leite ihn nicht über einen Proxy weiter und stelle ihn nicht in einem öffentlichen Netzwerk bereit.
Einrichtung und Authentifizierung
Aktiviere den API-Server unter Einstellungen > Erweitert. Der Standard-Port ist 8978. Solange der Server läuft, schreibt TypeWhisper den aktiven Port und ein generiertes Token nach ~/Library/Application Support/TypeWhisper/api-discovery.json.
Ab TypeWhisper 1.8 verlangt der API-Server standardmäßig das Token: Sende das Discovery-Token bei jedem Endpunkt außer GET /v1/status als Bearer-Token. War der API-Server beim Update auf 1.8 ohne Token eingeschaltet, funktioniert er weiter ohne, bis du „Require API Token“ einschaltest; bis dahin zeigen die Einstellungen eine Warnung. Einstellungen > Erweitert > „API-Token kopieren“ legt das Token in die Zwischenablage. Übergib das Token wie unten gezeigt über eine Header-Datei, nicht auf der Kommandozeile: macOS zeigt die Kommandozeilen laufender Programme allen Benutzern des Mac, und mktemp legt eine Datei an, die nur du lesen kannst. Das Beispiel läuft in einer Subshell, deren trap die Datei danach löscht. Die übrigen Beispiele lassen den Token-Header der Kürze halber weg: Lege die Header-Datei genauso an und ergänze bei jedem Request außer GET /v1/status -H @"$AUTH_HEADER".
DISCOVERY="$HOME/Library/Application Support/TypeWhisper/api-discovery.json"
export TYPEWHISPER_API_PORT="$(jq -r '.port' "$DISCOVERY")"
(
AUTH_HEADER="$(mktemp)" || exit
trap 'rm -f "$AUTH_HEADER"' EXIT
jq -r '"Authorization: Bearer " + .token' "$DISCOVERY" > "$AUTH_HEADER"
curl "http://127.0.0.1:$TYPEWHISPER_API_PORT/v1/models" -H @"$AUTH_HEADER"
)GET /v1/status bleibt für Bereitschaftsprüfungen öffentlich. Clients können dasselbe Token alternativ im X-TypeWhisper-API-Token Header senden.
Die Discovery-Datei wird mit ausschließlich für den Besitzer gesetzten Rechten (0600) angelegt und beim Stoppen des Servers entfernt. Die TypeWhisper-CLI erkennt Port und Token automatisch. Mit --port, --api-token und TYPEWHISPER_API_TOKEN kannst du sie explizit überschreiben.
Ab TypeWhisper 1.8 beantwortet der Server unabhängig vom Token Requests, die Browser im Auftrag anderer Websites senden, mit 403. Das betrifft Requests mit einem Host-Header außer 127.0.0.1, localhost oder [::1], mit einem Origin einer Website, die nicht von diesem Mac stammt (auch null), oder mit Sec-Fetch-Site: cross-site, sofern der Origin keine Seite von diesem Mac ist. Requests ohne diese Header, etwa von curl oder Skripten, sind nicht betroffen.
Endpunkt-Referenz
Die folgenden Tabellen ordnen die dokumentierten Routen der macOS-Implementierung nach Zweck, einschließlich der beiden Legacy-Aliase unter /v1/profiles und der Einstellungs-Backup-Routen.
Status, Modelle und Transkription
| Methode | Endpunkt | Zweck |
|---|---|---|
| GET | /v1/status | Meldet Bereitschaft, gewählte Engine und Modell, API-Version sowie Funktionsmerkmale. |
| GET | /v1/models | Listet alle von geladenen Transkriptions-Engines bereitgestellten Modelle und ihren aktuellen Zustand auf. |
| POST | /v1/models/load | Lädt ein Modell bei Bedarf herunter, lädt es und wählt es für die Transkription aus. |
| POST | /v1/models/unload | Entlädt das aktive Modell einer Engine und behält die heruntergeladenen Dateien. |
| DELETE | /v1/models | Löscht die heruntergeladenen Dateien eines Modells. |
| POST | /v1/transcribe | Transkribiert Multipart- oder Raw-Audio mit optionaler Sprache, Engine, Modell, Übersetzung, Prompt und Korrektursteuerung. |
| POST | /v1/transcribe/local-file | Transkribiert einen absoluten, für die laufende Mac-App erreichbaren Dateipfad. Die CLI vermeidet damit Uploads lokaler Dateien. |
Verlauf, Wörterbuch und Einstellungen
| Methode | Endpunkt | Zweck |
|---|---|---|
| GET | /v1/history | Durchsucht und paginiert den Transkriptionsverlauf. |
| DELETE | /v1/history | Löscht einen Verlaufseintrag per UUID. |
| PUT | /v1/history/speakers/name | Setzt den Namen eines Sprechers in einem Sprechertranskript des Verlaufs. Verfügbar ab TypeWhisper 1.8. |
| POST | /v1/history/speakers/enroll | Speichert die Stimme eines benannten Sprechers in einem Sprecherprofil, damit TypeWhisper sie wiedererkennt. Setzt Premium voraus. Verfügbar ab TypeWhisper 1.8. |
| POST | /v1/history/speakers/confirm | Bestätigt den Namen, den ein Sprecherprofil für einen Sprecher vorgeschlagen hat. Setzt Premium voraus. Verfügbar ab TypeWhisper 1.8. |
| GET | /v1/dictionary/terms | Listet aktive Erkennungsbegriffe und optionale CTC-Ähnlichkeitsschwellen auf. |
| PUT | /v1/dictionary/terms | Führt Erkennungsbegriffe zusammen oder ersetzt sie vollständig. |
| DELETE | /v1/dictionary/terms | Löscht einen Erkennungsbegriff. |
| GET | /v1/dictionary/corrections | Listet nachträgliche Wörterbuchkorrekturen auf. |
| PUT | /v1/dictionary/corrections | Ergänzt oder aktualisiert eine Wörterbuchkorrektur. |
| DELETE | /v1/dictionary/corrections | Löscht eine Wörterbuchkorrektur anhand ihres Originaltexts. |
| GET | /v1/settings/export | Exportiert das vollständige JSON-Dokument eines Einstellungs-Backups. |
| POST | /v1/settings/import | Importiert ein Einstellungs-Backup und liefert eine maschinenlesbare Zusammenfassung übernommener und übersprungener Daten. |
| GET | /v1/settings/audio | Liest die Mikrofon-Priorität, die angeschlossenen Eingabegeräte und die Audiooptionen für Aufnahmen. Verfügbar ab TypeWhisper 1.8. |
| PATCH | /v1/settings/audio | Ändert die Mikrofon-Priorität und die Audiooptionen für Aufnahmen. Verfügbar ab TypeWhisper 1.8. |
Workflows, Diktat und Recorder
| Methode | Endpunkt | Zweck |
|---|---|---|
| GET | /v1/rules | Listet Workflow-basierte Automatisierungsregeln auf. |
| PUT | /v1/rules/toggle | Schaltet eine Workflow-basierte Regel per UUID um. |
| GET | /v1/profiles | Legacy-Alias für GET /v1/rules. |
| PUT | /v1/profiles/toggle | Legacy-Alias für PUT /v1/rules/toggle. |
| POST | /v1/dictation/start | Startet das systemweite Diktat und erzwingt optional einen aktiven Workflow. |
| POST | /v1/dictation/stop | Stoppt die aktive API-Diktatsitzung. |
| GET | /v1/dictation/status | Meldet den laufenden Diktatzustand, das Modell und den aktiven Workflow. |
| GET | /v1/dictation/transcription | Fragt eine Diktatsitzung bis zum Abschluss, Transkript oder Fehler ab. |
| PUT | /v1/browser/context | Meldet den aktiven Browser-Tab aus einer Browser-Erweiterung, damit Website-Workflows greifen. Verfügbar ab TypeWhisper 1.8. |
| POST | /v1/recorder/start | Startet den Recorder mit optionalen Vorgaben für Mikrofon und Systemaudio. |
| POST | /v1/recorder/stop | Stoppt die aktive API-Recorder-Sitzung und beginnt ihre Finalisierung. |
| GET | /v1/recorder/status | Meldet, ob der Recorder gerade aufnimmt. |
| GET | /v1/recorder/session | Fragt Status, Text, Ausgabedatei oder Fehler einer Recorder-Sitzung ab. |
| GET | /v1/recorder/recordings | Listet das zuletzt gespeicherte Transkript jeder Aufnahme auf, gefiltert nach dem Zeitpunkt der Speicherung. Verfügbar ab TypeWhisper 1.8. |
Textverarbeitung
| Methode | Endpunkt | Zweck |
|---|---|---|
| GET | /v1/llm/models | Listet die Sprachmodelle dieses Macs auf und zeigt, ob sie bereit sind. Verfügbar ab TypeWhisper 1.8. |
| POST | /v1/llm/process | Verarbeitet Text mit einem Sprachmodell und deinem eigenen System-Prompt. Verfügbar ab TypeWhisper 1.8. |
| GET | /v1/workflows | Listet die aktiven Workflows auf, die Text ohne Textfeld verarbeiten können. Verfügbar ab TypeWhisper 1.8. |
| POST | /v1/workflows/run | Wendet einen Workflow auf Text an und liefert das Ergebnis, ohne es einzufügen. Verfügbar ab TypeWhisper 1.8. |
Status prüfen
curl http://localhost:8978/v1/status{
"status": "ready",
"engine": "whisper",
"model": "openai_whisper-large-v3_turbo",
"api_version": "1.2",
"supports_workflow_dictation": true,
"supports_streaming": true,
"supports_translation": true,
"supports_browser_context": true,
"capabilities": ["transcribe", "llm", "workflows"],
"remote_writing_allowed": false
}status ist ready, wenn das gewählte Modell transkribieren kann, andernfalls no_model. Die Funktionsfelder beschreiben die aktuell gewählte Engine. Ohne Auswahl entfallen die optionalen Felder engine und model.
Ab TypeWhisper 1.8 enthält die Antwort außerdem supports_browser_context, das immer true ist und einer Browser-Erweiterung zeigt, dass sie den aktiven Tab melden kann, capabilities mit transcribe, llm und workflows sowie remote_writing_allowed, das angibt, ob gekoppelte iPhones und iPads die Routen zur Textverarbeitung nutzen dürfen.
Audio transkribieren
curl -X POST http://localhost:8978/v1/transcribe \
-F "file=@recording.wav" \
-F "language_hint=de" \
-F "language_hint=en" \
-F "response_format=verbose_json"{
"text": "Hello, world!",
"language": "en",
"duration": 2.5,
"processing_time": 0.8,
"engine": "whisper",
"model": "openai_whisper-large-v3_turbo",
"segments": [
{ "start": 0, "end": 2.5, "text": "Hello, world!" }
]
}Hinweis
Upload-Limit: Multipart- und Raw-Body-Uploads an /v1/transcribe sind auf 256 MiB begrenzt. Größere Requests liefern 413 Payload Too Large. Die macOS-CLI nutzt für Dateipfade die Local-File-Route, während stdin weiterhin diesem Limit unterliegt.
Multipart-Parameter
language– Ein exakter Sprachcode wie en oder de. Für die automatische Erkennung weglassen und nicht mit language_hint kombinieren.language_hint– Eine wiederholbare, geordnete Vorauswahl für die eingeschränkte automatische Erkennung. Engines mit Hint-Unterstützung erhalten die ganze Liste, andere verwenden den ersten Eintrag.task– transcribe (Standard) oder translate. translate übersetzt ins Englische und setzt WhisperKit voraus.target_language– Ein Zielsprachcode für einen separaten Apple-Translate-Schritt. Dafür ist macOS 15 oder neuer erforderlich.response_format– json (Standard) oder verbose_json. Die ausführliche Ausgabe ergänzt Segmente mit Zeitstempeln und optionale Sprecher-Metadaten, sofern die Engine sie liefert.prompt– Ein transkriptionsspezifischer Prompt für diesen Request. TypeWhisper kombiniert ihn mit aktiven Wörterbuchbegriffen.engine/model– Engine- und Modellüberschreibungen für diesen Request. Ein Modell ohne Engine wird nur dann zugeordnet, wenn genau eine Engine diese ID anbietet.normalize_numbers– Eine boolesche Überschreibung für die Normalisierung gesprochener Zahlen.apply_corrections– Ein boolescher Wert, standardmäßig true. false liefert die rohe Engine-Ausgabe ohne nachträgliche Wörterbuchkorrekturen. Ab TypeWhisper 1.8 gelten die Korrekturen auch für die Segmente einerverbose_json-Antwort.detect_speakers– Verfügbar ab TypeWhisper 1.8. Ein boolescher Wert, standardmäßigfalse.trueergänzt in einerverbose_json-Antwort bei jedem Segment den Sprecher und setzt Premium voraus; siehe Sprechererkennung unten.speaker_count– Verfügbar ab TypeWhisper 1.8. Die Anzahl der Sprecher von 2 bis 8, wenn du sie kennst. Ohne sie ermittelt TypeWhisper die Anzahl. Wirkt nur zusammen mitdetect_speakers.?await_download=1– Wartet bei einer nicht eingerichteten lokalen Engine auf Wiederherstellung oder Modelldownload, statt sofort 409 zurückzugeben.
Bei Raw-Body-Uploads leitet TypeWhisper das Audioformat aus Content-Type ab. Optionen werden über die entsprechenden Header X-Language, X-Language-Hints, X-Task, X-Target-Language, X-Response-Format, X-Prompt, X-Engine, X-Model, X-Normalize-Numbers und X-Apply-Corrections übergeben. Ab TypeWhisper 1.8 setzen X-Detect-Speakers und X-Speaker-Count die Optionen der Sprechererkennung.
POST /v1/transcribe/local-file akzeptiert einen JSON-Body mit einem absoluten Pfad und denselben Optionen in snake_case. Die Route ist nur für Dateien sinnvoll, die der lokale TypeWhisper-Prozess lesen kann, und ist keine Remote-Datei-API.
Sprechererkennung
Verfügbar ab TypeWhisper 1.8.
Mit detect_speakers=true ermittelt TypeWhisper, wer wann gesprochen hat, und ergänzt in einer verbose_json-Antwort bei jedem Segment speaker (Speaker 1, Speaker 2, …) und, falls vorhanden, speaker_confidence von 0 bis 1. Der Text bleibt gleich. Die Sprechererkennung gehört zu Premium und läuft mit dem Plugin „Speaker Detection“ auf diesem Mac. Hat die Engine die Segmente schon Sprechern zugeordnet, behält TypeWhisper deren Angaben, sofern du kein speaker_count übergibst. POST /v1/transcribe/local-file akzeptiert detect_speakers und speaker_count in seinem JSON-Body. Nutze es mit response_format=verbose_json; bei anderen Formaten läuft die Sprechererkennung trotzdem, die Antwort zeigt sie aber nicht.
curl -X POST http://localhost:8978/v1/transcribe \
-F "file=@interview.m4a" \
-F "response_format=verbose_json" \
-F "detect_speakers=true" \
-F "speaker_count=2"{
"text": "How did the launch go? Better than we expected.",
"language": "en",
"duration": 5.8,
"processing_time": 2.1,
"engine": "parakeet",
"model": "parakeet-tdt-0.6b-v3",
"segments": [
{
"start": 0,
"end": 1.9,
"text": "How did the launch go?",
"speaker": "Speaker 1",
"speaker_confidence": 1
},
{
"start": 2.3,
"end": 5.8,
"text": "Better than we expected.",
"speaker": "Speaker 2",
"speaker_confidence": 1
}
]
}Ohne Premium antwortet die API mit 403, mit 503, wenn die Sprechererkennung nicht verfügbar ist, etwa weil das Plugin „Speaker Detection“ ausgeschaltet ist, und mit 422, wenn die Engine keine Zeitstempel geliefert hat. Ein ungültiger Wert für detect_speakers oder ein speaker_count außerhalb von 2 bis 8 ergibt 400. Fehlen die Modelle der Sprechererkennung, lädt der erste Request sie herunter; lassen verwaltete Einstellungen keine Modell-Downloads zu, antwortet die API mit 403.
Modelle auflisten
curl http://localhost:8978/v1/models{
"models": [
{
"id": "openai_whisper-large-v3_turbo",
"engine": "whisper",
"engine_name": "WhisperKit",
"name": "Large v3 Turbo",
"size_description": "~800 MB",
"language_count": 99,
"status": "ready",
"selected": true,
"downloaded": true,
"loaded": true
}
]
}status ist ready oder not_configured. selected kennzeichnet die aktuelle Auswahl in der Oberfläche. downloaded und loaded werden ausgegeben, wenn die Engine diese Zustände melden kann.
Ab TypeWhisper 1.8 enthält engine_name den Anzeigenamen der Engine, etwa WhisperKit für whisper.
Modelle laden, entladen und löschen
Übergib die Werte engine und id aus GET /v1/models als engine und model. POST /v1/models/load lädt das Modell bei Bedarf herunter, lädt es und wählt es für die Transkription aus. Die Antwort kommt, sobald das Modell bereit ist oder das Laden fehlgeschlagen ist; bei einem Download kann das bis zu zehn Minuten dauern.
curl -X POST http://localhost:8978/v1/models/load \
-H "Content-Type: application/json" \
-d '{"engine":"parakeet","model":"parakeet-tdt-0.6b-v3"}'
curl -X POST http://localhost:8978/v1/models/unload \
-H "Content-Type: application/json" \
-d '{"engine":"parakeet"}'
curl -X DELETE "http://localhost:8978/v1/models?engine=whisper&model=openai_whisper-large-v3_turbo"{
"engine": "parakeet",
"model": "parakeet-tdt-0.6b-v3",
"status": "ready"
}Jede Route liefert engine, model und status; status ist ready, unloaded oder deleted. POST /v1/models/unload erwartet nur engine, entlädt das Modell dieser Engine und behält die heruntergeladenen Dateien. model nennt das geladene Modell, sonst das ausgewählte Modell der Engine, und fehlt, wenn es keins von beiden gibt.
DELETE /v1/models erwartet engine und model als Query-Parameter und entfernt die heruntergeladenen Modelldateien. Das funktioniert nur bei Engines, deren Plugin seine Modelldownloads selbst verwaltet, etwa WhisperKit (whisper). Andere Engines, etwa Parakeet oder Cloud-Engines, antworten mit 409.
Ungültiges JSON oder ein fehlendes engine ergibt 400, bei Laden und Löschen auch ein fehlendes model. Eine unbekannte Engine oder ein Modell, das die Engine nicht anbietet, ergibt 404, ebenso das Löschen eines Modells, das nicht heruntergeladen ist. Mit 409 antworten die Routen, wenn die Engine die Aktion nicht ausführen kann, gerade beschäftigt ist oder das Laden des Modells fehlschlägt oder zu lange dauert. Cloud-Engines haben zum Beispiel kein lokales Modell, das sich entladen ließe.
Ab TypeWhisper 1.8 gilt: Erzwingen verwaltete Einstellungen eine Transkriptions-Engine und ein Modell, antwortet POST /v1/models/load für jede andere Engine und jedes andere Modell mit 403, ebenso wenn das erzwungene Paar auf diesem Mac nicht nutzbar ist.
Verlauf
curl "http://localhost:8978/v1/history?q=meeting&limit=10&offset=0"
curl -X DELETE "http://localhost:8978/v1/history?id=<uuid>"q ist optional. limit ist standardmäßig 50 und höchstens 200, offset standardmäßig 0. Ergebnisse enthalten finalen und rohen Text, ISO-8601-Zeitstempel, App-Kontext, Dauer, Sprache, Engine, Modell und Wortanzahl.
Sprecher und Recorder-Aufnahmen
Verfügbar ab TypeWhisper 1.8.
Einträge mit Sprechererkennung enthalten die folgenden Felder, und include=speaker_segments ergänzt ihre Segmente. Die Sprechererkennung gehört zu Premium. Felder, die auf einen Eintrag nicht zutreffen, fehlen.
curl "http://localhost:8978/v1/history?limit=10&include=speaker_segments"{
"entries": [
{
"id": "0B7A3C1E-2F4D-4E8A-9C61-3D5E7F9A1B2C",
"text": "Let's start with the roadmap. Sounds good to me.",
"raw_text": "Let's start with the roadmap. Sounds good to me.",
"timestamp": "2026-10-14T09:30:12Z",
"app_name": "Weekly Sync",
"duration": 6.1,
"language": "en",
"engine": "parakeet",
"model": "parakeet-tdt-0.6b-v3",
"words_count": 9,
"recording_id": "8F8C1F45-6D03-44D2-A38C-0C4DE4F7E5F7",
"speaker_state": "ready",
"transcript_revision": "6E2F8A4C-1B3D-4C5E-8F7A-9B0C1D2E3F4A",
"transcript_version": "f74d369e3227eb16d6374c3f0f6fbccdfec89351fc3ef4023182bb86ec8ff7d6",
"speakers": [
{
"id": "S1",
"name": "Lev",
"profile_id": "D3B07384-D113-4EC6-A3B0-1F2E3D4C5B6A",
"voice_state": "linked"
},
{
"id": "S2",
"name": "Speaker 2",
"suggested_name": "Mira",
"profile_id": "A1F2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D",
"voice_state": "suggestion"
}
],
"speaker_segments": [
{
"start": 0,
"end": 2.4,
"speaker": "S1",
"text": "Let's start with the roadmap."
},
{
"start": 2.9,
"end": 6.1,
"speaker": "S2",
"text": "Sounds good to me."
}
]
}
],
"total": 1,
"limit": 10,
"offset": 0
}| Feld | Beschreibung |
|---|---|
recording_ | Nur bei Einträgen, die der Recorder für die Sprechererkennung gespeichert hat: dieselbe recording_id wie in GET /v1/recorder/recordings und im Abschlussbeleg .transcript-ready.json der Aufnahme. Sie bleibt nach einer erneuten Transkription gleich. Auf andere Macs synchronisierte Kopien des Eintrags haben sie nicht. |
speaker_ | pending, ready oder failed. |
transcript_ | Kennzeichnet den Lauf der Sprechererkennung. Eine erneute Erkennung erzeugt eine neue Revision. |
transcript_ | Ändert sich bei jeder Korrektur von Sprechern oder Text des Transkripts, etwa beim Zusammenführen, Teilen oder Neuzuordnen von Sprechern, auch innerhalb derselben Revision. |
speakers | Vorhanden, sobald ein Sprechertranskript existiert, in der Reihenfolge des ersten Auftretens. Jeder Sprecher hat id (S1, S2, …), name und voice_state sowie profile_id, wenn ein Sprecherprofil verknüpft oder vorgeschlagen ist. name ist der bestätigte Name oder Speaker N. Einen Namen, den ein Sprecherprofil vorgeschlagen und noch niemand bestätigt hat, enthält suggested_name; name bleibt dann Speaker N. |
speaker_ | Nur mit include=speaker_segments: die Segmente mit start und end in Sekunden, speaker (die id des Sprechers) und text. |
voice_state hat einen dieser Werte:
| Wert | Bedeutung |
|---|---|
none | Kein Sprecherprofil ist verknüpft, und noch lässt sich keines anlegen: Der Sprecher hat keinen Namen, mehrere Sprecherprofile tragen diesen Namen, es gibt weniger als 20 Sekunden Sprechzeit, oder diesem Mac fehlt eine aktuelle Stimmprobe oder Premium. |
canEnroll | Der Sprecher hat einen Namen und mindestens 20 Sekunden Sprechzeit, und dieser Mac hat eine aktuelle Stimmprobe: Du kannst ein Sprecherprofil anlegen. Nur mit Premium. |
suggestion | Ein Sprecherprofil hat den Namen in suggested_name vorgeschlagen, und er wartet auf Bestätigung. |
linked | Der Sprecher ist mit dem Sprecherprofil in profile_id verknüpft. |
outdated | Das verknüpfte Sprecherprofil wurde mit einem älteren Sprechermodell gelernt und erkennt niemanden, bis du in der App „Stimme aus dieser Aufnahme neu lernen“ wählst. Nur mit Premium und einer aktuellen Stimmprobe, sonst zeigt der Sprecher linked. |
Sprecher benennen und Sprecherprofile anlernen
Verfügbar ab TypeWhisper 1.8.
Mit drei Routen kann ein Skript die Sprecher eines Verlaufseintrags benennen und TypeWhisper ihre Stimmen beibringen, etwa nachdem es die Sprecher eines Meetings den Teilnehmenden zugeordnet hat. Sie verlangen immer das API-Token, auch wenn „Require API Token“ ausgeschaltet ist, und gekoppelte iPhones und iPads können sie nicht aufrufen. Einen Namen setzt du auch ohne Premium. Ein Sprecherprofil anzulernen und einen Vorschlag zu bestätigen setzt Premium voraus, außerdem eine aktuelle Stimmprobe des Sprechers auf diesem Mac und mindestens 20 Sekunden seiner Sprechzeit. Audio oder Stimmdaten nehmen die Routen nie an und geben sie nie zurück.
Sprecherprofile bleiben auf diesem Mac. Sie werden nicht synchronisiert, exportiert oder in Backups aufgenommen. Hol dir wie in der App das Einverständnis der Person, bevor du ihre Stimme speicherst.
- Lies den Eintrag mit
GET /v1/history. Bei einer Recorder-Aufnahme nimmst du den Eintrag mit der passendenrecording_id. Warte, bisspeaker_stateden Wertreadyhat, und brich beifailedab. Merk dirid,transcript_revisionundtranscript_versiondes Eintrags und dieiddes gemeinten Sprechers. PUT /v1/history/speakers/namesetzt den Namen des Sprechers in diesem Transkript. Ein Sprecherprofil lernt dabei nie etwas, auch wenn der Name zu einem Vorschlag passt. Ein anderer Name löst die Verknüpfung mit dem Sprecherprofil; ändern sich nur Groß- und Kleinschreibung oder Akzente, bleibt sie bestehen. Bei einem Sprecher mit Vorschlag verwirft jeder Name den Vorschlag; zum Annehmen nutzt duconfirm.POST /v1/history/speakers/enrollfügt die Stimme des benannten Sprechers einem Sprecherprofil hinzu: dem inprofile_id, wenn du eines angibst, sonst dem bereits verknüpften Profil oder einem neuen Profil, wenn noch keines diesen Namen trägt. Gibt es schon Sprecherprofile mit diesem Namen, antwortet die API mit 409profile_name_existsund nennt ihre IDs inerror.profile_ids. Schick eine davon alsprofile_idodercreate_profile: true, um ein Profil für eine andere Person mit demselben Namen anzulegen. Der Name des Profils muss zum Namen des Sprechers passen.POST /v1/history/speakers/confirmbestätigt einen Vorschlag: Schick dieprofile_id, die der Sprecher mitvoice_statesuggestionträgt. TypeWhisper übernimmt dann den vorgeschlagenen Namen und fügt die Stimme diesem Profil hinzu.
DISCOVERY="$HOME/Library/Application Support/TypeWhisper/api-discovery.json"
SPEAKERS_URL="http://127.0.0.1:$(jq -r '.port' "$DISCOVERY")/v1/history/speakers"
(
AUTH_HEADER="$(mktemp)" || exit
trap 'rm -f "$AUTH_HEADER"' EXIT
jq -r '"Authorization: Bearer " + .token' "$DISCOVERY" > "$AUTH_HEADER"
curl -X PUT "$SPEAKERS_URL/name" \
-H @"$AUTH_HEADER" \
-H "Content-Type: application/json" \
-d '{"history_id":"<history-uuid>","transcript_revision":"<revision-uuid>","transcript_version":"<version>","speaker_id":"S1","name":"Lev"}'
curl -X POST "$SPEAKERS_URL/enroll" \
-H @"$AUTH_HEADER" \
-H "Content-Type: application/json" \
-d '{"history_id":"<history-uuid>","transcript_revision":"<revision-uuid>","transcript_version":"<version>","speaker_id":"S1"}'
curl -X POST "$SPEAKERS_URL/confirm" \
-H @"$AUTH_HEADER" \
-H "Content-Type: application/json" \
-d '{"history_id":"<history-uuid>","transcript_revision":"<revision-uuid>","transcript_version":"<version>","speaker_id":"S2","profile_id":"<profile-uuid>"}'
)Felder des Requests
| Feld | Beschreibung |
|---|---|
history_ | Die id des Verlaufseintrags, nicht die recording_id des Recorders. |
transcript_, transcript_ | Die Werte, die du gelesen hast. Hat sich das Transkript seitdem geändert, antwortet die API mit 409 stale_transcript. |
speaker_ | Die id des Sprechers, etwa S1. |
name | Nur bei name und dort Pflicht: 1 bis 100 Zeichen ohne Steuerzeichen. |
profile_ | Bei enroll optional: das Profil, dem die Stimme hinzugefügt wird. Bei confirm Pflicht: das vorgeschlagene Profil. |
create_ | Nur bei enroll: true legt ein neues Profil an, obwohl es Profile mit diesem Namen gibt. Nicht zusammen mit profile_id verwenden. |
Schick ein JSON-Objekt von höchstens 16 KiB, das nur diese Felder enthält. Jede erfolgreiche Antwort beschreibt den aktuellen Zustand des Sprechers:
{
"history_id": "0B7A3C1E-2F4D-4E8A-9C61-3D5E7F9A1B2C",
"transcript_revision": "6E2F8A4C-1B3D-4C5E-8F7A-9B0C1D2E3F4A",
"transcript_version": "f74d369e3227eb16d6374c3f0f6fbccdfec89351fc3ef4023182bb86ec8ff7d6",
"speaker_id": "S1",
"name": "Lev",
"profile_id": "D3B07384-D113-4EC6-A3B0-1F2E3D4C5B6A",
"voice_state": "linked",
"already_learned": false
}already_learned ist true, wenn das Profil diese Stimmprobe schon enthielt. Anlernen und Bestätigen zählen jede Probe nur einmal pro Profil. Du kannst einen Request also wiederholen, auch nach einem Neustart, ohne dass sie doppelt zählt.
Fehler
| Status und Code | Bedeutung |
|---|---|
400 bad_ | Der Body ist kein JSON-Objekt, hat andere Felder, ihm fehlt ein Pflichtfeld, er enthält eine ungültige UUID, oder er kombiniert create_profile mit profile_id. |
400 invalid_ | Der Name ist leer, länger als 100 Zeichen oder enthält Steuerzeichen. |
401 unauthorized | Der Request enthält kein gültiges API-Token. |
403 premium_ | enroll oder confirm ohne Premium. |
404 history_, speaker_ | Der Verlaufseintrag existiert nicht, oder der Sprecher gehört nicht zu seinem Transkript. |
409 speakers_ | Die Sprechererkennung ist noch nicht fertig oder fehlgeschlagen, oder der Eintrag hat keine Sprechererkennung. |
409 stale_ | Das Transkript hat sich geändert, seit du es gelesen hast. Lies den Eintrag neu und prüfe, wer der Sprecher ist, bevor du es erneut versuchst. |
409 profile_ | Es gibt Sprecherprofile mit diesem Namen; error.profile_ids listet sie auf. |
409 profile_ | Der Name des Sprechers passt nicht zum Namen des angefragten Profils. |
409 confirmation_, suggestion_ | enroll: Der Sprecher hat einen unbestätigten Vorschlag; bestätige ihn oder setze zuerst einen Namen. confirm: Der Sprecher hat diesen Vorschlag nicht mehr. |
409 sample_ | Diese Stimmprobe wurde schon ganz oder teilweise gelernt. Korrigiere das Profil in der App. |
409 stale_ | Die Stimmproben auf diesem Mac passen nicht zum Transkript. Lass die Sprecher erneut erkennen. |
409 profile_ | Das angefragte oder früher gelernte Profil wurde gelöscht. Wiederholungen legen es nicht neu an. |
409 profile_ | Das Profil wurde mit einem älteren Sprechermodell gelernt. Lerne es in der App neu. |
413 payload_ | Der Body ist größer als 16 KiB. |
422 name_ | enroll: Benenne den Sprecher zuerst. |
422 voice_, invalid_ | Dieser Mac hat keine brauchbare Stimmprobe des Sprechers oder weniger als 20 Sekunden seiner Sprechzeit. |
500 history_, speaker_ | Die Änderung ließ sich nicht speichern oder zurücklesen. Wiederhole denselben Request. |
Sprecher-IDs sind Bezeichnungen der Erkennung, keine Audiokanäle: S1 ist nicht unbedingt das Mikrofon. Prüfe, welcher Sprecher die gemeinte Person ist, etwa an dem, was sie sagt, statt dich auf die Reihenfolge oder die Einladungsliste zu verlassen. Ein neuer Name macht nicht rückgängig, was ein Profil gelernt hat; um ein Profil zu korrigieren, wähle in der App „Stimme aus dieser Aufnahme neu lernen“ oder lösche das Profil.
Wörterbuch
Erkennungsbegriffe beeinflussen die Transkription. Wörterbuchkorrekturen laufen danach und ersetzen passende Texte, sofern apply_corrections nicht false ist.
curl http://localhost:8978/v1/dictionary/terms
curl -X PUT http://localhost:8978/v1/dictionary/terms \
-H "Content-Type: application/json" \
-d '{"term_entries":[{"term":"TypeWhisper","ctc_min_similarity":0.65}],"replace":false}'
curl -X DELETE http://localhost:8978/v1/dictionary/terms \
-H "Content-Type: application/json" \
-d '{"term":"TypeWhisper"}'Für einfache Begriffe genügt ein String-Array unter terms. Für Parakeet-CTC-Tuning verwendest du term_entries mit optionalem ctc_min_similarity. replace: true ersetzt alle vorhandenen Erkennungsbegriffe, andernfalls werden die Einträge zusammengeführt.
curl http://localhost:8978/v1/dictionary/corrections
curl -X PUT http://localhost:8978/v1/dictionary/corrections \
-H "Content-Type: application/json" \
-d '{"original":"teh","replacement":"the","caseSensitive":false}'
curl -X DELETE http://localhost:8978/v1/dictionary/corrections \
-H "Content-Type: application/json" \
-d '{"original":"teh"}'Ab TypeWhisper 1.8 kann eine Wörterbuchkorrektur ein regulärer Ausdruck sein. Antworten zu Korrekturen enthalten isRegex. Mit isRegex: true bei PUT oder DELETE sprichst du einen regulären Ausdruck an; fehlt das Feld, eine wörtliche Korrektur. Ein regulärer Ausdruck wird an seinem genauen Text erkannt, einschließlich Groß- und Kleinschreibung und Leerzeichen; er kann daher neben einer wörtlichen Korrektur mit demselben Text bestehen. Um eine Korrektur zwischen beiden Arten umzustellen, löschst du sie und legst sie neu an. Ein ungültiges Muster ergibt 400. caseSensitive gilt auch für reguläre Ausdrücke. Die Ersetzung ist wörtlich, bis auf \, \, \, \ (ein Leerzeichen) und \; $1 verweist nicht auf eine Gruppe des Treffers.
curl -X PUT http://localhost:8978/v1/dictionary/corrections \
-H "Content-Type: application/json" \
-d '{"original":"type ?whisper","replacement":"TypeWhisper","isRegex":true}'Einstellungs-Backup: API und CLI
Die API verwendet dasselbe Schema wie Einstellungen > Erweitert > Sicherung & Wiederherstellung. Der Export enthält alle unterstützten Kategorien: Workflows, Wörterbucheinträge, Snippets, Prompt-Aktionen, Profile, Hotkeys, nicht gebündelte Plugins, Verlauf, Update-Kanal und Einstellungen.
DISCOVERY="$HOME/Library/Application Support/TypeWhisper/api-discovery.json"
TYPEWHISPER_API_PORT="$(jq -r '.port' "$DISCOVERY")"
(
AUTH_HEADER="$(mktemp)" || exit
settings_backup_tmp="$(mktemp ./typewhisper-settings.json.tmp.XXXXXX)" || exit
trap 'rm -f "$AUTH_HEADER" "$settings_backup_tmp"' EXIT
jq -r '"Authorization: Bearer " + .token' "$DISCOVERY" > "$AUTH_HEADER"
curl --fail --silent --show-error \
"http://localhost:$TYPEWHISPER_API_PORT/v1/settings/export" \
-H @"$AUTH_HEADER" \
--output "$settings_backup_tmp" &&
mv "$settings_backup_tmp" typewhisper-settings.json &&
curl --fail --silent --show-error -X POST \
"http://localhost:$TYPEWHISPER_API_PORT/v1/settings/import" \
-H @"$AUTH_HEADER" \
-H "Content-Type: application/json" \
--data-binary @typewhisper-settings.json
)Der Import übernimmt alle Kategorien des Dokuments nach den Regeln zum Zusammenführen und Überspringen und löscht nichts. Der Ziel-Mac wird vorher nicht geleert: Doppelte Wörterbucheinträge und Snippets werden übersprungen, belegte Hotkey-Slots bleiben erhalten, nicht verfügbare oder bereits installierte Plugins werden übersprungen und Verlauf außerhalb der Aufbewahrungsfrist des Ziel-Macs wird ausgelassen. Ab TypeWhisper 1.8 überspringt der Import außerdem Workflows, Profile, Prompt-Aktionen und Verlaufseinträge, die unverändert vorhanden sind. Ein Backup auf den Mac zurückzuspielen, von dem es stammt, verdoppelt also nichts. Geänderte Einträge kommen als neue hinzu.
Ab TypeWhisper 1.8 überschreibt mode=replace zusätzlich den ersten Workflow, das erste Profil oder die erste Prompt-Aktion mit gleichem Namen sowie die Hotkey-Slots aus dem Backup, wie „Vorhandene Einträge ersetzen“ beim Import unter Einstellungen > Erweitert > Sicherung & Wiederherstellung. Profile behalten ihre Priorität und Workflows ihre Position. Standard ist mode=merge; jeder andere Wert ergibt 400.
curl -X POST "http://localhost:8978/v1/settings/import?mode=replace" \
-H "Content-Type: application/json" \
--data-binary @typewhisper-settings.jsonImport-Antwort
{
"workflowsImported": 4,
"workflowsUpdated": 0,
"workflowsSkipped": 1,
"dictionaryImported": 52,
"dictionarySkipped": 3,
"snippetsImported": 6,
"snippetsSkipped": 1,
"promptActionsImported": 2,
"promptActionsUpdated": 0,
"promptActionsSkipped": 0,
"profilesImported": 2,
"profilesUpdated": 0,
"profilesSkipped": 0,
"hotkeysApplied": 1,
"hotkeysSkipped": 1,
"pluginsInstalled": 2,
"pluginsSkipped": 1,
"pluginsRegistryFetchFailed": false,
"historyImported": 120,
"historySkippedByRetention": 8,
"historySkippedAsDuplicate": 0,
"historySkippedUnreadableDestination": 0,
"updateChannelApplied": true,
"preferencesApplied": 27
}Ab TypeWhisper 1.8 enthält die Antwort außerdem: workflowsUpdated, promptActionsUpdated und profilesUpdated für Einträge, die mode=replace überschrieben hat; workflowsSkipped, promptActionsSkipped und profilesSkipped für Einträge, die unverändert vorhanden waren; historySkippedAsDuplicate für Verlaufseinträge, die es auf diesem Mac schon gibt; und historySkippedUnreadableDestination für Verlaufseinträge, die ausgelassen wurden, weil sich der vorhandene Verlauf nicht auf Duplikate prüfen ließ.
CLI-Befehle
Installiere die CLI unter Einstellungen > Erweitert > Kommandozeilen-Tool. export schreibt das API-Backup atomar. import akzeptiert relative, absolute und mit Tilde abgekürzte Pfade. Mit --json erhältst du eine maschinenlesbare Exportbestätigung oder Importzusammenfassung. Ab TypeWhisper 1.8 importiert --replace mit mode=replace.
mkdir -p ~/.config/typewhisper
typewhisper export ~/.config/typewhisper/settings.json
typewhisper import ~/.config/typewhisper/settings.json
typewhisper import ~/.config/typewhisper/settings.json --json
typewhisper import ~/.config/typewhisper/settings.json --replaceEin Backup kann Transkriptionsverlauf, Prompts, App- und Website-Regeln sowie weitere persönliche Konfiguration enthalten. Prüfe es, bevor du es in ein Dotfiles-Repository eincheckst. Die Implementierung ergänzt explizite Import- und Exportbefehle, lädt aber nicht automatisch $XDG_CONFIG_HOME/typewhisper/config.toml.
Audioeinstellungen
Verfügbar ab TypeWhisper 1.8.
GET /v1/settings/audio liefert die Mikrofon-Priorität und die Audiooptionen für Aufnahmen aus Einstellungen > Diktat. PATCH /v1/settings/audio ändert beliebige davon auf demselben Weg wie das Einstellungsfenster: Die Änderung wird gespeichert, gilt ab der nächsten Aufnahme und erscheint auch in einem geöffneten Einstellungsfenster.
So kann ein Skript eine Zeit lang von einem anderen Eingang aufnehmen und danach deine Einrichtung wiederherstellen, etwa um Sprache zu diktieren, die eine andere App über das virtuelle Gerät BlackHole 2ch ausgibt. Den Standardeingang von macOS umzustellen, reicht dafür nicht: TypeWhisper nimmt vom ersten angeschlossenen Gerät seiner Mikrofon-Priorität auf und verwendet den macOS-Standardeingang nur, wenn keines dieser Geräte angeschlossen ist.
curl http://localhost:8978/v1/settings/audio
curl -X PATCH http://localhost:8978/v1/settings/audio \
-H "Content-Type: application/json" \
-d '{
"input_priority": [{ "id": "BlackHole2ch_UID", "name": "BlackHole 2ch" }],
"audio_ducking_enabled": false
}'
curl -X PATCH http://localhost:8978/v1/settings/audio \
-H "Content-Type: application/json" \
-d '{"input_priority":[]}'{
"input_devices": [
{
"id": "BuiltInMicrophoneDevice",
"name": "MacBook Pro Microphone",
"is_system_default": true
},
{
"id": "BlackHole2ch_UID",
"name": "BlackHole 2ch",
"is_system_default": false
}
],
"input_priority": [
{
"id": "AppleUSBAudioEngine:HyperX:QuadCast 2",
"name": "HyperX QuadCast 2"
}
],
"active_input": {
"id": "BuiltInMicrophoneDevice",
"name": "MacBook Pro Microphone"
},
"audio_ducking_enabled": true,
"audio_ducking_level": 0.2,
"pause_media_during_recording": false,
"sound_feedback_enabled": true
}Felder
| Feld | Beschreibung |
|---|---|
input_ | Schreibgeschützt. Die aktuell angeschlossenen Eingabegeräte, jeweils mit id (der CoreAudio-Geräte-UID), name und is_system_default. |
input_ | Die gespeicherte Mikrofon-Priorität, auch mit Geräten, die gerade nicht angeschlossen sind. Jeder Eintrag braucht eine id. name ist optional und wird durch den aktuellen Namen ersetzt, solange das Gerät angeschlossen ist. [] nimmt vom macOS-Standardeingang auf. |
active_ | Schreibgeschützt. Der Eingang, den die nächste Aufnahme verwendet: der erste angeschlossene Eintrag aus input_priority, sonst der macOS-Standardeingang. null, wenn kein Eingang verfügbar ist. |
audio_ | Die Systemlautstärke während der Aufnahme absenken. |
audio_ | Anteil der aktuellen Lautstärke, der während der Aufnahme erhalten bleibt, von 0 (stumm) bis 1. Der Regler in den Einstellungen bietet 0 bis 0,5. |
pause_ | Die Medienwiedergabe während der Aufnahme pausieren. |
sound_ | Töne abspielen, wenn die Aufnahme startet, die Transkription gelingt oder ein Fehler auftritt. |
Sende ein JSON-Objekt mit genau den Feldern, die du ändern willst. Ein erfolgreicher PATCH liefert den vollständigen Zustand im selben Format wie GET.
PATCH antwortet mit 400 und ändert nichts bei ungültigem JSON, einem Wert mit falschem Typ oder außerhalb des erlaubten Bereichs, einer leeren oder doppelten Geräte-ID, einem schreibgeschützten oder einem unbekannten Feld. Ein Feld, das nur eine andere TypeWhisper-Plattform unterstützt, gilt als unbekannt; die Fehlermeldung nennt dann die Felder, die macOS akzeptiert. Solange ein Diktat oder eine Recorder-Aufnahme läuft oder noch verarbeitet wird, antwortet PATCH mit 409 und ändert nichts. GET funktioniert weiterhin.
Einstellungen vorübergehend ändern
Speichere die Antwort von GET, bevor du etwas änderst. Zum Wiederherstellen schickst du sie ohne die schreibgeschützten Felder input_devices und active_input zurück. Warte damit, bis die Aufnahme verarbeitet ist, denn ein PATCH während Aufnahme oder Verarbeitung ergibt 409.
DISCOVERY="$HOME/Library/Application Support/TypeWhisper/api-discovery.json"
TYPEWHISPER_API_PORT="$(jq -r '.port' "$DISCOVERY")"
AUDIO_URL="http://localhost:$TYPEWHISPER_API_PORT/v1/settings/audio"
(
AUTH_HEADER="$(mktemp)" || exit
trap 'rm -f "$AUTH_HEADER"' EXIT
jq -r '"Authorization: Bearer " + .token' "$DISCOVERY" > "$AUTH_HEADER"
saved="$(curl --fail --silent --show-error "$AUDIO_URL" -H @"$AUTH_HEADER")" || exit
curl --fail --silent --show-error -X PATCH "$AUDIO_URL" \
-H @"$AUTH_HEADER" \
-H "Content-Type: application/json" \
-d '{
"input_priority": [{ "id": "BlackHole2ch_UID", "name": "BlackHole 2ch" }],
"audio_ducking_enabled": false
}'
printf '%s ' "Spiele Sprache in BlackHole 2ch ab, diktiere sie und drücke dann die Eingabetaste, um deine Einstellungen wiederherzustellen."
read -r _
jq 'del(.input_devices, .active_input)' <<<"$saved" | \
curl --fail --silent --show-error -X PATCH "$AUDIO_URL" \
-H @"$AUTH_HEADER" \
-H "Content-Type: application/json" \
--data-binary @-
)Das CLI-Tool bietet dasselbe mit typewhisper audio und typewhisper audio set.
Workflow-basierte Regeln
curl http://localhost:8978/v1/rules
curl -X PUT "http://localhost:8978/v1/rules/toggle?id=<uuid>"Jeder Eintrag enthält UUID, Aktivierungszustand, Priorität, App-Bundle-IDs, URL-Muster, Sprachmodus und -Hints sowie ein optionales Übersetzungsziel. Beim Start eines Diktats mit festem Workflow verwendest du dessen Regel-UUID als workflow_id.
Legacy-Kompatibilität: /v1/profiles und /v1/profiles/toggle bleiben als exakte Aliase für ältere Integrationen verfügbar.
Text mit Sprachmodellen und Workflows verarbeiten
Verfügbar ab TypeWhisper 1.8.
Diese Routen verarbeiten Text mit den Sprachmodellen und Workflows dieses Macs und liefern das Ergebnis, ohne es irgendwo einzufügen. Lokale Tools nutzen sie wie die anderen Routen mit dem API-Token. Requests können an Cloud-Anbieter aus deiner Sprachmodell-Liste gehen und deren API-Kosten verursachen. Mit Premium nutzen gekoppelte iPhones und iPads dieselben Routen, sobald „Schreiben mit diesem Mac erlauben“ unter Einstellungen > Premium > iPhone und iPad eingeschaltet ist. Bis dahin erhalten sie 403 writing_not_allowed, und remote_writing_allowed in GET /v1/status ist false. Lokale Tools betrifft die Einstellung nicht.
Sprachmodelle
curl http://localhost:8978/v1/llm/models
curl -X POST http://localhost:8978/v1/llm/process \
-H "Content-Type: application/json" \
-d '{"system_prompt":"Rewrite the text as a short, friendly reply. Return only the reply.","text":"thanks got it will send the file tomorrow"}'{
"models": [
{
"provider_id": "appleIntelligence",
"provider_name": "Apple Intelligence",
"name": "Apple Intelligence",
"ready": true
},
{
"provider_id": "Claude",
"provider_name": "Claude",
"model_id": "claude-haiku-4-5",
"name": "Claude Haiku 4.5",
"ready": true
}
]
}GET /v1/llm/models listet jeden Sprachmodell-Anbieter mit seinen Modellen auf. ready gibt an, ob der Anbieter gerade nutzbar ist. Anbieter ohne Modellliste wie Apple Intelligence erscheinen einmal, ohne model_id. POST /v1/llm/process erwartet system_prompt und text, beide Pflicht, und liefert das Ergebnis als text. Mit provider_id und optional model_id ruft es genau diesen Anbieter auf; model_id ohne provider_id ergibt 400.
Ohne provider_id probiert TypeWhisper die Einträge der globalen LLM-Fallback-Liste der Reihe nach durch, wie bei Workflows, die sie übernehmen.
Workflows
curl http://localhost:8978/v1/workflows
jq -n --rawfile text call-notes.txt \
'{workflow_id: "<uuid>", text: $text, language: "en"}' |
curl -X POST http://localhost:8978/v1/workflows/run \
-H "Content-Type: application/json" \
--data-binary @- |
jq -r .text{
"workflows": [
{
"id": "3C2B1A09-8F7E-4D6C-B5A4-0D1E2F3A4B5C",
"name": "Meeting Notes",
"template": "meetingNotes"
}
]
}GET /v1/workflows listet die aktiven Workflows auf, die ohne Textfeld laufen können: Workflows mit Prompt und Workflows mit der Vorlage Nur Diktat und Inline-Befehlen. Workflows mit Apple Translate oder nur einem Action-Plugin fehlen; GET /v1/rules listet alle Workflows auf. template ist die ID der Vorlage, etwa meetingNotes oder custom.
POST /v1/workflows/run erwartet workflow_id und text, beide Pflicht, und optional language, den Sprachcode des Texts. Es führt den Workflow mit seinen eigenen Einstellungen für Anbieter und Modell aus und liefert text, workflow_id und workflow_name. TypeWhisper fügt nichts ein, drückt kein Enter und führt kein Action-Plugin aus. Ein festes Ausgabeformat bleibt erhalten; „Automatisch erkennen“ fällt mangels App auf Plain Text zurück. Ein unbekannter Workflow ergibt 404 workflow_not_found, ein deaktivierter 409 workflow_disabled und einer, der keinen Text verarbeitet, 409 workflow_not_runnable.
Grenzen und Fehler
Der Request-Body darf bis zu 512 KiB groß sein, system_prompt bis zu 32 KiB und text bis zu 400 KiB. Jeder Client kann jeweils einen Request und bis zu 30 pro Minute senden, und der Mac bearbeitet höchstens zwei auf einmal; alle lokalen Tools zusammen zählen als ein Client. Spätestens nach 120 Sekunden erhält ein Request seine Antwort. Fehlermeldungen sind kurz und enthalten keine Details des Anbieters.
| Status und Code | Bedeutung |
|---|---|
400 bad_ | Ungültiges JSON, ein fehlendes Feld, leerer text, eine ungültige workflow_id oder model_id ohne provider_id. |
403 writing_ | Ein gekoppeltes Gerät hat den Request gesendet, während „Schreiben mit diesem Mac erlauben“ aus ist. |
403 forbidden | Verwaltete Einstellungen sperren das Sprachmodell oder den Anbieter. |
404 workflow_ | Den Workflow gibt es nicht. |
409 workflow_, workflow_ | Der Workflow ist deaktiviert oder verarbeitet keinen Text. |
413 payload_ | Der Request, system_prompt oder text überschreitet seine Grenze. |
413 context_ | Der Text ist zu lang für das Sprachmodell. |
429 busy, rate_ | Von diesem Client läuft schon ein Request, es laufen bereits zwei Requests, oder der Client hat in der letzten Minute 30 Requests gesendet. |
502 llm_ | Das Sprachmodell ist fehlgeschlagen, oder sein Ergebnis ist größer als 1 MiB. |
503 llm_ | Kein Sprachmodell ist bereit. |
503 cancelled | Der Request wurde abgebrochen. |
504 timeout | Der Mac ist nicht innerhalb von 120 Sekunden fertig geworden. |
Diktiersteuerung
Diese Routen verwenden die systemweite Diktierpipeline und das Einfügeverhalten von TypeWhisper. start liefert eine Sitzungs-UUID, stop dieselbe UUID, damit ein Skript das Ergebnis abfragen kann.
curl -X POST http://localhost:8978/v1/dictation/start \
-H "Content-Type: application/json" \
-d '{"workflow_id":"<uuid>"}'
curl -X POST http://localhost:8978/v1/dictation/stop
curl http://localhost:8978/v1/dictation/status
curl "http://localhost:8978/v1/dictation/transcription?id=<uuid>"Der Body von start ist optional. Mit workflow_id muss er einen vorhandenen aktiven Workflow benennen. TypeWhisper liefert ID und Namen des gewählten Workflows in der Startantwort zurück.
Frage /v1/dictation/transcription ab, bis status completed oder failed ist. Eine abgeschlossene Antwort enthält finalen und rohen Text sowie Zeitstempel, App-Kontext, Dauer, Sprache, Engine, Modell und Wortanzahl.
Ab TypeWhisper 1.8 enthält die Antwort zu jedem der letzten 100 Diktate seit dem Start von TypeWhisper außerdem latency: die Zeiten der einzelnen Schritte vom Start-Request bis zum geprüften Einfügen und zur wiederhergestellten Zwischenablage (Felder auf _ms in Millisekunden, recording_seconds in Sekunden), dazu Engine, Modell und wie der Text eingefügt und geprüft wurde. Es enthält nie Transkripttext, Audio oder App-Inhalte. Andere Sitzungen haben kein Feld latency.
Aktiven Browser-Tab melden
Verfügbar ab TypeWhisper 1.8.
Browser-Erweiterungen melden mit PUT /v1/browser/context den aktiven Tab, damit Website-Workflows zur geöffneten Seite passen. Das funktioniert auch in der Mac-App-Store-Edition, die Browser-Adressen nicht selbst lesen kann, und in Browsern ohne AppleScript-Unterstützung wie Firefox. Solange für den Browser im Vordergrund eine aktuelle Meldung vorliegt, nutzt TypeWhisper sie, statt den Browser zu fragen. In der Mac-App-Store-Edition erscheint der Trigger Website im Workflow-Editor, sobald eine Erweiterung etwas gemeldet hat.
Die TypeWhisper-Erweiterung für Chrome und Firefox nutzt diese Route und sendet wie andere Clients das API-Token.
curl -X PUT http://localhost:8978/v1/browser/context \
-H "Content-Type: application/json" \
-d '{"client_id":"c7d1e0f2-4b3a-4f9e-9a1d-2b6c8e0f1a3d","focused":true,"url":"https://github.com/TypeWhisper/typewhisper-mac/pulls","title":"Pull requests"}'
curl -X PUT http://localhost:8978/v1/browser/context \
-H "Content-Type: application/json" \
-d '{"client_id":"c7d1e0f2-4b3a-4f9e-9a1d-2b6c8e0f1a3d","focused":false}'{
"status": "active",
"app_bundle_id": "com.google.Chrome",
"url": "https://github.com/TypeWhisper/typewhisper-mac/pulls"
}Felder des Requests
| Feld | Beschreibung |
|---|---|
client_ | Pflicht. Eine gleichbleibende ID der meldenden Erweiterung mit 1 bis 128 Zeichen. Eine Meldung mit focused: false entfernt nur die Meldung mit derselben client_id. |
focused | Pflicht. true, solange das Browserfenster den Fokus hat, false, wenn es ihn verliert. |
url | Die Adresse des aktiven Tabs. Nur Adressen mit http, https und file gelten als Website. Lass sie bei einer Seite ohne Website weg, etwa einem neuen Tab; andere Adressen wie chrome://settings zählen ebenfalls nicht als Website. |
title | Der Titel des Tabs. TypeWhisper entfernt Leerraum am Rand und behält bis zu 512 Zeichen. |
Eine Meldung mit Fokus ersetzt die vorherige und gehört zu der App, die beim Eintreffen im Vordergrund ist. TypeWhisper ignoriert sie, solange TypeWhisper selbst, keine App oder eine App im Vordergrund ist, die keine Webseiten öffnen kann. Meldungen verfallen nach drei Minuten. Wiederhole die Meldung deshalb jede Minute, solange der Browser im Vordergrund bleibt.
status ist active, wenn TypeWhisper die Meldung für die App in app_bundle_id gespeichert hat, ignored, wenn nicht, und cleared bei focused: false. url fehlt, wenn der Tab keine Website zeigt. Ungültiges JSON sowie ein fehlendes oder falsch typisiertes Feld client_id oder focused ergeben 400 mit Invalid JSON body; eine leere client_id oder eine mit mehr als 128 Zeichen ergibt 400 mit Missing or invalid 'client_id'.
Recorder-Steuerung
Der Recorder erstellt eine gespeicherte Aufnahme und kann Mikrofon, Systemaudio oder beides erfassen. Er folgt derselben Misch-, Finalisierungs- und optionalen Transkriptionspipeline wie die Recorder-Oberfläche, ohne Text in eine andere App einzufügen.
curl -X POST "http://localhost:8978/v1/recorder/start?mic=true&system_audio=true"
curl -X POST http://localhost:8978/v1/recorder/stop
curl http://localhost:8978/v1/recorder/status
curl "http://localhost:8978/v1/recorder/session?id=<uuid>"mic und system_audio akzeptieren true, false, 1 oder 0. Fehlende Werte übernehmen die aktuellen Recorder-Einstellungen. Mindestens eine der daraus resultierenden Quellen muss aktiv bleiben.
{
"id": "8F8C1F45-6D03-44D2-A38C-0C4DE4F7E5F7",
"status": "completed",
"text": "Meeting notes from the recording.",
"output_file": "/Users/alex/Documents/TypeWhisper Recordings/Recording.m4a"
}Sitzungen durchlaufen recording, finalizing und completed oder failed. text entfällt bei deaktivierter oder leerer Transkription. output_file wird nach erfolgreicher Finalisierung ausgegeben, fehlgeschlagene Sitzungen enthalten error.
Fertige Recorder-Transkripte
Verfügbar ab TypeWhisper 1.8.
GET /v1/recorder/recordings liefert das zuletzt erfolgreich gespeicherte Transkript jeder Aufnahme, egal ob sie manuell, von der Kalenderintegration oder über die API gestartet wurde. Die Ergebnisse überstehen einen Neustart der App und hängen weder von der Live-Vorschau noch von einer API-Sitzung ab. So kann eine Integration Transkripte nachholen, die sie verpasst hat.
curl "http://localhost:8978/v1/recorder/recordings?since=1791100000.123456"
curl "http://localhost:8978/v1/recorder/recordings?since=2026-10-04T07:46:40Z"{
"recordings": [
{
"source": "recorder",
"recording_id": "8F8C1F45-6D03-44D2-A38C-0C4DE4F7E5F7",
"completion_id": "59CBC40C-274A-47A9-804C-8774AB504401",
"completed_at": 1791100000.123456,
"text": "Meeting notes from the recording.",
"audio_file": "/Users/alex/Documents/TypeWhisper Recordings/Weekly Sync.m4a",
"transcript_file": "/Users/alex/Documents/TypeWhisper Recordings/Weekly Sync.txt",
"markdown_file": "/Users/alex/Documents/TypeWhisper Recordings/Weekly Sync.transcript.md"
}
]
}Felder der Antwort
source– Immerrecorder.recording_id– Kennzeichnet die Aufnahme und bleibt auch nach einer erneuten Transkription gleich.completion_id– Kennzeichnet eine erfolgreiche Speicherung. Jede erneute Transkription erhält eine neue.completed_at– Zeitpunkt der erfolgreichen Speicherung in Unix-Sekunden, mit Sekundenbruchteilen.text– Das gespeicherte Transkript.audio_file,transcript_file– Pfade der Audiodatei und der Transkript-Textdatei (.txt). Beide Dateien existieren, wenn die Antwort erstellt wird.markdown_file– Pfad des Markdown-Transkripts, nur vorhanden, wenn eines gespeichert wurde und noch existiert. Derzeit erhalten Kalenderaufnahmen mit Meeting-Metadaten eines.
since akzeptiert Unix-Sekunden oder einen ISO-8601-Zeitstempel mit Zeitzone, etwa 2026-10-04T07:46:40Z, und filtert inklusiv nach dem Zeitpunkt, an dem ein Transkript gespeichert wurde, nicht nach dem Start der Aufnahme. Ohne since listet die Antwort alle Aufnahmen mit gespeichertem Transkript. Die Ergebnisse sind nach completed_at sortiert, die ältesten zuerst.
Damit du jedes Transkript nur einmal verarbeitest, merkst du dir completed_at des zuletzt verarbeiteten Ergebnisses und übergibst den Wert beim nächsten Request als since. Weil der Filter inklusiv ist, kommt dieses Ergebnis erneut zurück, ebenso alle anderen mit demselben Zeitpunkt. Überspringe deshalb completion_id-Werte, die du schon verarbeitet hast.
Eine erfolgreiche erneute Transkription behält die recording_id, vergibt eine neue completion_id und ersetzt das frühere Ergebnis. Die Liste enthält das jeweils neueste Ergebnis jeder Aufnahme, keine Versionsgeschichte, und ein fehlgeschlagener Versuch lässt das letzte erfolgreiche Ergebnis stehen. Aufnahmen ohne gespeichertes Transkript fehlen in der Liste. Aufnahmen aus der Zeit vor TypeWhisper 1.8 erscheinen nach ihrer nächsten erfolgreichen Transkription.
TypeWhisper legt neben jeder Aufnahme einen Abschlussbeleg ab, etwa Weekly Sync.m4a.transcript-ready.json, und löscht ihn, wenn du die Aufnahme in TypeWhisper löschst. Lässt sich ein Beleg nicht lesen, antwortet die API mit 500, statt die Aufnahme wegzulassen. So schiebt ein Client seinen Cursor nicht an ihr vorbei. Ein ungültiger Wert für since ergibt 400.
Webhooks, Skripte und Plugin-Events
Um direkt nach dem Speichern auf ein Transkript zu reagieren, nutzt du eine der folgenden Möglichkeiten. Beide Add-on-Optionen sind standardmäßig ausgeschaltet, auch bei Webhooks und Skripten, die du schon früher eingerichtet hast.
- Webhook – Ist „Auch fertige Recorder-Transkripte senden“ eingeschaltet, erhält ein Webhook jedes gespeicherte Transkript als JSON mit den oben beschriebenen Feldern. Dafür brauchst du Version 1.2.0 oder neuer des Add-ons.
- Script Runner – Ist „Auch für fertige Recorder-Transkripte ausführen“ eingeschaltet, erhält ein Skript das Transkript über stdin und die Dateipfade in Umgebungsvariablen. Dafür brauchst du Version 1.2.0 oder neuer des Add-ons.
recorderTranscriptReady– TypeWhisper sendet dieses Plugin-SDK-Event, nachdem Transkript und Abschlussbeleg gespeichert sind, auch nach einer erneuten Transkription und bei ausgeschalteter Live-Vorschau. Es ist vontranscriptionCompletedgetrennt; Plugins, die auf Diktate reagieren, erhalten deshalb keine Recorder-Transkripte.
Webhooks, Skripte und Plugins erhalten Transkripte nur, solange TypeWhisper und das Add-on laufen, und die Zustellung ist nicht garantiert. Mit GET /v1/recorder/recordings holst du nach, was sie verpasst haben.
Fehlerantworten
Fehler verwenden ein verschachteltes JSON-Objekt error mit den Feldern code und message. Werte zuerst den HTTP-Status aus und nutze message für Details:
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API token"
}
}Häufige HTTP-Statuscodes
400– Fehlender oder ungültiger Body, Query-Parameter, Dateipfad, Audioformat, Workflow oder Optionswert.401– Das Token ist erforderlich (ab TypeWhisper 1.8 der Standard, bei den Sprecher-Routen immer), und der Request enthält keinen gültigen Bearer- oder X-TypeWhisper-API-Token-Wert.403– Der Request kam von einem Browser im Auftrag einer anderen Website, verwaltete Einstellungen sperren die angefragte Engine, das Modell oder den Anbieter, eine Premium-Funktion wie die Sprechererkennung ist nicht verfügbar, oder ein gekoppeltes Gerät darf nicht mit diesem Mac schreiben (alles ab TypeWhisper 1.8).404– Der angeforderte Verlaufseintrag, der Sprecher (ab TypeWhisper 1.8), die Regel, der Workflow, die Diktat- oder Recorder-Sitzung, die Engine oder das Modell existiert nicht.409– Der Request widerspricht dem aktuellen Zustand: Eine Aufnahme läuft bereits oder wird noch verarbeitet, eine überschriebene Engine ist nicht eingerichtet, oder eine Engine kann das angeforderte Modell nicht laden, entladen oder löschen. Ab TypeWhisper 1.8 außerdem: Ein Workflow ist deaktiviert oder verarbeitet keinen Text, oder ein Sprecher-Request passt nicht zum aktuellen Transkript oder zu den Sprecherprofilen.413– Der Request-Body überschreitet das Upload-Limit von 256 MiB. Ab TypeWhisper 1.8 außerdem: Der Body überschreitet die kleinere Grenze der Routen für Textverarbeitung oder Sprecher, oder der Text ist zu lang für das Sprachmodell.422– Sprechererkennung oder ein Request zum Sprecherprofil ist nicht möglich: Die Engine hat keine Zeitstempel geliefert, der Sprecher hat noch keinen Namen, oder es gibt keine brauchbare Stimmprobe (ab TypeWhisper 1.8).429– Ein Request zur Textverarbeitung läuft bereits, oder innerhalb einer Minute kamen zu viele (ab TypeWhisper 1.8).501– Eine Zielsprachenübersetzung wurde auf einer macOS-Version vor 15 angefordert.502– Das Sprachmodell ist fehlgeschlagen oder hat mehr als 1 MiB geliefert (ab TypeWhisper 1.8).503– Es ist keine Transkriptions-Engine ausgewählt, oder ein neuerer Request hat eine Übersetzung verdrängt; wiederhole ihn. Ab TypeWhisper 1.8 außerdem: Sprechererkennung oder Sprachmodell sind nicht verfügbar, oder die Textverarbeitung wurde abgebrochen.504– Die Textverarbeitung ist nicht innerhalb von 120 Sekunden fertig geworden (ab TypeWhisper 1.8).500– Ein interner Fehler bei Transkription, Wörterbuch, Einstellungs-Backup, Sitzungsverarbeitung oder einem Recorder-Abschlussbeleg ist aufgetreten. Prüfe App-Logs oder Diagnose-Export für Details.