API başvurusu

Açık API v1'in tüm uçları. Örnekler curl, JavaScript (fetch) ve Python (requests) ile; seçtiğiniz dil sayfa boyunca hatırlanır.

Taban adreshttps://hubvocal.com/v1
KimlikAuthorization: Bearer vt_live_…
Hız sınırıAnahtar başına 120 istek/dk · 429 + Retry-After
Kapsamlarread · write · calls
Her anahtarda read, write ve/veya calls bulunur. read GET isteklerini, write değişiklikleri, calls giden aramaları kapsar. Anahtarın kapsamı dışındaki bir istek 403 alır.
Hata gövdesi{"detail": "..."}
OpenAPIGET /v1/openapi.json

Kimlik doğrulama, gömme ve hata kodları için Geliştiriciler sayfasına bakın.

Ajanlar

Görüşmeler metin modunda koşar; yani talimatı ve araç kullanımını dener, sesi ya da gecikmeyi değil. Simülasyonlar panelden koşturulur; bunlar için henüz /v1 ucu yoktur.

Ajanları listele

GET /v1/agents

Organizasyonunuzdaki tüm ajanları paneldeki sırayla döner.

İstek

curl
curl "https://hubvocal.com/v1/agents" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "id": "resepsiyon",
    "name": "Resepsiyon",
    "lang": "tr",
    "engine": "live",
    "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
    "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
    "voice": {
      "voice": "marin",
      "speed": 1
    },
    "tools": {
      "builtins": [
        "end_call",
        "take_message"
      ],
      "webhooks": [
        "tl_8f3a2c"
      ]
    },
    "turn": {
      "first_speaker": "agent",
      "idle_check_s": 30
    },
    "recording": {
      "enabled": false,
      "announce": true
    },
    "post_call": {
      "summary": true,
      "fields": [
        {
          "name": "appointment_date",
          "type": "date",
          "description": "Requested appointment date, if any"
        },
        {
          "name": "callback",
          "type": "boolean",
          "description": "Does the caller want a callback?"
        }
      ]
    },
    "knowledge": {
      "doc_ids": [
        "kb_7d21e4"
      ],
      "mode": "tool"
    },
    "published_version": 3,
    "draft_changed": false
  }
]

Ajan oluştur

POST /v1/agents

Yeni ajan oluşturur. Her alan sunucuda doğrulanır; sınırı aşan değerler kısaltılır. Var olan bir id gönderirseniz 409 döner; güncellemek için PUT kullanın.

AdYerTürAçıklama
id body string İsteğe bağlı. Küçük harf, rakam ve tire; en fazla 48 karakter. Verilmezse addan üretilir.
name
zorunlu
body string Görünen ad, en fazla 60 karakter.
lang
zorunlu
body string Görüşme dili kodu, ör. tr, en, de. Tam liste GET /v1/voices yanıtında.
engine
zorunlu
body "live" | "gemini" | "realtime" | "classic" live: GPT-Live 1, gemini: Gemini Live, realtime: OpenAI Realtime, classic: STT → LLM → TTS.
instructions body string Ajan talimatı, en fazla 8000 karakter.
greeting body string Ajanın ilk cümlesi, en fazla 400 karakter.
voice body object voice (/v1/voices listesinden bir ad), speed (yalnız classic ve realtime; live ve gemini'de 1.0 sabit), tone (serbest konuşma tarzı, en fazla 600 karakter).
tools body object builtins (end_call, take_message) ve webhooks (araç kimlikleri); toplam en fazla 16 araç. Boş ya da yoksa araç yoktur. mcp: [{server_id, tools}] MCP sunucularınızdaki araçları ekler; aynı sınıra dahildir.
turn body object Söz alma ayarları: sensitivity (low, balanced, high; yalnız Klasik motor), first_speaker (agent ya da caller), silence_wait_s (1–5), idle_check_s (0 ya da 10–120), agent_timeout_s (0 ya da 10–60). Boş alanlar varsayılanı kullanır.
recording body object recording: {enabled (varsayılan false), announce (varsayılan true), announce_text?}. Açıksa ajan karşılamadan önce kaydı anons eder.
post_call body object post_call.summary: görüşme bitince özet yaz (varsayılan true). post_call.fields: görüşmeden sonra doldurulacak en fazla 24 alan ({name, type, description, enum?, required?}).
knowledge body object doc_ids (en fazla 50 bilgi bankası belgesi) ve mode ("tool"). Ajan bu durumda search_knowledge aracını alır.
calendar body object Panelden integration_id ve calendar_id, duration_min (15–240), buffer_min (0–60), timezone, working_hours, min_notice_h (0–72), max_days_ahead (1–90). Randevu araçlarını açar.

İstek

curl
curl -X POST "https://hubvocal.com/v1/agents" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Resepsiyon",
  "lang": "tr",
  "engine": "live",
  "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
  "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
  "voice": {
    "voice": "marin",
    "speed": 1
  },
  "tools": {
    "builtins": [
      "end_call",
      "take_message"
    ],
    "webhooks": [
      "tl_8f3a2c"
    ]
  },
  "turn": {
    "first_speaker": "agent",
    "idle_check_s": 30
  },
  "recording": {
    "enabled": false,
    "announce": true
  },
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date, if any"
      },
      {
        "name": "callback",
        "type": "boolean",
        "description": "Does the caller want a callback?"
      }
    ]
  },
  "knowledge": {
    "doc_ids": [
      "kb_7d21e4"
    ],
    "mode": "tool"
  }
}'

Yanıt · 201

JSON
{
  "id": "resepsiyon",
  "name": "Resepsiyon",
  "lang": "tr",
  "engine": "live",
  "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
  "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
  "voice": {
    "voice": "marin",
    "speed": 1
  },
  "tools": {
    "builtins": [
      "end_call",
      "take_message"
    ],
    "webhooks": [
      "tl_8f3a2c"
    ]
  },
  "turn": {
    "first_speaker": "agent",
    "idle_check_s": 30
  },
  "recording": {
    "enabled": false,
    "announce": true
  },
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date, if any"
      },
      {
        "name": "callback",
        "type": "boolean",
        "description": "Does the caller want a callback?"
      }
    ]
  },
  "knowledge": {
    "doc_ids": [
      "kb_7d21e4"
    ],
    "mode": "tool"
  },
  "published_version": null,
  "draft_changed": true
}

Hatalar

  • 409 Bu id ile bir ajan zaten var.

Ajanı getir

GET /v1/agents/{id}

Tek bir ajanı döner. published_version yayındaki sürüm numarasıdır (hiç yayımlanmadıysa null); draft_changed taslağın ondan farklı olup olmadığını söyler.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.

İstek

curl
curl "https://hubvocal.com/v1/agents/resepsiyon" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "id": "resepsiyon",
  "name": "Resepsiyon",
  "lang": "tr",
  "engine": "live",
  "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
  "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
  "voice": {
    "voice": "marin",
    "speed": 1
  },
  "tools": {
    "builtins": [
      "end_call",
      "take_message"
    ],
    "webhooks": [
      "tl_8f3a2c"
    ]
  },
  "turn": {
    "first_speaker": "agent",
    "idle_check_s": 30
  },
  "recording": {
    "enabled": false,
    "announce": true
  },
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date, if any"
      },
      {
        "name": "callback",
        "type": "boolean",
        "description": "Does the caller want a callback?"
      }
    ]
  },
  "knowledge": {
    "doc_ids": [
      "kb_7d21e4"
    ],
    "mode": "tool"
  },
  "published_version": 3,
  "draft_changed": false
}

Hatalar

  • 404 Bu id ile ajan yok.

Ajanı güncelle

PUT /v1/agents/{id}

Ajanı gönderdiğiniz nesneyle değiştirir. Nesnenin tamamını gönderin; eksik bıraktığınız alanlar varsayılana döner. Yoldaki id, gövdedeki id'den önce gelir.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.
name
zorunlu
body string Görünen ad, en fazla 60 karakter.
lang
zorunlu
body string Görüşme dili kodu, ör. tr, en, de. Tam liste GET /v1/voices yanıtında.
engine
zorunlu
body "live" | "gemini" | "realtime" | "classic" live: GPT-Live 1, gemini: Gemini Live, realtime: OpenAI Realtime, classic: STT → LLM → TTS.
instructions body string Ajan talimatı, en fazla 8000 karakter.
greeting body string Ajanın ilk cümlesi, en fazla 400 karakter.
voice body object voice (/v1/voices listesinden bir ad), speed (yalnız classic ve realtime; live ve gemini'de 1.0 sabit), tone (serbest konuşma tarzı, en fazla 600 karakter).
tools body object builtins (end_call, take_message) ve webhooks (araç kimlikleri); toplam en fazla 16 araç. Boş ya da yoksa araç yoktur. mcp: [{server_id, tools}] MCP sunucularınızdaki araçları ekler; aynı sınıra dahildir.
turn body object Söz alma ayarları: sensitivity (low, balanced, high; yalnız Klasik motor), first_speaker (agent ya da caller), silence_wait_s (1–5), idle_check_s (0 ya da 10–120), agent_timeout_s (0 ya da 10–60). Boş alanlar varsayılanı kullanır.
recording body object recording: {enabled (varsayılan false), announce (varsayılan true), announce_text?}. Açıksa ajan karşılamadan önce kaydı anons eder.
post_call body object post_call.summary: görüşme bitince özet yaz (varsayılan true). post_call.fields: görüşmeden sonra doldurulacak en fazla 24 alan ({name, type, description, enum?, required?}).
knowledge body object doc_ids (en fazla 50 bilgi bankası belgesi) ve mode ("tool"). Ajan bu durumda search_knowledge aracını alır.
calendar body object Panelden integration_id ve calendar_id, duration_min (15–240), buffer_min (0–60), timezone, working_hours, min_notice_h (0–72), max_days_ahead (1–90). Randevu araçlarını açar.

İstek

curl
curl -X PUT "https://hubvocal.com/v1/agents/resepsiyon" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Resepsiyon",
  "lang": "tr",
  "engine": "live",
  "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
  "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
  "voice": {
    "voice": "cedar",
    "speed": 1
  },
  "tools": {
    "builtins": [
      "end_call",
      "take_message"
    ],
    "webhooks": [
      "tl_8f3a2c"
    ]
  },
  "turn": {
    "first_speaker": "agent",
    "idle_check_s": 30
  },
  "recording": {
    "enabled": false,
    "announce": true
  },
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date, if any"
      },
      {
        "name": "callback",
        "type": "boolean",
        "description": "Does the caller want a callback?"
      }
    ]
  },
  "knowledge": {
    "doc_ids": [
      "kb_7d21e4"
    ],
    "mode": "tool"
  }
}'

Yanıt · 200

JSON
{
  "id": "resepsiyon",
  "name": "Resepsiyon",
  "lang": "tr",
  "engine": "live",
  "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
  "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
  "voice": {
    "voice": "cedar",
    "speed": 1
  },
  "tools": {
    "builtins": [
      "end_call",
      "take_message"
    ],
    "webhooks": [
      "tl_8f3a2c"
    ]
  },
  "turn": {
    "first_speaker": "agent",
    "idle_check_s": 30
  },
  "recording": {
    "enabled": false,
    "announce": true
  },
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date, if any"
      },
      {
        "name": "callback",
        "type": "boolean",
        "description": "Does the caller want a callback?"
      }
    ]
  },
  "knowledge": {
    "doc_ids": [
      "kb_7d21e4"
    ],
    "mode": "tool"
  },
  "published_version": 3,
  "draft_changed": true
}

Hatalar

  • 404 Bu id ile ajan yok. Önce POST ile oluşturun.

Ajanı sil

DELETE /v1/agents/{id}

Ajanı siler. Organizasyonda en az bir ajan kalmalı; son ajan silinemez.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.

İstek

curl
curl -X DELETE "https://hubvocal.com/v1/agents/resepsiyon" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "deleted": "resepsiyon"
}

Hatalar

  • 400 Organizasyondaki son ajan.
  • 404 Bu id ile ajan yok.

Sürümleri listele

GET /v1/agents/{id}/versions

Ajanın yayımlanmış sürümleri, yeniden eskiye. is_live, görüşmelerin şu an kullandığını işaretler.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.

İstek

curl
curl "https://hubvocal.com/v1/agents/resepsiyon/versions" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "version": 3,
    "note": "Shorter greeting",
    "published_at": 1793829000,
    "published_by": "ayse@example.com",
    "is_live": true
  },
  {
    "version": 2,
    "note": "Added price list",
    "published_at": 1793740000,
    "published_by": "ayse@example.com",
    "is_live": false
  }
]

Hatalar

  • 404 Bu id ile ajan yok.

Sürümü getir

GET /v1/agents/{id}/versions/{n}

Ajanın o sürümdeki tam hali.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.
n
zorunlu
path integer Sürüm numarası.

İstek

curl
curl "https://hubvocal.com/v1/agents/resepsiyon/versions/2" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "id": "resepsiyon",
  "name": "Resepsiyon",
  "lang": "tr",
  "engine": "live",
  "instructions": "Bir diş kliniğinin resepsiyonistisin. Randevu almak isteyenlere yardım et, genel soruları kısa yanıtla. Bilmediğin bir şeyi uydurma; ilgili kişinin geri döneceğini söyle.",
  "greeting": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
  "voice": {
    "voice": "marin",
    "speed": 1
  },
  "tools": {
    "builtins": [
      "end_call",
      "take_message"
    ],
    "webhooks": [
      "tl_8f3a2c"
    ]
  },
  "turn": {
    "first_speaker": "agent",
    "idle_check_s": 30
  },
  "recording": {
    "enabled": false,
    "announce": true
  },
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date, if any"
      },
      {
        "name": "callback",
        "type": "boolean",
        "description": "Does the caller want a callback?"
      }
    ]
  },
  "knowledge": {
    "doc_ids": [
      "kb_7d21e4"
    ],
    "mode": "tool"
  },
  "version": 2
}

Hatalar

  • 404 Böyle bir ajan ya da sürüm yok.

Taslağı yayımla

POST /v1/agents/{id}/publish

Mevcut taslağı yeni bir sürüm olarak kaydeder ve yayına alır. Süren görüşmeler kendi sürümüyle devam eder.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.
note body string Neyin değiştiğine dair kısa bir not.

İstek

curl
curl -X POST "https://hubvocal.com/v1/agents/resepsiyon/publish" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "Shorter greeting"
}'

Yanıt · 200

JSON
{
  "version": 4
}

Hatalar

  • 404 Bu id ile ajan yok.

Geri al

POST /v1/agents/{id}/rollback

Önceki bir sürümü taslağa kopyalar ve yeni bir sürüm olarak yayımlar.

AdYerTürAçıklama
id
zorunlu
path string Ajan kimliği, ör. resepsiyon.
version
zorunlu
body integer Geri getirilecek sürüm.

İstek

curl
curl -X POST "https://hubvocal.com/v1/agents/resepsiyon/rollback" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "version": 2
}'

Yanıt · 200

JSON
{
  "version": 5
}

Hatalar

  • 404 Böyle bir ajan ya da sürüm yok.

Bilgi bankası

Belgeleri listele

GET /v1/knowledge

Organizasyonunuzun belgeleri; işleme durumu, boyut, parça sayısı ve onları kullanan ajanlarla.

İstek

curl
curl "https://hubvocal.com/v1/knowledge" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "id": "kb_7d21e4",
    "title": "Fiyat listesi 2026",
    "kind": "file",
    "filename": "price-list-2026.pdf",
    "url": null,
    "size_bytes": 248113,
    "chunks": 42,
    "status": "ready",
    "error": null,
    "created_at": 1793740000,
    "used_by": [
      "resepsiyon"
    ]
  }
]

Belge ekle

POST /v1/knowledge

Dosyayı multipart/form-data (file alanı) olarak yükleyin, metni JSON {title, text} ya da tek bir web sayfasını JSON {url} olarak gönderin. 201 ve status processing döner; belge ready ya da failed olana kadar sorgulayın.

AdYerTürAçıklama
file body file multipart/form-data: pdf, docx, txt, md ya da html; en fazla 10 MB.
title body string Başlık; text ile birlikte.
text body string Düz metin içerik.
url body string Bunun yerine alınacak tek bir https sayfası.

İstek

curl
curl -X POST "https://hubvocal.com/v1/knowledge" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Çalışma saatleri",
  "text": "Hafta içi 09:00–18:00, cumartesi 10:00–14:00 açığız. Pazar kapalıyız."
}'

Yanıt · 201

JSON
{
  "id": "kb_9f03b1",
  "title": "Çalışma saatleri",
  "kind": "text",
  "filename": null,
  "url": null,
  "size_bytes": 96,
  "chunks": 0,
  "status": "processing",
  "error": null,
  "created_at": 1793740000,
  "used_by": []
}

Hatalar

  • 400 Desteklenmeyen dosya türü, 10 MB'tan büyük dosya, https olmayan ya da özel bir adrese giden URL, ya da organizasyon sınırı (200 belge, 200 MB) doldu.

Belgeyi getir

GET /v1/knowledge/{id}

Belge ve ilk 2000 karakterinin önizlemesi.

AdYerTürAçıklama
id
zorunlu
path string Belge kimliği.

İstek

curl
curl "https://hubvocal.com/v1/knowledge/kb_7d21e4" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "id": "kb_7d21e4",
  "title": "Fiyat listesi 2026",
  "kind": "file",
  "filename": "price-list-2026.pdf",
  "url": null,
  "size_bytes": 248113,
  "chunks": 42,
  "status": "ready",
  "error": null,
  "created_at": 1793740000,
  "used_by": [
    "resepsiyon"
  ],
  "preview": "Fiyat listesi 2026. Muayene 1.500 TL, diş taşı temizliği 2.000 TL…"
}

Hatalar

  • 404 Bu kimlikle belge yok.

Belgeyi sil

DELETE /v1/knowledge/{id}

Belgeyi siler ve onu kullanan tüm ajanlardan kaldırır.

AdYerTürAçıklama
id
zorunlu
path string Belge kimliği.

İstek

curl
curl -X DELETE "https://hubvocal.com/v1/knowledge/kb_7d21e4" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "deleted": "kb_7d21e4"
}

Hatalar

  • 404 Bu kimlikle belge yok.

Ara

POST /v1/knowledge/search

Ajanın kullandığı aramanın aynısını yapar ve en iyi eşleşen parçaları puanla döner. Yayına almadan önce belgelerinizi denemek için.

AdYerTürAçıklama
query
zorunlu
body string Aranacak şey.
doc_ids body string[] Aramayı bu belgelerle sınırla.

İstek

curl
curl -X POST "https://hubvocal.com/v1/knowledge/search" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "diş taşı temizliği ne kadar"
}'

Yanıt · 200

JSON
[
  {
    "doc_id": "kb_7d21e4",
    "title": "Fiyat listesi 2026",
    "chunk_index": 3,
    "text": "Diş taşı temizliği: 2.000 TL, yaklaşık 30 dakika.",
    "score": 0.82
  }
]

Araçlar

Yerleşik araçlar

Bu araçlar tanım gerektirmez. Ajanın tools.builtins listesinde açın. knowledge ayarlanınca search_knowledge eklenir. calendar ayarlanınca randevu araçları eklenir.

AdNe yapar
end_callAjan vedalaşır, konuşması bittikten 0,75 sn sonra kapatır. Arayan bu arada konuşursa kapatma iptal olur. Görüşme kaydında ended_by: "agent" görünür.
take_messagename, phone, message ve callback_requested alır ve görüşme kaydında outcomes[] içine yazar. Onay istemez.
search_knowledgeAjanın knowledge alanında belge varsa kendiliğinden eklenir. Belgelerde arar ve kaynakları görüşme kaydına yazar.
check_availabilityOkuma. Ajanın çalışma saatleri içinde date_from ile date_to arasındaki boş zamanları döner. calendar ayarlıysa eklenir.
book_appointmentYazma; onay kapısından geçer. name ve phone için start zamanına randevu alır; isteğe bağlı note. Randevu outcomes[] içine yazılır.
cancel_appointmentYazma; onay kapısından geçer. booking_ref ile randevuyu iptal eder.

Takvim entegrasyonları (Google Calendar) yalnız panelden bağlanır; bunlar için /v1 ucu yoktur. Ajanın calendar alanında panelden aldığınız entegrasyon ve takvim kimliklerini kullanın.

Araçları listele

GET /v1/tools

Organizasyonunuzun webhook araçları. Gizli anahtar hiç dönmez; has_secret tanımlı olup olmadığını gösterir.

İstek

curl
curl "https://hubvocal.com/v1/tools" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "id": "tl_8f3a2c",
    "name": "check_order",
    "description": "Sipariş numarasıyla kargo durumunu getirir.",
    "kind": "read",
    "url": "https://crm.example.com/hooks/order",
    "parameters": {
      "type": "object",
      "properties": {
        "order_id": {
          "type": "string",
          "description": "Sipariş numarası"
        }
      },
      "required": [
        "order_id"
      ]
    },
    "timeout_s": 8,
    "enabled": true,
    "has_secret": true,
    "created_at": 1793830000,
    "updated_at": 1793830000
  }
]

Aracı getir

GET /v1/tools/{id}

Tek bir webhook aracı. Gizli anahtar hiç dönmez.

AdYerTürAçıklama
id
zorunlu
path string Araç kimliği.

İstek

curl
curl "https://hubvocal.com/v1/tools/tl_8f3a2c" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "id": "tl_8f3a2c",
  "name": "check_order",
  "description": "Sipariş numarasıyla kargo durumunu getirir.",
  "kind": "read",
  "url": "https://crm.example.com/hooks/order",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Sipariş numarası"
      }
    },
    "required": [
      "order_id"
    ]
  },
  "timeout_s": 8,
  "enabled": true,
  "has_secret": true,
  "created_at": 1793830000,
  "updated_at": 1793830000
}

Hatalar

  • 404 Bu kimlikle araç yok.

Araç oluştur

POST /v1/tools

Organizasyon için bir webhook aracı tanımlar. Kullanmak için kimliğini ajanın tools.webhooks listesine ekleyin. Adres https olmalı, yerel ya da özel bir adrese gidemez.

AdYerTürAçıklama
name
zorunlu
body string Küçük harf, rakam ve alt çizgi; harfle başlar (3–41 karakter). Organizasyonda benzersiz; end_call ve take_message ayrılmıştır.
description
zorunlu
body string Modele aracı ne zaman ve nasıl kullanacağını anlatır.
kind
zorunlu
body "read" | "write" read hemen çalışır; write önce arayandan onay ister.
url
zorunlu
body string Sizin ucunuz. Yalnız https; yerel ve özel adresler reddedilir.
parameters body object JSON Schema nesnesi: string, number, integer ya da boolean türünde en fazla 20 alan (enum olur).
timeout_s body integer 2–15 saniye.
enabled body boolean Kapalı araçlar modele sunulmaz.
secret body string İstekleri imzalamak için. Yalnız yazılır; güncellemede boş değer mevcut anahtarı korur, "-" siler.

İstek

curl
curl -X POST "https://hubvocal.com/v1/tools" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "check_order",
  "description": "Sipariş numarasıyla kargo durumunu getirir.",
  "kind": "read",
  "url": "https://crm.example.com/hooks/order",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Sipariş numarası"
      }
    },
    "required": [
      "order_id"
    ]
  },
  "timeout_s": 8,
  "enabled": true,
  "secret": "whsec_2b7f…"
}'

Yanıt · 201

JSON
{
  "id": "tl_8f3a2c",
  "name": "check_order",
  "description": "Sipariş numarasıyla kargo durumunu getirir.",
  "kind": "read",
  "url": "https://crm.example.com/hooks/order",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Sipariş numarası"
      }
    },
    "required": [
      "order_id"
    ]
  },
  "timeout_s": 8,
  "enabled": true,
  "has_secret": true,
  "created_at": 1793830000,
  "updated_at": 1793830000
}

Hatalar

  • 400 Bir alan kurala uymuyor: ad biçimi, https adres, özel adres, 20'den fazla parametre ya da aralık dışı zaman aşımı.
  • 409 Bu adla bir araç zaten var ya da ad ayrılmış.

Aracı güncelle

PUT /v1/tools/{id}

Aracı gönderdiğiniz nesneyle değiştirir. Mevcut gizli anahtarı korumak için secret alanını boş bırakın ya da göndermeyin; silmek için "-" gönderin.

AdYerTürAçıklama
id
zorunlu
path string Araç kimliği.
name
zorunlu
body string Küçük harf, rakam ve alt çizgi; harfle başlar (3–41 karakter). Organizasyonda benzersiz; end_call ve take_message ayrılmıştır.
description
zorunlu
body string Modele aracı ne zaman ve nasıl kullanacağını anlatır.
kind
zorunlu
body "read" | "write" read hemen çalışır; write önce arayandan onay ister.
url
zorunlu
body string Sizin ucunuz. Yalnız https; yerel ve özel adresler reddedilir.
parameters body object JSON Schema nesnesi: string, number, integer ya da boolean türünde en fazla 20 alan (enum olur).
timeout_s body integer 2–15 saniye.
enabled body boolean Kapalı araçlar modele sunulmaz.
secret body string İstekleri imzalamak için. Yalnız yazılır; güncellemede boş değer mevcut anahtarı korur, "-" siler.

İstek

curl
curl -X PUT "https://hubvocal.com/v1/tools/tl_8f3a2c" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "check_order",
  "description": "Sipariş numarasıyla kargo durumunu getirir.",
  "kind": "read",
  "url": "https://crm.example.com/hooks/order",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Sipariş numarası"
      }
    },
    "required": [
      "order_id"
    ]
  },
  "timeout_s": 10,
  "enabled": true,
  "secret": ""
}'

Yanıt · 200

JSON
{
  "id": "tl_8f3a2c",
  "name": "check_order",
  "description": "Sipariş numarasıyla kargo durumunu getirir.",
  "kind": "read",
  "url": "https://crm.example.com/hooks/order",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Sipariş numarası"
      }
    },
    "required": [
      "order_id"
    ]
  },
  "timeout_s": 10,
  "enabled": true,
  "has_secret": true,
  "created_at": 1793830000,
  "updated_at": 1793833600
}

Hatalar

  • 400 Bir alan kurala uymuyor: ad biçimi, https adres, özel adres, 20'den fazla parametre ya da aralık dışı zaman aşımı.
  • 404 Bu kimlikle araç yok.

Aracı sil

DELETE /v1/tools/{id}

Aracı siler ve onu kullanan tüm ajanlardan kaldırır.

AdYerTürAçıklama
id
zorunlu
path string Araç kimliği.

İstek

curl
curl -X DELETE "https://hubvocal.com/v1/tools/tl_8f3a2c" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "deleted": "tl_8f3a2c"
}

Hatalar

  • 404 Bu kimlikle araç yok.

Aracı dene

POST /v1/tools/{id}/test

Verdiğiniz argümanlarla aracın adresine gerçek bir istek atar; durum kodunu, süreyi ve yanıt gövdesinin en fazla 4 KB'ını döner.

AdYerTürAçıklama
id
zorunlu
path string Araç kimliği.
arguments body object parameters ile uyumlu örnek argümanlar.

İstek

curl
curl -X POST "https://hubvocal.com/v1/tools/tl_8f3a2c/test" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "arguments": {
    "order_id": "A-10234"
  }
}'

Yanıt · 200

JSON
{
  "ok": true,
  "status": 200,
  "ms": 412,
  "body": "{\"order_id\":\"A-10234\",\"status\":\"shipped\",\"eta\":\"2026-11-07\"}"
}

Hatalar

  • 404 Bu kimlikle araç yok.

MCP sunucuları

MCP sunucularını listele

GET /v1/mcp-servers

Organizasyonunuzun MCP sunucuları; durumları ve eşitlenmiş araçlarıyla. auth_set bir gizli anahtarın kayıtlı olup olmadığını gösterir; anahtar hiç dönmez.

İstek

curl
curl "https://hubvocal.com/v1/mcp-servers" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "id": "mcp_2b8e41",
    "name": "crm",
    "url": "https://mcp.example.com/mcp",
    "transport": "streamable_http",
    "auth": "bearer",
    "auth_set": true,
    "enabled": true,
    "status": "ok",
    "error": null,
    "tools_synced_at": 1793831000,
    "tools": [
      {
        "name": "find_customer",
        "description": "Find a customer by phone number.",
        "input_schema": {
          "type": "object",
          "properties": {
            "phone": {
              "type": "string"
            }
          },
          "required": [
            "phone"
          ]
        },
        "enabled": true,
        "access": "read"
      },
      {
        "name": "create_ticket",
        "description": "Open a support ticket.",
        "input_schema": {
          "type": "object",
          "properties": {
            "subject": {
              "type": "string"
            },
            "body": {
              "type": "string"
            }
          },
          "required": [
            "subject"
          ]
        },
        "enabled": false,
        "access": "write"
      }
    ]
  }
]

MCP sunucusu ekle

POST /v1/mcp-servers

Sunucuyu kaydeder ve araç listesini çeker. Yeni araçlar kapalı gelir. Organizasyon başına en fazla 10 sunucu.

AdYerTürAçıklama
name
zorunlu
body string Kısa ad; araç adlarında önek olarak kullanılır (<ad>.<araç>).
url
zorunlu
body string Sunucunun MCP ucu. Yalnız https; yerel ve özel adresler reddedilir.
transport body string streamable_http (varsayılan) ya da sse.
auth body string none, bearer ya da header.
secret body string Token ya da başlık değeri. Şifreli saklanır, hiç dönmez; "-" siler.
header_name body string auth header ise başlığın adı.

İstek

curl
curl -X POST "https://hubvocal.com/v1/mcp-servers" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "crm",
  "url": "https://mcp.example.com/mcp",
  "auth": "bearer",
  "secret": "sk_live_…"
}'

Yanıt · 201

JSON
{
  "id": "mcp_2b8e41",
  "name": "crm",
  "url": "https://mcp.example.com/mcp",
  "transport": "streamable_http",
  "auth": "bearer",
  "auth_set": true,
  "enabled": true,
  "status": "ok",
  "error": null,
  "tools_synced_at": 1793831000,
  "tools": [
    {
      "name": "find_customer",
      "description": "Find a customer by phone number.",
      "input_schema": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string"
          }
        },
        "required": [
          "phone"
        ]
      },
      "enabled": false,
      "access": "write"
    },
    {
      "name": "create_ticket",
      "description": "Open a support ticket.",
      "input_schema": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string"
          }
        },
        "required": [
          "subject"
        ]
      },
      "enabled": false,
      "access": "write"
    }
  ]
}

Hatalar

  • 400 Adres https değil ya da özel bir adrese gidiyor, ya da sunucunun araç listesi alınamadı.
  • 409 Organizasyonda zaten 10 MCP sunucusu var.

MCP sunucusunu güncelle

PUT /v1/mcp-servers/{id}

Adı, adresi, kimlik doğrulamayı ya da açık/kapalı durumunu; hangi araçların açık olduğunu ve okuma mı yazma mı olduğunu değiştirir. Gizli anahtarı silmek için secret: "-" gönderin.

AdYerTürAçıklama
id
zorunlu
path string MCP sunucusu kimliği.
name body string Kısa ad; araç adlarında önek olarak kullanılır (<ad>.<araç>).
url body string Sunucunun MCP ucu. Yalnız https; yerel ve özel adresler reddedilir.
enabled body boolean Kapalı bir sunucu ajanlara sunulmaz.
auth body string none, bearer ya da header.
secret body string Token ya da başlık değeri. Şifreli saklanır, hiç dönmez; "-" siler.
tools body object[] Araç başına [{name, enabled, access}]; access read ya da write.

İstek

curl
curl -X PUT "https://hubvocal.com/v1/mcp-servers/mcp_2b8e41" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "tools": [
    {
      "name": "find_customer",
      "enabled": true,
      "access": "read"
    },
    {
      "name": "create_ticket",
      "enabled": true,
      "access": "write"
    }
  ]
}'

Yanıt · 200

JSON
{
  "id": "mcp_2b8e41",
  "name": "crm",
  "url": "https://mcp.example.com/mcp",
  "transport": "streamable_http",
  "auth": "bearer",
  "auth_set": true,
  "enabled": true,
  "status": "ok",
  "error": null,
  "tools_synced_at": 1793831000,
  "tools": [
    {
      "name": "find_customer",
      "description": "Find a customer by phone number.",
      "input_schema": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string"
          }
        },
        "required": [
          "phone"
        ]
      },
      "enabled": true,
      "access": "read"
    },
    {
      "name": "create_ticket",
      "description": "Open a support ticket.",
      "input_schema": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string"
          }
        },
        "required": [
          "subject"
        ]
      },
      "enabled": true,
      "access": "write"
    }
  ]
}

Hatalar

  • 400 Adres https değil ya da özel bir adrese gidiyor, ya da sunucunun araç listesi alınamadı.
  • 404 Bu kimlikle MCP sunucusu yok.

MCP sunucusunu sil

DELETE /v1/mcp-servers/{id}

Sunucuyu siler ve araçlarını tüm ajanlardan kaldırır.

AdYerTürAçıklama
id
zorunlu
path string MCP sunucusu kimliği.

İstek

curl
curl -X DELETE "https://hubvocal.com/v1/mcp-servers/mcp_2b8e41" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "deleted": "mcp_2b8e41"
}

Hatalar

  • 404 Bu kimlikle MCP sunucusu yok.

Araçları eşitle

POST /v1/mcp-servers/{id}/sync

Araç listesini yeniden çeker. Yeni araçlar kapalı ve access write olarak gelir.

AdYerTürAçıklama
id
zorunlu
path string MCP sunucusu kimliği.

İstek

curl
curl -X POST "https://hubvocal.com/v1/mcp-servers/mcp_2b8e41/sync" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "id": "mcp_2b8e41",
  "name": "crm",
  "url": "https://mcp.example.com/mcp",
  "transport": "streamable_http",
  "auth": "bearer",
  "auth_set": true,
  "enabled": true,
  "status": "ok",
  "error": null,
  "tools_synced_at": 1793831000,
  "tools": [
    {
      "name": "find_customer",
      "description": "Find a customer by phone number.",
      "input_schema": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string"
          }
        },
        "required": [
          "phone"
        ]
      },
      "enabled": true,
      "access": "read"
    },
    {
      "name": "create_ticket",
      "description": "Open a support ticket.",
      "input_schema": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string"
          }
        },
        "required": [
          "subject"
        ]
      },
      "enabled": false,
      "access": "write"
    }
  ]
}

Hatalar

  • 400 Adres https değil ya da özel bir adrese gidiyor, ya da sunucunun araç listesi alınamadı.
  • 404 Bu kimlikle MCP sunucusu yok.

Aracı dene

POST /v1/mcp-servers/{id}/test

Sunucudaki bir aracı verdiğiniz argümanlarla çağırır; süreyi, içeriğin en fazla 4 KB'ını ve aracın hata bildirip bildirmediğini döner.

AdYerTürAçıklama
id
zorunlu
path string MCP sunucusu kimliği.
tool
zorunlu
body string Çağrılacak aracın adı.
arguments body object Aracın input_schema'sına uyan argümanlar.

İstek

curl
curl -X POST "https://hubvocal.com/v1/mcp-servers/mcp_2b8e41/test" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "find_customer",
  "arguments": {
    "phone": "+905321234567"
  }
}'

Yanıt · 200

JSON
{
  "ok": true,
  "ms": 236,
  "content": "{\"customer_id\":\"C-1042\",\"name\":\"Ayşe Yılmaz\",\"open_tickets\":0}",
  "is_error": false
}

Hatalar

  • 404 Bu kimlikle MCP sunucusu yok.

Webhook'lar

Webhook'ları listele

GET /v1/webhooks

Organizasyonunuzun webhook'ları ve son teslimlerinin sonucu. Gizli anahtar burada dönmez; secret_set tanımlı olup olmadığını gösterir.

İstek

curl
curl "https://hubvocal.com/v1/webhooks" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "id": "wh_3c9d1e",
    "url": "https://crm.example.com/hooks/voice",
    "events": [
      "call.ended"
    ],
    "enabled": true,
    "secret_set": true,
    "created_at": 1793830000,
    "last_delivery": {
      "status": "ok",
      "at": 1793832440.2,
      "http_status": 200
    }
  }
]

Webhook oluştur

POST /v1/webhooks

Bir adresi olaylara abone eder. Şimdilik tek olay call.ended. Organizasyon başına en fazla 5 webhook. secret vermezseniz biri üretilir ve yalnız bu yanıtta döner.

AdYerTürAçıklama
url
zorunlu
body string Sizin ucunuz. Yalnız https; yerel ve özel adresler reddedilir.
events
zorunlu
body string[] Alınacak olaylar. Şimdilik ["call.ended"].
enabled body boolean Kapalı webhook'lara hiçbir şey gönderilmez.
secret body string İmza anahtarı. Verilmezse üretilir; yalnız bir kez döner.

İstek

curl
curl -X POST "https://hubvocal.com/v1/webhooks" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://crm.example.com/hooks/voice",
  "events": [
    "call.ended"
  ]
}'

Yanıt · 201

JSON
{
  "id": "wh_3c9d1e",
  "url": "https://crm.example.com/hooks/voice",
  "events": [
    "call.ended"
  ],
  "enabled": true,
  "secret_set": true,
  "created_at": 1793830000,
  "last_delivery": null,
  "secret": "whsec_9QmZ…"
}

Hatalar

  • 400 Adres https değil, özel bir adrese gidiyor ya da olay bilinmiyor.
  • 409 Organizasyonda zaten 5 webhook var.

Webhook'u güncelle

PUT /v1/webhooks/{id}

Adresi, olayları ya da açık/kapalı durumunu değiştirir. Yeni bir gizli anahtar üretmek için secret: "-" gönderin; yanıtta döner.

AdYerTürAçıklama
id
zorunlu
path string Webhook kimliği.
url body string Sizin ucunuz. Yalnız https; yerel ve özel adresler reddedilir.
events body string[] Alınacak olaylar. Şimdilik ["call.ended"].
enabled body boolean Kapalı webhook'lara hiçbir şey gönderilmez.
secret body string "-" yeni bir anahtar üretir. Mevcut anahtarı korumak için göndermeyin.

İstek

curl
curl -X PUT "https://hubvocal.com/v1/webhooks/wh_3c9d1e" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "enabled": false
}'

Yanıt · 200

JSON
{
  "id": "wh_3c9d1e",
  "url": "https://crm.example.com/hooks/voice",
  "events": [
    "call.ended"
  ],
  "enabled": false,
  "secret_set": true,
  "created_at": 1793830000,
  "last_delivery": {
    "status": "ok",
    "at": 1793832440.2,
    "http_status": 200
  }
}

Hatalar

  • 400 Adres https değil, özel bir adrese gidiyor ya da olay bilinmiyor.
  • 404 Bu kimlikle webhook yok.

Webhook'u sil

DELETE /v1/webhooks/{id}

Webhook'u siler. Bekleyen teslimler düşer.

AdYerTürAçıklama
id
zorunlu
path string Webhook kimliği.

İstek

curl
curl -X DELETE "https://hubvocal.com/v1/webhooks/wh_3c9d1e" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "deleted": "wh_3c9d1e"
}

Hatalar

  • 404 Bu kimlikle webhook yok.

Webhook'u dene

POST /v1/webhooks/{id}/test

Adrese örnek bir call.ended olayı gönderir; durum kodunu, süreyi ve yanıt gövdesini döner.

AdYerTürAçıklama
id
zorunlu
path string Webhook kimliği.

İstek

curl
curl -X POST "https://hubvocal.com/v1/webhooks/wh_3c9d1e/test" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "ok": true,
  "http_status": 200,
  "ms": 184,
  "body": "{\"received\":true}"
}

Hatalar

  • 404 Bu kimlikle webhook yok.

Teslimleri listele

GET /v1/webhooks/{id}/deliveries

Bir webhook'un son 50 teslimi, yeniden eskiye: durum (pending, ok, failed), deneme sayısı, HTTP durumu, hata ve sonraki denemenin zamanı.

AdYerTürAçıklama
id
zorunlu
path string Webhook kimliği.

İstek

curl
curl "https://hubvocal.com/v1/webhooks/wh_3c9d1e/deliveries" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "id": "dl_51b7a9",
    "event": "call.ended",
    "call_id": "demo-8585522d",
    "status": "ok",
    "attempts": 1,
    "http_status": 200,
    "error": null,
    "created_at": 1793832440.2,
    "next_attempt_at": null
  },
  {
    "id": "dl_51a3c4",
    "event": "call.ended",
    "call_id": "tel-6b1f04d2",
    "status": "pending",
    "attempts": 2,
    "http_status": 503,
    "error": "HTTP 503",
    "created_at": 1793832101.7,
    "next_attempt_at": 1793833901.7
  }
]

Hatalar

  • 404 Bu kimlikle webhook yok.

Teslimi yeniden dene

POST /v1/webhooks/deliveries/{id}/retry

Başarısız bir teslimi yeniden kuyruğa alır.

AdYerTürAçıklama
id
zorunlu
path string Teslim listesinden teslim kimliği.

İstek

curl
curl -X POST "https://hubvocal.com/v1/webhooks/deliveries/dl_51a3c4/retry" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "ok": true
}

Hatalar

  • 404 Bu kimlikle teslim yok ya da başarısız değil.

Sesler ve motorlar

Motorları, sesleri ve sınırları listele

GET /v1/voices

Ajan formu kurmak için gereken her şey: motor adları, motor başına geçerli sesler, hız aralıkları, diller, hazır ton seçenekleri, her motorun arkasındaki model ve alan uzunluğu sınırları. Aşağıdaki örnek kısaltıldı.

İstek

curl
curl "https://hubvocal.com/v1/voices" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "engines": {
    "live": "GPT-Live 1 (OpenAI full-duplex ses modeli)",
    "gemini": "Gemini Live (Google ses-sese model)",
    "realtime": "Realtime (OpenAI ses-sese model)",
    "classic": "Klasik (Deepgram + OpenAI LLM + OpenAI TTS)"
  },
  "voices": {
    "live": [
      "marin",
      "cedar",
      "gleam",
      "meridian"
    ],
    "gemini": [
      "Kore",
      "Aoede",
      "Charon",
      "Puck"
    ],
    "realtime": [
      "marin",
      "cedar",
      "alloy"
    ],
    "classic": [
      "alloy",
      "coral",
      "sage"
    ]
  },
  "speed": {
    "live": {
      "min": 1,
      "max": 1
    },
    "gemini": {
      "min": 1,
      "max": 1
    },
    "realtime": {
      "min": 0.25,
      "max": 1.5
    },
    "classic": {
      "min": 0.25,
      "max": 4
    }
  },
  "langs": {
    "tr": "Türkçe",
    "en": "English"
  },
  "presets": [
    {
      "id": "calm",
      "label": "Sakin ve güven veren",
      "text": "Sakin, yumuşak ve güven veren bir tonla konuş."
    }
  ],
  "models": {
    "live": {
      "model": "gpt-live-1",
      "backend": "gpt-5.6-luna"
    },
    "gemini": {
      "model": "gemini-3.8-live",
      "ready": true
    },
    "realtime": {
      "model": "gpt-realtime-2.1-mini"
    },
    "classic": {
      "stt": "nova-3",
      "llm": "gpt-4.1-mini",
      "tts": "gpt-4o-mini-tts"
    }
  },
  "limits": {
    "tone": 600,
    "instructions": 8000,
    "greeting": 400
  }
}

Görüşmeler

Saklama süresi organizasyon başına panelden ayarlanır: recordings_days (varsayılan 30), transcripts_days (varsayılan 365) ve pii_redaction. Günlük bir iş süresi dolan kayıtları ve dökümleri siler; görüşme satırı ve maliyeti kalır.

Web widget'ı: herkese açık anahtarlar (pk_…) panelde ajan başına oluşturulur. Widget betiği POST /api/public/web-calls çağırır; ayrıntı Geliştiriciler sayfasındaki rehberde.

Web görüşmesi başlat

POST /v1/web-calls

Tarayıcı görüşmesi için bir oda açar ve kısa ömürlü bir erişim token'ı döner. server_url ve token'ı tarayıcıda livekit-client'a verin; ajan odaya kendisi katılır. Bu ucu kendi sunucunuzdan çağırın, API anahtarı tarayıcıya hiç gitmesin. agent_id yerine tam bir agent nesnesi göndererek taslağı kaydetmeden deneyebilirsiniz.

AdYerTürAçıklama
agent_id body string Kayıtlı ajanın kimliği. agent göndermiyorsanız zorunlu.
agent body object Yalnız bu görüşmede kullanılacak tam ajan nesnesi (POST /v1/agents ile aynı alanlar).
version body string | integer Kullanılacak sürüm: "live" (varsayılan), "draft" ya da bir sürüm numarası.

İstek

curl
curl -X POST "https://hubvocal.com/v1/web-calls" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "resepsiyon"
}'

Yanıt · 200

JSON
{
  "server_url": "wss://hubvocal.com",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
  "room": "demo-3f9a1c2e",
  "max_seconds": 300
}

Hatalar

  • 400 agent_id ya da agent gönderilmedi.
  • 402 Organizasyonun aylık harcama limiti doldu.
  • 403 Organizasyon askıda.
  • 404 Bu id ile ajan yok.

Giden telefon araması başlat

POST /v1/calls

Organizasyonunuzun numaralarından biriyle bir numarayı arar; arama cevaplanınca ajan bağlanır. Sağlayıcı (DIDWW, Twilio ya da kendi SIP hattınız) arayan numaraya göre seçilir.

AdYerTürAçıklama
from
zorunlu
body string Organizasyonunuzun numaralarından biri, E.164 biçiminde (+90…).
to
zorunlu
body string Aranacak numara, E.164 biçiminde.
agent_id body string Kullanılacak ajan. Verilmezse arayan numaraya atanmış ajan konuşur.
version body string | integer Kullanılacak sürüm: "live" (varsayılan), "draft" ya da bir sürüm numarası.

İstek

curl
curl -X POST "https://hubvocal.com/v1/calls" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "from": "+908501234567",
  "to": "+905321234567",
  "agent_id": "resepsiyon"
}'

Yanıt · 200

JSON
{
  "room": "tel-out-9c41e0b7",
  "provider": "didww",
  "sip_call_id": "SCL_7mVt2kQb9xRa"
}

Hatalar

  • 400 Numara uluslararası biçimde değil ya da arayan numara organizasyonunuzun değil.
  • 402 Organizasyonun aylık harcama limiti doldu.
  • 502 Telefon sağlayıcısı aramayı reddetti.

Görüşmeleri listele

GET /v1/calls

Görüşmeler, yeniden eskiye; web ve telefon birlikte. quality tarayıcı ölçümünün özetidir, telefon görüşmelerinde null. ended_by: caller, agent, max_call_seconds, caller_unresponsive, agent_unresponsive, no_answer ya da unknown. channel: web, phone_in ya da phone_out. Her satırda ayrıca outcome ve summary_text (özetin ilk 160 karakteri) bulunur. Görüşmeyi canlı konsoldan bir yönetici bitirdiyse ended_by supervisor olur.

AdYerTürAçıklama
limit query integer Varsayılan 50, en fazla 500.
agent query string Yalnız bu ajanın görüşmeleri (ajan adı).
outcome query string Yalnız bu sonuçtaki görüşmeler.

İstek

curl
curl "https://hubvocal.com/v1/calls?limit=20" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
[
  {
    "room": "demo-8585522d",
    "org_id": "6f1c2a40-3b7e-4d0c-9a51-2f8e7c1d9b03",
    "org_name": "Örnek Klinik",
    "channel": "web",
    "profile": "Resepsiyon",
    "engine": "live",
    "lang": "tr",
    "voice": "marin",
    "started_at": 1793832409.1,
    "ended_at": 1793832434.2,
    "duration_s": 25.1,
    "total_usd": 0.021215,
    "ended_by": "caller",
    "outcome": "message_taken",
    "summary_text": "Arayan perşembe öğleden sonra için randevu istedi; geri arama için mesaj alındı.",
    "extracted": {
      "appointment_date": "2026-11-12",
      "callback": true
    },
    "first_audio_s": 2.43,
    "turns": 4,
    "source_gaps": {
      "count": 0,
      "total_ms": 0,
      "max_ms": 0
    },
    "quality": {
      "verdict": "Temiz: kayıp ve boşluk yok.",
      "protocol": "UDP",
      "loss_pct": 0,
      "conceal_pct": 0,
      "jitter_ms": 4,
      "rtt_ms": 38
    }
  }
]

Görüşme detayı

GET /v1/calls/{room}

Görüşmenin tam kaydı: sağlayıcı başına maliyet kırılımı, döküm, karşılama zamanlaması, ajan tarafı kaynak boşlukları ve 2 saniyelik pencerelerle tarayıcı kalite zaman çizelgesi. Maliyet alanları motora göre değişir (live, llm, stt, tts, realtime…); her biri usd içerir. source_gaps.events [saniye, ms] çiftleridir. summary; text, outcome (resolved, message_taken, transferred, unresolved, no_conversation, spam), sentiment, topics ve action_items içerir. supervisors canlı konsoldan görüşmeye kimin, hangi kiplerde katıldığını listeler. recording; available, duration_s ve size_bytes içerir. extracted ajanın post_call.fields alanlarının değerlerini tutar (konuşulmadıysa null).

AdYerTürAçıklama
room
zorunlu
path string Görüşme listesinden ya da POST /v1/web-calls yanıtından oda adı.

İstek

curl
curl "https://hubvocal.com/v1/calls/demo-8585522d" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "call": {
    "room": "demo-8585522d",
    "org_id": "6f1c2a40-3b7e-4d0c-9a51-2f8e7c1d9b03",
    "org_name": "Örnek Klinik",
    "channel": "web",
    "profile": "Resepsiyon",
    "engine": "live",
    "lang": "tr",
    "voice": "marin",
    "started_at": 1793832409.1,
    "ended_at": 1793832434.2,
    "duration_s": 25.1,
    "total_usd": 0.021215,
    "ended_by": "caller",
    "outcome": "message_taken",
    "summary_text": "Arayan perşembe öğleden sonra için randevu istedi; geri arama için mesaj alındı.",
    "extracted": {
      "appointment_date": "2026-11-12",
      "callback": true
    },
    "first_audio_s": 2.43,
    "turns": 4,
    "source_gaps": {
      "count": 2,
      "total_ms": 230,
      "max_ms": 141,
      "agent_audio_s": 31.2,
      "events": [
        [
          16.4,
          141
        ],
        [
          40.1,
          89
        ]
      ]
    },
    "quality": {
      "verdict": "Temiz: kayıp ve boşluk yok.",
      "protocol": "UDP",
      "loss_pct": 0,
      "conceal_pct": 0,
      "jitter_ms": 4,
      "rtt_ms": 38
    },
    "cost": {
      "live": {
        "billed_s": 25.1,
        "reported": true,
        "voice_usd": 0.020917,
        "backend": {
          "in": 1840,
          "cached": 1024,
          "out": 96
        },
        "backend_usd": 0.000298
      },
      "llm": {
        "input_tokens": 1840,
        "cached_tokens": 1024,
        "output_tokens": 96,
        "usd": 0.000298
      },
      "tts": {
        "input_tokens": 0,
        "audio_tokens": 0,
        "audio_s": 25.1,
        "usd": 0.020917
      },
      "stt": {
        "audio_s": 0,
        "usd": 0
      }
    },
    "tools": [
      {
        "t": 14.2,
        "name": "check_order",
        "kind": "read",
        "ok": true,
        "ms": 412,
        "status": 200
      }
    ],
    "outcomes": [],
    "summary": {
      "text": "Arayan perşembe öğleden sonra için randevu istedi; geri arama için mesaj alındı.",
      "language": "tr",
      "outcome": "message_taken",
      "sentiment": "neutral",
      "topics": [
        "randevu"
      ],
      "action_items": [
        "Arayanı perşembe sabahı geri ara"
      ]
    },
    "recording": {
      "available": true,
      "duration_s": 25.1,
      "size_bytes": 201344
    },
    "supervisors": [
      {
        "user": "ayse@example.com",
        "joined_at": 1793832420.4,
        "left_at": 1793832431,
        "modes": [
          "listen",
          "whisper"
        ]
      }
    ],
    "greeting": {
      "connect_s": 0.15,
      "session_started_s": 0.05,
      "reply_requested_s": 0.05,
      "first_audio_s": 2.4,
      "reply_done_s": 7.1
    },
    "transcript": [
      {
        "role": "assistant",
        "text": "Merhaba, kliniğimizi aradığınız için teşekkürler. Size nasıl yardımcı olabilirim?",
        "t": 2.4,
        "interrupted": false
      },
      {
        "role": "user",
        "text": "Perşembe öğleden sonra randevu almak istiyorum.",
        "t": 9.8
      }
    ]
  },
  "quality": {
    "summary": {
      "verdict": "Temiz: kayıp ve boşluk yok.",
      "protocol": "UDP",
      "rtt_ms": 38,
      "protocols_seen": [
        "UDP"
      ],
      "loss_pct": 0,
      "conceal_pct": 0,
      "jitter_ms": 4,
      "buffer_ms": 62
    },
    "timeline": [
      {
        "t": 2,
        "loss": 0,
        "conceal": 0,
        "jitter": 3,
        "buffer": 60,
        "proto": "UDP"
      },
      {
        "t": 4,
        "loss": 0,
        "conceal": 0,
        "jitter": 4,
        "buffer": 62,
        "proto": "UDP"
      }
    ]
  }
}

Hatalar

  • 404 Görüşme bulunamadı.

Kaydı indir

GET /v1/calls/{room}/recording

Görüşmenin sesi, OGG/Opus olarak. Range isteklerini destekler. Görüşme kaydedilmediyse ya da kaydın süresi dolduysa 404.

AdYerTürAçıklama
room
zorunlu
path string Görüşme listesinden ya da POST /v1/web-calls yanıtından oda adı.

İstek

curl
curl "https://hubvocal.com/v1/calls/demo-8585522d/recording" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -o call.ogg

Yanıt · 200

audio/ogg
HTTP/1.1 200 OK
Content-Type: audio/ogg
Accept-Ranges: bytes
Content-Length: 201344

<OGG/Opus>

Hatalar

  • 404 Görüşme kaydedilmedi ya da kaydın süresi doldu.

Görüşmeyi sil

DELETE /v1/calls/{room}

Görüşmenin kaydını, dökümünü ve özetini hemen siler; örneğin bir KVKK ya da GDPR talebi için. Görüşme satırı ve maliyeti kalır.

AdYerTürAçıklama
room
zorunlu
path string Görüşme listesinden ya da POST /v1/web-calls yanıtından oda adı.

İstek

curl
curl -X DELETE "https://hubvocal.com/v1/calls/demo-8585522d" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "deleted": "demo-8585522d"
}

Hatalar

  • 404 Görüşme bulunamadı.

Görüşmeleri dışa aktar (CSV)

GET /v1/calls/export

Bir tarih aralığındaki görüşmeler CSV olarak, görüşme başına bir satır; yapılandırılmış alanlar ek sütunlar olarak.

AdYerTürAçıklama
format
zorunlu
query string Yalnız csv.
from query date YYYY-AA-GG, dahil.
to query date YYYY-AA-GG, dahil.
agent_id query string Yalnız bu ajanın görüşmeleri.

İstek

curl
curl "https://hubvocal.com/v1/calls/export?format=csv&from=2026-11-01&to=2026-11-05" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -o calls.csv

Yanıt · 200

text/csv
room,started_at,agent,channel,duration_s,total_usd,outcome,appointment_date,callback
demo-8585522d,2026-11-05T09:46:49Z,front-desk,web,25.1,0.021215,message_taken,2026-11-12,true

Telefon numaraları

Numaraları listele

GET /v1/numbers

Organizasyonunuzun numaraları ve her birine cevap veren ajan (profile_id); ayrıca her telefon sağlayıcısının hazır olup olmadığı. Numaraları platform ekibi ekler; ajanı siz atarsınız.

İstek

curl
curl "https://hubvocal.com/v1/numbers" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "numbers": [
    {
      "number": "+908501234567",
      "provider": "didww",
      "org_id": "6f1c2a40-3b7e-4d0c-9a51-2f8e7c1d9b03",
      "org_name": "Örnek Klinik",
      "profile_id": "resepsiyon",
      "label": "Ana hat"
    }
  ],
  "sip": {
    "enabled": true,
    "room_prefix": "tel-",
    "providers": {
      "didww": {
        "inbound_ips": "46.19.209.14,46.19.210.14",
        "inbound_auth": false,
        "outbound_host": "trunk.example.com",
        "outbound_auth": true,
        "outbound_ready": true,
        "inbound_ready": true
      }
    }
  }
}

Numaraya ajan ata

PUT /v1/numbers/{number}

Bu numaraya gelen aramalara cevap verecek ajanı seçer. Atamayı kaldırmak için agent_id: null gönderin. Yoldaki numaranın + işaretini %2B olarak yazın (00 öneki de olur).

AdYerTürAçıklama
number
zorunlu
path string E.164 biçiminde, URL kodlanmış numara.
agent_id body string | null Gelen aramalara cevap verecek ajan.
label body string Ekibiniz için kısa not, en fazla 60 karakter.

İstek

curl
curl -X PUT "https://hubvocal.com/v1/numbers/%2B908501234567" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "resepsiyon",
  "label": "Ana hat"
}'

Yanıt · 200

JSON
{
  "ok": true
}

Hatalar

  • 400 Seçilen ajan yok.
  • 404 Numara organizasyonunuza ait değil.

Tüketim

Tüketim

GET /v1/usage

Organizasyonunuzun görüşme, dakika ve sağlayıcı maliyeti; sağlayıcıya ve güne göre (Europe/Istanbul). Varsayılan aralık bu ay. kind: llm, tts, stt ya da voice (ses-sese motorlar).

AdYerTürAçıklama
from query date YYYY-AA-GG, dahil.
to query date YYYY-AA-GG, dahil.

İstek

curl
curl "https://hubvocal.com/v1/usage?from=2026-11-01&to=2026-11-05" \
  -H "Authorization: Bearer $VT_API_KEY"

Yanıt · 200

JSON
{
  "from": "2026-11-01",
  "to": "2026-11-05",
  "totals": {
    "calls": 42,
    "minutes": 81.2,
    "usd": 3.94
  },
  "by_provider": [
    {
      "provider": "openai",
      "model": "gpt-live-1",
      "kind": "voice",
      "calls": 30,
      "input_tokens": 0,
      "cached_tokens": 0,
      "output_tokens": 0,
      "audio_s": 2900.1,
      "usd": 2.41
    }
  ],
  "by_day": [
    {
      "date": "2026-11-05",
      "usd": 1.2,
      "minutes": 20.5,
      "calls": 9
    }
  ],
  "by_org": [
    {
      "org_id": "6f1c2a40-3b7e-4d0c-9a51-2f8e7c1d9b03",
      "org_name": "Örnek Klinik",
      "usd": 3.94,
      "minutes": 81.2,
      "calls": 42
    }
  ]
}

Tanım

OpenAPI tanımı

GET /v1/openapi.json Anahtar gerekmez

Bu API'nin OpenAPI 3.1 belgesi. Anahtar gerekmez. Postman, Insomnia ya da bir istemci üreticisine aktarabilirsiniz.

İstek

curl
curl "https://hubvocal.com/v1/openapi.json"

Yanıt · 200

JSON
{
  "openapi": "3.1.0",
  "info": {
    "title": "HubVocal API",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://hubvocal.com/v1"
    }
  ],
  "paths": {}
}