REST API # REST API > Introduction to the ResponsiveVoice REST API The ResponsiveVoice REST API generates speech audio from any language or platform — no website required. Use it for: * Server-side audio generation * Mobile apps (Android, iOS) and other non-browser clients * Batch processing of text to speech * Platforms without Web Speech API support **Base URL:** `https://texttospeech.responsivevoice.org/v2` Prefer a client library A client library wraps these endpoints with typing, retries, and streaming. For TypeScript or Node, use [`@responsivevoice/api-client`](/sdks/typescript/). From a language without a client library, call the REST endpoints directly as documented below. Tip Building a website rather than calling the API directly? Embed [`@responsivevoice/core`](/getting-started/quick-start/) instead — it speaks via the browser’s Web Speech API and only falls back to this REST API when needed. ## Features * **Multilingual built-in voice catalog** * **Streaming support** via HTTP audio streaming and WebSocket streaming * **BYOK premium providers** — bring your own provider API keys for premium voices * **CDN-cacheable** GET endpoint for efficient audio delivery * **HATEOAS navigation** links in voice responses ## Interactive Documentation Explore the API interactively with the [Scalar API Reference](https://texttospeech.responsivevoice.org/reference). The full OpenAPI specification is available at [`/openapi.json`](https://texttospeech.responsivevoice.org/openapi.json) — import it into Postman, Insomnia, or other API tools. ## Endpoint Reference Detailed endpoint documentation is auto-generated from the OpenAPI specification — see the [Endpoint Reference](/rest-api/reference/). V1 Deprecation V1 is deprecated. Only `GET /v1/text:synthesize` remains for backward compatibility with the legacy JS client. All new integrations should use the v2 endpoints documented in the [Endpoint Reference](/rest-api/reference/). # Authentication > API key and secret authentication for the ResponsiveVoice REST API ## Authentication Every REST API request is authenticated with two credentials sent as headers: * **`X-API-Key`** — your website’s public identifier. * **`X-API-Secret`** — your non-public server credential. Both must be sent together: ```bash curl https://texttospeech.responsivevoice.org/v2/voices \ -H "X-API-Key: YOUR_API_KEY" \ -H "X-API-Secret: YOUR_API_SECRET" ``` ### Getting your credentials Both live in your website’s settings in the [ResponsiveVoice dashboard](https://app.responsivevoice.org) (no account yet? [sign up](https://responsivevoice.org/register)): * **API key** — shown in the “Your site code” snippet (`key: XXXXX`). * **API secret** — created under “Server-to-server API secrets”. It is shown **only once** when generated, so copy it immediately; you can revoke it there at any time. Caution The API secret is a credential — keep it server-side. Never embed it in browser code or commit it to source control. Browser apps use the [`@responsivevoice/core`](/getting-started/quick-start/) SDK, which authenticates by origin and does not need the secret. # Error Handling > Error responses and rate limits for the ResponsiveVoice REST API ## Error Responses All errors return JSON with an `error` object. Validation errors add an `errors` array detailing each problem: ```json { "error": { "message": "Language code is required", "code": "VALIDATION_ERROR", "statusCode": 400, "errors": ["Provide \"lang\" or \"voice\" parameter"] } } ``` ### Error Codes | HTTP Code | Code | Description | | --------- | ---------------------------- | -------------------------------------------------------------------------------------- | | 400 | VALIDATION\_ERROR | Invalid request parameters | | 401 | UNAUTHORIZED | Invalid or missing API key or secret | | 404 | NOT\_FOUND | Voice or resource not found | | 429 | RATE\_LIMIT\_EXCEEDED | Tier request-rate limit exceeded | | 429 | BURST\_RATE\_LIMIT\_EXCEEDED | Too many requests from one client in a short window | | 500 | INTERNAL\_ERROR | Server error | | 502 | *(none)* | Upstream TTS provider error; `message` carries the provider’s failure, no `code` field | ## Rate Limits Rate limits apply per API key, which is required — requests without a valid key are rejected. The same limits apply to both the v1 and v2 APIs. | Plan | Requests per minute | | ---------- | ------------------- | | Free | 100 | | Commercial | 1,000 | | Enterprise | Custom | The per-minute limits above are counted per API key. A separate burst check applies per API key **and** client IP over a short window, so unusually rapid bursts from one client can be limited briefly even while you’re under the per-minute limit. ### Monthly character quota | Plan | Characters per month | | ---------- | ------------------------------------- | | Free | 1,000,000 | | Commercial | Fair use — contact us for high volume | | Enterprise | Custom | Keys that exceed the monthly quota are suspended until upgraded. Note A `429` carries a `Retry-After` header — the seconds to wait before retrying (dynamic; read and honor it, and the retry will succeed). The body `code` says which limit was hit: `RATE_LIMIT_EXCEEDED` (per-minute tier limit) or `BURST_RATE_LIMIT_EXCEEDED` (per API key + client IP burst). `X-RateLimit-Limit` and `X-RateLimit-Remaining` accompany responses and reflect the per-minute limit, so a burst `429` may show remaining requests alongside a short `Retry-After`.