curl --request POST \
--url https://gateway.prem.io/rvenc/audio/translations \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "whisper-large-v3",
"encryptedInference": "encrypted_inference_payload_data",
"cipherText": "cipher_text_for_key_exchange",
"nonce": "nonce_value",
"fileNameNonce": "file_name_nonce_value",
"encryptedFileName": "encrypted_audio_file_name_data",
"fileNonce": "file_nonce_value",
"encryptedFile": "encrypted_audio_file_data"
}
'import requests
url = "https://gateway.prem.io/rvenc/audio/translations"
payload = {
"model": "whisper-large-v3",
"encryptedInference": "encrypted_inference_payload_data",
"cipherText": "cipher_text_for_key_exchange",
"nonce": "nonce_value",
"fileNameNonce": "file_name_nonce_value",
"encryptedFileName": "encrypted_audio_file_name_data",
"fileNonce": "file_nonce_value",
"encryptedFile": "encrypted_audio_file_data"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'whisper-large-v3',
encryptedInference: 'encrypted_inference_payload_data',
cipherText: 'cipher_text_for_key_exchange',
nonce: 'nonce_value',
fileNameNonce: 'file_name_nonce_value',
encryptedFileName: 'encrypted_audio_file_name_data',
fileNonce: 'file_nonce_value',
encryptedFile: 'encrypted_audio_file_data'
})
};
fetch('https://gateway.prem.io/rvenc/audio/translations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.prem.io/rvenc/audio/translations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'whisper-large-v3',
'encryptedInference' => 'encrypted_inference_payload_data',
'cipherText' => 'cipher_text_for_key_exchange',
'nonce' => 'nonce_value',
'fileNameNonce' => 'file_name_nonce_value',
'encryptedFileName' => 'encrypted_audio_file_name_data',
'fileNonce' => 'file_nonce_value',
'encryptedFile' => 'encrypted_audio_file_data'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.prem.io/rvenc/audio/translations"
payload := strings.NewReader("{\n \"model\": \"whisper-large-v3\",\n \"encryptedInference\": \"encrypted_inference_payload_data\",\n \"cipherText\": \"cipher_text_for_key_exchange\",\n \"nonce\": \"nonce_value\",\n \"fileNameNonce\": \"file_name_nonce_value\",\n \"encryptedFileName\": \"encrypted_audio_file_name_data\",\n \"fileNonce\": \"file_nonce_value\",\n \"encryptedFile\": \"encrypted_audio_file_data\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.prem.io/rvenc/audio/translations")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"whisper-large-v3\",\n \"encryptedInference\": \"encrypted_inference_payload_data\",\n \"cipherText\": \"cipher_text_for_key_exchange\",\n \"nonce\": \"nonce_value\",\n \"fileNameNonce\": \"file_name_nonce_value\",\n \"encryptedFileName\": \"encrypted_audio_file_name_data\",\n \"fileNonce\": \"file_nonce_value\",\n \"encryptedFile\": \"encrypted_audio_file_data\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.prem.io/rvenc/audio/translations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"whisper-large-v3\",\n \"encryptedInference\": \"encrypted_inference_payload_data\",\n \"cipherText\": \"cipher_text_for_key_exchange\",\n \"nonce\": \"nonce_value\",\n \"fileNameNonce\": \"file_name_nonce_value\",\n \"encryptedFileName\": \"encrypted_audio_file_name_data\",\n \"fileNonce\": \"file_nonce_value\",\n \"encryptedFile\": \"encrypted_audio_file_data\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "123"
},
"error": null,
"log": null,
"validator": null,
"support_id": null,
"message": "Resource created successfully",
"env": "development"
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 401,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 403,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 413,
"error": "Audio file size exceeds the maximum allowed limit of 25MB."
}{
"status": 429,
"error": "Rate limit exceeded. Please try again later."
}Encrypted Audio Translations (RVENC)
Translate an end-to-end encrypted audio file into English text, whatever the input language. Nothing is stored: neither the audio nor the translation.
curl --request POST \
--url https://gateway.prem.io/rvenc/audio/translations \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "whisper-large-v3",
"encryptedInference": "encrypted_inference_payload_data",
"cipherText": "cipher_text_for_key_exchange",
"nonce": "nonce_value",
"fileNameNonce": "file_name_nonce_value",
"encryptedFileName": "encrypted_audio_file_name_data",
"fileNonce": "file_nonce_value",
"encryptedFile": "encrypted_audio_file_data"
}
'import requests
url = "https://gateway.prem.io/rvenc/audio/translations"
payload = {
"model": "whisper-large-v3",
"encryptedInference": "encrypted_inference_payload_data",
"cipherText": "cipher_text_for_key_exchange",
"nonce": "nonce_value",
"fileNameNonce": "file_name_nonce_value",
"encryptedFileName": "encrypted_audio_file_name_data",
"fileNonce": "file_nonce_value",
"encryptedFile": "encrypted_audio_file_data"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'whisper-large-v3',
encryptedInference: 'encrypted_inference_payload_data',
cipherText: 'cipher_text_for_key_exchange',
nonce: 'nonce_value',
fileNameNonce: 'file_name_nonce_value',
encryptedFileName: 'encrypted_audio_file_name_data',
fileNonce: 'file_nonce_value',
encryptedFile: 'encrypted_audio_file_data'
})
};
fetch('https://gateway.prem.io/rvenc/audio/translations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.prem.io/rvenc/audio/translations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'whisper-large-v3',
'encryptedInference' => 'encrypted_inference_payload_data',
'cipherText' => 'cipher_text_for_key_exchange',
'nonce' => 'nonce_value',
'fileNameNonce' => 'file_name_nonce_value',
'encryptedFileName' => 'encrypted_audio_file_name_data',
'fileNonce' => 'file_nonce_value',
'encryptedFile' => 'encrypted_audio_file_data'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.prem.io/rvenc/audio/translations"
payload := strings.NewReader("{\n \"model\": \"whisper-large-v3\",\n \"encryptedInference\": \"encrypted_inference_payload_data\",\n \"cipherText\": \"cipher_text_for_key_exchange\",\n \"nonce\": \"nonce_value\",\n \"fileNameNonce\": \"file_name_nonce_value\",\n \"encryptedFileName\": \"encrypted_audio_file_name_data\",\n \"fileNonce\": \"file_nonce_value\",\n \"encryptedFile\": \"encrypted_audio_file_data\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.prem.io/rvenc/audio/translations")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"whisper-large-v3\",\n \"encryptedInference\": \"encrypted_inference_payload_data\",\n \"cipherText\": \"cipher_text_for_key_exchange\",\n \"nonce\": \"nonce_value\",\n \"fileNameNonce\": \"file_name_nonce_value\",\n \"encryptedFileName\": \"encrypted_audio_file_name_data\",\n \"fileNonce\": \"file_nonce_value\",\n \"encryptedFile\": \"encrypted_audio_file_data\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.prem.io/rvenc/audio/translations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"whisper-large-v3\",\n \"encryptedInference\": \"encrypted_inference_payload_data\",\n \"cipherText\": \"cipher_text_for_key_exchange\",\n \"nonce\": \"nonce_value\",\n \"fileNameNonce\": \"file_name_nonce_value\",\n \"encryptedFileName\": \"encrypted_audio_file_name_data\",\n \"fileNonce\": \"file_nonce_value\",\n \"encryptedFile\": \"encrypted_audio_file_data\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "123"
},
"error": null,
"log": null,
"validator": null,
"support_id": null,
"message": "Resource created successfully",
"env": "development"
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 401,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 403,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 413,
"error": "Audio file size exceeds the maximum allowed limit of 25MB."
}{
"status": 429,
"error": "Rate limit exceeded. Please try again later."
}TypeScript SDK
The SDK providesclient.audio.translations.create(...). The Confidential Proxy provides the /v1/audio/translations route.
Set the KEK
Create a 32-byte KEK. Encode it as 64 hexadecimal characters. Keep the KEK. Reuse it for later requests.export CLIENT_KEK="$(openssl rand -hex 32)"
List the models
Start the proxy:npx -p @premai/api-sdk@1.0.64 confidential-proxy \
--compat openai \
--kek "$CLIENT_KEK"
curl http://127.0.0.1:8787/v1/models \
-H "Authorization: Bearer $PREM_API_KEY"
API Reference
Authorizations
Send your access token as header Authorization: Bearer {accessToken}
Your API key that starts with sk_live or sk_test. You can create yours at go.prem.io/api-keys.
Body
Audio translation request with an end-to-end encrypted payload and the key material needed to decrypt it.
Model identifier to use for translation
Encrypted JSON string containing all audio translation parameters. When decrypted, this string must match the structure shown in the expandable _decryptedInference property below (reference only - do not send this property).
Cipher text for shared secret generation (ECDH key exchange)
Nonce used for encrypting the inference payload
The encrypted audio file name. The file name is encrypted using XChaCha20-Poly1305 with the shared secret and fileNameNonce.
Nonce used for encrypting the encrypted audio file name
The encrypted audio file data. The audio content is encrypted using XChaCha20-Poly1305 with the shared secret and fileNonce.
Nonce used for encrypting the encrypted audio file
Response
Encrypted audio translation response. The response contains the encrypted translation result (always to English) which must be decrypted using the shared secret derived from the request's cipherText, along with the response nonce.
Status code of the response
200, 201, 202 Encrypted audio translation response. Contains the encrypted translation result (always translated to English) that must be decrypted using the shared secret derived from the request's cipherText.
Show child attributes
Show child attributes
{
"encryptedResponse": "b2c3d4e5f67890abcdef1234567890abcdef12345678901234567890abcdef12345678...",
"nonce": "e5d4c3b2a19876543210fedcba987654"
}
Message of the response, human readable
"Resource created successfully"
API environment
development, production Error message of the response, human readable
"Invalid email address"
Useful informaiton, not always present, to debug the response
{ "request_id": "req_1234567890" }
"Some pertinent log message"
Validator response object, each key is the field name and value is the error message
{
"email": "Invalid email address",
"password": "Password is required"
}
Support ID linked to the response, used to identify it when talking with our team
"support_uuidv7-something-else"