VOIS

VOIS Ses API

Santralinizi kendi yazılımınızdan kullanın: CRM'de müşteri kartına tıklayınca masadaki telefon çalsın ve müşteri aransın, gelen çağrıda yazılımınız arayanı göstersin, çağrı bitince süre ve kayıt yazılımınıza düşsün.

Temel adreshttps://api.vois.com.tr/v1/voice

Genel bilgiler

Ses API'sini açtırma

Ses API'si hesap bazında VOIS tarafından açılır. Kullanmak istiyorsanız müşteri temsilcinizle iletişime geçin.

Açık olmayan bir hesapta tüm ses uçları 403 voice_not_enabled döner. Yurt dışı ve 0900 numaraları aramak varsayılan olarak kapalıdır; ihtiyacınız varsa açtırmak için yine bize ulaşın.

API anahtarı ve yetkiler

Anahtarı VOIS panelinizden kendiniz oluşturursunuz: Ayarlar › API & Webhook.

Her istekte anahtar şu başlıklardan biriyle gönderilir:

HTTP BAŞLIĞI
Authorization: Bearer vois_1234_0123456789abcdef0123456789abcdef01234567
# ya da
X-API-Key: vois_1234_0123456789abcdef0123456789abcdef01234567

Anahtarı oluştururken ihtiyacınız olan yetkileri işaretleyin:

Yetkiİzin verdiği
voice:readDahililer, süren çağrılar, çağrı geçmişi
voice:callTıkla-ara ve çağrı kapatma
voice:recordingsSes kaydı indirme
Anahtar yalnız bir kez gösterilir. Yalnızca sunucu tarafındaki kodunuzda saklayın; tarayıcıya veya mobil uygulamaya koymayın. Sızdığından şüphelenirseniz panelden iptal edip yenisini oluşturun.

Hızlı başlangıç

101 numaralı dahiliyi çaldır, açınca 0532 123 45 67'yi ara.

curl -X POST https://api.vois.com.tr/v1/voice/calls \
  -H 'Authorization: Bearer ANAHTAR' \
  -H 'Content-Type: application/json' \
  -d '{"extension":"101","number":"05321234567","reference":"musteri-4521","auto_answer":true}'

Tıkla-ara

Önce dahili çalar (ya da auto_answer ile kendiliğinden açılır); dahili açınca numara, santralinizin normal giden arama kurallarıyla aranır (hat seçimi, arayan numara, kayıt ve çağrı geçmişi masadaki telefondan aranmış gibi işler).

POST/calls
AlanAçıklama
extension string zorunluÇalacak dahili. Telefonu santrale kayıtlı (bağlı) olmalı.
number string zorunluAranacak numara. 05321234567, +905321234567, 0532 123 45 67 biçimlerinin hepsi kabul edilir. Kendi dahilileriniz de aranabilir. Bkz. aranabilen numaralar.
caller_id_number string opsiyonelKarşı tarafta görünecek numara. Yalnız hesabınızdaki hat numaralarından biri olabilir; verilmezse dahilinin normal kuralı uygulanır.
auto_answer bool opsiyoneltrue ise dahilinin telefonu çalmadan kendiliğinden açılır (hoparlör/kulaklık) ve kullanıcı hemen karşı tarafın çalma sesini duyar — "karta bas, müşteri çalsın" deneyimi. Güvenlik nedeniyle hesap bazında VOIS tarafından açılır (açık değilse 403 auto_answer_not_allowed). Telefonda otomatik cevap/intercom izni de açık olmalıdır (Yealink, Grandstream, Fanvil destekler). Varsayılan false.
reference string opsiyonelKendi sisteminizdeki kayıt numarası (≤64; harf, rakam, . _ : -). Bu çağrının tüm webhook olaylarında ve çağrı geçmişinde geri döner.
İSTEK
{
  "extension": "101",
  "number": "05321234567",
  "reference": "musteri-4521"
}
YANIT · 202
{
  "data": {
    "call_id": "9aeba619-e656-4afd-aacc-ba64dcf24aef",
    "status": "ringing_extension"
  },
  "meta": {}
}

202 çağrının başlatıldığını gösterir. Dahili 30 saniye içinde açılmazsa çağrı düşer; sonucu call.ended olayından ya da çağrı geçmişinden öğrenirsiniz.

Çağrıyı kapat

DELETE/calls/{call_id}

Süren bir çağrıyı kapatır (voice:call). Yanıt {"data":{"hung_up":true}}; çağrı yoksa ya da hesabınıza ait değilse 404.

Süren çağrılar

GET/calls/active
YANIT
{ "data": [{
  "call_id": "9aeba619-…", "direction": "outbound",
  "from": "101", "to": "05321234567", "extension": "101",
  "state": "ACTIVE", "started_at": "2026-11-12T01:17:50+03:00"
}] }

state: RINGING (çalıyor), EARLY (karşı taraf çalıyor), ACTIVE (görüşmede), HELD (beklemede).

Dahililer

GET/extensions
YANIT
{ "data": [
  { "extension": "101", "name": "Satış 1", "enabled": true,
    "registered": true, "in_call": false, "user_agent": "Yealink T31P" }
] }

registered: telefon santrale bağlı mı. Tıkla-ara yalnız bağlı dahililerle çalışır. in_call: dahili şu an görüşmede mi.

Çağrı geçmişi (CDR)

Dışarıyla yapılan çağrılar (gelen ve giden). Dahililer arası çağrılar listelenmez.

GET/cdr?from=2026-11-01&to=2026-11-12
ParametreAçıklama
from, to zorunluYYYY-MM-DD; aralık en çok 31 gün.
directioninbound (gelen) ya da outbound (giden).
statusanswered, no_answer, busy, failed.
extensionDahili numarası.
numberArayan ya da aranan numara (son 10 hane eşleşir).
page, per_pageSayfalama; per_page en çok 200 (varsayılan 50). Toplam sayı meta.total.
YANIT
{ "data": [{
  "call_id": "9aeba619-e656-4afd-aacc-ba64dcf24aef",
  "direction": "outbound", "from": "101", "to": "05321234567", "extension": "101",
  "started_at": "2026-11-12T01:17:50+03:00", "answered_at": "2026-11-12T01:17:54+03:00",
  "ended_at": "2026-11-12T01:18:45+03:00", "duration": 51, "talk_time": 51,
  "status": "answered", "recording_available": true, "reference": "musteri-4521"
}], "meta": { "page": 1, "per_page": 50, "total": 1 } }

duration: toplam süre (sn), talk_time: konuşma süresi (sn).

Tek çağrı

GET/cdr/{call_id}

Çağrı geçmişindeki tek satırı döndürür. Çağrı bittikten birkaç saniye sonra kullanılabilir.

Ses kaydı

GET/recordings/{call_id}

Kaydı WAV dosyası olarak indirir (voice:recordings). Kayıt yoksa 404.

Ses kayıtları kişisel veridir (KVKK). İndirdiğiniz kayıtları yalnız yetkili kişilerin erişebileceği yerde saklayın.

Webhook olayları

Çağrı olayları, panelde tanımladığınız adrese anında POST edilir: Ayarlar › API & Webhook bölümünde adresi ekleyip olayları seçin.

OlayNe zaman
call.ringingGelen çağrı dahilileri çaldırmaya başladı (ekranda arayanı göstermek için). Tıkla-ara'da dahili çalmaya başladı.
call.answeredGelen çağrıyı bir dahili açtı; giden/tıkla-ara çağrısında karşı taraf açtı.
call.endedÇağrı bitti.
call.ringing
{
  "id": "3b1f6c2e-8d4a-4f0e-9a51-2c7e0b9d6a14",
  "event": "call.ringing",
  "data": {
    "call_id": "fe4a0d0d-3e2d-451c-a6fa-72f13eef4d8a",
    "direction": "inbound",
    "from": "905321234567",
    "to": "902124189159",
    "did": "902124189159",
    "ringing_extensions": ["101", "102"],
    "reference": null,
    "at": "2026-11-12T01:22:31+03:00"
  },
  "fired_at": "2026-11-12T01:22:31+03:00"
}
call.ended
{
  "id": "a90e5d77-41c3-4b2b-8f6d-0d5e3c1f7b28",
  "event": "call.ended",
  "data": {
    "call_id": "fe4a0d0d-3e2d-451c-a6fa-72f13eef4d8a",
    "direction": "inbound",
    "from": "905321234567",
    "to": "902124189159",
    "extension": "101",
    "status": "answered",
    "duration": 9,
    "talk_time": 5,
    "recording_available": true,
    "reference": null,
    "at": "2026-11-12T01:22:38+03:00"
  },
  "fired_at": "2026-11-12T01:22:38+03:00"
}

call.answered aynı alanları ve açan extension'ı taşır. Tıkla-ara çağrılarında direction outbound, from dahili, to aranan numara ve reference sizin verdiğiniz değerdir.

Adresiniz internetten erişilebilir olmalı (iç ağ/yerel adresler kabul edilmez), https:// ile başlamalı (çağrı olayları telefon numarası taşıdığı için zorunlu), 80 ya da 443 portunu kullanmalı ve 3 saniye içinde 2xx dönmeli; başarısız istek bir kez tekrar denenir, yönlendirme (3xx) izlenmez. "Çalıyor" ve "açıldı" olayları 30 saniyeden fazla gecikirse gönderilmez. Webhook'lar anlık bilgi içindir: bir olay kaçarsa kesin kayıt için çağrı geçmişini kullanın.

İmza doğrulama

Her isteğin X-VOIS-Signature başlığında, gövdenin webhook gizli anahtarınızla HMAC-SHA256 imzası bulunur: sha256=<hex>. Gizli anahtar panelde webhook'u eklediğinizde gösterilir. İmzası tutmayan istekleri reddedin.

Tekrar gönderime karşı: imzalı gövdede her olay için benzersiz bir id ve gönderim zamanı fired_at bulunur. İmzayı doğruladıktan sonra fired_at 5 dakikadan eskiyse isteği reddedin; işlediğiniz id'leri bir süre saklayıp aynı olayı ikinci kez işlemeyin. Başarısız bir istek tekrar denendiğinde aynı id ile gelir.
<?php
$body = file_get_contents('php://input');           // ham gövde — json_decode etmeden önce
$expected = 'sha256=' . hash_hmac('sha256', $body, 'GIZLI_ANAHTAR');
if (! hash_equals($expected, $_SERVER['HTTP_X_VOIS_SIGNATURE'] ?? '')) {
    http_response_code(401); exit;
}
$event = json_decode($body, true);
// $event['event'] === 'call.ringing' → arayanı ekranda göster
http_response_code(200);

Aranabilen numaralar

Kötüye kullanıma karşı tıkla-ara yalnız aşağıdaki numaraları arar.

Numara türüÖrnekDurum
Cep0532 123 45 67Açık
Sabit (yurt içi)0212 418 91 59Açık
0850 / 4440850 123 45 67, 444 1 234Açık
Kendi dahilileriniz102Açık
Yurt dışı+49 30 1234567Kapalı — VOIS açabilir
Ücretli (0900, 0898)0900 123 45 67Kapalı — VOIS açabilir
Rehber (118xx), diğer kısa numaralar11880Kapalı
Acil numaralar112, 155, 110, 177 …Her zaman kapalı
Özellik kodları*21*…#Kapalı

Panelinizdeki "Aranmasın" (DNC) listesindeki numaralar da aranmaz.

Hata kodları

KodHTTPAnlamı
unauthorized401Anahtar eksik, hatalı ya da iptal edilmiş.
voice_not_enabled403Ses API'si bu hesapta açık değil.
insufficient_scope403Anahtarda bu işlem için gereken yetki yok.
invalid_request422Parametre eksik ya da hatalı; ayrıntı message'da.
extension_not_found422Dahili yok ya da pasif.
number_not_allowed422Numara aranamaz; sebep message'da (bkz. aranabilen numaralar).
number_blocked422Numara "Aranmasın" listesinde.
caller_id_not_allowed422Arayan numara hesabınızın hatlarından biri değil.
extension_unavailable409Dahilinin telefonu santrale bağlı değil.
extension_busy409Dahili şu an görüşmede.
auto_answer_not_allowed403Otomatik cevap bu hesapta açık değil.
rate_limited429Dakikadaki arama sınırı aşıldı.
daily_limit429Günlük API arama sınırına ulaşıldı.
too_many_calls429Aynı anda çok fazla API çağrısı var.
not_found404Çağrı/kayıt yok ya da hesabınıza ait değil.
pbx_unavailable503Santrale geçici olarak ulaşılamıyor; tekrar deneyin.

Sorun giderme