API referansı
Webhook olayları
Veri Merkezi, abone olduğunuz olayları HTTPS üzerinden POST ile sunucunuza gönderir. Meta kaynaklı olaylar (mesaj, durum, arama, form…) genellikle 1 saniye içinde teslim edilir; Meta dışından tetiklenen olaylar (credit.*, number.detached / number.purged, panelden contact.opt_out_changed, kampanya/otomasyon message.sent, privacy.erasure_completed) dakikalık kuyrukla en geç ~1 dakikada gider. Başarısız teslimler yeniden denenir. Her istek event, event_id (UUIDv7), event_type, occurred_at, created_at ve data alanlarını taşıyan bir zarf içerir. * aboneliği yalnız 12 klasik olayı kapsar; diğer 23 olayı açıkça seçmelisiniz.
#İmza doğrulama
Başlık: X-VeriMerkezi-Signature-256 · Algoritma: HMAC-SHA256 (hex), biçim: sha256=<imza>
1. Ham istek gövdesini ayrıştırmadan okuyun. 2. X-VeriMerkezi-Timestamp değerini alın; 300 saniyeden eskiyse isteği reddedin (tekrar saldırısı koruması). 3. zaman_damgasi + "." + ham_gövde metnini abonelik anahtarınızla (whsec_...) HMAC-SHA256 ile imzalayın ve başına sha256= ekleyin. 4. Sonucu X-VeriMerkezi-Signature-256 başlığıyla sabit zamanlı karşılaştırın. 5. Anahtar döndürme süresince eşleşme yoksa aynı yöntemle eski anahtarı X-VeriMerkezi-Signature-256-Previous başlığına karşı deneyin. 6. Kısa sürede 2xx döndürün; işi arka plana alın. event_id ile yinelenen teslimleri ayıklayın.
const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/wa-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const secret = process.env.VM_WEBHOOK_SECRET; // whsec_...
const ts = req.header('X-VeriMerkezi-Timestamp') || '';
const sig = req.header('X-VeriMerkezi-Signature-256') || '';
const body = req.body.toString('utf8');
if (Math.abs(Date.now() / 1000 - parseInt(ts, 10)) > 300) return res.status(401).end();
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(ts + '.' + body).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(sig);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.status(401).end();
const event = JSON.parse(body);
// event.event_id ile yinelenenleri ayıklayın, işi kuyruğa alın
res.status(200).json({ ok: true });
});import hmac, hashlib, os, time, json
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ['VM_WEBHOOK_SECRET'].encode() # whsec_...
@app.post('/wa-webhook')
def webhook():
ts = request.headers.get('X-VeriMerkezi-Timestamp', '')
sig = request.headers.get('X-VeriMerkezi-Signature-256', '')
body = request.get_data(as_text=True)
if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
abort(401)
expected = 'sha256=' + hmac.new(SECRET, f'{ts}.{body}'.encode(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, sig):
abort(401)
event = json.loads(body)
# event['event_id'] ile yinelenenleri ayıklayın
return {'ok': True}<?php
$secret = getenv('VM_WEBHOOK_SECRET'); // whsec_...
$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_VERIMERKEZI_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_VERIMERKEZI_SIGNATURE_256'] ?? '';
if (abs(time() - (int) $ts) > 300) { http_response_code(401); exit; }
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
if (!hash_equals($expected, $sig)) { http_response_code(401); exit; }
$event = json_decode($body, true);
// $event['event_id'] ile yinelenenleri ayıklayın
http_response_code(200);
echo json_encode(['ok' => true]);#message.received
data.text düz metindir; medyada açıklamayı taşır, dosya data.media.media_id ile indirilir. Telefonu görünmeyen kullanıcıda from null, kimlik user_id olur. Buton yanıtlarında button: { payload, text } dolar. Etkileşimli mesajda interactive: { type, name } dolar (ör. button_reply, list_reply; form yanıtında { "type": "nfm_reply", "name": "flow" }), diğer mesajlarda null. Düğme ve liste seçiminde interactive ayrıca reply_id, reply_title ve (yalnız listede) reply_description taşır. Bilinmeyen mesaj türlerinde ham Meta mesajı data.raw alanında gelir (boyut sınırını aşarsa null). type: "unsupported" olduğunda data.unsupported = { type, raw_type, error_code, error_title } Meta'nın nedenini taşır (ör. 131060: WhatsApp mesajın içeriğini iletmedi); diğer türlerde null.{
"event": "message.received",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb00",
"event_type": "message.received",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhggQTNFQkQ2RjQ3MEIyQzk0RTE4AA==",
"from": "905550000000",
"user_id": null,
"username": null,
"name": "Ayşe Yılmaz",
"type": "text",
"text": "Merhaba, siparişim ne durumda?",
"media": null,
"timestamp": "1791619200",
"phone_number_id": "1234567890",
"contact": {
"wa_id": "905550000000",
"user_id": null,
"username": null,
"profile_name": "Ayşe Yılmaz"
},
"context": null,
"reaction": null,
"location": null,
"contacts": null,
"original_message_id": null,
"button": null,
"interactive": null
}
}#message.echo
from işletme, to müşteridir. Botunuzun çift yanıt vermesini önlemek için kullanın. Etkileşimli mesajda interactive: { type, name } dolar (ör. button_reply, list_reply; form yanıtında { "type": "nfm_reply", "name": "flow" }), diğer mesajlarda null. Düğme ve liste seçiminde interactive ayrıca reply_id, reply_title ve (yalnız listede) reply_description taşır.{
"event": "message.echo",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb01",
"event_type": "message.echo",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSRUNITzE=",
"from": "905550000001",
"to": "905550000000",
"type": "text",
"text": "Teşekkürler, hemen dönüyorum.",
"timestamp": "1791619300",
"source": "coexistence_app",
"phone_number_id": "1234567890",
"user_id": null,
"media": null,
"context": null,
"reaction": null,
"location": null,
"contacts": null,
"original_message_id": null,
"button": null,
"interactive": null
}
}#message.status.sent
{
"event": "message.status.sent",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb02",
"event_type": "message.status.sent",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"recipient": "905550000000",
"timestamp": "1791619260",
"errors": null,
"phone_number_id": "1234567890",
"conversation": null,
"pricing": null,
"biz_opaque_callback_data": "018f3a2b-7c1d-7f4e-9b21-6d0c1e2f3a4b",
"user_id": null,
"direction": "outbound"
}
}#message.status.delivered
{
"event": "message.status.delivered",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb03",
"event_type": "message.status.delivered",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"recipient": "905550000000",
"timestamp": "1791619260",
"errors": null,
"phone_number_id": "1234567890",
"conversation": null,
"pricing": null,
"biz_opaque_callback_data": "018f3a2b-7c1d-7f4e-9b21-6d0c1e2f3a4b",
"user_id": null,
"direction": "outbound"
}
}#message.status.read
{
"event": "message.status.read",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb04",
"event_type": "message.status.read",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"recipient": "905550000000",
"timestamp": "1791619260",
"errors": null,
"phone_number_id": "1234567890",
"conversation": null,
"pricing": null,
"biz_opaque_callback_data": "018f3a2b-7c1d-7f4e-9b21-6d0c1e2f3a4b",
"user_id": null,
"direction": "outbound"
}
}#message.status.failed
errors Meta'nın hata listesini aynen taşır (error_data.details dahil). Her öğeye message_tr, action_tr, severity, retryable, category ve known (sözlükte var mı) eklenir; ilk hatanın özeti üst düzeyde: error_code, error_message_tr, error_action_tr, error_severity, error_retryable, error_category.{
"event": "message.status.failed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb05",
"event_type": "message.status.failed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"recipient": "905550000000",
"timestamp": "1791619260",
"errors": [
{
"code": 131047,
"title": "Re-engagement message",
"message": "Re-engagement message",
"error_data": {
"details": "Message failed to send because more than 24 hours have passed since the customer last replied to this number."
},
"href": "https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/",
"message_tr": "Kişinin son mesajının üzerinden 24 saatten fazla geçti; serbest mesaj gönderilemez.",
"action_tr": "Onaylı bir şablon mesajı gönderin; kişi yanıt verince 24 saat yeniden açılır.",
"severity": "info",
"retryable": false,
"category": "recipient",
"known": true
}
],
"phone_number_id": "1234567890",
"conversation": null,
"pricing": null,
"biz_opaque_callback_data": "018f3a2b-7c1d-7f4e-9b21-6d0c1e2f3a4b",
"user_id": null,
"direction": "outbound",
"error_code": 131047,
"error_message_tr": "Kişinin son mesajının üzerinden 24 saatten fazla geçti; serbest mesaj gönderilemez.",
"error_action_tr": "Onaylı bir şablon mesajı gönderin; kişi yanıt verince 24 saat yeniden açılır.",
"error_severity": "info",
"error_retryable": false,
"error_category": "recipient"
}
}#template.approved
rejected_reason, rejected_reason_text (yalnız REJECTED), previous_status, quality_score, occurred_at ve source (webhook ya da sync) alanları da gelir. Meta webhook'u gelmediyse geçiş senkronda yakalanır (source: "sync"); aynı geçiş iki kez yayınlanmaz. reason eski alandır ve korunur.{
"event": "template.approved",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb06",
"event_type": "template.approved",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "APPROVED",
"previous_status": "PENDING",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-10T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon onaylandı.",
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.rejected
reason (ve aynı değerle rejected_reason) alanındadır, Türkçe açıklaması rejected_reason_text'tedir. rejected_reason_text her redde doludur; ayrıca reason_code, reason_tr, action_tr.{
"event": "template.rejected",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb07",
"event_type": "template.rejected",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "REJECTED",
"previous_status": "PENDING",
"reason": "INVALID_FORMAT",
"rejected_reason": "INVALID_FORMAT",
"rejected_reason_text": "Şablon biçimi geçersiz (değişken/örnek eksik olabilir).",
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-10T10:00:00+03:00",
"source": "webhook",
"reason_code": "INVALID_FORMAT",
"reason_tr": "Şablon reddedildi.",
"action_tr": "Red nedenine göre şablonu düzenleyip yeniden gönderin ya da itiraz edin.",
"paused_until": null,
"meta_description": null
}
}#template.flagged
{
"event": "template.flagged",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb08",
"event_type": "template.flagged",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "FLAGGED",
"previous_status": "PENDING",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-10T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": null,
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.paused
reason_code (Meta other_info.title: FIRST_PAUSE, SECOND_PAUSE, RATE_LIMITING_PAUSE, UNPAUSE, DISABLED), reason_tr, action_tr, paused_until (ilk duraklatmada 3, ikincide 6 saat sonrası; bilinmiyorsa null) ve meta_description gelir.{
"event": "template.paused",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb09",
"event_type": "template.paused",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "PAUSED",
"previous_status": "PENDING",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-10T10:00:00+03:00",
"source": "webhook",
"reason_code": "FIRST_PAUSE",
"reason_tr": "Şablon düşük kalite nedeniyle ilk kez duraklatıldı.",
"action_tr": "İçeriği ve gönderim kitlesini gözden geçirin.",
"paused_until": "2026-10-10T10:00:00Z",
"meta_description": "Your template has been paused for 3 hours."
}
}#quality.changed
{
"event": "quality.changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb0a",
"event_type": "quality.changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"phone": "+90 555 000 00 00",
"quality": "YELLOW"
}
}#account.alert
type (payment_method, business_verification, policy_violation, restriction, account_disabled, disconnected, reconnected, messaging_limit, other), severity, message_tr, action_tr, link, waba_id, alert_type, alert_status, meta_description, occurred_at. type Meta'nın olay adından ve alert_type değerinden türetilir; bilinmeyen değerleri tolere edin.{
"event": "account.alert",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb0b",
"event_type": "account.alert",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"field": "account_update",
"event": "DISABLED_UPDATE",
"type": "account_disabled",
"severity": null,
"message_tr": "WhatsApp işletme hesabı Meta tarafından kapatıldı ya da kapatılmak üzere.",
"action_tr": "Meta Business Suite'teki bildirimi inceleyin ve itiraz edin; destek için bize yazın.",
"link": "https://business.facebook.com/",
"waba_id": "1029384756",
"alert_type": null,
"alert_status": null,
"meta_description": null,
"occurred_at": "2026-10-10T10:00:00+03:00"
}
}#message.revoked
* aboneliğine dahil değildir.{
"event": "message.revoked",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb0c",
"event_type": "message.revoked",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhgSUkVWT0tF",
"original_message_id": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhggQTNFQkQ2RjQ3MEIyQzk0RTE4AA==",
"direction": "inbound",
"revoked_by": "customer",
"from": "905550000000",
"user_id": null,
"phone_number_id": "1234567890",
"timestamp": "1791619400"
}
}#message.edited
* aboneliğine dahil değildir.{
"event": "message.edited",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb0d",
"event_type": "message.edited",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhgSRURJVA==",
"original_message_id": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhggQTNFQkQ2RjQ3MEIyQzk0RTE4AA==",
"direction": "inbound",
"edited_by": "customer",
"from": "905550000000",
"user_id": null,
"phone_number_id": "1234567890",
"timestamp": "1791619420",
"type": "text",
"text": "Merhaba, siparişim nerede?"
}
}#message.sent
source kaynağı belirtir. * aboneliğine dahil değildir.{
"event": "message.sent",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb0e",
"event_type": "message.sent",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"source": "campaign",
"from": "905550000001",
"to": "905550000000",
"user_id": null,
"type": "template",
"text": null,
"media": null,
"template_name": "ekim_kampanyasi",
"campaign_id": 88,
"phone_number_id": "1234567890",
"timestamp": "1791619500"
}
}#message.history
chunk_order ile sıralayın. * aboneliğine dahil değildir.{
"event": "message.history",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb0f",
"event_type": "message.history",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhgSSElTVA==",
"history": true,
"direction": "inbound",
"from": "905550000000",
"to": null,
"thread_id": "905550000000",
"type": "text",
"text": "Eski mesaj",
"media": null,
"status": "READ",
"timestamp": "1781000000",
"phase": 1,
"chunk_order": 3,
"progress": 45,
"phone_number_id": "1234567890"
}
}#number.status_changed
event için bilinmeyen değerleri tolere edin. * aboneliğine dahil değildir. Kopma olayları: PARTNER_REMOVED, PARTNER_APP_UNINSTALLED (2.30.0), ACCOUNT_DELETED, ACCOUNT_OFFBOARDED → status: "disconnected"; Meta ikisini art arda gönderse de numara başına tek olay yayınlanır. Yetki kaybında event: "REAUTH_REQUIRED" (numara status değeri korunur, GET /numbers → reauth_required: true). 2.31.0: disconnect_message_tr, disconnect_action_tr, reconnect_url (sözlük: GET /meta/disconnect-reasons). ACCOUNT_RESTRICTION → status: "restricted" + restriction_type, restriction_types, restricted_until (ISO 8601), remediation. DISABLED_UPDATE → reason = ban_info.waba_ban_state (DISABLE, SCHEDULE_FOR_DISABLE, REINSTATE → status: "connected") ve ban_date. Yeniden bağlanınca event: "CONNECTED_VIA_PANEL". 2.31.1: Meta kopma olaylarını ters sırayla gönderebilir (önce nedensiz PARTNER_APP_UNINSTALLED, sonra nedenli PARTNER_REMOVED). Kopmadan sonraki 10 dakika içinde aynı WABA için nedenli bir olay gelirse disconnect_reason / disconnect_initiated_by güncellenir ve nedenli tek bir number.status_changed daha gönderilir; aynı neden tekrar gönderilmez. Aynı numara için ikinci kopma olayını önceki olayın güncellemesi olarak işleyin. ACCOUNT_VIOLATION olayı status: "restricted" ve violation_type ile yayınlanır.{
"event": "number.status_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb10",
"event_type": "number.status_changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"phone_number_id": "1234567890",
"display_phone_number": "+90 555 000 00 00",
"status": "disconnected",
"event": "PARTNER_REMOVED",
"reason": "PRIMARY_INACTIVITY",
"initiated_by": "SYSTEM",
"occurred_at": "2026-10-10T10:00:00+03:00",
"disconnect_message_tr": "Telefondaki WhatsApp Business uygulaması uzun süre açılmadığı için Meta bağlantıyı kaldırdı.",
"disconnect_action_tr": "Telefonda WhatsApp Business uygulamasını açın; ardından Veri Merkezi panelinde WhatsApp › Ayarlar › Numaralar sayfasından numarayı yeniden bağlayın.",
"reconnect_url": "https://verimerkezi.app/panel/wa/ayarlar?bolum=numaralar"
}
}#credit.low
* aboneliğine dahil değildir.{
"event": "credit.low",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb11",
"event_type": "credit.low",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"balance": 42,
"threshold": 100,
"unit": "messages",
"occurred_at": "2026-10-10T10:30:00+03:00"
}
}#credit.exhausted
* aboneliğine dahil değildir.{
"event": "credit.exhausted",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb12",
"event_type": "credit.exhausted",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"balance": 0,
"unit": "messages",
"occurred_at": "2026-10-10T11:00:00+03:00"
}
}#privacy.erasure_completed
POST /privacy/erasure) tamamlandı. * aboneliğine dahil değildir. Talebi erasure_id ile eşleştirin; istekte reference verdiyseniz olayda da aynen döner (2.29.0, verilmediyse null). Olay, 202 yanıtı istemciye ulaşmadan önce yayınlanabilir.{
"event": "privacy.erasure_completed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb13",
"event_type": "privacy.erasure_completed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"erasure_id": "ers_0123456789abcdef01234567",
"phone_number_id": "1234567890",
"wa_id": "905550000000",
"user_id": null,
"reference": "crm-silme-4711",
"completed_at": "2026-10-10T09:00:00Z",
"erased": {
"messages": 42,
"media": 3
}
}
}#contact.opt_out_changed
* aboneliğine dahil değildir.{
"event": "contact.opt_out_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb14",
"event_type": "contact.opt_out_changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"contact_id": 26470,
"phone": "905550000001",
"opted_out": true,
"previous_opted_out": false,
"source": "whatsapp_ret",
"phone_number_id": "1234567890",
"changed_at": "2026-10-05T16:40:00+03:00"
}
}#template.category_changed
category alanı kendiliğinden güncellenir. * aboneliğine dahil değildir.{
"event": "template.category_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb15",
"event_type": "template.category_changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"language": "tr",
"waba_id": "1029384756",
"previous_category": "UTILITY",
"new_category": "MARKETING",
"correct_category": null,
"occurred_at": "2026-10-10T10:00:00+03:00"
}
}#template.quality_changed
* aboneliğine dahil değildir.{
"event": "template.quality_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb16",
"event_type": "template.quality_changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"previous_quality_score": "GREEN",
"new_quality_score": "YELLOW",
"occurred_at": "2026-10-10T10:00:00+03:00"
}
}#template.disabled
status: "DISABLED"; devre dışı şablon silinemez, gönderimde kullanılamaz). Yük template.approved ile aynı alanları taşır. * aboneliğine dahil değildir.{
"event": "template.disabled",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb40",
"event_type": "template.disabled",
"occurred_at": "2026-10-14T10:00:00+03:00",
"created_at": "2026-10-14 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "DISABLED",
"previous_status": "PAUSED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon kullanıcı geri bildirimleri nedeniyle kapatıldı.",
"action_tr": "Yeni bir şablon oluşturun ya da itiraz edin.",
"paused_until": null,
"meta_description": null
}
}#template.reinstated
status: "APPROVED"). Yük template.approved ile aynı alanları taşır. * aboneliğine dahil değildir.{
"event": "template.reinstated",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb41",
"event_type": "template.reinstated",
"occurred_at": "2026-10-14T10:00:00+03:00",
"created_at": "2026-10-14 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "APPROVED",
"previous_status": "PAUSED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": null,
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#number.name_changed
* aboneliğine dahil değildir. Redde rejection_reason_tr (Türkçe açıklama; Meta ad reddi için kod listesi yayınlamaz, ham neden rejection_reasonda kalır).{
"event": "number.name_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb17",
"event_type": "number.name_changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"phone_number_id": "1234567890",
"display_phone_number": "+90 555 000 00 00",
"decision": "APPROVED",
"requested_name": "Firma A.Ş.",
"rejection_reason": null,
"rejection_reason_tr": null,
"occurred_at": "2026-10-10T10:00:00+03:00"
}
}#call.connect
sdp_offer dolu) ya da başlattığınız aramada Meta yanıt verdi (sdp_answer dolu). SDP ilk teslimden sonra kayıtlarda maskelenir. * aboneliğine dahil değildir. SDP içeren teslimatlar 1 saatten eskiyse kuyrukta maskelenir ([sdp N bytes]); yeniden teslimde (redeliver) SDP gelmeyebilir.{
"event": "call.connect",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb18",
"event_type": "call.connect",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"phone_number_id": "1234567890",
"from": "905550000000",
"to": "905550000001",
"direction": "user_initiated",
"name": "Ayşe Yılmaz",
"sdp_offer": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n...",
"sdp_answer": null,
"timestamp": "1791619600",
"biz_opaque_callback_data": null
}
}#call.status
ringing, accepted, rejected, missed, failed. * aboneliğine dahil değildir.{
"event": "call.status",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb19",
"event_type": "call.status",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE2",
"phone_number_id": "1234567890",
"status": "ringing",
"recipient": "905550000000",
"timestamp": "1791619610",
"biz_opaque_callback_data": "crm-ticket-42"
}
}#call.terminate
* aboneliğine dahil değildir.{
"event": "call.terminate",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb1a",
"event_type": "call.terminate",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"call_id": "wacid.HBgLOTA1NTUxMjM0NTY3FQIAEhggQkE1",
"phone_number_id": "1234567890",
"direction": "user_initiated",
"from": "905550000000",
"to": "905550000001",
"status": "completed",
"duration_sec": 74,
"start_time": "2026-10-10T14:00:05+03:00",
"end_time": "2026-10-10T14:01:19+03:00",
"billable_pulses": null,
"errors": null,
"timestamp": "1791619679",
"biz_opaque_callback_data": null
}
}#call.permission_reply
* aboneliğine dahil değildir.{
"event": "call.permission_reply",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb1b",
"event_type": "call.permission_reply",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"phone_number_id": "1234567890",
"from": "905550000000",
"user_id": null,
"granted": true,
"response": "accept",
"permanent": false,
"expires_at": "2026-10-17T10:00:00+03:00",
"response_source": "user_action",
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhggQTNFQkQ2RjQ3MEIyQzk0RTE4AA==",
"timestamp": "1791619700"
}
}#flow.completed
GET /media/{media_id} ile alınır. Aynı mesaj ayrıca message.received (type: interactive) olarak gelir (data.interactive.type: nfm_reply, name: flow). * aboneliğine dahil değildir.{
"event": "flow.completed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb1c",
"event_type": "flow.completed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"event_id": "flow_7f3c2a91",
"phone_number_id": "1234567890",
"from": "905550000000",
"user_id": null,
"contact_name": "Ahmet",
"message_id": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAEhggQTNFQkQ2RjQ3MEIyQzk0RTE4AA==",
"context_message_id": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"flow_token": "crm-basvuru-42",
"flow_id": "1234567890123456",
"response": {
"flow_token": "crm-basvuru-42",
"ad": "Ahmet",
"brans": "trafik"
},
"response_raw": null,
"media": [],
"timestamp": "1791619800"
}
}#flow.status_changed
* aboneliğine dahil değildir.{
"event": "flow.status_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb1d",
"event_type": "flow.status_changed",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"flow_id": "1234567890123456",
"waba_id": "1029384756",
"old_status": "PUBLISHED",
"new_status": "THROTTLED",
"reason": "Flow Webhook Status Change",
"occurred_at": "2026-10-10T12:00:00+03:00"
}
}#number.detached
POST /numbers/{id}/detach). * aboneliğine dahil değildir.{
"event": "number.detached",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb1e",
"event_type": "number.detached",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"phone_number_id": "1234567890",
"display_phone_number": "+90 555 000 00 00",
"reason": "Numara başka sisteme taşındı",
"detached_at": "2026-10-08T14:05:00+03:00",
"cancelled_outbound": 3
}
}#number.purged
purge_messages: true). * aboneliğine dahil değildir. counts.app_contacts: silinen uygulama rehberi kaydı.{
"event": "number.purged",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb1f",
"event_type": "number.purged",
"occurred_at": "2026-10-10T10:00:00+03:00",
"created_at": "2026-10-10 10:00:00",
"data": {
"phone_number_id": "1234567890",
"purged_at": "2026-10-09T13:00:00+03:00",
"counts": {
"messages": 1520,
"media_files": 84,
"media_rows": 84,
"conversations": 210,
"calls": 6,
"flow_sends": 12,
"webhook_log": 3000,
"api_log": 900,
"campaign_recipients": 400,
"webhook_deliveries": 1600,
"deferred_jobs": 2,
"app_contacts": 842
}
}
}#contact.synced
batch.index / batch.count ile bölünür. sync_type: initial (numara bağlanınca ilk aktarım) ya da incremental. changes[].action: add, update, remove; remove'da ad alanları nulldır. changes[].id, GET /app-contacts kaydının kimliğidir. Kaçan olaylar GET /app-contacts?updated_since=…&include_removed=true ile telafi edilir. Kapsam: contacts:read. * aboneliğine dahil değildir.{
"event": "contact.synced",
"event_id": "0192f3a1-0000-7000-8000-0000000000aa",
"event_type": "contact.synced",
"occurred_at": "2026-10-13T10:15:00+03:00",
"created_at": "2026-10-13 10:15:00",
"data": {
"phone_number_id": "1234567890",
"sync_type": "incremental",
"batch": {
"index": 1,
"count": 1
},
"changes": [
{
"action": "add",
"id": 501,
"phone": "+905551112233",
"wa_id": "905551112233",
"user_id": "TR.1A2B3C4D5E6F7G8H",
"full_name": "Ayşe Yılmaz",
"first_name": "Ayşe",
"changed_at": "2026-10-13T10:15:00+03:00"
},
{
"action": "update",
"id": 502,
"phone": "+905552223344",
"wa_id": "905552223344",
"user_id": null,
"full_name": "Mehmet Kaya (İş)",
"first_name": "Mehmet",
"changed_at": "2026-10-13T10:15:00+03:00"
},
{
"action": "remove",
"id": 503,
"phone": "+905553334455",
"wa_id": "905553334455",
"user_id": null,
"full_name": null,
"first_name": null,
"changed_at": "2026-10-13T10:15:00+03:00"
}
]
}
}#template.pending
* aboneliğine dahil değildir.{
"event": "template.pending",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb50",
"event_type": "template.pending",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "PENDING",
"previous_status": null,
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon incelemede.",
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.in_appeal
* aboneliğine dahil değildir.{
"event": "template.in_appeal",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb51",
"event_type": "template.in_appeal",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "IN_APPEAL",
"previous_status": "REJECTED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon itiraz sürecinde.",
"action_tr": "İtiraz sonucunu bekleyin.",
"paused_until": null,
"meta_description": null
}
}#template.locked
* aboneliğine dahil değildir.{
"event": "template.locked",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb52",
"event_type": "template.locked",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "LOCKED",
"previous_status": "APPROVED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon kilitlendi; düzenlenemez.",
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.archived
* aboneliğine dahil değildir.{
"event": "template.archived",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb53",
"event_type": "template.archived",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "ARCHIVED",
"previous_status": "APPROVED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon kullanılmadığı için arşivlendi; 28 gün içinde arşivden çıkarılmazsa silinir.",
"action_tr": "Kullanmaya devam edecekseniz şablonu arşivden çıkarın.",
"paused_until": null,
"meta_description": null
}
}#template.unarchived
* aboneliğine dahil değildir.{
"event": "template.unarchived",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb54",
"event_type": "template.unarchived",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "UNARCHIVED",
"previous_status": "ARCHIVED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon arşivden çıkarıldı.",
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.deleted
* aboneliğine dahil değildir.{
"event": "template.deleted",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb55",
"event_type": "template.deleted",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "DELETED",
"previous_status": "APPROVED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon silindi.",
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.pending_deletion
* aboneliğine dahil değildir.{
"event": "template.pending_deletion",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb56",
"event_type": "template.pending_deletion",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "PENDING_DELETION",
"previous_status": "APPROVED",
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Şablon silinmek üzere.",
"action_tr": null,
"paused_until": null,
"meta_description": null
}
}#template.limit_exceeded
* aboneliğine dahil değildir.{
"event": "template.limit_exceeded",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb57",
"event_type": "template.limit_exceeded",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"template_id": 512,
"meta_template_id": "1249033812345678",
"name": "siparis_onayi",
"template_name": "siparis_onayi",
"language": "tr",
"category": "UTILITY",
"waba_id": "1029384756",
"status": "LIMIT_EXCEEDED",
"previous_status": null,
"reason": null,
"rejected_reason": null,
"rejected_reason_text": null,
"quality_score": "UNKNOWN",
"occurred_at": "2026-10-14T10:00:00+03:00",
"source": "webhook",
"reason_code": null,
"reason_tr": "Hesap şablon sınırına ulaştı.",
"action_tr": "Kullanılmayan şablonları silin.",
"paused_until": null,
"meta_description": null
}
}#message.status.deleted
* aboneliğine dahil değildir.{
"event": "message.status.deleted",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb58",
"event_type": "message.status.deleted",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"wamid": "wamid.HBgMOTA1NTUxMjM0NTY3FQIAERgSMUI4QzY3RDFFNzBBNDlGRTlBAA==",
"recipient": "905550000000",
"timestamp": "1791619260",
"errors": null,
"phone_number_id": "1234567890",
"conversation": null,
"pricing": null,
"biz_opaque_callback_data": null,
"user_id": null,
"direction": "outbound"
}
}#number.limit_changed
current_limit / old_limit: TIER_50, TIER_250, TIER_1K, TIER_2K, TIER_10K, TIER_100K, TIER_UNLIMITED, TIER_NOT_SET; bilinmeyen değerleri tolere edin. * aboneliğine dahil değildir.{
"event": "number.limit_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb59",
"event_type": "number.limit_changed",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"phone_number_id": "1234567890",
"display_phone_number": "+90 555 000 00 00",
"event": "UPGRADE",
"current_limit": "TIER_10K",
"old_limit": "TIER_2K",
"limit_tr": "24 saatte 10.000 kişi",
"occurred_at": "2026-10-22T10:00:00+03:00"
}
}#account.review_changed
decision: APPROVED, REJECTED, PENDING, DEFERRED). * aboneliğine dahil değildir.{
"event": "account.review_changed",
"event_id": "01a0c7ea-0d80-7d4d-aaf0-a2cc64a6bb60",
"event_type": "account.review_changed",
"occurred_at": "2026-10-22T10:00:00+03:00",
"created_at": "2026-10-22 10:00:00",
"data": {
"waba_id": "1029384756",
"decision": "APPROVED",
"message_tr": "WhatsApp işletme hesabı incelemesi onaylandı.",
"action_tr": null,
"severity": "info",
"occurred_at": "2026-10-22T10:00:00+03:00"
}
}