gRPC API Reference
Package: lopatnov.translate.v1 · Port: 5100
Proto source: src/Lopatnov.Translate.Grpc/Protos/translate.proto
Contents
- Language code formats
- RPCs
- TranslateText
- TranslateLocalization
- DetectLanguage
- TranscribeAudio
- SynthesizeSpeech
- TranslateAudio
- GetCapabilities
- Error codes
Language code formats
All RPCs that accept or return language codes support a language_format field on the request.
| Value | Description | Example |
|---|---|---|
"bcp47" |
BCP-47 tags. Default when field is empty or omitted. | "uk", "zh-Hans" |
"flores200" |
FLORES-200 codes used internally by NLLB and M2M-100 | "ukr_Cyrl", "zho_Hans" |
"iso639-1" |
ISO 639-1 two-letter codes | "uk", "de" |
"iso639-2" |
ISO 639-2 three-letter codes (terminological form) | "ukr", "deu" |
"iso639-3" |
ISO 639-3 three-letter codes | "ukr", "deu" |
"native" |
No conversion — pass the code through unchanged. | any string |
Unknown or unrecognised codes are returned unchanged regardless of format.
RPCs
| RPC | Description |
|---|---|
TranslateText |
Translate a text string |
TranslateLocalization |
Translate all strings in a JSON i18n file |
DetectLanguage |
Detect the language of a text string |
TranscribeAudio |
Transcribe speech from a WAV file to text (STT) |
SynthesizeSpeech |
Synthesize text to a WAV audio file (TTS) |
TranslateAudio |
End-to-end speech-to-speech: STT → translate → TTS in one call |
GetCapabilities |
List available models, voices, and service capabilities |
TranslateText
Translates a single text string between two languages.
Request
message TranslateTextRequest {
string text = 1;
string source_language = 2; // language code (see language_format); "auto" or "" = auto-detect
string target_language = 3; // language code (see language_format)
string model = 4; // model key from appsettings.json (e.g. "m2m100_418M"); "" = default
string context = 5; // optional: free-form hint (reserved for LLM-based models)
string language_format = 6; // "bcp47" (default) | "flores200" | "native"
}
Response
message TranslateTextResponse {
string translated_text = 1;
string detected_language = 2; // set when source_language was "auto" or ""; in language_format
string model_used = 3; // key of the model that performed the translation
}
Examples
BCP-47 (default):
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Привіт, як справи?", "source_language": "uk", "target_language": "en"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateText
With FLORES-200 codes:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Привіт, як справи?", "source_language": "ukr_Cyrl", "target_language": "eng_Latn", "language_format": "flores200"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateText
With auto language detection:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Привіт, як справи?", "source_language": "auto", "target_language": "en"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateText
# → {"translatedText": "Hello, how are you?", "detectedLanguage": "uk", "modelUsed": "m2m100_418M"}
TranslateLocalization
Translates all leaf string values in a JSON localization file, preserving the key structure. Non-string values (numbers, booleans, null) and blank strings are passed through unchanged. Supports arbitrary nesting depth and arrays.
source_languagemust be an explicit language code —"auto"is not supported for this RPC.
Request
message TranslateLocalizationRequest {
string json = 1;
string source_language = 2; // language code (see language_format)
string target_language = 3;
string model = 4; // optional; "" = default model
string existing_translation = 5; // optional: same-structure JSON with already-translated values; matching keys are reused as-is
string context = 6; // optional: same-structure JSON with context hints per key
string language_format = 7;
}
Response
message TranslateLocalizationResponse {
string json = 1; // translated JSON, same structure as input
int32 strings_translated = 2; // number of strings newly translated (excludes reused from existing_translation)
}
Examples
Translate a full i18n file:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"json": "{\"auth\":{\"email\":\"Email\",\"password\":\"Password\",\"signIn\":\"Sign in\"}}", "source_language": "en", "target_language": "uk"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateLocalization
Incremental translation — reuse existing, translate only new keys:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"json": "{\"auth\":{\"email\":\"Email\",\"password\":\"Password\",\"signIn\":\"Sign in\"}}", "source_language": "en", "target_language": "uk", "existing_translation": "{\"auth\":{\"signIn\":\"Увійти\"}}"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateLocalization
DetectLanguage
Detects the language of a text string. Returns BCP-47 by default.
Requires Translation:AutoDetect to be set in appsettings.json.
If not configured, falls back to heuristic detection (Unicode block analysis).
Request
message DetectLanguageRequest {
string text = 1;
string language_format = 2; // "bcp47" (default) | "flores200" | "native"
}
Response
message DetectLanguageResponse {
string language = 1; // language code in the requested format
float probability = 2; // confidence score (0.0–1.0); populated if the detector supports it
}
Examples
# BCP-47 (default)
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Привіт, як справи?"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/DetectLanguage
# → {"language": "uk"}
# FLORES-200
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Привіт, як справи?", "language_format": "flores200"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/DetectLanguage
# → {"language": "ukr_Cyrl"}
TranscribeAudio
Transcribes speech from a WAV audio file.
Requires Translation:AudioToText to be set in appsettings.json (see docs/models.md).
The model is loaded lazily on first request and unloaded after ModelTtlMinutes of inactivity.
Request
message TranscribeAudioRequest {
bytes audio_data = 1; // WAV file bytes, max 50 MB (any sample rate / channels — resampled automatically to 16 kHz mono)
string language = 2; // BCP-47 language hint (e.g. "en", "ru"); "" or "auto" = Whisper auto-detection
string audio_format = 3; // reserved; pass "" or "wav"
string language_format = 4; // format for detected_language in response: "bcp47" (default) | "flores200"
}
Response
message TranscribeAudioResponse {
repeated TranscriptionSegment segments = 1;
string detected_language = 2; // in language_format
string full_text = 3; // all segments joined with spaces
}
message TranscriptionSegment {
string text = 1;
float start_time = 2; // seconds from start of audio
float end_time = 3;
}
Examples
bash / macOS / Linux:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d "{\"audio_data\": \"$(base64 -w0 recording.wav)\", \"language\": \"auto\"}" \
localhost:5100 lopatnov.translate.v1.TranslateService/TranscribeAudio
PowerShell (Windows):
$audioBase64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes("recording.wav"))
$body = "{`"audio_data`": `"$audioBase64`", `"language`": `"auto`"}"
grpcurl -plaintext `
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto `
-d $body `
localhost:5100 lopatnov.translate.v1.TranslateService/TranscribeAudio
With explicit language and FLORES-200 response:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d "{\"audio_data\": \"$(base64 -w0 recording.wav)\", \"language\": \"uk\", \"language_format\": \"flores200\"}" \
localhost:5100 lopatnov.translate.v1.TranslateService/TranscribeAudio
# → {"segments":[{"text":"Привіт","startTime":0.0,"endTime":1.2}], "detectedLanguage":"ukr_Cyrl", "fullText":"Привіт"}
SynthesizeSpeech
Synthesizes text to a WAV audio file using Piper TTS.
Requires Translation:TextToAudio to be configured in appsettings.json for the requested language (see docs/models.md).
The voice model is loaded lazily on first request and unloaded after ModelTtlMinutes of inactivity.
espeak-ng must be installed on the server (see docs/models.md).
Request
message SynthesizeSpeechRequest {
string text = 1;
string language = 2; // BCP-47 language code (e.g. "en", "uk"); matched against TextToAudio map
string voice = 3; // optional: speaker name for multi-speaker models (e.g. "mykyta", "lada", "tetiana")
float speed = 4; // speech rate multiplier; 1.0 = normal, 0.5 = half speed, 2.0 = double speed
string language_format = 5; // format for the language field: "bcp47" (default) | "flores200" | "native"
}
Response
message SynthesizeSpeechResponse {
bytes audio_data = 1; // WAV file bytes (16-bit PCM, RIFF header)
int32 sample_rate = 2; // sample rate of the output audio, typically 22050 Hz
}
Examples
bash / Linux:
# Synthesize and save to file
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Hello, world!", "language": "en"}' \
localhost:5100 lopatnov.translate.v1.TranslateService/SynthesizeSpeech \
| jq -r '.audioData' | base64 -d > output.wav
PowerShell (Windows):
$body = '{"text":"Привіт, як справи?","language":"uk","voice":"mykyta","speed":1.0}'
$resp = grpcurl -plaintext `
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto `
-d $body `
localhost:5100 lopatnov.translate.v1.TranslateService/SynthesizeSpeech `
| ConvertFrom-Json
[IO.File]::WriteAllBytes("output.wav", [Convert]::FromBase64String($resp.audioData))
With custom speed (half speed):
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{"text": "Хорошо, что ты пришёл!", "language": "ru", "speed": 0.75}' \
localhost:5100 lopatnov.translate.v1.TranslateService/SynthesizeSpeech \
| jq -r '.audioData' | base64 -d > output.wav
TranslateAudio
End-to-end speech-to-speech translation: transcribes the input audio (Whisper STT), translates the text (default translation model), and synthesizes the result (Piper TTS). Returns all intermediate results along with the translated audio.
Requires both Translation:AudioToText (Whisper) and Translation:TextToAudio (Piper) to be configured in appsettings.json.
Request
message TranslateAudioRequest {
bytes audio_data = 1; // WAV file bytes, max 50 MB (resampled automatically to 16 kHz mono for STT)
string source_language = 2; // BCP-47 source language hint; "" or "auto" = Whisper auto-detection
string target_language = 3; // BCP-47 target language; selects the TTS voice via TextToAudio map
string audio_format = 4; // reserved; pass "" or "wav"
string target_voice = 5; // optional: speaker name for multi-speaker target voice
string language_format = 6; // format for source_language/target_language: "bcp47" (default) | "flores200" | "native"
}
Response
message TranslateAudioResponse {
bytes translated_audio = 1; // synthesized WAV (16-bit PCM, RIFF header)
string transcription = 2; // full text transcribed from the input audio
string translated_text = 3; // translated text before TTS synthesis
int32 sample_rate = 4; // sample rate of the output audio, typically 22050 Hz
}
Examples
bash / Linux:
# Translate Ukrainian speech to English
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d "{\"audio_data\": \"$(base64 -w0 speech-uk.wav)\", \"source_language\": \"uk\", \"target_language\": \"en\"}" \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateAudio \
| tee /tmp/resp.json \
| jq -r '.translatedAudio' | base64 -d > translated.wav
# Show transcription and translation
cat /tmp/resp.json | jq '{transcription, translatedText}'
PowerShell (Windows):
$audioBase64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes("speech.wav"))
$body = "{`"audio_data`":`"$audioBase64`",`"source_language`":`"uk`",`"target_language`":`"en`"}"
$resp = grpcurl -plaintext `
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto `
-d $body `
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateAudio `
| ConvertFrom-Json
Write-Host "Transcription: $($resp.transcription)"
Write-Host "Translation: $($resp.translatedText)"
[IO.File]::WriteAllBytes("translated.wav", [Convert]::FromBase64String($resp.translatedAudio))
With auto language detection and a specific target speaker:
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d "{\"audio_data\": \"$(base64 -w0 speech.wav)\", \"source_language\": \"auto\", \"target_language\": \"uk\", \"target_voice\": \"mykyta\"}" \
localhost:5100 lopatnov.translate.v1.TranslateService/TranslateAudio \
| jq -r '.translatedAudio' | base64 -d > translated.wav
GetCapabilities
Returns service capabilities and the list of available translation models and TTS voices.
message GetCapabilitiesResponse {
repeated string available_voices = 2; // TTS language keys from Translation:TextToAudio (e.g. "en", "ru", "uk")
repeated string available_models = 3; // translation model keys from AllowedModels
bool stt_available = 4; // true when Translation:AudioToText is configured
bool tts_available = 5; // true when Translation:TextToAudio has at least one entry
}
grpcurl -plaintext \
-proto src/Lopatnov.Translate.Grpc/Protos/translate.proto \
-d '{}' \
localhost:5100 lopatnov.translate.v1.TranslateService/GetCapabilities
# → {"availableVoices":["en","ru","uk"], "availableModels":["m2m100_418M"], "sttAvailable":true, "ttsAvailable":true}
Error codes
| Scenario | gRPC Status |
|---|---|
Unknown model key |
INVALID_ARGUMENT |
model not in AllowedModels |
PERMISSION_DENIED |
TranscribeAudio called when AudioToText is not configured |
FAILED_PRECONDITION |
SynthesizeSpeech called when no voice is configured for language |
FAILED_PRECONDITION |
TranslateAudio called when STT or TTS is not configured |
FAILED_PRECONDITION |
Redirect cycle detected (x-redirect-id loop) |
FAILED_PRECONDITION |
Invalid JSON in TranslateLocalization |
INVALID_ARGUMENT |
| Language code not supported by the translation model | INVALID_ARGUMENT |
| Model file missing at configured path | INTERNAL |