API referansı
Aramalar
WhatsApp sesli aramalarını yönetin: gelen aramayı kabul edin ya da reddedin, izin veren müşteriyi arayın, arama ayarlarını ve geçmişini görün. Ses WebRTC ile sizin ucunuz ve Meta arasında akar; Veri Merkezi yalnız sinyal verisini (SDP) iletir.
#Call nesnesi
call_idstringArama kimliği.phone_number_idstringNumaranızın Meta kimliği.directionstringYön.Değerler:user_initiated,business_initiatedfromstring · boş olabilirArayan.tostring · boş olabilirAranan.statusstringDurum.Değerler:initiated,ringing,pre_accepted,accepted,terminating,rejected,missed,failed,completedstarted_atstring · boş olabilirBaşlangıç.ended_atstring · boş olabilirBitiş.duration_secinteger · boş olabilirSüre (saniye).billable_pulsesinteger · boş olabilir⌈süre / 6⌉; yalnız işletme başlatmalı aramada, bilgi amaçlı (Meta doğrudan faturalar).last_actionstring · boş olabilirSon eylem.errorsarray · boş olabilirHatalar.is_testbooleanTest anahtarıyla oluşturuldu mu.created_atstringKayıt zamanı.
Call nesnesi
{
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"phone_number_id": "1234567890",
"direction": "user_initiated",
"from": "905550000000",
"to": "905550000001",
"status": "completed",
"started_at": "2026-10-09T14:00:05+03:00",
"ended_at": "2026-10-09T14:01:19+03:00",
"duration_sec": 74,
"billable_pulses": null,
"last_action": "accept",
"errors": null,
"is_test": false,
"created_at": "2026-10-09T14:00:00+03:00"
}#Arama ayarlarını getir
GET
/numbers/{phone_number_id}/callingNumaranın arama ayarlarını ve arama uygunluğunu (
eligibility) döndürür. Kapsam: calls:readUygunluk kontrolleri:
cloud_api_only, messaging_limit, calls_webhook, payment_method (yalnız müşteriyi arama), country (yalnız müşteriyi arama). ok: null bilginin bilinmediğini gösterir; son kararı Meta verir.Yol parametreleri
phone_number_idstringzorunluNumaranızın Meta kimliği (yalnız rakam, 5–32 hane).
Sorgu parametreleri
rawbooleanisteğe bağlı1Meta'nın ham calling nesnesini ekler (raw).
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:read kapsamı yok. |
| 404 | number_not_found | Numara size ait değil. |
| 409 | number_detached | Numara hesabınızdan ayrılmış; panelden yeniden bağlayın. |
| 422 | invalid_phone_number_id | phone_number_id rakam değil. |
curl -X GET "https://api.verimerkezi.app/wa/numbers/1234567890/calling" \
-H "Authorization: Bearer $VM_API_KEY"const res = await fetch("https://api.verimerkezi.app/wa/numbers/1234567890/calling", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.verimerkezi.app/wa/numbers/1234567890/calling",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/numbers/1234567890/calling");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
],
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"phone_number_id": "1234567890",
"enabled": true,
"callback_permission": true,
"call_icon_visibility": "DEFAULT",
"call_hours": {
"status": "ENABLED",
"timezone_id": "Europe/Istanbul",
"weekly_operating_hours": [
{
"day_of_week": "MONDAY",
"open_time": "0900",
"close_time": "1800"
}
]
},
"messaging_limit_tier": "TIER_2K",
"messaging_limit_ok": true,
"eligibility": {
"eligible_inbound": true,
"eligible_outbound": true,
"checks": [
{
"key": "cloud_api_only",
"ok": true,
"applies_to": [
"inbound",
"outbound"
],
"title_tr": "Numara yalnız API'ye bağlı olmalı",
"detail_tr": "Numara Cloud API'ye bağlı.",
"how_to_fix_tr": null
},
{
"key": "messaging_limit",
"ok": true,
"applies_to": [
"inbound",
"outbound"
],
"title_tr": "Günlük mesaj limiti en az 2.000 olmalı",
"detail_tr": "Limit yeterli.",
"how_to_fix_tr": null
},
{
"key": "payment_method",
"ok": null,
"applies_to": [
"outbound"
],
"title_tr": "Ödeme yöntemi",
"detail_tr": "Bilgi Meta'dan okunamadı.",
"how_to_fix_tr": "Meta Business Suite'te ödeme yöntemini kontrol edin."
}
]
}
}#Arama ayarlarını güncelle
PATCH
/numbers/{phone_number_id}/callingAramayı açar/kapatır, arama saatlerini ve geri arama iznini ayarlar. Yalnız gönderdiğiniz alanlar değişir. Kapsam:
calls:writeenabled: true isteğinde numara coexistence ise ya da Meta'dan okunan limit 2.000'in altındaysa istek Meta'ya gönderilmeden reddedilir; hata gövdesinde error.eligibility ve error.checked_locally: true döner.Test anahtarıyla Meta'ya istek gitmez.
Yol parametreleri
phone_number_idstringzorunluNumaranızın Meta kimliği (yalnız rakam, 5–32 hane).
İstek gövdesi
enabledbooleanisteğe bağlıAramayı açar/kapatır.callback_permissionbooleanisteğe bağlıMüşteri aradığında geri arama izni önerilir.call_icon_visibilitystringisteğe bağlıSohbetteki arama simgesi.Değerler:DEFAULT,DISABLE_ALLcall_hoursobjectisteğe bağlıArama saatleri.Alt alanları göster
statusstringisteğe bağlıDurum.Değerler:ENABLED,DISABLEDtimezone_idstringisteğe bağlıSaat dilimi (ör.Europe/Istanbul).weekly_operating_hoursarrayisteğe bağlı{ day_of_week, open_time, close_time }listesi (saatHHMM).holiday_schedulearrayisteğe bağlıTatil takvimi.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | number_not_found | Numara size ait değil. |
| 409 | number_detached | Numara hesabınızdan ayrılmış; panelden yeniden bağlayın. |
| 422 | invalid_request | Parametre hatalı. |
| 422 | calling_not_supported_for_number | Coexistence ya da Cloud API dışı numara. |
| 422 | calling_messaging_limit_too_low | Günlük mesaj limiti 2.000'in altında. |
| 422 | calling_prerequisites_unmet | Teknik önkoşullar karşılanmıyor (Meta 138018). |
| 422 | calling_outbound_unavailable | İşletme başlatmalı arama bu numara/ülkede yok (Meta 138013). |
| 422 | calling_disabled_quality | Meta kalite nedeniyle aramayı geçici kapattı (Meta 138014). |
curl -X PATCH "https://api.verimerkezi.app/wa/numbers/1234567890/calling" \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"callback_permission": true,
"call_icon_visibility": "DEFAULT",
"call_hours": {
"status": "ENABLED",
"timezone_id": "Europe/Istanbul",
"weekly_operating_hours": [
{
"day_of_week": "MONDAY",
"open_time": "0900",
"close_time": "1800"
}
]
}
}'const res = await fetch("https://api.verimerkezi.app/wa/numbers/1234567890/calling", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"enabled": true,
"callback_permission": true,
"call_icon_visibility": "DEFAULT",
"call_hours": {
"status": "ENABLED",
"timezone_id": "Europe/Istanbul",
"weekly_operating_hours": [
{
"day_of_week": "MONDAY",
"open_time": "0900",
"close_time": "1800"
}
]
}
}),
});
const data = await res.json();import os, requests
res = requests.patch(
"https://api.verimerkezi.app/wa/numbers/1234567890/calling",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
json={
"enabled": True,
"callback_permission": True,
"call_icon_visibility": "DEFAULT",
"call_hours": {
"status": "ENABLED",
"timezone_id": "Europe/Istanbul",
"weekly_operating_hours": [
{
"day_of_week": "MONDAY",
"open_time": "0900",
"close_time": "1800"
}
]
}
},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/numbers/1234567890/calling");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"enabled" => true,
"callback_permission" => true,
"call_icon_visibility" => "DEFAULT",
"call_hours" => [
"status" => "ENABLED",
"timezone_id" => "Europe/Istanbul",
"weekly_operating_hours" => [
[
"day_of_week" => "MONDAY",
"open_time" => "0900",
"close_time" => "1800"
]
]
]
]),
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"phone_number_id": "1234567890",
"enabled": true,
"callback_permission": true,
"call_icon_visibility": "DEFAULT",
"call_hours": {
"status": "ENABLED",
"timezone_id": "Europe/Istanbul",
"weekly_operating_hours": [
{
"day_of_week": "MONDAY",
"open_time": "0900",
"close_time": "1800"
}
]
},
"messaging_limit_tier": "TIER_2K",
"messaging_limit_ok": true,
"eligibility": {
"eligible_inbound": true,
"eligible_outbound": true,
"checks": [
{
"key": "cloud_api_only",
"ok": true,
"applies_to": [
"inbound",
"outbound"
],
"title_tr": "Numara yalnız API'ye bağlı olmalı",
"detail_tr": "Numara Cloud API'ye bağlı.",
"how_to_fix_tr": null
},
{
"key": "messaging_limit",
"ok": true,
"applies_to": [
"inbound",
"outbound"
],
"title_tr": "Günlük mesaj limiti en az 2.000 olmalı",
"detail_tr": "Limit yeterli.",
"how_to_fix_tr": null
},
{
"key": "payment_method",
"ok": null,
"applies_to": [
"outbound"
],
"title_tr": "Ödeme yöntemi",
"detail_tr": "Bilgi Meta'dan okunamadı.",
"how_to_fix_tr": "Meta Business Suite'te ödeme yöntemini kontrol edin."
}
]
},
"updated": true
}#Arama geçmişini listele
GET
/callsArama kayıtlarını yeniden eskiye döndürür. Kapsam:
calls:readSorgu parametreleri
phone_number_idstringisteğe bağlıNumara süzgeci.fromstringisteğe bağlıBaşlangıç (ISO 8601).tostringisteğe bağlıBitiş (ISO 8601).peerstringisteğe bağlıKarşı taraf numarası.limitintegeristeğe bağlıSayfa boyutu (1–100).Varsayılan:50cursorstringisteğe bağlıÖnceki yanıttakinext_cursor.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:read kapsamı yok. |
| 404 | number_not_found | Numara size ait değil. |
curl -X GET "https://api.verimerkezi.app/wa/calls?phone_number_id=1234567890" \
-H "Authorization: Bearer $VM_API_KEY"const res = await fetch("https://api.verimerkezi.app/wa/calls?phone_number_id=1234567890", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.verimerkezi.app/wa/calls?phone_number_id=1234567890",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls?phone_number_id=1234567890");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
],
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"calls": [
{
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"phone_number_id": "1234567890",
"direction": "user_initiated",
"from": "905550000000",
"to": "905550000001",
"status": "completed",
"started_at": "2026-10-09T14:00:05+03:00",
"ended_at": "2026-10-09T14:01:19+03:00",
"duration_sec": 74,
"billable_pulses": null,
"last_action": "accept",
"errors": null,
"is_test": false,
"created_at": "2026-10-09T14:00:00+03:00"
}
],
"has_more": false,
"next_cursor": null
}#Müşteriyi ara
POST
/callsİşletme başlatmalı arama yapar. Müşterinin arama izni olmalıdır. Sonuç
call.status ve Meta yanıtıyla gelen call.connect (SDP answer) olaylarıyla izlenir. Kapsam: calls:writeArama eylemleri kredi düşmez; işletme başlatmalı aramayı Meta 6 saniyelik dilimlerle doğrudan faturalar.
Başlattığınız aramada yalnız
terminate eylemi kullanılabilir.Test anahtarıyla Meta'ya gitmeden simüle edilir (
simulated: true).Başlıklar
Idempotency-Keyisteğe bağlı8–128 karakterlik benzersiz anahtar (UUID önerilir). Aynı anahtar ve aynı gövdeyle yapılan tekrar, ilk yanıtıIdempotent-Replay: truebaşlığıyla döndürür. 24 saat saklanır.
İstek gövdesi
phone_number_idstringzorunluNumaranızın Meta kimliği.tostringzorunluAranacak müşteri.sdp_offerstringzorunluWebRTC SDP teklifi (RFC 8866).biz_opaquestringisteğe bağlıEn fazla 512 karakterlik eşleştirme değeri.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | call_permission_required | Müşterinin arama izni yok. |
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | number_not_found | Numara size ait değil. |
| 409 | number_detached | Numara hesabınızdan ayrılmış; panelden yeniden bağlayın. |
| 409 | calling_not_enabled | Numarada arama kapalı. |
| 409 | meta_outcome_unknown | Sonuç belirsiz; tekrar göndermeyin, call.* olayını bekleyin. |
| 409 | idempotency_in_progress | Aynı anahtarla bir istek hâlâ işleniyor. Retry-After kadar bekleyin. |
| 422 | idempotency_key_conflict | Aynı anahtar farklı bir gövdeyle kullanılmış. |
| 422 | invalid_sdp | SDP boş ya da geçersiz. |
| 422 | invalid_phone | Telefon geçersiz. |
| 422 | calling_not_available_in_country | Alıcının ülkesinde işletme araması yok. |
| 429 | call_rate_limited | Arama sınırı aşıldı. |
curl -X POST "https://api.verimerkezi.app/wa/calls" \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number_id": "1234567890",
"to": "905550000000",
"sdp_offer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n...",
"biz_opaque": "crm-ticket-42"
}'const res = await fetch("https://api.verimerkezi.app/wa/calls", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"phone_number_id": "1234567890",
"to": "905550000000",
"sdp_offer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n...",
"biz_opaque": "crm-ticket-42"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.verimerkezi.app/wa/calls",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
json={
"phone_number_id": "1234567890",
"to": "905550000000",
"sdp_offer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n...",
"biz_opaque": "crm-ticket-42"
},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"phone_number_id" => "1234567890",
"to" => "905550000000",
"sdp_offer" => "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n...",
"biz_opaque" => "crm-ticket-42"
]),
]);
$data = json_decode(curl_exec($ch), true);Yanıt 201
{
"ok": true,
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE2",
"status": "initiated",
"direction": "business_initiated",
"to": "905550000000"
}#Gelen aramayı ön-kabul et
POST
/calls/{call_id}/pre_acceptBağlantıyı önceden kurmak için gelen aramayı SDP yanıtıyla ön-kabul eder; ardından
accept çağırın. Kapsam: calls:writeHer eylem
(call_id, eylem) bazında idempotenttir; tekrar gönderilirse ilk sonuç Idempotent-Replay: true ile döner.Yol parametreleri
call_idstringzorunluArama kimliği (URL-kodlu). İçinde/varsa yol yerine_yazıp gövdedecall_idgönderin.
İstek gövdesi
sdp_answerstringzorunluWebRTC SDP yanıtı.call_idstringisteğe bağlıYalnız yol_ise.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | call_not_found | Arama yok, size ait değil ya da test/canlı anahtar uyuşmuyor. |
| 409 | call_ended | Arama sona ermiş. |
| 409 | call_action_conflict | Aynı eylem farklı parametreyle uygulanmış. |
| 409 | action_in_progress | Eylem hâlâ işleniyor. |
| 409 | invalid_action_for_direction | Başlattığınız aramada yalnız terminate. |
| 422 | invalid_sdp | SDP geçersiz. |
curl -X POST "https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/pre_accept" \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sdp_answer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
}'const res = await fetch("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/pre_accept", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"sdp_answer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/pre_accept",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
json={
"sdp_answer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/pre_accept");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"sdp_answer" => "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
]),
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"action": "pre_accept",
"success": true
}#Gelen aramayı kabul et
POST
/calls/{call_id}/acceptGelen aramayı SDP yanıtıyla kabul eder. Kapsam:
calls:writeYol parametreleri
call_idstringzorunluArama kimliği (URL-kodlu). İçinde/varsa yol yerine_yazıp gövdedecall_idgönderin.
İstek gövdesi
sdp_answerstringzorunluWebRTC SDP yanıtı.call_idstringisteğe bağlıYalnız yol_ise.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | call_not_found | Arama bulunamadı. |
| 409 | call_ended | Arama sona ermiş. |
| 409 | call_action_conflict | Aynı eylem farklı parametreyle uygulanmış. |
curl -X POST "https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/accept" \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sdp_answer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
}'const res = await fetch("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/accept", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"sdp_answer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/accept",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
json={
"sdp_answer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/accept");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"sdp_answer" => "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n..."
]),
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"action": "accept",
"success": true
}#Gelen aramayı reddet
POST
/calls/{call_id}/rejectGelen aramayı reddeder. Kapsam:
calls:writeYol parametreleri
call_idstringzorunluArama kimliği (URL-kodlu). İçinde/varsa yol yerine_yazıp gövdedecall_idgönderin.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | call_not_found | Arama bulunamadı. |
| 409 | call_ended | Arama sona ermiş. |
curl -X POST "https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/reject" \
-H "Authorization: Bearer $VM_API_KEY"const res = await fetch("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/reject", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/reject",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/reject");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
],
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"action": "reject",
"success": true
}#Aramayı sonlandır
POST
/calls/{call_id}/terminateSüren aramayı kapatır. İşletme başlatmalı aramalarda kullanılabilen tek eylemdir. Kapsam:
calls:writeYol parametreleri
call_idstringzorunluArama kimliği (URL-kodlu). İçinde/varsa yol yerine_yazıp gövdedecall_idgönderin.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | call_not_found | Arama bulunamadı. |
| 409 | call_ended | Arama sona ermiş. |
curl -X POST "https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/terminate" \
-H "Authorization: Bearer $VM_API_KEY"const res = await fetch("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/terminate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/terminate",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls/wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1/terminate");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
],
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"action": "terminate",
"success": true
}#Arama izni iste
POST
/calls/permission-requestMüşteriye arama izni isteyen etkileşimli bir mesaj gönderir. Yanıt
call.permission_reply olayıyla gelir. Normal mesaj gibi 1 kredi düşer; başarısızsa iade edilir. Kapsam: calls:writeİzin durumları:
no_permission, temporary (7 gün), permanent. Art arda 4 cevapsız işletme araması kalıcı izni geri alır.Başlıklar
Idempotency-Keyisteğe bağlı8–128 karakterlik benzersiz anahtar (UUID önerilir). Aynı anahtar ve aynı gövdeyle yapılan tekrar, ilk yanıtıIdempotent-Replay: truebaşlığıyla döndürür. 24 saat saklanır.
İstek gövdesi
phone_number_idstringzorunluNumaranızın Meta kimliği.tostringzorunluMüşteri telefonu.bodystringisteğe bağlıMesaj metni (en fazla 1024).
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 402 | insufficient_credits | Kredi yetersiz. |
| 403 | insufficient_scope | Anahtarda calls:write kapsamı yok. |
| 404 | number_not_found | Numara size ait değil. |
| 409 | number_detached | Numara hesabınızdan ayrılmış; panelden yeniden bağlayın. |
| 409 | idempotency_in_progress | Aynı anahtarla bir istek hâlâ işleniyor. Retry-After kadar bekleyin. |
| 422 | idempotency_key_conflict | Aynı anahtar farklı bir gövdeyle kullanılmış. |
| 422 | outside_service_window | 24 saatlik pencere kapalı. |
| 422 | invalid_phone | Telefon geçersiz. |
| 429 | permission_request_limited | Aynı kişiye 24 saatte 1, 7 günde 2 istek sınırı. |
curl -X POST "https://api.verimerkezi.app/wa/calls/permission-request" \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number_id": "1234567890",
"to": "905550000000",
"body": "Siparişiniz hakkında sizi arayabilir miyiz?"
}'const res = await fetch("https://api.verimerkezi.app/wa/calls/permission-request", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"phone_number_id": "1234567890",
"to": "905550000000",
"body": "Siparişiniz hakkında sizi arayabilir miyiz?"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.verimerkezi.app/wa/calls/permission-request",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
json={
"phone_number_id": "1234567890",
"to": "905550000000",
"body": "Siparişiniz hakkında sizi arayabilir miyiz?"
},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls/permission-request");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"phone_number_id" => "1234567890",
"to" => "905550000000",
"body" => "Siparişiniz hakkında sizi arayabilir miyiz?"
]),
]);
$data = json_decode(curl_exec($ch), true);Yanıt 201
{
"ok": true,
"message_id": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"to": "905550000000",
"credits_consumed": 1,
"balance": 4999
}#Arama izni durumunu getir
GET
/calls/permissionBir müşterinin arama izni durumunu döndürür. Kapsam:
calls:readactions dizisi Meta'nın döndürdüğü eylem bilgilerini aynen iletir.Sorgu parametreleri
phone_number_idstringzorunluNumaranızın Meta kimliği.tostringzorunluMüşteri telefonu.
Hatalar
| Durum | Kod | Ne zaman |
|---|---|---|
| 403 | insufficient_scope | Anahtarda calls:read kapsamı yok. |
| 404 | number_not_found | Numara size ait değil. |
| 422 | invalid_phone_number_id | phone_number_id rakam değil. |
curl -X GET "https://api.verimerkezi.app/wa/calls/permission?phone_number_id=1234567890&to=905550000000" \
-H "Authorization: Bearer $VM_API_KEY"const res = await fetch("https://api.verimerkezi.app/wa/calls/permission?phone_number_id=1234567890&to=905550000000", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.VM_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.verimerkezi.app/wa/calls/permission?phone_number_id=1234567890&to=905550000000",
headers={"Authorization": f"Bearer {os.environ['VM_API_KEY']}"},
)
data = res.json()<?php
$ch = curl_init("https://api.verimerkezi.app/wa/calls/permission?phone_number_id=1234567890&to=905550000000");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("VM_API_KEY"),
],
]);
$data = json_decode(curl_exec($ch), true);Yanıt 200
{
"ok": true,
"status": "temporary",
"expires_at": "2026-10-15T10:00:00+03:00",
"can_request": false,
"can_call": true,
"actions": []
}