API Anahtarınızı Edinin
Konuşmatik web panelinizden (Profil / API Anahtarları) bir anahtar oluşturun ve KONUSMATIK_API_KEY ortam değişkeninde saklayın.
Yerel Konuşmatik TTS ve ASR modellerini REST API veya Realtime WebSocket üzerinden uygulamalarınıza entegre edin.
Konuşmatik API servislerine doğrudan REST uç noktaları veya OpenAI Python SDK üzerinden bağlanabilirsiniz.
Konuşmatik web panelinizden (Profil / API Anahtarları) bir anahtar oluşturun ve KONUSMATIK_API_KEY ortam değişkeninde saklayın.
Canonical uç noktalar resmi OpenAI Python SDK ve cURL istekleriyle doğrudan uyumludur. Yüksek hacimli toplu işler için Kurumsal Asenkron API kullanın.
Resmi model isimleri: konusmatik-asr-v2 ve konusmatik-tts-v2. TTS sesleri: sila, deniz, taha.
https://api.konusmatik.com/api/v1wss://api.konusmatik.com/api/v1/realtimeTüm API isteklerinizi HTTP Authorization başlığı altında API anahtarınız ile gönderin.
Authorization: Bearer $KONUSMATIK_API_KEYMevcut OpenAI SDK entegrasyonunuzda yalnızca base_url, API anahtarı ve Konuşmatik model adını tanımlayın. ASR, TTS ve model listeleme işlemlerini standart SDK metotlarıyla çağırın.
Resmi openai paketini kurarak başlayın:
pip install openai # Linux / macOSexport KONUSMATIK_API_KEY="km_live_..." # Windows PowerShell$env:KONUSMATIK_API_KEY="km_live_..." # Windows CMDset KONUSMATIK_API_KEY=km_live_...Konuşmatik TTS, Türkçe metinleri doğal ve akıcı biçimde seslendirir. Sesin tamamı oluşturulduktan sonra üretilen ses verisi istemciye tek bir kayıpsız WAV dosyası olarak döner. Bu yapı özellikle ses dosyası oluşturma, arşivleme ve tamamlanmış içeriğin sonradan oynatıldığı uygulamalar için uygundur.
/audio/speechSesin tamamı üretildikten sonra başarılı yanıt tek bir audio/wav binary içeriği döndürür. (WAV-Only)
Asistan, müşteri deneyimi, eğitim ve uzun anlatımlar için dengeli doğal kadın sesi.
Haber bültenleri, kurumsal duyurular ve resmi açıklamalar için net kadın sesi.
Diyaloglar, kısa bilgilendirmeler ve dinamik içerikler için modern erkek sesi.
| Parametre | Tür | Zorunlu | Varsayılan | Açıklama |
|---|---|---|---|---|
model | string | Evet | konusmatik-tts-v2 | Üretim TTS model adı: konusmatik-tts-v2 |
input | string | Evet | - | Seslendirilecek metin (Maksimum 10.000 karakter). |
voice | string | Evet | sila | Ses seçimi: sila (Kadın), deniz (Kadın), taha (Erkek). |
response_format | string | Hayır | wav | Üretim standardı gereği WAV-only format desteklenir. (audio/wav) |
speed | number | Hayır | 1.0 | Konuşma hızı çarpanı (0.25 - 4.0). |
import osfrom pathlib import Pathfrom openai import OpenAI client = OpenAI( api_key=os.environ["KONUSMATIK_API_KEY"], base_url="https://api.konusmatik.com/api/v1",) speech_file_path = Path("speech.wav") with client.audio.speech.with_streaming_response.create( model="konusmatik-tts-v2", voice="sila", input="Merhaba, Konuşmatik API testine hoş geldiniz.", response_format="wav",) as response: response.stream_to_file(speech_file_path) print(f"Ses dosyası kaydedildi: {speech_file_path}")Konuşmatik Streaming TTS, sesin tamamının oluşturulmasını beklemeden üretilen ses verisini istemciye aktarmaya başlar. Bu yapı özellikle gerçek zamanlı ses oynatma, sesli asistanlar ve düşük gecikmeli uygulamalar için uygundur.
/audio/speechPCM ses verisini parça parça aktarır.
Streaming TTS isteklerinde response_format değeri pcm olmalıdır.
import asyncioimport osfrom openai import AsyncOpenAIimport openai.helpers.local_audio_player as lapfrom openai.helpers import LocalAudioPlayer lap.SAMPLE_RATE = 48000 openai = AsyncOpenAI( api_key=os.environ["KONUSMATIK_API_KEY"], base_url="https://api.konusmatik.com/api/v1",) async def main() -> None: async with openai.audio.speech.with_streaming_response.create( model="konusmatik-streaming-tts-v2", voice="deniz", input="Merhaba, Konuşmatik Streaming TTS ile ses gerçek zamanlı olarak oluşturulmaktadır.", response_format="pcm", ) as response: await LocalAudioPlayer().play(response) if __name__ == "__main__": asyncio.run(main())Content-Type: audio/pcm
X-Audio-Sample-Rate: <sample_rate>
X-Audio-Channels: <channels>
X-Audio-Format: pcm_s16le
X-Request-ID: <request_id>Ses verileri stream üzerinden parça parça iletilir. Chunk boyutları sabit değildir ve istemci uygulamaları chunk sınırlarına bağlı bir mantık oluşturmamalıdır. Gelen PCM verileri sırasıyla oynatılabilir, kaydedilebilir veya farklı bir ses formatında işlenebilir.
100 MB boyuta ve 3 saate kadar ses dosyalarını yüksek doğrulukla Türkçe metne dönüştürün.
/audio/transcriptionsİstek gövdesi multipart/form-data olarak gönderilmelidir.
| Parametre | Tür | Zorunlu | Varsayılan | Açıklama |
|---|---|---|---|---|
file | file | Evet | - | Ses dosyası (Maksimum 100 MB, Maksimum 3 saat / 10.800s). |
model | string | Evet | konusmatik-asr-v2 | Üretim ASR model adı: konusmatik-asr-v2 |
language | string | Hayır | tr | Ses dili (Varsayılan: tr). Şu an yalnızca Türkçe desteklenir; diğer değerler 400 unsupported_language hatası döner. |
response_format | string | Hayır | json | json, text veya verbose_json. |
import osfrom openai import OpenAI client = OpenAI( api_key=os.environ["KONUSMATIK_API_KEY"], base_url="https://api.konusmatik.com/api/v1",) with open("ses_kaydi.wav", "rb") as audio_file: transcription = client.audio.transcriptions.create( model="konusmatik-asr-v2", file=audio_file, language="tr", response_format="json", ) print("Deşifre Metni:", transcription.text)AsyncOpenAI istemcisiyle mikrofonunuzdan PCM16 ses gönderin ve canlı deşifre olaylarını doğrudan dinleyin.
/realtimeOpenAI Python SDK uyumlu gerçek zamanlı deşifre bağlantısı.
import asyncioimport base64import os import sounddevice as sdfrom openai import AsyncOpenAI SAMPLE_RATE = 24000CHANNELS = 1BLOCK_SIZE = 2400 # 100 ms async def main(): client = AsyncOpenAI( api_key=os.environ["KONUSMATIK_API_KEY"], base_url="https://api.konusmatik.com/api/v1", ) audio_queue = asyncio.Queue() loop = asyncio.get_running_loop() def audio_callback(indata, frames, time, status): if status: print(status) loop.call_soon_threadsafe( audio_queue.put_nowait, bytes(indata), ) async with client.realtime.connect( model="konusmatik-asr-v2", ) as connection: await connection.session.update( session={ "input_audio_format": "pcm16", "turn_detection": { "type": "server_vad", }, } ) async def send_audio(): while True: pcm_chunk = await audio_queue.get() audio_b64 = base64.b64encode(pcm_chunk).decode("ascii") await connection.input_audio_buffer.append( audio=audio_b64, ) async def receive_events(): async for event in connection: if event.type == "conversation.item.input_audio_transcription.delta": print(event.delta, end="", flush=True) elif event.type == "conversation.item.input_audio_transcription.completed": print(f"\nFinal: {event.transcript}") elif event.type == "error": print(f"\nHata: {event}") with sd.RawInputStream( samplerate=SAMPLE_RATE, channels=CHANNELS, dtype="int16", blocksize=BLOCK_SIZE, callback=audio_callback, ): print("Dinleniyor... Ctrl+C ile çıkabilirsiniz.") await asyncio.gather( send_audio(), receive_events(), ) if __name__ == "__main__": asyncio.run(main())Konuşmatik servisleri kamuya açık resmi model kimlikleriyle çalışır.
konusmatik-asr-v2Ses dosyalarını yüksek doğrulukla Türkçe metne dönüştürür.
konusmatik-tts-v2Türkçe metinleri doğal ve akıcı seslendirerek kayıpsız WAV ses çıktısı üretir.
/modelsAktif üretim modellerini listeler.
import osfrom openai import OpenAI client = OpenAI( api_key=os.environ["KONUSMATIK_API_KEY"], base_url="https://api.konusmatik.com/api/v1",) models = client.models.list()for model in models.data: print("Model ID:", model.id)Kurumsal API, yüksek hacimli toplu ASR ve TTS işleri için job tabanlı asenkron kuyruk modeli sunar. POST istekleri inference bitimini beklemez; anında HTTP 201 Created ve job_id döndürür.
Ses dosyasını kuyruğa ekleyin, işi tamamlanana kadar takip edin ve transkripsiyon sonucunu alın.
/corporate/asr/jobsYeni bir ASR işi kuyruğa ekler ve hemen job_id döndürür.
/corporate/asr/jobs/{id}İş durumunu sorgular (pending, processing, completed, failed).
/corporate/asr/jobs/{id}/resultTamamlanan işin transkripsiyon metnini döndürür.
import osimport timeimport requests API_KEY = os.environ["KONUSMATIK_API_KEY"]BASE_URL = "https://api.konusmatik.com/api/v1"HEADERS = {"Authorization": f"Bearer {API_KEY}"} def transcribe_audio_corporate_async(file_path: str) -> str: # 1. İşi Oluştur (HTTP 201 Created döner, bağlantı inference süresince açık kalmaz) with open(file_path, "rb") as f: resp = requests.post( f"{BASE_URL}/corporate/asr/jobs", headers=HEADERS, files={"file": (os.path.basename(file_path), f, "audio/wav")}, data={"language": "tr"} ) resp.raise_for_status() job_id = resp.json()["id"] print(f"İş başarıyla kabul edildi. Job ID: {job_id}") # 2. Polling ile Durumu Sorgula (2-3 saniyelik makul aralık) while True: poll_resp = requests.get(f"{BASE_URL}/corporate/asr/jobs/{job_id}", headers=HEADERS) poll_resp.raise_for_status() job_data = poll_resp.json() status = job_data["status"] if status == "completed": print("İş tamamlandı!") break elif status == "failed": raise RuntimeError(f"İş başarısız oldu: {job_data.get('error_message')}") print(f"Mevcut durum: {status}... Bekleniyor.") time.sleep(2.5) # 3. Sonucu Al result_resp = requests.get(f"{BASE_URL}/corporate/asr/jobs/{job_id}/result", headers=HEADERS) result_resp.raise_for_status() return result_resp.json()["text"] if __name__ == "__main__": text = transcribe_audio_corporate_async("toplanti_kaydi.wav") print("\nTranskripsiyon Sonucu:\n", text)Ses veya video dosyasını yüklemek yerine HTTPS adresini verin; Konuşmatik dosyayı sunucu tarafında indirir ve kuyruğa alır. Yanıt HTTP 202 Accepted döner.
/corporate/asr/jobs/urlUzak bir URL'den asenkron ASR işi oluşturur. /corporate/asr/jobs uç noktası da JSON gövdede audio_url kabul eder.
| Parametre | Tür | Zorunlu | Varsayılan | Açıklama |
|---|---|---|---|---|
audio_url | string | Evet | - | Doğrudan erişilebilir HTTPS ses veya video adresi. Özel/iç ağ adresleri engellenir (SSRF koruması). Maksimum 100 MB. |
language | string | Hayır | tr | Ses dili. Şu an yalnızca Türkçe (tr) desteklenir; diğer değerler 400 unsupported_language döner. |
timestamp_granularities | string[] | Hayır | - | "segment" ve/veya "word". Sonuçta zaman damgalı segment ve kelime listesi döner. |
webhook_id | uuid | Hayır | - | Kayıtlı ve aktif bir webhook uç noktasının kimliği. İş bitince olay bu adrese gönderilir. |
import osimport requests API_KEY = os.environ["KONUSMATIK_API_KEY"]BASE_URL = "https://api.konusmatik.com/api/v1"HEADERS = {"Authorization": f"Bearer {API_KEY}"} # Dosya yüklemeden, uzak bir URL'den asenkron ASR işi başlat (HTTP 202 Accepted)resp = requests.post( f"{BASE_URL}/corporate/asr/jobs/url", headers=HEADERS, json={ "audio_url": "https://cdn.example.com/kayitlar/toplanti.mp3", "language": "tr", "timestamp_granularities": ["segment", "word"], "webhook_id": "WEBHOOK_ID_BURAYA", # opsiyonel },)resp.raise_for_status()job_id = resp.json()["job_id"]print("Job ID:", job_id) # Sonuç: segments, words, srt ve vtt alanlarını içerirresult = requests.get( f"{BASE_URL}/corporate/asr/jobs/{job_id}/result", headers=HEADERS, params={"timestamp_granularities[]": ["segment", "word"]},).json()for word in result["words"][:5]: print(word["word"], word["start"], word["end"])İş oluştururken veya sonuç alırken timestamp_granularities[] ile segment ve/veya word seçin. Sonuç ayrıca srt ve vtt altyazı çıktıları içerir.
/corporate/asr/jobs/{id}/downloadSonuç dosyası için süreli indirme bağlantısı döndürür (url, expires_in_seconds).
| Parametre | Tür | Zorunlu | Varsayılan | Açıklama |
|---|---|---|---|---|
job_id | uuid | Evet | - | İş kimliği. |
status | string | Evet | - | pending, processing, completed veya failed. |
text | string | Hayır | null | Tam transkripsiyon metni. |
segments | array | Hayır | [] | Her biri id, start, end, text içeren zaman damgalı cümleler. |
words | array | Hayır | [] | Her biri word, start, end ve opsiyonel probability içeren kelime zamanları. |
srt / vtt | string | Hayır | null | Hazır altyazı çıktıları. |
error | string | Hayır | null | İş başarısız olduysa hata mesajı. |
/corporate/asr/jobs/syncKısa dosyalar için kuyruk beklemeden sonucu aynı istekte döndürür (HTTP 201).
import osimport requests API_KEY = os.environ["KONUSMATIK_API_KEY"]BASE_URL = "https://api.konusmatik.com/api/v1" # Kısa dosyalar için: sonuç aynı istekte döner (HTTP 201)with open("kisa_kayit.wav", "rb") as f: resp = requests.post( f"{BASE_URL}/corporate/asr/jobs/sync", headers={"Authorization": f"Bearer {API_KEY}"}, files={"file": ("kisa_kayit.wav", f, "audio/wav")}, data={"language": "tr", "timestamp_granularities[]": ["segment", "word"]}, )resp.raise_for_status()print(resp.json()["text"])Polling yapmak yerine, ASR işi tamamlandığında veya başarısız olduğunda Konuşmatik'in HTTPS adresinize imzalı bir olay göndermesini sağlayın.
| Metod | Yol | Açıklama |
|---|---|---|
| POST | /corporate/webhooks | Yeni webhook uç noktası kaydeder. Yanıttaki secret (whsec_...) imza doğrulaması için saklanmalıdır. |
| GET | /corporate/webhooks | Hesabınıza ait tüm webhook uç noktalarını listeler. |
| GET | /corporate/webhooks/{id} | Tek bir uç noktanın ayrıntılarını döndürür. |
| PATCH | /corporate/webhooks/{id} | url, description veya is_active alanlarını günceller (PUT da desteklenir). |
| DELETE | /corporate/webhooks/{id} | Uç noktayı siler. 204 No Content döner. |
| POST | /corporate/webhooks/{id}/rotate-secret | Yeni secret üretir; eski secret 24 saat daha geçerli kalır (kesintisiz geçiş). |
| POST | /corporate/webhooks/{id}/ping | Adresinize anında test olayı gönderir ve yanıt durumunu döndürür. |
| GET | /corporate/webhooks/{id}/deliveries | Son 100 teslimat kaydını (durum, deneme sayısı, hata kodu) listeler. |
İşe bağlamak için ASR iş oluştururken webhook_id gönderin. Uç nokta HTTPS olmalıdır; özel ağ adresleri reddedilir ve yönlendirmeler (redirect) takip edilmez.
import osimport requests API_KEY = os.environ["KONUSMATIK_API_KEY"]BASE_URL = "https://api.konusmatik.com/api/v1"HEADERS = {"Authorization": f"Bearer {API_KEY}"} # 1. Uç nokta kaydet (yalnızca HTTPS)ep = requests.post( f"{BASE_URL}/corporate/webhooks", headers=HEADERS, json={"url": "https://api.sirketiniz.com/hooks/konusmatik", "description": "Üretim"},).json()print("Webhook ID:", ep["id"])print("Secret:", ep["secret"]) # whsec_... güvenli saklayın # 2. Erişilebilirliği test etprint(requests.post(f"{BASE_URL}/corporate/webhooks/{ep['id']}/ping", headers=HEADERS).json()) # 3. ASR işine bağlarequests.post( f"{BASE_URL}/corporate/asr/jobs/url", headers=HEADERS, json={"audio_url": "https://cdn.example.com/a.mp3", "webhook_id": ep["id"]},) # 4. Teslimat geçmişifor d in requests.get(f"{BASE_URL}/corporate/webhooks/{ep['id']}/deliveries", headers=HEADERS).json(): print(d["event_type"], d["status"], d["attempt_count"]) # 5. Secret rotasyonu (eski secret 24 saat geçerli)new = requests.post(f"{BASE_URL}/corporate/webhooks/{ep['id']}/rotate-secret", headers=HEADERS).json()print(new["secret"], new["secret_previous_expires_at"])Desteklenen olaylar: asr.job.completed ve asr.job.failed. Her istek POST + application/json olarak gelir.
{ "event_id": "evt_3f9a1c...", "event_type": "asr.job.completed", "event_version": "1", "created_at": "2026-11-02T10:15:30Z", "data": { "job_id": "8c1f6a52-...", "status": "completed", "result_url": "https://api.konusmatik.com/api/v1/corporate/asr/jobs/8c1f6a52-.../result" }}| Hata Kodu | Açıklama |
|---|---|
INSUFFICIENT_QUOTA | Kota yetersiz. |
AUDIO_DOWNLOAD_FAILED | audio_url indirilemedi. |
SECURITY_VIOLATION | URL güvenlik politikası tarafından engellendi. |
TIMEOUT_EXCEEDED | İşlem zaman aşımına uğradı. |
INVALID_AUDIO_FORMAT | Desteklenmeyen ses/video formatı. |
ASR_PROCESSING_FAILED | Genel işleme hatası. |
İmza, HMAC_SHA256(secret, "{timestamp}." + ham_gövde) değerinin hex karşılığıdır. İmzayı ham gövde üzerinden, sabit zamanlı karşılaştırmayla doğrulayın ve 5 dakikadan eski zaman damgalarını reddedin.
| Başlık | Örnek | Açıklama |
|---|---|---|
X-Konusmatik-Event | asr.job.completed | Olay türü. |
X-Konusmatik-Event-ID | evt_... | Benzersiz olay kimliği; tekrar teslimatlarda aynıdır (idempotency için kullanın). |
X-Konusmatik-Timestamp | 1767225600 | İmza zamanı (Unix saniye). |
X-Konusmatik-Signature | v1=<hex>[,v1=<hex>] | HMAC-SHA256 imzası. Secret rotasyonu sırasında iki imza birlikte gelir. |
import hashlibimport hmacimport time from flask import Flask, request, abort app = Flask(__name__)SECRET = "whsec_..." # kayıt sırasında aldığınız secretTOLERANCE_SECONDS = 300seen_event_ids = set() # üretimde kalıcı bir depo kullanın def verify(raw_body: bytes, signature_header: str, timestamp: str) -> bool: if abs(time.time() - int(timestamp)) > TOLERANCE_SECONDS: return False # replay koruması signed = f"{timestamp}.".encode() + raw_body expected = hmac.new(SECRET.encode(), signed, hashlib.sha256).hexdigest() for part in signature_header.split(","): part = part.strip() if part.startswith("v1=") and hmac.compare_digest(part[3:], expected): return True return False @app.post("/hooks/konusmatik")def konusmatik_hook(): raw = request.get_data() # JSON parse etmeden önce HAM gövdeyi kullanın if not verify(raw, request.headers["X-Konusmatik-Signature"], request.headers["X-Konusmatik-Timestamp"]): abort(401) event = request.get_json() if event["event_id"] in seen_event_ids: return "", 200 # tekrar teslimat seen_event_ids.add(event["event_id"]) if event["event_type"] == "asr.job.completed": print("Sonuç hazır:", event["data"]["result_url"]) elif event["event_type"] == "asr.job.failed": print("Hata:", event["data"]["error"]["code"]) return "", 200 # 2xx dönün, aksi halde yeniden denenir2xx yanıtı başarılı sayılır. 408, 429 ve 5xx yanıtları ile ağ hataları toplam 6 denemeye kadar üstel bekleme ile tekrarlanır; diğer 4xx yanıtlar kalıcı hata sayılır ve tekrar denenmez. Başarısız teslimatlar deliveries kaydında dead_letter durumuna geçer. Yanıtınızı 10 saniye içinde döndürün.
| Deneme | Bekleme |
|---|---|
1 | Anında |
2 | ~30 saniye |
3 | ~2 dakika |
4 | ~10 dakika |
5 | ~30 dakika |
6 | ~2 saat |
Konuşmatik Asenkron TTS, ses sentezi isteğini kuyruğa alır ve sesin oluşturulmasını beklemeden istemciye bir job_id döner. İşlem arka planda tamamlandıktan sonra durum job_id ile takip edilebilir ve üretilen ses tek bir kayıpsız WAV dosyası olarak indirilebilir. Bu yapı özellikle yüksek hacimli, toplu veya uzun süren ses üretim işleri için uygundur.
/corporate/tts/jobsToplu TTS sentez işi oluşturur.
/corporate/tts/jobs/{id}İş durumunu sorgular.
/corporate/tts/jobs/{id}/streamÜretilen WAV ses akışını indirir.
import osimport timeimport requests API_KEY = os.environ["KONUSMATIK_API_KEY"]BASE_URL = "https://api.konusmatik.com/api/v1"HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"} def synthesize_corporate_async(text: str, output_path: str = "output.wav"): # 1. İşi Oluştur (Anında 201 Created döner) resp = requests.post( f"{BASE_URL}/corporate/tts/jobs", headers=HEADERS, json={ "text": text, "voice": "deniz", "synthesis_options": {"format": "wav", "speed": 1.0} } ) resp.raise_for_status() job_id = resp.json()["id"] print(f"TTS İşi oluşturuldu. Job ID: {job_id}") # 2. Polling ile Takip Et while True: poll_resp = requests.get(f"{BASE_URL}/corporate/tts/jobs/{job_id}", headers={"Authorization": f"Bearer {API_KEY}"}) poll_resp.raise_for_status() job_data = poll_resp.json() status = job_data["status"] if status == "completed": print("Ses sentezi tamamlandı!") break elif status == "failed": raise RuntimeError(f"Hata: {job_data.get('error_message')}") time.sleep(2.0) # 3. Sesi İndir (Stream veya Signed Download URL) stream_resp = requests.get(f"{BASE_URL}/corporate/tts/jobs/{job_id}/stream", headers={"Authorization": f"Bearer {API_KEY}"}) stream_resp.raise_for_status() with open(output_path, "wb") as f: f.write(stream_resp.content) print(f"WAV Ses dosyası kaydedildi: {output_path}") if __name__ == "__main__": synthesize_corporate_async("Kurumsal toplu seslendirme sistemi.")PCM16 ses akışını WebSocket üzerinden gerçek zamanlı gönderin; sunucu tabanlı VAD ile kelime kelime veya tam cümle transkriptlerini anlık alın.
/realtimewss://api.konusmatik.com/api/v1/realtime
| Yön | Olay (Event) | Açıklama |
|---|---|---|
| Server -> Client | session.created | Bağlantı kabul edilince varsayılan oturum objesi döner. |
| Client -> Server | session.update | Model (konusmatik-asr-v2), ses formatı ve VAD ayarlarını yapılandırır. |
| Server -> Client | session.updated | Güncellenen oturum yapılandırmasını onaylar. |
| Client -> Server | input_audio_buffer.append | Base64 PCM16 ses parçasını gönderir. |
| Server -> Client | conversation.item.input_audio_transcription.delta | Canlı transkripsiyon parçasını (kelime/hece) döner. |
| Server -> Client | conversation.item.input_audio_transcription.completed | Server VAD sessizlik tespit ettiğinde nihai cümleyi döner. |
| Server -> Client | error | Kapasite aşımı, yetki veya biçim hatalarını bildirir. |
import asyncioimport base64import jsonimport osimport sysimport sounddevice as sdimport websockets API_KEY = os.environ.get("KONUSMATIK_API_KEY")if not API_KEY: print("HATA: 'KONUSMATIK_API_KEY' ortam değişkeni bulunamadı.") print("PowerShell'de ayarlamak için: $env:KONUSMATIK_API_KEY = 'API_ANAHTARINIZ'") sys.exit(1) WS_URL = "wss://api.konusmatik.com/api/v1/realtime"SAMPLE_RATE = 24000 # Konuşmatik Realtime PCM16 varsayılan örnekleme hızı (24 kHz)CHANNELS = 1 # MonoBLOCK_SIZE = 2400 # Her 100ms için 2400 örnek (4800 byte) async def main(): headers = {"Authorization": f"Bearer {API_KEY}"} audio_queue = asyncio.Queue() loop = asyncio.get_running_loop() # Mikrofon geri çağırma fonksiyonu (ayrı ses thread'inden çalışır) def audio_callback(indata, frames, time_info, status): if status: print(f"[Ses Uyarısı]: {status}", file=sys.stderr) loop.call_soon_threadsafe(audio_queue.put_nowait, bytes(indata)) print("Konuşmatik Realtime API'ye bağlanılıyor...") async with websockets.connect(WS_URL, additional_headers=headers) as ws: # 1. Oturum Yapılandırması await ws.send(json.dumps({ "type": "session.update", "session": { "model": "konusmatik-asr-v2", "input_audio_format": "pcm16", "language": "tr", "turn_detection": {"type": "server_vad"} } })) # 2. Mikrofondan Ses Gönderme Görevi async def send_audio(): try: while True: data = await audio_queue.get() audio_b64 = base64.b64encode(data).decode("ascii") await ws.send(json.dumps({ "type": "input_audio_buffer.append", "audio": audio_b64 })) except asyncio.CancelledError: pass # 3. Sunucudan Gelen Yanıtları Dinleme Görevi async def receive_events(): try: async for message in ws: event = json.loads(message) event_type = event.get("type", "") if event_type == "session.updated": print("Mikrofon aktif! Konuşmaya başlayabilirsiniz (Çıkmak için Ctrl+C)...") print("------------------------------------------------------------------") elif event_type == "conversation.item.input_audio_transcription.delta": print(event.get("delta", ""), end="", flush=True) elif event_type == "conversation.item.input_audio_transcription.completed": transcript = event.get("transcript", "") print(f"\n[Nihai Cümle]: {transcript}\n") elif event_type == "error": print(f"\n[Sunucu Hatası]: {event.get('error', event)}") except asyncio.CancelledError: pass # Mikrofon akışını başlat (sounddevice) stream = sd.RawInputStream( samplerate=SAMPLE_RATE, channels=CHANNELS, dtype="int16", blocksize=BLOCK_SIZE, callback=audio_callback ) with stream: send_task = asyncio.create_task(send_audio()) receive_task = asyncio.create_task(receive_events()) try: # İki görevi aynı anda çalıştır await asyncio.gather(send_task, receive_task) except asyncio.CancelledError: pass finally: send_task.cancel() receive_task.cancel() if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: print("\n\nProgram kullanıcı tarafından durduruldu.")Konuşmatik altyapısı üç bağımsız koruma katmanıyla donanım kararlılığını garanti altına alır.
Belirli bir zaman aralığında (60s) gönderilebilecek maksimum HTTP istek sayısıdır.
Henüz tamamlanmamış (pending + processing) kuyrukta bekleyen toplam iş tavanıdır.
Donanım/GPU üzerinde aynı anda çalışan gerçek yapay zeka çıkarım limitidir (ASR: 14, TTS: 32).
| Paket / Katman | İş Yükü | Hesap Başına Açık İş | Aktif GPU İnference | İstek Limiti |
|---|---|---|---|---|
| Standart | TTS (Ses Sentezi) | 32 açık iş | 32 eşzamanlı inference | 120 istek / dk |
| Standart | ASR (Deşifre) | 20 açık iş | 14 eşzamanlı inference | 60 istek / dk |
| Kurumsal | TTS (Ses Sentezi) | 128 açık iş / hesap (Global: 256) | 32 eşzamanlı inference | 300 istek / dk |
| Kurumsal | ASR (Deşifre) | 100 açık iş / hesap (Global: 200) | 14 eşzamanlı inference | 120 istek / dk |
| Realtime Canlı | Realtime ASR | - | 50 eşzamanlı canlı oturum | 60 istek / dk |
Kapasite dolduğunda deterministik HTTP 429 Too Many Requests ve Retry-After başlığı döner.
Kapasite aşımlarında (asr_capacity_saturated, tts_capacity_saturated) sunucunun belirttiği saniye kadar bekleyerek yeniden deneyin:
import timeimport requests def request_with_retry_after(url, headers, payload, max_retries=3): for attempt in range(max_retries): response = requests.post(url, headers=headers, json=payload) if response.status_code == 429: # Backend'den dönen Retry-After başlığına uyun (Varsayılan 3 saniye) retry_after = int(response.headers.get("Retry-After", 3)) print(f"Kapasite dolu (429). {retry_after}s sonra tekrar deneniyor... (Deneme {attempt+1}/{max_retries})") time.sleep(retry_after) continue return response raise RuntimeError("Maksimum yeniden deneme sınırına ulaşıldı.")| HTTP Durumu | Hata Türü / Kodu | Açıklama |
|---|---|---|
| 400 Bad Request | invalid_request_error | Geçersiz model, ses adı, parametre veya desteklenmeyen format (WAV dışında format talebi). |
| 401 Unauthorized | authentication_error | API anahtarı eksik, geçersiz veya iptal edilmiş. |
| 402 Payment Required | insufficient_corporate_quota | Hesap paketindeki kredi veya saniye kotası tükendi. |
| 404 Not Found | resource_not_found | Belirtilen job_id bulunamadı veya başka bir müşteriye ait. |
| 413 Payload Too Large | invalid_request_error | 100 MB ses yükleme veya 10.000 karakter metin sınırı aşıldı. |
| 422 Unprocessable Entity | validation_error | Eksik veya hatalı form / JSON alanları. |
| 429 Too Many Requests | capacity_error / rate_limit_error | Kapasite doldu veya hız sınırı aşıldı. Retry-After başlığı içerir (asr_capacity_saturated, tts_capacity_saturated). |
| 500 / 503 | server_error | Geçici sunucu veya kuyruk servis kesintisi. |