> 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

# Puter

> Use the Speechify TTS provider in Puter's puter.js SDK: on puter.com with no API key, or on your own Puter instance with your key.

## Overview

[Puter](https://github.com/HeyPuter/puter) is an open-source internet OS with a serverless SDK, [`puter.js`](https://docs.puter.com), that gives web apps auth, storage, and AI from a single script tag.
Its text-to-speech call, [`puter.ai.txt2speech()`](https://docs.puter.com/AI/txt2speech/), includes a native Speechify provider, selected with `provider: 'speechify'`.

|                        | puter.com (hosted)                                    | Your own Puter instance                                          |
| ---------------------- | ----------------------------------------------------- | ---------------------------------------------------------------- |
| Speechify API key      | Not needed: Puter runs the provider                   | Yours, in the instance's `config.json`, never sent to the client |
| Who pays for synthesis | The signed-in user, through Puter's User-Pays model   | Your Speechify workspace                                         |
| Setup                  | Load `https://js.puter.com/v2/` and call `txt2speech` | The steps below                                                  |

For the hosted path, [Puter's Speechify tutorial](https://developer.puter.com/tutorials/free-unlimited-speechify-api/) has the full walkthrough.
The rest of this page covers a self-hosted instance.

## Prerequisites

* Speechify API key ([platform.speechify.ai/api-keys](https://platform.speechify.ai/api-keys))
* A [Puter instance](https://github.com/HeyPuter/puter) running a build that includes the Speechify TTS provider (Node 24+, `npm install && npm start`)
* A Puter account on that instance (`txt2speech` prompts sign-in on the first call; the first boot prints admin credentials)

## Enable the provider on your instance

Create `config.json` in the Puter repo root (or point `PUTER_CONFIG_PATH` at a config file) with your key under `providers.speechify`:

```json
{
  "providers": {
    "speechify": { "apiKey": "your Speechify API key" }
  }
}
```

The instance registers the provider at boot. Without this entry, `provider: 'speechify'` is not available, so restart after adding it. The key stays in the instance's server-side config; pages calling `puter.ai.txt2speech()` never see it, and synthesis is billed to the Speechify account the key belongs to.

## Use the Speechify provider

`puter.js` is JavaScript-only, so there are no Python or cURL variants of this integration: the whole point is calling TTS straight from the page.

```html
<html>
<body>
  <script src="https://js.puter.com/v2/"></script>
  <button id="play">Speak!</button>
  <script>
    document.getElementById('play').addEventListener('click', async () => {
      const audio = await puter.ai.txt2speech(
        "Hello from Speechify Simba 3.2, running inside Puter.",
        { provider: 'speechify' }
      );
      audio.play();
    });
  </script>
</body>
</html>
```

`txt2speech` resolves to an `HTMLAudioElement`, ready to `play()`. With no other options, the Speechify provider defaults to the `simba-3.2` model and the `geffen_32` voice.

> **Note**
>
> `puter.js` targets the instance that serves the page. For a standalone page against your own instance, open it with the `puter.api_origin` query parameter (e.g. `?puter.api_origin=http://api.puter.localhost:4100`), which `puter.js` reads at load time.

## Options

| Option          | Type      | Default       | Notes                                                                                                                      |
| --------------- | --------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `provider`      | `String`  | `'aws-polly'` | Set to `'speechify'` to route through Speechify                                                                            |
| `model`         | `String`  | `'simba-3.2'` | The provider's only current model. `simba-3.0` is not in Puter's list and returns `Invalid model`                          |
| `voice`         | `String`  | `'geffen_32'` | Example Simba 3.2 voices: `'geffen_32'`, `'dominic_32'`, `'harper_32'` - call `GET /v1/voices` for the full English roster |
| `output_format` | `String`  | `'mp3'`       | `'mp3'`, `'wav'`, `'ogg'`, `'aac'`                                                                                         |
| `test_mode`     | `Boolean` | `false`       | Returns sample audio without hitting the Speechify API                                                                     |

The provider calls `POST /v1/audio/speech`, which accepts up to 2,000 spoken characters per call. The `<speak>` tags the provider wraps plain text in don't count, so 2,000 characters of plain text fit in one call. Puter's own client allows 3,000, so the API's limit is the one you hit first.

`simba-3.2` is English-only, and it is the provider's only current model (see the table above). For non-English speech today, call the [Speechify API](/build/guides/text-to-speech/streaming) directly with `simba-3.5`, which speaks 48 languages (see [Models](/build/guides/concepts/models)).

#### Retired model ids: \`simba-english\` and \`simba-multilingual\`

Puter's provider also lists `simba-english` and `simba-multilingual`, the Simba 1.6 models. They are retired from API version `2026-09-21`, and from `2026-11-21` served by our current models. Use `simba-3.2` instead.

```js
const audio = await puter.ai.txt2speech(
  "Same sentence, different voice.",
  { provider: 'speechify', model: 'simba-3.2', voice: 'dominic_32' }
);
audio.play();
```

## Test without hitting the API

Pass `test_mode: true` (or the `testMode` positional argument) while developing:

```js
const audio = await puter.ai.txt2speech(
  "This returns sample audio and costs nothing.",
  { provider: 'speechify', test_mode: true }
);
audio.play();
```

## Troubleshooting

| Symptom                               | Likely cause                                                                                                                             | Fix                                                                                                                                                   |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Unknown or unsupported provider error | The instance has no Speechify API key configured (the provider isn't registered without one), or the build predates the Speechify driver | Set `providers.speechify.apiKey` in `config.json` and restart; run a current build                                                                    |
| `voice is not available` error        | A non-English voice on `simba-3.2`, which is English only                                                                                | Use an English voice on `simba-3.2`. For other languages call the Speechify API directly with `simba-3.5`                                             |
| `Invalid model` error                 | A model id Puter's provider does not list, such as `simba-3.0`                                                                           | For English, use `simba-3.2`. For another language, call the Speechify API directly with `simba-3.5`, since Puter's provider has no non-English model |
| No audio plays on click               | Browser autoplay policy                                                                                                                  | Call `audio.play()` from a user-gesture handler, as in the examples                                                                                   |
| Text rejected as too long             | Over the API's limit of 2,000 spoken characters per call, or Puter's 3,000-character client cap                                          | Split the text at sentence ends and synthesize per chunk                                                                                              |

## Resources

* [`puter.ai.txt2speech()` reference](https://docs.puter.com/AI/txt2speech/)
* [Puter's Speechify tutorial](https://developer.puter.com/tutorials/free-unlimited-speechify-api/) (hosted puter.com, no API key)
* [Puter on GitHub](https://github.com/HeyPuter/puter)
* [Speechify TTS models](/build/guides/concepts/models)