Code Examples
Code Examples
Complete examples for common API operations.
Python
Transcribe an Audio File
import requests
import time
import os
API_KEY = os.environ["NAGOVORI_API_KEY"]
BASE_URL = "https://api.nagovori.ru/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def transcribe(file_path: str, language: str = "auto") -> str:
"""Upload and transcribe an audio file. Returns the transcript text."""
filename = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
# 1. Get presigned upload URL
presign = requests.post(
f"{BASE_URL}/uploads/presign",
headers=HEADERS,
json={
"filename": filename,
"content_type": "audio/mpeg",
"size_bytes": file_size,
},
).json()
# 2. Upload the file
with open(file_path, "rb") as f:
requests.put(
presign["upload_url"],
data=f,
headers={"Content-Type": "audio/mpeg"},
)
# 3. Create transcription
job = requests.post(
f"{BASE_URL}/transcriptions",
headers=HEADERS,
json={
"object_key": presign["object_key"],
"filename": filename,
"content_type": "audio/mpeg",
"size_bytes": file_size,
"language": language,
},
).json()
# 4. Poll until complete
while job["status"] in ("queued", "processing"):
time.sleep(3)
job = requests.get(
f"{BASE_URL}/transcriptions/{job['id']}",
headers=HEADERS,
).json()
if job["status"] == "failed":
raise RuntimeError(f"Transcription failed: {job.get('error_message')}")
return job["transcript_text"]
if __name__ == "__main__":
text = transcribe("meeting.mp3")
print(text)
TypeScript / Node.js
Transcribe an Audio File
import fs from "node:fs";
import path from "node:path";
const API_KEY = process.env.NAGOVORI_API_KEY!;
const BASE_URL = "https://api.nagovori.ru/v1";
async function api<T>(endpoint: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${BASE_URL}${endpoint}`, {
...init,
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
...init?.headers,
},
});
if (!res.ok) throw new Error(`API error ${res.status}: ${await res.text()}`);
return res.json() as Promise<T>;
}
async function transcribe(filePath: string, language = "auto"): Promise<string> {
const filename = path.basename(filePath);
const fileBuffer = fs.readFileSync(filePath);
const sizeBytes = fileBuffer.length;
// 1. Presign
const presign = await api<{ upload_url: string; object_key: string }>(
"/uploads/presign",
{
method: "POST",
body: JSON.stringify({
filename,
content_type: "audio/mpeg",
size_bytes: sizeBytes,
}),
}
);
// 2. Upload
await fetch(presign.upload_url, {
method: "PUT",
body: fileBuffer,
headers: { "Content-Type": "audio/mpeg" },
});
// 3. Create transcription
let job = await api<{ id: string; status: string; transcript_text?: string }>(
"/transcriptions",
{
method: "POST",
body: JSON.stringify({
object_key: presign.object_key,
filename,
content_type: "audio/mpeg",
size_bytes: sizeBytes,
language,
}),
}
);
// 4. Poll
while (job.status === "queued" || job.status === "processing") {
await new Promise((r) => setTimeout(r, 3000));
job = await api(`/transcriptions/${job.id}`);
}
if (job.status === "failed") throw new Error("Transcription failed");
return job.transcript_text ?? "";
}
// Usage
const text = await transcribe("meeting.mp3");
console.log(text);
Go
Transcribe an Audio File
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
const baseURL = "https://api.nagovori.ru/v1"
var apiKey = os.Getenv("NAGOVORI_API_KEY")
func transcribe(filePath, language string) (string, error) {
if language == "" {
language = "auto"
}
fileInfo, err := os.Stat(filePath)
if err != nil {
return "", fmt.Errorf("stat file: %w", err)
}
// 1. Presign
presignBody, _ := json.Marshal(map[string]interface{}{
"filename": fileInfo.Name(),
"content_type": "audio/mpeg",
"size_bytes": fileInfo.Size(),
})
presignResp, err := apiCall("POST", "/uploads/presign", presignBody)
if err != nil {
return "", fmt.Errorf("presign: %w", err)
}
uploadURL := presignResp["upload_url"].(string)
objectKey := presignResp["object_key"].(string)
// 2. Upload
fileData, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("read file: %w", err)
}
req, _ := http.NewRequest("PUT", uploadURL, bytes.NewReader(fileData))
req.Header.Set("Content-Type", "audio/mpeg")
if _, err := http.DefaultClient.Do(req); err != nil {
return "", fmt.Errorf("upload: %w", err)
}
// 3. Create transcription
createBody, _ := json.Marshal(map[string]interface{}{
"object_key": objectKey,
"filename": fileInfo.Name(),
"content_type": "audio/mpeg",
"size_bytes": fileInfo.Size(),
"language": language,
})
job, err := apiCall("POST", "/transcriptions", createBody)
if err != nil {
return "", fmt.Errorf("create transcription: %w", err)
}
// 4. Poll
id := job["id"].(string)
for {
status := job["status"].(string)
if status == "completed" {
return job["transcript_text"].(string), nil
}
if status == "failed" {
return "", fmt.Errorf("transcription failed: %v", job["error_message"])
}
time.Sleep(3 * time.Second)
job, err = apiCall("GET", "/transcriptions/"+id, nil)
if err != nil {
return "", err
}
}
}
func apiCall(method, path string, body []byte) (map[string]interface{}, error) {
var bodyReader io.Reader
if body != nil {
bodyReader = bytes.NewReader(body)
}
req, err := http.NewRequest(method, baseURL+path, bodyReader)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
if resp.StatusCode >= 400 {
return nil, fmt.Errorf("api error %d: %v", resp.StatusCode, result["error"])
}
return result, nil
}
func main() {
text, err := transcribe("meeting.mp3", "auto")
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println(text)
}
cURL
Complete Step-by-Step Transcription
# Step 1: Get presigned upload URL
PRESIGN=$(curl -s -X POST https://api.nagovori.ru/v1/uploads/presign \
-H "Authorization: Bearer $NAGOVORI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "meeting.mp3",
"content_type": "audio/mpeg",
"size_bytes": 5242880
}')
UPLOAD_URL=$(echo $PRESIGN | jq -r '.upload_url')
OBJECT_KEY=$(echo $PRESIGN | jq -r '.object_key')
# Step 2: Upload the file
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: audio/mpeg" \
--data-binary @meeting.mp3
# Step 3: Create transcription job
JOB=$(curl -s -X POST https://api.nagovori.ru/v1/transcriptions \
-H "Authorization: Bearer $NAGOVORI_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"object_key\": \"$OBJECT_KEY\",
\"filename\": \"meeting.mp3\",
\"content_type\": \"audio/mpeg\",
\"size_bytes\": 5242880,
\"language\": \"auto\"
}")
JOB_ID=$(echo $JOB | jq -r '.id')
# Step 4: Poll for result
while true; do
RESULT=$(curl -s https://api.nagovori.ru/v1/transcriptions/$JOB_ID \
-H "Authorization: Bearer $NAGOVORI_API_KEY")
STATUS=$(echo $RESULT | jq -r '.status')
if [ "$STATUS" = "completed" ]; then
echo $RESULT | jq -r '.transcript_text'
break
elif [ "$STATUS" = "failed" ]; then
echo "Error: $(echo $RESULT | jq -r '.error_message')"
break
fi
sleep 3
done
List Transcriptions
curl -s https://api.nagovori.ru/v1/transcriptions?limit=10 \
-H "Authorization: Bearer $NAGOVORI_API_KEY" | jq
Create TTS Job
curl -s -X POST https://api.nagovori.ru/v1/tts \
-H "Authorization: Bearer $NAGOVORI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello, this is a text-to-speech test.",
"voice": "alloy"
}' | jq