Skip to main content
Your engine image selects the model. Requests use that model over HTTP, gRPC, or WebSocket. These interfaces apply to the standalone licensed deployment. The cloud API and legacy API container have their own contracts. The model image configures the ports above. Use those ports for the quickstart. A bare engine binary defaults to HTTP port 7464 and gRPC port 7463.

Caller authentication

Your gateway must authenticate callers and provide TLS for every exposed protocol. In offline-license mode, the engine authorizes synthesis through the mounted runtime license. HTTP and gRPC callers do not need to send the metering key or license with each request.
WebSocket still requires an Authorization upgrade header or an initial config.authorization message within ten seconds, even in offline-license mode. The engine skips validation of this value when it has a verified offline license. The field is required, but it provides no access control in this mode. For a private engine with a verified offline license, set config.authorization to an empty string. Keep the metering API key on the engine. Your gateway must authenticate callers. An empty value does not authenticate clients in other deployment modes.

HTTP

Send the complete text to POST /. You can also use its alias, POST /invocations. Set Content-Type: application/json and choose an audio format with Accept, such as audio/wav or audio/mpeg. Check the response Content-Type before you decode the audio.
For compatibility with existing HTTP clients, the engine also accepts audioFormat in the request body. Valid short values, such as wav or mp3, override Accept. If the field is absent or invalid, the engine uses Accept. Without either a valid body format or an Accept header, the request fails. Use Accept for new clients.
This request writes the WAV response to output.wav:
Read the response as audio bytes. The engine does not use the legacy audioContent.model_output JSON wrapper. Before audio starts, a failure can return an HTTP error. After audio starts, a failure aborts the response body. HTTP 200 alone is not proof that synthesis completed. Word timestamps are currently unavailable over all three standalone engine protocols.

gRPC

The engine exposes rime.TextToSpeech without gRPC reflection, so you need the schema to call it. Ask Rime for rime/text_to_speech.proto and its imports that match your image. Client generation also requires google/protobuf/duration.proto and google/rpc/status.proto, including their imports. With grpcurl installed and the schema bundle in ./rime-protos, this command sends complete text and prints the streamed response messages:
Keep -plaintext for the private local listener. Use TLS through your gateway. grpcurl prints JSON with base64 audio fields. A generated protobuf client receives those fields as bytes. Append the audio payloads in order to build the audio file. Writing whole protobuf messages would include data outside the audio payload. For incremental input, send one header followed by textChunk messages. Close the request side when you have sent all the text, then keep reading until the response stream completes. This example sends two complete sentences:
If your input arrives a token at a time, set header.splitStrategy to SPLIT_STRATEGY_ACCUMULATE_SENTENCE. The engine collects text into sentences before synthesis. The selected image still determines model-specific synthesis behavior. Check the final RPC status. Anything other than OK means synthesis is incomplete. Cancel the RPC to stop generation. The schema defines timestamp fields and a response trailer, but the standalone engine currently sends only audio messages. Setting timestamps.enable has no effect.

WebSocket

Open /ws on the engine’s HTTP port. Offer rime.v1.json for JSON text responses or rime.v1.binary for protobuf binary responses. The engine defaults to JSON if you omit the subprotocol. Both encodings use WebSocketRequest and WebSocketResponse from the gRPC schema bundle. Each frame contains one message envelope. JSON uses camelCase fields and base64 audio values. Binary frames contain protobuf envelopes. With either encoding, extract the audio payload before you write it to an audio file. Wait for ready before you send start. For each context, the server sends started, zero or more audio messages, then done, cancelled, or error. Match responses by contextId. An error with an empty context ID applies to the connection. You can keep the connection open for later contexts. Save this example as stream.mjs and run it with Node.js 22 or later against a private engine with a verified offline license. It sends an empty authorization value and needs no metering API key. Running node stream.mjs writes output.wav only after the engine sends done:
If your input arrives a token at a time, set start.splitStrategy to SPLIT_STRATEGY_ACCUMULATE_SENTENCE. Wait for done to confirm that all audio has arrived. This event does not currently include timestamp spans. Migration from the API container’s WebSocket ports requires changes to your client’s messages. Move synthesis parameters from the old query parameters into start. Replace flush, clear, and eos with the context lifecycle above. Use end to finish input and cancel to stop a context. Decode the audio payload from each envelope. For language support, read the languages in ready and test the voices in your image. The old API container’s port-specific restrictions do not define this protocol.

Routing, health, and failures

Route traffic using HTTP or gRPC health checks. Your gateway must support HTTP/2 gRPC and WebSocket upgrades. Set its timeouts to allow streams to stay open for the duration your application needs. All three protocols share one inference capacity limit. At that limit, or during request drain, the engine refuses new synthesis. It returns gRPC UNAVAILABLE, HTTP 503, or a WebSocket error with kind unavailable. Before you retry, check whether the client already received audio. Retry with backoff only if your application can avoid playing that audio again. See Load balancing for stream routing and shutdown.