npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@responsivevoice/api-client

v2.0.1

Published

TypeScript REST client for the ResponsiveVoice text-to-speech (TTS) API — speech synthesis & voice generation

Downloads

277

Readme


Installation

# npm
npm install @responsivevoice/api-client

# pnpm
pnpm add @responsivevoice/api-client

# yarn
yarn add @responsivevoice/api-client

Get your API credentials

You need both an API key and an API secret to authenticate your requests — neither works alone.

  1. Register for a free ResponsiveVoice account.
  2. A default website is created for you automatically. Its identifier is your API key — copy it from the dashboard.
  3. Create your API secret manually in the dashboard section "Server-to-server API secrets" (it is not auto-generated).
  4. The secret is shown once: click to copy it immediately and paste it straight into your code (next to the API key from step 2). It can't be retrieved later — if you lose it, create a new one.

Keep your API secret server-side — don't ship it in browser code.

Usage

import { ResponsiveVoiceAPIClient } from '@responsivevoice/api-client';

// Authenticate with BOTH your API key and API secret (see above).
const client = new ResponsiveVoiceAPIClient({
  apiKey: 'your-api-key',
  apiSecret: 'your-api-secret',
});

// Synthesize speech: pass text and a ResponsiveVoice voice name.
// The server resolves the right voice for you.
const audio = await client.synthesize({
  text: 'Hello, world!',
  voice: 'UK English Female',
  format: 'mp3',
});

// The result gives you the audio in a few forms:
audio.blob; // the raw audio Blob
audio.url; // an object URL you can play
audio.format; // 'mp3'
audio.duration; // length in seconds (when known)

// Play it in the browser
const audioElement = new Audio(audio.url);
audioElement.play();

// Free the object URL when you're done with it
URL.revokeObjectURL(audio.url);

API Reference

Constructor

new ResponsiveVoiceAPIClient(config: ResponsiveVoiceAPIClientConfig)

Configuration Options

| Option | Type | Default | Description | | --------------- | -------------- | --------------------------------------------- | --------------------------------------------- | | apiKey | string | required | Your registered website/origin identifier | | apiSecret | string | required | The credential that authorizes requests | | baseUrl | string | https://texttospeech.responsivevoice.org/v2 | API base URL | | timeout | number | 30000 | Request timeout in milliseconds | | retryAttempts | number | 3 | Number of retry attempts for transient errors | | retryDelay | number | 1000 | Base delay between retries in milliseconds | | fetch | typeof fetch | globalThis.fetch | Custom fetch implementation |

Methods

synthesize(options, requestOptions?)

Synthesize text to speech audio.

const audio = await client.synthesize({
  text: 'Hello, world!',
  voice: 'UK English Female', // ResponsiveVoice name (resolved server-side)
  pitch: 0.5, // 0-1, optional
  rate: 0.5, // 0-1, optional
  volume: 1.0, // 0-1, optional
  format: 'mp3', // 'mp3' | 'ogg' | 'wav', optional
  gender: 'female', // 'male' | 'female', optional
});

console.log(audio.blob); // Blob
console.log(audio.url); // string (blob URL)
console.log(audio.format); // 'mp3' | 'ogg' | 'wav'
console.log(audio.duration); // number | undefined (seconds)

getVoices(filters?, requestOptions?)

Get all available voices, optionally filtered.

// getVoices() returns { voices, systemVoices } — destructure what you need.

// Get all voices
const { voices } = await client.getVoices();

// Filter by language
const { voices: britishVoices } = await client.getVoices({ lang: 'en-GB' });

// Filter by gender
const { voices: femaleVoices } = await client.getVoices({ gender: 'female' });

// Filter by both
const { voices: britishFemaleVoices } = await client.getVoices({
  lang: 'en-GB',
  gender: 'female',
});

getVoice(name, requestOptions?)

Get a specific voice by name.

const voice = await client.getVoice('UK English Female');
console.log(voice.name); // 'UK English Female'
console.log(voice.lang); // 'en-GB'
console.log(voice.service); // 'g1'

getVoicesByLanguage(lang, requestOptions?)

Get all voices for a specific language.

const germanVoices = await client.getVoicesByLanguage('de-DE');
const frenchVoices = await client.getVoicesByLanguage('fr');

Request Options

All methods accept an optional RequestOptions object:

interface RequestOptions {
  timeout?: number; // Custom timeout for this request
  signal?: AbortSignal; // Abort signal for cancellation
  skipRetry?: boolean; // Skip retry logic for this request
}

Example with abort:

const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  const audio = await client.synthesize(
    { text: 'Long text...', lang: 'en-US' },
    { signal: controller.signal },
  );
} catch (error) {
  if (error.name === 'TimeoutError') {
    console.log('Request was cancelled');
  }
}

Error Handling

The client throws specific error types for different failure scenarios:

import {
  ResponsiveVoiceError, // Base error class
  ApiError, // API returned an error response
  AuthError, // Authentication failed (401/403)
  NotFoundError, // Resource not found (404)
  RateLimitError, // Rate limited (429)
  ValidationError, // Request validation failed (400)
  NetworkError, // Network connectivity issues
  TimeoutError, // Request timed out
  RetryExhaustedError, // All retry attempts failed
} from '@responsivevoice/api-client';

try {
  const audio = await client.synthesize({ text: '', lang: 'en-US' });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Validation failed:', error.errors);
  } else if (error instanceof AuthError) {
    console.error('Authentication failed:', error.message);
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof TimeoutError) {
    console.error(`Request timed out after ${error.timeout}ms`);
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  }
}

Retry Behavior

The client automatically retries requests that fail due to:

  • Server errors (5xx status codes)
  • Rate limiting (429) - uses Retry-After header if provided
  • Network errors

Client errors (4xx except 429) are NOT retried.

Retry uses exponential backoff with jitter:

  • Base delay: 1000ms
  • Multiplier: 2x per attempt
  • Max delay: 30000ms

You can customize retry behavior:

const client = new ResponsiveVoiceAPIClient({
  apiKey: 'your-key',
  apiSecret: 'your-secret',
  retryAttempts: 5, // More attempts
  retryDelay: 500, // Faster initial retry
});

Or skip retries for a specific request:

const audio = await client.synthesize(
  { text: 'Hello', lang: 'en-US' },
  { skipRetry: true },
);

Browser Support

This package supports all modern browsers. For detailed compatibility information, see the Browser Support documentation.

Minimum browser versions:

  • Chrome 66+
  • Firefox 57+
  • Safari 12+
  • Edge 17+

Node.js Support

The package requires Node.js 16+ and works in both Node.js and browser environments.

Node.js 18+ — all features work out of the box (native fetch, Blob, AbortController).

Node.js 16–17 — pass a fetch implementation via config:

import fetch from 'node-fetch';

const client = new ResponsiveVoiceAPIClient({
  apiKey: 'your-key',
  apiSecret: 'your-secret',
  fetch,
});

WebSocket streaming on Node.js < 22 — the global WebSocket was added in Node.js 22. On older versions, pass a WebSocket implementation:

import WebSocket from 'ws';
import { WebSocketConnection } from '@responsivevoice/api-client';

const ws = new WebSocketConnection({
  baseUrl: 'https://texttospeech.responsivevoice.org',
  apiKey: 'your-key',
  WebSocket,
});

License

MIT


Other language SDKs: Python · Go · PHP · Java