Get per-word timestamps from audio using phonetic forced alignment. Upload an audio or video file with a transcript, and receive precise start/end times for every word. Powered by the same Sawalign pipeline as the Speech Alignment API.
POST https://api.sawalni.com/v1/speech/word-align
Unlike /v1/speech/align, this endpoint is synchronous — it returns the result directly without job polling.
Send a multipart/form-data request with the audio file and text.
| Parameter | Type | Required | Description |
|---|---|---|---|
audio | file | Yes | Audio or video file (wav, mp3, flac, mp4, mov, mkv, etc.) |
text | string | Yes | Transcript text (words extracted, order preserved) |
Size limits:
curl -X POST https://api.sawalni.com/v1/speech/word-align \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "audio=@my_recording.wav" \ -F "text=Hello everyone welcome to the presentation"
import requests API_KEY = "YOUR_API_KEY" BASE = "https://api.sawalni.com/v1" with open("recording.wav", "rb") as f: resp = requests.post( f"{BASE}/speech/word-align", headers={"Authorization": f"Bearer {API_KEY}"}, files={"audio": ("recording.wav", f, "audio/wav")}, data={"text": "Hello everyone welcome to the presentation"}, ) result = resp.json() for w in result["words"]: print(f"{w['index']:3d} {w['start']:7.3f} → {w['end']:7.3f} {w['word']}")
const API_KEY = 'YOUR_API_KEY'; const BASE = 'https://api.sawalni.com/v1'; const form = new FormData(); form.append('audio', audioFile); form.append('text', 'Hello everyone welcome to the presentation'); const resp = await fetch(`${BASE}/speech/word-align`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}` }, body: form, }); const result = await resp.json(); result.words.forEach(w => { console.log(`${w.index} ${w.start.toFixed(3)} → ${w.end.toFixed(3)} ${w.word}`); });
{ "job_id": "abc123", "status": "done", "words": [ { "word": "Hello", "index": 0, "start": 0.320, "end": 0.680 }, { "word": "everyone", "index": 1, "start": 0.720, "end": 1.240 }, { "word": "welcome", "index": 2, "start": 1.400, "end": 1.760 }, { "word": "to", "index": 3, "start": 1.800, "end": 1.920 }, { "word": "the", "index": 4, "start": 1.960, "end": 2.080 }, { "word": "presentation", "index": 5, "start": 2.120, "end": 2.840 } ], "duration": 5.760, "usage": { "audio_bytes": 1567890, "text_bytes": 82 } }
| Field | Type | Description |
|---|---|---|
job_id | string | Unique identifier for the alignment |
status | string | Always "done" on success |
words | array | Per-word alignment results |
words[].word | string | The text token |
words[].index | integer | Position in the original word list |
words[].start | number | Start timestamp in seconds (3 decimal places, ~20ms precision) |
words[].end | number | End timestamp in seconds |
duration | number | Total audio duration in seconds |
usage | object | Metering data |
| Feature | /v1/speech/align | /v1/speech/word-align |
|---|---|---|
| Output | SRT subtitles | Per-word timestamps |
| Mode | Async (job polling) | Synchronous |
| Segmentation | Pause-based grouping | Individual words |
| Use case | Subtitles | Karaoke, word highlighting, TTS timing |
wav, mp3, flac, ogg, m4a, aac, wma, mp4, mov, mkv, avi, webm, m4v
Audio is automatically converted to 16kHz mono WAV and denoised before alignment.
| HTTP Code | Meaning |
|---|---|
| 200 | Success — word alignments returned |
| 400 | Invalid input (unsupported format, empty text, file too large) |
| 413 | Audio file exceeds 128 MB limit |
| 500 | Internal alignment error |
Word alignment is metered by audio file size (bytes uploaded) — same rate as speech alignment.
| Metric | Rate |
|---|---|
| Audio bytes | 0.1 credits per 1 MB |