Skip to main content
This guide builds a working voice agent in a Next.js (App Router) project: the browser captures speech, your server decides what to say, and Rime speaks the reply. There is no Rime npm package to install — and you don’t need one. Rime is a single HTTPS/WebSocket API, so the only new dependency in this guide is ws (and only for the optional WebSocket variant). Architecture: the browser never talks to Rime directly. Your API key stays server-side, and the browser calls your own /api/tts route:

Prerequisites

  • A Rime API key from the API Tokens page — put it in .env.local as RIME_API_KEY=...
  • A Next.js 14+ project using the App Router (npx create-next-app@latest defaults work)

1. Server: the TTS proxy route

Create app/api/tts/route.ts (or src/app/api/tts/route.ts if your project uses src/):
app/api/tts/route.ts
Verify it works before touching the frontend:
test.mp3 should be playable audio. If you get a 401, check that RIME_API_KEY is set in .env.local and the dev server was restarted after adding it.

2. Client: mic in, Rime audio out

Create app/voice-agent/page.tsx. It uses the browser’s built-in SpeechRecognition for input (Chrome/Edge/Safari), a stub respond() function as the agent brain, and your /api/tts route for the voice:
app/voice-agent/page.tsx
Open http://localhost:3000/voice-agent, click Speak, say something, and the agent answers in Rime’s astra voice.

3. Optional: stream over WebSockets

The HTTP route above is the right default for most apps. Switch to WebSockets when you want incremental synthesis — audio starts playing while the rest of the sentence is still being generated — or barge-in handling with word-level timestamps. Two things make the WebSocket setup different:
  1. Rime’s WebSocket endpoints authenticate with an Authorization header, which browser WebSockets cannot send — so the bridge must live on your server. (This is also what keeps your key off the client.)
  2. Next.js route handlers can’t hold WebSocket connections, so you need a small custom server.
Install ws, then create server.mjs in the project root:
server.mjs
Point your dev/start scripts at it:
package.json
On the client, connect to your bridge and play chunks as they arrive:
The full /ws3 message schema — chunk, timestamps, done, error events and the flush/clear/eos operations — is in the Coda WebSocket reference, and the WebSocket overview explains segmentation and interruption patterns.

Next steps

WebSocket API overview

Endpoints, word-level timestamps, context IDs, and interruption handling.

Voices

Swap astra for any Coda voice across six languages.

Streaming formats

Choose between Opus, MP3, WAV, PCM, and μ-law for your latency budget.

LiveKit & Pipecat

Building on an agent framework? Use the ready-made Rime plugins instead.