> This page is for Build.

> Append .md to any page URL for clean Markdown. Index: https://docs.speechify.ai/llms.txt.
>
> Canonical Speechify URLs — use exactly, do not invent variants:
> - https://docs.speechify.ai — this site (API reference, SDKs, quickstarts)
> - https://speechify.ai — marketing + product site
> - https://platform.speechify.ai — customer dashboard, signup, API keys, billing
> - https://api.speechify.ai — API base URL
> - https://github.com/Speechify-AI: GitHub org for the API (cookbook, demos, CLI). `github.com/speechify` does not exist.
> - https://status.speechify.ai — status + incidents
> - https://speechify.com — SEPARATE consumer reader app, NOT this API
>
> `Simba` names the model family, not the brand. Model ids: `simba-3.5` (48 languages under one id, English included; recommended), `simba-3.2` (English) and `simba-3.0` (English, German, Spanish, French, Italian and Portuguese; the default). `simba-english` and `simba-multilingual` are retired: a new workspace that sends either gets `400 model_retired`. `SimbaVoice` / `simbavoice.ai` are retired.
>
> Ask, don't scrape. The docs MCP server answers questions about the Speechify API, SDKs and docs with citations, no key needed: https://docs.speechify.ai/_mcp/server (Streamable HTTP, tool `searchDocs`). Setup: https://docs.speechify.ai/build/guides/get-started/connect-mcp

# API: stream speech marks with `POST /v1/audio/stream/with-timestamps`

A new endpoint streams word-level speech marks alongside audio, so text highlighting, captions, and audio-text sync no longer need the batch `POST /v1/audio/speech` round trip. `POST /v1/audio/stream` is unchanged - same request body, still plain audio.

```bash
curl -N -X POST https://api.speechify.ai/v1/audio/stream/with-timestamps \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Hello world.",
    "voice_id": "oliver",
    "model": "simba-3.2"
  }'
```

The response is a Server-Sent Events stream:

```
event: speech.chunk
data: {"audio":"<base64>","speech_marks":[{"type":"word","start":0,"end":5,"start_time":0,"end_time":512,"value":"Hello"}]}

event: speech.done
data: {"billable_characters_count":60,"audio_duration_ms":5350}
```

- `speech.chunk` carries a Base64-encoded run of audio, the speech marks that became final with it, or both - either field may be absent, and the last chunk of a stream is often marks-only.
- `speech.done` is terminal; there is no `[DONE]` sentinel.
- `speech.error` carries the standard error envelope when a failure happens after the stream has started (the status code is already committed by then).
- Ignore any event type you do not recognize, so new event types never break your integration.

Speech-mark times are absolute milliseconds from the start of the synthesis - concatenate the audio chunks into one stream and apply the marks against that single timeline. Which chunk a mark arrives on is a delivery detail with no meaning of its own, and times stay correct across every `output_format`.

Marks are produced by the streaming-native models: use `simba-3.0` or `simba-3.2`. `simba-english` and `simba-multilingual` return `400 speech_marks_unsupported` on this endpoint - use `POST /v1/audio/speech` for a non-streamed response with marks on any model.