अपलोड केल्यावर ट्रान्सक्रिप्ट नाही, तर एक जॉब मिळतो. प्रत्येक create ला Idempotency-Key द्या, म्हणजे retry मुळे दुसरे ट्रान्सक्रिप्शन तयार होणार नाही किंवा त्याचे पैसे आकारले जाणार नाहीत; मग जॉब पूर्ण होईपर्यंत पोल करा, आणि त्याच id वरून वाक्ये, शब्द किंवा एक्सपोर्ट वाचा.
फाइल ट्रान्सक्रिप्शन हे VocalStack API ने करता येणारे सर्वात सोपे काम आहे, आणि त्याचा आकार कोणत्याही असिंक्रोनस जॉबसारखा आहे: अपलोड करा, थांबा, वाचा. अपलोड लगेच उत्तर देतो, त्यात एक ट्रान्सक्रिप्शन आणि त्याचा जॉब असतो, पण अजून एकही शब्द नसतो. तुमचा प्रोग्राम जॉबची पोलिंग करत असताना, सर्व्हर फाइल ऑडिओ वाजण्याच्या कितीतरी पट वेगाने ट्रान्सक्रिप्ट करतो. state done झाल्यावर तुम्ही ट्रान्सक्रिप्ट वक्त्यांसह आणि वेळेसह वाक्यांच्या स्वरूपात वाचता, किंवा चार फॉरमॅटपैकी एका स्वरूपात फाइल म्हणून एक्सपोर्ट करता, बोलल्या गेलेल्या भाषेत किंवा भाषांतरित स्वरूपात.
या आकारातील प्रत्येक गोष्ट कोणत्याही बॅच API ला लागू होते: id देणारे create, पोल करायचे status, आणि नंतर घ्यायचा result. फक्त फील्डची नावे VocalStack ची आहेत, आणि हा ट्यूटोरियल TypeScript आणि Python SDK तसेच जिथे उपयोगी ठरतील तिथे HTTP कॉल्स वापरून ते दाखवतो.
VocalStack डॅशबोर्डमध्ये Developers → API keys उघडा आणि Read व Write परवानग्यांसह एक key तयार करा. key फक्त एकदाच दाखवली जाते; ती एका environment variable मध्ये कॉपी करा:
export VOCALSTACK_API_KEY="<your API key>"
Key सर्व्हर आणि स्क्रिप्टसाठी असते. ब्राउझरमध्ये जाणारी कोणतीही गोष्ट key सोबत पाठवली जाते, म्हणून ती पेज कोडमध्ये आणि URL मध्ये ठेवू नका, कारण URL लॉगमध्ये जातात. ब्राउझरमधून स्ट्रीम करण्यासाठी तुमचा सर्व्हर त्यासाठी realtime session तयार करतो; ते वेगळ्या ट्यूटोरियलमध्ये आहे.
प्रत्येक कॉल key ला bearer token म्हणून प्रमाणित करतो:
Authorization: Bearer vs_key_...
तुमच्या environment मध्ये key असेल की पुढची गोष्ट म्हणजे ती पाठवण्यासाठी एक client.
दोन SDK आहेत. प्रत्येकात एकच client असतो, VocalStack, आणि त्याच्या मेथड्स resource नुसार गटबद्ध असतात: vs.transcriptions, vs.jobs, vs.recordings, vs.realtime आणि आणखी काही. TypeScript SDK Node 20 किंवा नवीन आवृत्तीवर आणि ब्राउझरमध्ये चालते; Python SDK asyncio वर बनलेला आहे आणि त्यासाठी Python 3.10 किंवा नवीन आवृत्ती लागते.
SDK npm किंवा PyPI वर नाहीत. API हे build प्रत्येक खात्याला देतो. तुमच्या वातावरणासाठी भरलेल्या इन्स्टॉल कमांड्स API reference मधील quickstart च्या Install विभागात आहेत, आणि त्या तुमची key फक्त API होस्टलाच पाठवतात. काहीच इन्स्टॉल करायचे नसेल, तर खालील HTTP कॉल्सना फक्त curl आणि jq लागतात.
तुम्ही जे काही निवडाल, पहिला कॉल अपलोडचा असतो.
POST /v1/transcriptions फाइल multipart/form-data म्हणून घेतो: एक file भाग, आणि त्यासोबत JSON असलेला ऐच्छिक options भाग. तो 201 सोबत ट्रान्सक्रिप्शन परत करतो. त्याचा job.recordingId म्हणजे फाइलपासून बनलेल्या रेकॉर्डिंगचा id, आणि त्यानंतरचे प्रत्येक कॉल त्या id ने संबोधले जातात.
पहिल्या रनसाठी दोन सेटिंग्ज महत्त्वाच्या आहेत, दोन्ही options.settings च्या आत:
spokenLanguage: en सारखा कोड. तो सोडून दिला तर भाषा ओळखली जाते. तो नाव देऊन सांगितल्यास गोंगाटाच्या रेकॉर्डिंगमध्ये आणि जड उच्चारांमध्ये अचूकता सुधारते.speakerLabels: auto, on किंवा off. on असेल तर प्रत्येक वाक्यासोबत वक्त्याचा क्रमांक येतो; auto असेल तर दुसरा वक्ता बोलल्यानंतरच लेबल दिसतात.बहुतेक ऑडिओ आणि व्हिडिओ फाइल्स स्वीकारल्या जातात: mp3, wav, flac, ogg, m4a, mp4 आणि इतर. व्हिडिओतून फक्त ऑडिओ ठेवला जातो. फॉरमॅट अचूकतेवर फारसा परिणाम करत नाही, कारण स्पीच रेकग्निशन 16 kHz mono वर चालते आणि आल्यावर सर्वकाही त्यावर resample करून घेतले जाते. एका व्यक्तीच्या बोलण्याची 48 kHz stereo WAV फाइल आपल्या बहुतेक bytes शांततेचे उच्च दर्जाचे वर्णन करण्यात खर्च करते. ती 64 kbps mono MP3 किंवा Opus फाइलइतक्याच अचूकतेने ट्रान्सक्रिप्ट होते, पण ती सुमारे वीसपट मोठी असते, त्यामुळे अपलोडलाही वीसपट वेळ लागतो. अपलोड करण्यापूर्वी तुम्ही रूपांतर केले, तर mono आणि माफक bitrate या दोनच सेटिंग्ज बदलण्यासारख्या आहेत.
प्रत्येक अपलोडसोबत Idempotency-Key पाठवा, आणि ते का ते समजून घ्या. नेटवर्क timeout वरून सर्व्हरने काय केले हे कळत नाही: त्याने विनंती कधी पाहिलीच नसेल, किंवा उत्तर हरवण्यापूर्वी फाइल साठवून जॉब रांगेत टाकला असेल. त्यामुळे आंधळा retry दुसऱ्या ट्रान्सक्रिप्शनचा आणि दुसऱ्या बिलाचा धोका निर्माण करतो. key ही समस्या सोडवते. एकच key आणि एकच body असलेली विनंती 24 तासांच्या आत पुन्हा आली, तर सर्व्हर काहीही नवीन तयार न करता पहिलेच उत्तर परत करतो, आणि "किमान एकदा" हे "प्रभावीपणे एकदाच" होते. म्हणून नियम असा: प्रत्येक तार्किक अपलोडसाठी एक key, पहिल्या प्रयत्नापूर्वी तयार केलेली आणि प्रत्येक retry मध्ये पुन्हा वापरलेली. प्रत्येक प्रयत्नासाठी नवीन key दिली तर प्रत्येक retry नवीन अपलोड ठरेल आणि header काहीच संरक्षण देणार नाही.
import { VocalStack } from '@vocalstack/sdk';
const vs = new VocalStack({ baseUrl: '{{api}}', apiKey: process.env.VOCALSTACK_API_KEY });
const uploadKey = crypto.randomUUID(); // one key for this upload, however many attempts it takes
const tx = await vs.transcriptions.create(
{ file: './talk.mp3', name: 'Talk', settings: { spokenLanguage: 'en', speakerLabels: 'on' } },
{ idempotencyKey: uploadKey },
);
const recordingId = tx.job!.recordingId;
import asyncio
import os
import uuid
from vocalstack import VocalStack
async def main() -> None:
upload_key = str(uuid.uuid4()) # one key for this upload, however many attempts it takes
async with VocalStack("{{api}}", api_key=os.environ["VOCALSTACK_API_KEY"]) as vs:
tx = await vs.transcriptions.create(
file="./talk.mp3",
name="Talk",
settings={"spokenLanguage": "en", "speakerLabels": "on"},
idempotency_key=upload_key,
)
assert tx.job is not None
recording_id = tx.job.recording_id
curl वापरून तोच कॉल:
API={{api}}
AUTH="Authorization: Bearer $VOCALSTACK_API_KEY"
UPLOAD_KEY=$(uuidgen)
REC=$(curl -sSf "$API/v1/transcriptions" -H "$AUTH" -H "Idempotency-Key: $UPLOAD_KEY" \
-F file=@talk.mp3 \
-F 'options={"name":"Talk","settings":{"spokenLanguage":"en","speakerLabels":"on"}}' \
| jq -r .job.recordingId)
201 एकही शब्द ट्रान्सक्रिप्ट होण्यापूर्वीच येतो; तुमच्या हातात जॉब id असतो, त्यामुळे पुढची पायरी म्हणजे त्या जॉबची वाट पाहणे.
जॉब queued → transcribing → done असा पुढे जातो, किंवा failed वर संपतो, त्यासोबत error संदेश आणि कारण यंत्र-वाचनीय असेल तर errorCode. चौथी state, cropping, म्हणजे कोणीतरी ट्रान्सक्रिप्ट करायचा रेकॉर्डिंगचा कोणता भाग निवडेपर्यंत जॉब थांबलेला असतो, जसे Dashboard च्या trim पायरीत होते. साधा अपलोड कधीच या state मध्ये जात नाही, जरी jobs.wait जॉब तिथे पोहोचला तरी परत येतो. state done किंवा failed होईपर्यंत GET /v1/recordings/{id}/job वाचा.
येथे webhooks नाहीत, आणि ही जाणीवपूर्वक घेतलेली तडजोड आहे. Webhook ला तुमच्या बाजूला सार्वजनिक HTTPS endpoint, कोणी दुसऱ्याने कॉल करू नये म्हणून signature तपासणी, आणि तुमचा endpoint बंद असताना retry धोरण लागते. एका मिनिटाच्या जॉबसाठी हे खूपच plumbing आहे. Polling ला यातले काहीच लागत नाही. तुमची स्क्रिप्ट दर दोन सेकंदांनी "झाले का?" असे विचारेल, मागच्या सीटवरच्या लहान मुलासारखी; पण त्या मुलाच्या विरुद्ध, तिला टक्केवारी परत मिळते.
आधीच उघडे असलेले वेब पेज त्याऐवजी ट्रान्सक्रिप्शनचा events socket वापरू शकते (WS /v1/transcriptions/{id}/events, जॉब पुढे सरकताना job.progress frame). स्क्रिप्टसाठी polling हेच योग्य साधन आहे.
SDK polling करतात: vs.jobs.wait दर 2 सेकंदांनी जॉब वाचतो आणि प्रत्येक वाचन onProgress ला देतो (Python मध्ये on_progress). जॉबच्या progress मध्ये pct (0 ते 100) आणि processedS असतात, म्हणजे आतापर्यंत ट्रान्सक्रिप्ट झालेले मीडियाचे सेकंद. खालील प्रोग्राम्स state किंवा टक्केवारी बदलली तरच एक ओळ छापतात.
let last = '';
const job = await vs.jobs.wait(recordingId, {
onProgress: (j) => {
const line = `${j.state} ${j.progress.pct}%`;
if (line !== last) console.log((last = line));
},
});
if (job.state !== 'done') throw new Error(`transcription ${job.state}: ${job.error ?? ''}`);
last = ""
def on_progress(j) -> None:
nonlocal last
line = f"{j.state} {j.progress.pct}%"
if line != last:
last = line
print(line)
job = await vs.jobs.wait(recording_id, on_progress=on_progress)
if job.state != "done":
raise RuntimeError(f"transcription {job.state}: {job.error}")
लक्षात ठेवा की wait failed वर exception देत नाही; तो जॉब परत देतो आणि तपासणी तुमच्यावर सोडतो. एका talk साठी दोन सेकंद योग्य आहेत. तीन तासांच्या रेकॉर्डिंगसाठी किंवा शेकडो फाइल्सच्या बॅचसाठी अंतर वाढवा (intervalMs, interval_s), किंवा जॉब चालू असताना हळूहळू अंतर वाढवा: सुरुवातीची वाचने सर्वात जास्त सांगतात, नंतरची बहुतेक फक्त सर्व्हर अजून व्यस्त आहे याची खात्री करतात. SDK शिवाय, तेच लूप हाताने लिहा:
while :; do
JOB=$(curl -sSf "$API/v1/recordings/$REC/job" -H "$AUTH")
STATE=$(jq -r .state <<<"$JOB")
echo "$STATE $(jq -r .progress.pct <<<"$JOB")%"
case $STATE in
done) break ;;
failed) jq -r .error <<<"$JOB" >&2; exit 1 ;;
esac
sleep 2
done
state done वाचले की ट्रान्सक्रिप्ट तयार आहे.
GET /v1/recordings/{id}/transcript संपूर्ण ट्रान्सक्रिप्ट एकाच दस्तऐवजात परत करतो:
sentences: लोकांना दाखवायचे. प्रत्येकात text, speaker, आणि सेकंदांमध्ये start व end असतात.segments: इंजिनच्या ओळी, प्रत्येकात words मध्ये शब्द-स्तरीय वेळा (प्रत्येक शब्दात text, start आणि end असतात).speakers: प्रत्येक वक्त्याच्या क्रमांकासाठी एक नोंद, तिच्या name सह.वक्त्यांचे क्रमांक 0 पासून सुरू होतात. speaker -1 असेल तर त्या रेकॉर्डिंगसाठी speaker labels बंद होते. स्पॅनिशमध्ये भाषांतरित ट्रान्सक्रिप्ट वाचण्यासाठी ?lang=es जोडा; वाक्ये त्या भाषेत परत येतात.
const { sentences } = await vs.recordings.transcript(recordingId);
for (const s of sentences) console.log(s.speaker >= 0 ? `[speaker ${s.speaker}] ${s.text}` : s.text);
snapshot = await vs.recordings.transcript(recording_id)
for s in snapshot.sentences:
print(f"[speaker {s.speaker}] {s.text}" if s.speaker >= 0 else s.text)
curl -sSf "$API/v1/recordings/$REC/transcript" -H "$AUTH" \
| jq -r '.sentences[] | if .speaker >= 0 then "[speaker \(.speaker)] \(.text)" else .text end'
दोन वेळ-स्तर दोन कामांसाठी आहेत. वाक्ये वाचण्याचे एकक आहेत, म्हणून सबटायटल किंवा ट्रान्सक्रिप्ट पेज त्यांनाच दाखवते. शब्द निर्देशित करण्याचे एकक आहेत, म्हणून karaoke-शैलीतील हायलाइट, शोध-परिणाम किंवा क्लिप कापणी segments[].words मधून जाते. एक्सपोर्ट फॉरमॅट वाक्यांवरूनच बनतात.
GET /v1/recordings/{id}/export एक खरी फाइल परत करतो. format हे srt, json, xlsx किंवा pdf पैकी एक असते, आणि फाइलमध्ये केलेल्या सर्व दुरुस्त्या असतात. भाषांतरित फाइलसाठी lang= जोडा: तेव्हा एक्सपोर्ट त्या भाषेत वाचला जातो, प्रत्येक वाक्यासाठी एक ओळ, आणि जे वाक्य अजून भाषांतरित नाही ते आधी भाषांतरित केले जाते.
SRT ओळखीचा असणे उपयोगी आहे, कारण हे सबटायटल फॉरमॅट जवळजवळ प्रत्येक player स्वीकारतो आणि ते साधा मजकूर आहे. फाइल म्हणजे रिकाम्या ओळींनी वेगळे केलेल्या cues ची यादी, आणि प्रत्येक cue मध्ये एक क्रमांक, वेळेचा कालावधी आणि मजकूर असतो. मिलिसेकंदांआधी वेळेत स्वल्पविराम वापरला जातो, ही एक फ्रेंच सवय आहे जी हा फॉरमॅट कधीच सोडू शकला नाही:
1
00:00:01,000 --> 00:00:04,200
Welcome, everyone. Let's get started.
प्रत्येक cue मध्ये एक वाक्य हे योग्य प्रमाण आहे: प्रत्येक cue स्क्रीनवर असलेल्या वेळेत वाचता येतो, आणि कोणताही विचार मध्येच तुटत नाही. रेकॉर्डिंगमध्ये speaker labels असतील, तर प्रत्येक cue चा मजकूर वक्त्याच्या नावाने आणि कोलनने सुरू होतो.
TypeScript SDK मध्ये vs.recordings.export एक Response परत करतो; त्याचे bytes arrayBuffer() ने वाचा. Python मध्ये ते bytes परत करते.
import { writeFile } from 'node:fs/promises';
const srt = await vs.recordings.export(recordingId, 'srt');
await writeFile('talk.srt', Buffer.from(await srt.arrayBuffer()));
const pdf = await vs.recordings.export(recordingId, 'pdf', { lang: 'es' });
await writeFile('talk.es.pdf', Buffer.from(await pdf.arrayBuffer()));
srt = await vs.recordings.export(recording_id, "srt")
with open("talk.srt", "wb") as f:
f.write(srt)
pdf = await vs.recordings.export(recording_id, "pdf", lang="es")
with open("talk.es.pdf", "wb") as f:
f.write(pdf)
asyncio.run(main())
curl -sSf "$API/v1/recordings/$REC/export?format=srt" -H "$AUTH" -o talk.srt
curl -sSf "$API/v1/recordings/$REC/export?format=pdf&lang=es" -H "$AUTH" -o talk.es.pdf
ट्रान्सक्रिप्शन साठवले जाते, म्हणून ते Dashboard मध्ये Transcriptions खाली दिसते, लिंकने शेअर करता येते, आणि नंतर कधीही पुन्हा वाचता येते. हाच मुख्य चक्र आहे: create, wait, read, export. या ट्यूटोरियलचा उर्वरित भाग त्यातील प्रकार सांगतो: आधीच ऑनलाइन असलेला मीडिया, तुम्हाला भेटणाऱ्या त्रुटी, आणि एका फाइलचा खर्च.
मीडिया आधीच ऑनलाइन असेल, तर API ला लिंक द्या आणि तो फाइल स्वतः आणेल: सार्वजनिक http(s) पत्ता (mp3, व्हिडिओ, podcast चा भाग) किंवा YouTube व्हिडिओ. कॉल तोच POST /v1/transcriptions आहे, फक्त multipart अपलोडऐवजी JSON body { "url": "..." } आहे, आणि name व settings पूर्वीप्रमाणेच. SDK मध्ये vs.transcriptions.createFromUrl(url) (TypeScript) आणि vs.transcriptions.create(url=...) (Python) तीच विनंती करतात.
काहीही तयार करण्यापूर्वी, GET /v1/transcriptions/probe?url= सांगते की लिंक काय आहे. तिचा kind तीनपैकी एक असतो:
file: शेवट असलेले रेकॉर्डिंग; येथे ट्रान्सक्रिप्ट करा.live: YouTube लाइव्ह स्ट्रीम, न संपणारा radio स्ट्रीम किंवा शेवट नसलेली HLS playlist. लाइव्ह लिंक कधीच संपत नाही, म्हणून तिला फाइल म्हणून ट्रान्सक्रिप्ट करता येत नाही; त्याऐवजी ती लाइव्ह ट्रान्सक्रिप्शनचा स्रोत म्हणून वापरा.unknown: सर्व्हरला ते ओळखता आले नाही.लिंक मीडिया म्हणून अजिबात उघडत नसेल (उदाहरणार्थ वेब पेज), तर ok false असते आणि problem एका वाक्यात कारण सांगते. probe ऐच्छिक आहे, आणि तो प्रति मिनिट 60 कॉल्सपुरता मर्यादित आहे.
लिंक जॉब fetching मध्ये सुरू होतो, मग transcribing आणि done मध्ये जातो. आणताना progress.phase सर्व्हर काय करत आहे ते सांगते: बाइट्स येत असताना fetching (आणि दुसरी बाजू एकूण किती ते सांगत असेल तर fetchedBytes व fetchTotalBytes सह), किंवा व्हिडिओमधून ऑडिओ काढताना extracting. progress.phasePct त्या टप्प्यात जॉब किती पुढे आहे ते सांगते. लांब व्हिडिओला वेळ लागतो, म्हणून दर काही सेकंदांनी पोल करा; त्यासाठी vs.jobs.wait intervalMs (Python मध्ये interval_s) घेतो.
const probe = await vs.transcriptions.probe(url);
if (!probe.ok) throw new Error(`that link did not open: ${probe.problem}`);
if (probe.kind === 'live') throw new Error('a live link: record it with a live transcription instead');
const linkKey = crypto.randomUUID();
const tx = await vs.transcriptions.createFromUrl(url, { name: 'From a link' }, { idempotencyKey: linkKey });
const job = await vs.jobs.wait(tx.job!.recordingId, {
intervalMs: 3000,
onProgress: (j) => {
const p = j.progress;
if (j.state === 'fetching') console.log(`${p.phase ?? 'fetching'} ${p.phasePct ?? 0}%`);
else console.log(`${j.state} ${p.pct}%`);
},
});
Transcribe a link मार्गदर्शकात दोन्ही भाषांत आणि HTTP मध्ये पूर्ण प्रोग्राम आहे. लिंकवरून आणण्यात अपयशाचे आणखी मार्ग आहेत, म्हणून प्रत्यक्षात भेटणाऱ्या त्रुटी येथे आहेत.
प्रत्येक अयशस्वी कॉल एक JSON envelope परत करतो. ज्यावर शाखा घ्यायची ते string code असते आणि status म्हणजे HTTP status; message लोकांसाठी असतो आणि requestId support साठी. data अंतर्गत retryable सांगते की तीच विनंती पुन्हा पाठवल्याने मदत होऊ शकते का, आणि details मध्ये त्या code ला लागणारे सर्व काही असते. SDK एकच error type, VocalStackError, देतात, त्याच फील्ड्ससह.
पहिल्या दिवशीच हाताळण्यासारखे तीन code आहेत.
402 insufficient_credit: खात्याचे क्रेडिट संपले आहे, आणि काहीही आकारले गेले नाही. details.balance डॉलरमध्ये शिल्लक दाखवते आणि details.topUpUrl क्रेडिट जोडण्याचा पत्ता आहे. खर्च आधीच माहीत असतो तेव्हा, जसे ठराविक लांबीच्या फाइलसाठी, details.required सांगते की तो किती झाला असता.429 rate_limited: Retry-After सेकंद थांबा. details.metric creates_per_hour असेल, तर तुम्ही प्लॅनच्या creation rate ची (प्रति तास नवीन ट्रान्सक्रिप्शन) मर्यादा गाठली आहे, burst मर्यादा नाही; limit आणि resetsAt सांगतात की मर्यादा किती आहे आणि ती कधी मोकळी होईल.503 unavailable: सेवा थोड्या वेळासाठी उपलब्ध नाही. Retry-After नंतर विनंती पुन्हा पाठवा.SDK 429 आणि 503 ला Retry-After नंतर retry करतात, डिफॉल्टने दोनदा (client वरील maxRetries / max_retries). पण 503 फक्त अशा कॉलवर retry होतो जो दोनदा पाठवणे सुरक्षित आहे: GET, किंवा Idempotency-Key असलेला create. Idempotency-Key नसलेला create तुमच्यावर सोडलेला असतो, कारण पहिला प्रयत्न पोहोचला की नाही हे SDK ला कळू शकत नाही. प्रत्येक अपलोडवर key ठेवण्याचे व्यावहारिक कारण हेच आहे.
प्रत्येक response मध्ये RateLimit-Limit, RateLimit-Remaining आणि RateLimit-Reset देखील असतात, म्हणजे व्यस्त pipeline 429 येण्यापूर्वीच वेग कमी करू शकते.
{
"code": "insufficient_credit",
"status": 402,
"message": "this account has no credit left; add credit to continue",
"data": {
"retryable": false,
"details": { "balance": -0.42, "required": 0.075, "currency": "usd", "plan": "payg", "topUpUrl": "https://…" }
},
"requestId": "01J…"
}
कोडची संपूर्ण यादी Errors, retries and limits मध्ये आहे. ती 402 त्रुटी ही एकमेव पैशांशी संबंधित त्रुटी आहे, म्हणून येथे एका फाइलचा खर्च सांगितला आहे.
फाइल्ससाठी दर तास ऑडिओला $0.20 आहे, प्रति सेकंद आकारणी होते ($0.0033 प्रति मिनिट) आणि किमान 5 मिनिटांचे बिल असते: 30 मिनिटांच्या फाइलसाठी $0.10 लागतात. हे दहा सेंट आहेत, प्रोग्रेस बार भरत असताना तुम्ही पीत असलेल्या कॉफीपेक्षा कमी. हा दर प्रत्येक प्लॅनसाठी सारखा आहे, आणि API वर तो Dashboard प्रमाणेच आहे. नवीन खात्याला एकदाचे $5 signup credit मिळते, आणि कार्ड लागत नाही.
या ट्यूटोरियलशी तीन प्लॅन मर्यादा संबंधित आहेत.
GET /v1/realtime/capabilities मध्ये limits.maxUploadBytes म्हणून दिसते. दोनपैकी लहान मर्यादा लागू होते, आणि त्यापेक्षा मोठी फाइल काहीही ट्रान्सक्रिप्ट होण्यापूर्वीच 413 ने नाकारली जाते. लांब रेकॉर्डिंगसाठी, WAV ऐवजी संकुचित mono फाइल अपलोड करण्याचे आणखी एक कारण हेच आहे.GET /v1/billing तुमचा प्लॅन, शिल्लक आणि मर्यादा कधीही सांगते; संपूर्ण तक्ता pricing page वर आहे.
येथून पुढची पावले: जेव्हा फाइल पूर्ण होण्याची वाट पाहणे शक्य नसते तेव्हा रिअल-टाइममध्ये ऑडिओ स्ट्रीम करणे, किंवा वरील कोणताही कोड न लिहिता, ट्रान्सक्रिप्ट करणारा आणि शोधणारा AI agent जोडणे त्याच खात्याशी MCP सर्व्हरद्वारे.