نِت اَرز · مستندات API هوش مصنوعی
همهٔ مستندات
مدل‌ها و قیمت‌ها مرجع تعاملی دریافت کلید

صوت (STT / TTS)

گفتار به متن با Whisper، GPT Transcribe و Gemini Transcribe (جدا کردن گوینده‌ها و زیرنویس)، ترجمهٔ صوت، و متن به گفتار با صداهای OpenAI و ۳۰ صدای Gemini.

base_url: https://netarz.ir/api/ai/v1 به‌روزرسانی: 1405/07/16

درگاه سه endpoint صوتی سازگار با OpenAI دارد: گفتار به متن، ترجمهٔ گفتار به انگلیسی و متن به گفتار. مدل‌های این endpointها از OpenAI و Google هستند و فارسی را خوب می‌فهمند: کنار Whisper و سری GPT Transcribe، Gemini 3.5 Transcribe گوینده‌ها را از هم جدا می‌کند و زیرنویس می‌سازد، و کنار صداهای OpenAI، Gemini TTS سی صدای آماده و گفت‌وگوی دو نفره دارد. همه را با همان کلید و همان قالب OpenAI صدا می‌زنید. مدل‌های صوتی Groq روی درگاه فعال نیستند. فایل بلند را هم می‌توانید مستقیم در /chat/completions به مدل‌های Gemini بدهید و متن زمان‌بندی‌شده بگیرید؛ روشش را در بخش فایل صوتی بلند با Gemini نوشته‌ایم.

گفتار به متن

POST /api/ai/v1/audio/transcriptions نیازمند کلید API

درخواست از نوع multipart/form-data با فیلد file (حداکثر ۲۵ مگابایت؛ mp3، mp4، mpeg، mpga، m4a, wav, webm, ogg) و model:

Python
with open("meeting.mp3", "rb") as f:
    text = client.audio.transcriptions.create(
        model="whisper-1",
        file=f,
        language="fa",              # دقت فارسی را بالا می‌برد
        response_format="text",     # json | text | srt | vtt | verbose_json
    )
print(text)
Node.js
import fs from "node:fs";

const result = await client.audio.transcriptions.create({
  model: "whisper-1",
  file: fs.createReadStream("meeting.mp3"),
  language: "fa",
  response_format: "verbose_json",
  timestamp_granularities: ["segment"],
});
console.log(result.text, result.duration);
cURL
curl https://netarz.ir/api/ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -F file=@meeting.mp3 \
  -F model=whisper-1 \
  -F language=fa \
  -F response_format=srt
فیلدتوضیح
file الزامیفایل صوتی، حداکثر ۲۵ مگابایت.
model الزامیwhisper-1، gpt-transcribe، gpt-4o-transcribe، gpt-4o-mini-transcribe یا gpt-4o-transcribe-diarize (تفکیک گوینده) یا gemini-3.5-transcribe (جزئیات). فهرست
languageکد زبان ISO-639-1؛ برای فارسی fa. دقت و سرعت را بهبود می‌دهد.
response_formatjson (پیش‌فرض) | text | srt | vtt | verbose_json (با زمان‌بندی؛ فقط مدل‌هایی که capabilities.verbose_json دارند). gemini-3.5-transcribe قالب diarized_json را هم دارد.
promptمتن راهنما (مثلاً اسامی خاص یا سبک نگارش) برای بهبود خروجی.
temperature، timestamp_granularitiesاختیاری؛ عبور مستقیم.

فیلدهای دیگر نادیده گرفته می‌شوند. فایل بزرگ‌تر از ۲۵ مگابایت را تکه‌تکه کنید، بیت‌ریتش را پایین بیاورید یا به Gemini بدهید.

Gemini 3.5 Transcribe: جدا کردن گوینده‌ها، زمان‌بندی و زیرنویس

gemini-3.5-transcribe از همین endpoint و با همین درخواست multipart/form-data کار می‌کند، با فایل تا ۲۵ مگابایت. کنار متن ساده، گوینده‌ها را از هم جدا می‌کند (diarization)، زمان هر کلمه را می‌دهد و مستقیم فایل زیرنویس SRT یا VTT می‌سازد.

Python
with open("interview.mp3", "rb") as f:
    srt = client.audio.transcriptions.create(
        model="gemini-3.5-transcribe",
        file=f,
        language="fa",
        response_format="srt",      # زیرنویس با زمان‌بندی کلمه‌به‌کلمه
    )
open("interview.srt", "w", encoding="utf-8").write(srt)
cURL
# جدا کردن گوینده‌ها، برچسب هر نوبت داخل خود متن
curl https://netarz.ir/api/ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -F file=@meeting.mp3 \
  -F model=gemini-3.5-transcribe \
  -F language=fa \
  -F diarize=true \
  -F response_format=text
پاسخ (diarize با text)
[spk_1] سلام، جلسه را شروع کنیم؟
[spk_2] بله، اول گزارش فروش هفته را مرور کنیم.
[spk_1] باشد، من شروع می‌کنم.
فیلدروی این مدل
languageکد زبان، مثلاً fa. اگر نفرستید، مدل زبان را خودش تشخیص می‌دهد.
response_formatjson (پیش‌فرض) | text | verbose_json (متن، فهرست کلمه‌ها با زمان شروع و پایان، و بخش‌ها یا segments) | srt | vtt | diarized_json (بخش‌ها با برچسب گوینده).
diarizeبا true گوینده‌ها برچسب می‌گیرند: spk_1، spk_2 و… تا ۸ نفر. با json و text برچسب داخل خود متن می‌آید ([spk_1] …، هر نوبت در یک خط)؛ در srt و vtt اول هر زیرنویس.
promptواژه‌نامهٔ اختصاصی (custom vocabulary): نام‌ها و اصطلاح‌هایی که باید درست نوشته شوند، جداشده با ویرگول. فقط با json یا text اثر دارد؛ وقتی diarize، زمان‌بندی (verbose_json، srt، vtt، diarized_json) یا mode=smart روشن است، نادیده گرفته می‌شود.
modeبا smart کلمه‌های پرکنندهٔ گفتار حذف می‌شوند و متن تمیزتری می‌گیرید. مثل prompt، فقط با json یا text و بدون diarize اثر دارد.
timestamp_granularitiesبا ["word"] زمان‌بندی کلمه‌به‌کلمه روشن می‌شود.

نمونهٔ واژه‌نامه؛ این‌طور اسم برند یا اصطلاح فنی در متن درست نوشته می‌شود:

cURL
curl https://netarz.ir/api/ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -F file=@support-call.mp3 \
  -F model=gemini-3.5-transcribe \
  -F language=fa \
  -F prompt="نِت اَرز, Nano Banana, زرین‌پال, کلید API"

فایل صوتی بلند با Gemini (متن با زمان‌بندی)

POST /api/ai/v1/chat/completions نیازمند کلید API

فایل را با base64 در بخش input_audio کنار دستورتان بفرستید و از مدل بخواهید متن را با زمان هر جمله بنویسد. جلسه، کلاس یا مصاحبهٔ فارسی را همین‌طور به متن زمان‌بندی‌شده تبدیل می‌کنید. اگر پیش‌تر همین کار را با کلید Google AI Studio می‌کردید، فرقش این است که درگاه فقط قالب OpenAI را می‌پذیرد؛ کتابخانهٔ google-genai و آپلود فایل گوگل (Files API) این‌جا کار نمی‌کنند.

محدودیتمقدار
بدنهٔ هر درخواست۲۰ مگابایت. base64 حجم فایل را یک‌سوم بیشتر می‌کند، پس هر درخواست حدود ۱۵ مگابایت صوت جا می‌دهد.
زمان پاسخهر درخواست حداکثر ۹۰ ثانیه فرصت دارد.
قالب فایلmp3 یا wav در فیلد input_audio.format.

فایل ۱۰۰ مگابایتی در یک درخواست جا نمی‌شود، ولی لازم هم نیست آن را یک‌جا بفرستید. Gemini پیش از شنیدن، صوت را تک‌کاناله (mono) و ۱۶ کیلوبیت بر ثانیه می‌کند؛ پس اگر خودتان فایل را mono و ۳۲ کیلوبیت ذخیره کنید، دقت متن پایین نمی‌آید و هر ساعت صوت حدود ۱۴ مگابایت می‌شود. بعد فایل را به تکه‌های ۱۵ دقیقه‌ای تقسیم کنید تا جواب هر تکه در مهلت پاسخ برسد:

ffmpeg
# mono، ۱۶ کیلوهرتز، ۳۲ کیلوبیت؛ تکه‌های ۱۵ دقیقه‌ای (۹۰۰ ثانیه)
ffmpeg -i lecture.wav -ac 1 -ar 16000 -b:a 32k \
  -f segment -segment_time 900 -reset_timestamps 1 part-%03d.mp3

هر تکه را جدا بفرستید. زمان‌هایی که مدل در متن هر تکه می‌نویسد از صفر شروع می‌شوند؛ شروع همان تکه در فایل اصلی (۰، ۱۵، ۳۰ دقیقه…) را به آن‌ها اضافه کنید:

Python
import base64, glob, os
from openai import OpenAI

client = OpenAI(base_url="https://netarz.ir/api/ai/v1", api_key=os.environ["NETARZ_API_KEY"])
PROMPT = "Transcribe this Persian audio verbatim. Start every sentence with a [mm:ss] timestamp."

for i, path in enumerate(sorted(glob.glob("part-*.mp3"))):
    with open(path, "rb") as f:
        audio = base64.b64encode(f.read()).decode()

    reply = client.chat.completions.create(
        model="gemini-3.8-flash",
        messages=[{"role": "user", "content": [
            {"type": "text", "text": PROMPT},
            {"type": "input_audio", "input_audio": {"data": audio, "format": "mp3"}},
        ]}],
    )
    print(f"--- تکهٔ {i + 1}، از دقیقهٔ {i * 15}")   # زمان‌های این تکه از صفر شروع می‌شوند
    print(reply.choices[0].message.content)
PowerShell
$bytes = [IO.File]::ReadAllBytes("part-000.mp3")
$body = @{
  model    = "gemini-3.8-flash"
  messages = @(@{
    role    = "user"
    content = @(
      @{ type = "text"; text = "Transcribe this Persian audio verbatim. Start every sentence with a [mm:ss] timestamp." },
      @{ type = "input_audio"; input_audio = @{ data = [Convert]::ToBase64String($bytes); format = "mp3" } }
    )
  })
} | ConvertTo-Json -Depth 10          # بدون -Depth، بخش صوت از دست می‌رود

$reply = Invoke-RestMethod -Method Post -Uri "https://netarz.ir/api/ai/v1/chat/completions" `
  -Headers @{ Authorization = "Bearer $env:NETARZ_API_KEY" } `
  -ContentType "application/json; charset=utf-8" `
  -Body ([Text.Encoding]::UTF8.GetBytes($body))   # بدنه با UTF-8
$reply.choices[0].message.content
Windows PowerShell 5.1

دو چیز درخواست را خراب می‌کند. یکی، ConvertTo-Json بدون -Depth فقط دو سطح را می‌نویسد و بخش صوت را از دست می‌دهد. دیگر، خودِ PowerShell بدنهٔ متنی را بدون UTF-8 می‌فرستد و متن فارسی به‌هم می‌ریزد یا خطای invalid_json برمی‌گردد. -Depth 10 بگذارید و بدنه را با [Text.Encoding]::UTF8.GetBytes() بفرستید؛ مثل نمونهٔ بالا.

هزینه: Gemini هر ثانیه صوت را حدود ۳۲ توکن ورودی می‌شمارد (هر ساعت ۱۱۵٬۲۰۰ توکن) و ما همین توکن‌ها را با قیمت ورودی همان مدل حساب می‌کنیم. یک ساعت صوت با gemini-3.8-flash، اگر حدود ۲۰ هزار توکن متن برگردد، نزدیک $0.19 می‌شود؛ با نرخ امروز حدود ۵۴٬۰۰۰ تومان. پیش از هر درخواست، مبلغ رزرو را از حجم فایل برآورد می‌کنیم و بعد از پاسخ، با مصرف واقعی تسویه می‌کنیم.

ترجمهٔ گفتار به انگلیسی

POST /api/ai/v1/audio/translations نیازمند کلید API
cURL
curl https://netarz.ir/api/ai/v1/audio/translations \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -F file=@voice-message.ogg \
  -F model=whisper-1
# → متن انگلیسی گفتار (هر زبانی به انگلیسی)

متن به گفتار

POST /api/ai/v1/audio/speech نیازمند کلید API

خروجی فایل صوتی باینری است (پیش‌فرض mp3). حداکثر طول متن ۴٬۰۹۶ کاراکتر است و در مدل‌های Gemini TTS ۳٬۰۰۰ کاراکتر؛ سقف هر مدل در capabilities.max_input_chars آمده است. متن بلندتر را در چند درخواست بفرستید.

Python
speech = client.audio.speech.create(
    model="tts-1",
    voice="alloy",            # alloy | echo | fable | onyx | nova | shimmer
    input="به نِت اَرز خوش آمدید. سفارش شما ثبت شد.",
    response_format="mp3",    # mp3 | opus | aac | flac | wav | pcm
)
speech.write_to_file("welcome.mp3")
Node.js
import fs from "node:fs";

const speech = await client.audio.speech.create({
  model: "gpt-4o-mini-tts",
  voice: "nova",
  input: "به نِت اَرز خوش آمدید. سفارش شما ثبت شد.",
  instructions: "گرم و آرام صحبت کنید.",   // فقط gpt-4o-mini-tts
});
fs.writeFileSync("welcome.mp3", Buffer.from(await speech.arrayBuffer()));
cURL
curl https://netarz.ir/api/ai/v1/audio/speech \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "tts-1", "voice": "alloy", "input": "به نِت اَرز خوش آمدید."}' \
  --output welcome.mp3

پارامترها: model، input، voice (صداهای هر مدل در capabilities.voices)، response_format، speed (۰٫۲۵ تا ۴) و برای gpt-4o-mini-tts و مدل‌های Gemini TTS فیلد instructions برای لحن.

Gemini TTS: سی صدا، لحن جدا از متن و گفت‌وگوی دو نفره

gemini-3.8-flash-tts و gemini-3.8-flash-lite-tts از همین endpoint کار می‌کنند و فارسی را طبیعی می‌خوانند. هر چیزی که در input بنویسید، همان‌طور که نوشته شده خوانده می‌شود؛ پس دستور لحن را داخل متن ننویسید و در instructions بفرستید (مثلاً «گرم و دوستانه» یا «لحن خبری»). این دستور روی شیوهٔ خواندن اثر دارد و بلند خوانده نمی‌شود.

Python
speech = client.audio.speech.create(
    model="gemini-3.8-flash-tts",
    voice="Sulafat",                         # یکی از ۳۰ صدای Gemini
    input="به نِت اَرز خوش آمدید. سفارش شما ثبت شد.",
    instructions="گرم و دوستانه، با سرعت معمولی",
    response_format="mp3",
)
speech.write_to_file("welcome.mp3")
cURL
curl https://netarz.ir/api/ai/v1/audio/speech \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-lite-tts",
    "voice": "Charon",
    "input": "خبر امروز: نرخ دلار نسبت به دیروز تغییری نکرد.",
    "instructions": "لحن خبری، رسمی و آرام",
    "speed": 1.1
  }' --output news.mp3
پارامترروی این مدل‌ها
voiceیکی از ۳۰ صدای Gemini (فهرست پایین). اگر نام صداهای OpenAI مثل alloy یا nova را بفرستید، نزدیک‌ترین صدای Gemini انتخاب می‌شود؛ پس کد فعلی‌تان جز نام مدل تغییری لازم ندارد.
instructionsلحن و حالت گفتار، جدا از متن.
speakersبرای گفت‌وگوی دو نفره: دو گوینده، هر کدام با نام و صدای خودش (پایین‌تر).
speedسرعت خواندن، ۰٫۲۵ تا ۴.
response_formatmp3 (پیش‌فرض) | opus | aac | flac | wav | pcm.
inputمتن، حداکثر ۳٬۰۰۰ کاراکتر در هر درخواست؛ متن بلندتر خطای ۴۰۰ با کد input_too_long می‌گیرد، پیش از آنکه هزینه‌ای کم شود.

صداهای Gemini: Zephyr، Puck، Charon، Kore، Fenrir، Leda، Orus، Aoede، Callirrhoe، Autonoe، Enceladus، Iapetus، Umbriel، Algieba، Despina، Erinome، Algenib، Rasalgethi، Laomedeia، Achernar، Alnilam، Schedar، Gacrux، Pulcherrima، Achird، Zubenelgenubi، Vindemiatrix، Sadachbia، Sadaltager، Sulafat

گفت‌وگوی دو نفره

در speakers دقیقاً دو گوینده را با نام و صدا تعریف کنید و هر خط input را با نام گوینده و دونقطه شروع کنید. خطی که نام نداشته باشد، مال گویندهٔ خط قبلی است. اگر فقط یک گوینده بفرستید، گفت‌وگو ساخته نمی‌شود و متن با صدای voice خوانده می‌شود. این حالت برای پادکست، تبلیغ دیالوگی یا آموزش پرسش و پاسخ مناسب است.

cURL
curl https://netarz.ir/api/ai/v1/audio/speech \
  -H "Authorization: Bearer $NETARZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": "سارا: امروز دربارهٔ API هوش مصنوعی حرف می‌زنیم.\nعلی: یعنی با یک کلید به چند مدل وصل می‌شویم؟\nسارا: دقیقاً همین‌طور است.",
    "speakers": [
      {"speaker": "سارا", "voice": "Leda"},
      {"speaker": "علی", "voice": "Puck"}
    ],
    "instructions": "گفت‌وگوی صمیمی یک پادکست"
  }' --output podcast.mp3

گفتار و صدا از راه OpenRouter

مدل‌های صوتی دیگر هم با شناسهٔ openrouter/… از همین دو endpoint کار می‌کنند: برای متن به گفتار ElevenLabs، MiniMax، Deepgram Aura، Fish Audio و Qwen TTS، و برای گفتار به متن ElevenLabs Scribe، Deepgram Nova، AssemblyAI، Voxtral و Qwen ASR. چند تفاوت دارند:

  • متن به گفتار: خروجی mp3 است، یا pcm اگر صریح بخواهید؛ قالب‌های دیگر به mp3 برمی‌گردند. هر درخواست حداکثر ۳٬۰۰۰ کاراکتر. نام صداهای هر مدل در capabilities.voices آمده است (مثلاً sarah در ElevenLabs).
  • گفتار به متن: پاسخ json یا verbose_json است؛ srt و vtt از این مدل‌ها نمی‌آید و مسیر /audio/translations برایشان نیست.
  • هزینه: هزینهٔ واقعی‌ای که سرویس‌دهنده برای همان درخواست حساب می‌کند. واحد قیمت هر مدل در فهرست آمده است: هر یک میلیون کاراکتر، هر دقیقه، یا توکنی.

قیمت‌گذاری

  • گفتار به متن دقیقه‌ای (whisper-1 و gpt-transcribe): به‌ازای هر دقیقه (per_minute)، با محاسبهٔ دقیق به ثانیه بر اساس مدت‌زمانی که ارائه‌دهنده گزارش می‌کند. اگر مدت گزارش نشود، از حجم فایل برآورد می‌شود.
  • مدل‌های توکنی (سری gpt-4o-transcribe): بر اساس توکن‌های صوتی ورودی و متن خروجی که OpenAI گزارش می‌کند.
  • Gemini 3.5 Transcribe: توکنی؛ صوت ورودی حدود ۲۵ توکن برای هر ثانیه، به‌علاوهٔ توکن‌های متن خروجی، با نرخ توکن همان مدل.
  • متن به گفتار OpenAI: به‌ازای هر یک میلیون کاراکتر ورودی (per_million_characters).
  • Gemini TTS: توکنی؛ مبنای هزینه طول صدای ساخته‌شده است، هر ثانیه گفتار حدود ۲۵ توکن صوتی، به‌علاوهٔ توکن‌های متن ورودی.

نرخ هر مدل به تومان و دلار در صفحهٔ مدل‌ها آمده است.

مبلغ رزرو پیش از درخواست از حجم فایل (برای صوت) یا طول متن (برای گفتار) برآورد می‌شود و پس از پاسخ با مصرف واقعی تسویه می‌شود.