Müşteriye 24 saat penceresi dışında ulaşmanın tek yolu Meta onaylı bir şablondur. Bu sayfa şablonları API ile nasıl oluşturacağınızı, doğrulayacağınızı ve yöneteceğinizi anlatır.
#Temel kavramlar
- Şablonlar işletme hesabı (WABA) düzeyindedir. Aynı WABA'daki tüm numaralar aynı onaylı şablonları kullanır.
- Yeni şablon Meta incelemesine gider ve
PENDINGdurumunda başlar. Sonuçtemplate.approvedya datemplate.rejectedolayıyla bildirilir. - Kurallar Meta'ya gönderilmeden önce denetlenir; ihlaller
422 template_invalidolarak hemen döner.
| Kategori | Kullanım |
|---|---|
UTILITY | Sipariş onayı, kargo, randevu, fatura bildirimi. |
MARKETING | Kampanya, indirim, duyuru. |
AUTHENTICATION | Doğrulama kodu (OTP). |
Meta kategoriyi kendisi belirleyebilir; değiştirirse template.category_changed olayı gelir.
| Durum | Anlamı |
|---|---|
DRAFT | Taslak, Meta'ya gönderilmedi. |
PENDING | Meta inceliyor. |
APPROVED | Kullanıma hazır. |
REJECTED | Reddedildi; sebep rejected_reason alanında. |
PAUSED | Kalite nedeniyle geçici durduruldu. |
DISABLED | Devre dışı. |
#Şablon oluşturun
curl -X POST https://api.verimerkezi.app/wa/templates \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "police_yenileme_hatirlatma",
"language": "tr",
"category": "UTILITY",
"header_media_url": "https://cdn.example.com/logo.jpg",
"components": [
{ "type": "HEADER", "format": "IMAGE" },
{ "type": "BODY",
"text": "Sayın {{1}}, {{2}} plakalı aracınızın poliçesi {{3}} tarihinde sona eriyor.",
"example": { "body_text": [["Ahmet Yılmaz", "34 ABC 123", "12.10.2026"]] } },
{ "type": "FOOTER", "text": "Firma Sigorta" },
{ "type": "BUTTONS", "buttons": [ { "type": "QUICK_REPLY", "text": "Teklif istiyorum" } ] }
]
}'const tpl = await vm.createTemplate({
name: 'police_yenileme_hatirlatma',
language: 'tr',
category: 'UTILITY',
components: [
{ type: 'BODY', text: 'Sayın {{1}}, poliçeniz {{2}} tarihinde sona eriyor.', example: { body_text: [['Ahmet', '12.10.2026']] } },
],
});
console.log(tpl.id, tpl.status); // PENDINGtpl = vm.create_template({
'name': 'police_yenileme_hatirlatma',
'language': 'tr',
'category': 'UTILITY',
'components': [
{'type': 'BODY', 'text': 'Sayın {{1}}, poliçeniz {{2}} tarihinde sona eriyor.', 'example': {'body_text': [['Ahmet', '12.10.2026']]}},
],
})
print(tpl['id'], tpl['status'])<?php
$tpl = $vm->createTemplate([
'name' => 'police_yenileme_hatirlatma',
'language' => 'tr',
'category' => 'UTILITY',
'components' => [
['type' => 'BODY', 'text' => 'Sayın {{1}}, poliçeniz {{2}} tarihinde sona eriyor.', 'example' => ['body_text' => [['Ahmet', '12.10.2026']]]],
],
]);
echo $tpl['id'];Yanıt 202 Accepted döner ve şablon PENDING durumundadır.
#Hedef işletme hesabı
- Hesabınızda tek WABA varsa hedef belirtmeniz gerekmez.
- Birden çok WABA varsa
waba_idgönderin; aksi hâlde422 waba_requireddöner. waba_idyerinephone_number_idda verebilirsiniz; WABA numaradan çözülür.
#Medya başlığı
Başlık IMAGE, VIDEO ya da DOCUMENT ise önce örnek dosyayı POST /templates/media ile yükleyin. Üç giriş biçimi vardır: multipart/form-data file, JSON url (herkese açık https://) ya da JSON media_id (POST /media ile yüklenmiş medya).
curl -X POST https://api.verimerkezi.app/wa/templates/media \
-H "Authorization: Bearer $VM_API_KEY" \
-F [email protected] -F format=IMAGE{ "ok": true, "header_handle": "4::aW1hZ2UvanBlZw==:ARb...", "header_media_ref": 8812,
"format": "IMAGE", "mime_type": "image/jpeg", "file_size": 183244, "waba_id": "1029384756" }Kabul edilen türler: IMAGE JPEG/PNG (en çok 5 MB), VIDEO MP4 (16 MB), DOCUMENT PDF (100 MB). Sonra şablonda header_handle değerini HEADER bileşeninin example.header_handle[0] alanına, header_media_ref değerini gövdenin üst düzeyine koyun:
{ "header_media_ref": 8812,
"components": [ { "type": "HEADER", "format": "IMAGE", "example": { "header_handle": ["4::aW1hZ2UvanBlZw==:ARb..."] } }, ... ] }header_handle kısa ömürlüdür; hemen kullanın. header_media_ref, dosyanın Veri Merkezi'ndeki kopyasıdır: şablona bağlanınca panel ve kampanya gönderimlerinde başlık medyası otomatik bulunur. Eski header_media_url alanı çalışmaya devam eder. Hiçbiri yoksa 422 invalid_request (field: header_media_ref) döner.
#Ad kuralları
Şablon adında yalnız küçük harf, rakam ve alt çizgi kullanın (ör. siparis_onayi). Diğer karakterler _ ile değiştirilir; büyük harfler de buna dahildir.
#Adlı değişkenler, başlık değişkeni ve yeni bileşenler
parameter_format: "NAMED"ile değişkenleri{{ad_soyad}}biçiminde adlandırın (küçük harf, rakam,_; harfle başlar; benzersiz). Örneklerexample.body_text_named_paramsveexample.header_text_named_paramsiçinde[{ "param_name": "...", "example": "..." }]olarak verilir. VarsayılanPOSITIONALbiçimde örneklerexample.body_textveexample.header_textiçindedir.- Metin başlığı (
HEADERTEXT) en çok 60 karakter ve en çok 1 değişken içerir; değişken varsa örnek zorunludur. LOCATIONbaşlığında oluştururken parametre yoktur (yalnızUTILITY/MARKETING); konum gönderimde verilir.COPY_CODEdüğmesi (en çok 1):{ "type": "COPY_CODE", "example": "YENI2026" }; düğme metnini Meta koyar.- Ek alanlar:
allow_category_change,message_send_ttl_seconds,cta_url_link_tracking_opted_out.
{ "name": "police_yenileme_hatirlatma", "language": "tr", "category": "UTILITY",
"parameter_format": "NAMED",
"components": [
{ "type": "HEADER", "format": "TEXT", "text": "Poliçe {{police_no}}",
"example": { "header_text_named_params": [ { "param_name": "police_no", "example": "TR-2026-001" } ] } },
{ "type": "BODY", "text": "Sayın {{ad_soyad}}, {{bitis_tarihi}} tarihinde biten poliçeniz için teklifiniz hazır.",
"example": { "body_text_named_params": [
{ "param_name": "ad_soyad", "example": "Ayşe Yılmaz" },
{ "param_name": "bitis_tarihi", "example": "30.10.2026" } ] } },
{ "type": "BUTTONS", "buttons": [
{ "type": "URL", "text": "Teklifi gör", "url": "https://ornek.com/teklif/{{1}}", "example": ["https://ornek.com/teklif/abc123"] },
{ "type": "COPY_CODE", "example": "YENI2026" } ] } ] }Adlı değişkenli, değişkenli metin başlıklı ya da LOCATION başlıklı şablonlar yalnız API ile (POST /messages, components ile) gönderilebilir; panel kampanya ve otomasyonları bunları "yalnız API" uyarısıyla engeller.
#Hatalar
Doğrulama hataları (422 invalid_request, 422 template_invalid) error.field alanında hatalı yolu verir (ör. components[0].text, components[2].buttons[0].url). Aynı WABA'da aynı ad ve dil varsa 409 template_exists. Hata Meta'dan geldiyse meta_code, meta_subcode, meta_message, meta_user_title, meta_user_message ve fbtrace_id de döner; Meta'ya ulaşılamazsa 502 meta_unavailable.
#Göndermeden doğrulayın
Kullanıcı arayüzünde "gönder" düğmesinden önce kuralları denetlemek için POST /templates/validate kullanın. Meta'ya hiçbir şey gönderilmez.
curl -X POST https://api.verimerkezi.app/wa/templates/validate \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "deneme", "language": "tr", "category": "UTILITY",
"components": [ { "type": "BODY", "text": "Merhaba {{1}}", "example": { "body_text": [["Ahmet"]] } } ] }'{ "ok": true, "valid": true, "message": "Şablon Meta kurallarına uygun görünüyor." }#Meta kuralları
- Gövde en fazla 1024 karakter olabilir; değişkenler sıralı olmalıdır:
{{1}},{{2}},{{3}}. - Her değişken için
example.body_textiçinde örnek değer verin. - Gövde yalnız değişkenden oluşamaz; sabit metin içermelidir.
- Bileşen sırası
HEADER,BODY,FOOTER,BUTTONSolmalıdır. Alt bilgi en fazla 60 karakterdir. - Genel ifadeler yerine markanızı ve bağlamı açıkça belirtin; yanıltıcı vaatler reddedilir.
#Dinamik URL butonu
Her alıcıya kişiye özel bağlantı göndermek için URL butonunun adresini {{1}} ile bitirin ve tam bir örnek adres verin. Gönderimde değişken kısmı button bileşeniyle iletilir. Bkz. Mesaj gönderme.
#Doğrulama kodu şablonu
AUTHENTICATION kategorisinde gövde metnini Meta üretir; siz yalnız ayarları verirsiniz:
| Alan | Açıklama |
|---|---|
add_security_recommendation | "Bu kodu kimseyle paylaşmayın" satırı. |
code_expiration_minutes | Kodun geçerlilik süresi (dakika). |
otp_type | COPY_CODE (her cihazda kodu kopyalar) ya da ONE_TAP (Android uygulamanıza otomatik doldurur). |
otp_button_text | Buton metni. |
autofill_text, package_name, signature_hash | ONE_TAP için zorunlu. |
#Form butonu
Şablona WhatsApp formu açan bir buton ekleyebilirsiniz:
{ "type": "BUTTONS", "buttons": [
{ "type": "FLOW", "text": "Formu doldur", "flow_id": "1234567890123456", "navigate_screen": "WELCOME", "flow_action": "navigate" }
] }Ayrıntı: Formlar.
#Listeleyin ve izleyin
curl "https://api.verimerkezi.app/wa/templates?status=APPROVED&category=UTILITY&language=tr&limit=50" \
-H "Authorization: Bearer $VM_API_KEY"- Her kayıtta
waba_idve şablonu kullanabilecek numaraları gösterenphone_number_idsdöner. - Ret sebebini ve kalite puanını
GET /templates/{id}ile görün. - Durum değişikliklerini
template.approved,template.rejected,template.flagged,template.paused,template.quality_changedvetemplate.category_changedolaylarıyla izleyin.template.disabledvetemplate.reinstatedolayları*aboneliğine dahil değildir; açıkça seçin. Durum olaylarındaprevious_status,rejected_reason,rejected_reason_text,quality_score,occurred_atvesourcebulunur. - Liste satırında
quality_score,parameter_format,previous_categoryverejected_reason_textdöner; ayrıntıda ayrıcaheader_media_refveedit_limitvardır. Önizleme içincomponentsistemcide çizilir.
#Meta ile senkronlayın
Şablonlar arka planda 15 dakikada bir Meta ile senkronlanır. Hemen güncellemek için:
curl -X POST https://api.verimerkezi.app/wa/templates/sync \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "phone_number_id": "1234567890" }'Senkron WABA başına dakikada 1 kez yapılabilir; sınırda 429 sync_rate_limited döner. Listeyi okurken GET /templates?refresh=1 aynı senkronu dener ve sınırdaysa hata vermeden mevcut listeyi refreshed: false ile döndürür. Senkron başarılıysa yanıtta refreshed: true ve refreshed_at (senkron zamanı) bulunur; başarısızsa refreshed_at null olur.
#Düzenleyin ve silin
#Düzenleme
PATCH /templates/{id} (eşdeğeri POST /templates/{id}) yeni bileşenleri Meta onayına gönderir; durum yeniden PENDING olur.
- Yalnız
APPROVED,REJECTEDvePAUSEDşablon düzenlenir; aksi409 template_not_editable. - Onaylı şablon 24 saatte 1, 30 günde en çok 10 kez düzenlenebilir ve kategorisi değişmez (
422 category_not_editable). Reddedilen ve duraklatılan şablonlarda sınır yoktur, kategori değişebilir. Sınır dolunca429 template_edit_limit(next_edit_at,retry_after) döner. - Düzenleme TÜM bileşenleri değiştirir: gönderdiğiniz liste tam olmalıdır.
name,languageveparameter_formatdeğişmez (422 invalid_request); yeni ad ya da dil için kopyalayın.GET /templates/{id}yanıtındakiedit_limit(editable,edits_last_30d,max_edits_30d,next_edit_at) ile düğmeyi önceden kapatabilirsiniz. Yalnız Veri Merkezi üzerinden yapılan düzenlemeler sayılır; WhatsApp Manager'daki düzenlemeyi Meta429ile bildirir.
#Kopyalama
POST /templates/{id}/copy yeni ad ve/veya dille kopya açar; components verirseniz çeviri için onlar kullanılır:
curl -X POST https://api.verimerkezi.app/wa/templates/512/copy \
-H "Authorization: Bearer $VM_API_KEY" -H "Content-Type: application/json" \
-d '{ "name": "police_yenileme_hatirlatma_en", "language": "en_US" }'Medya başlıklı kaynağın Veri Merkezi'nde kopyası yoksa (ör. başka bir sağlayıcıdan senkronlanmış) 422 invalid_request (field: header_media_ref) döner; önce POST /templates/media, sonra header_media_ref ile tekrar deneyin.
#Silme
DELETE /templates/{id}yalnız o dili siler.DELETE /templates?name=police_yenileme_hatirlatmaadın tüm dillerini siler (idsvelanguagesdöner). Birden çok WABA'nız varsawaba_idekleyin.- Silinen onaylı şablonun adı 30 gün yeniden kullanılamaz;
DISABLEDşablon silinemez. Meta'da zaten yoksa yerel kayıt silinir (meta_missing: true). Geçmiş mesajlar etkilenmez.
#Önerilen akış
- Liste:
GET /templates(gerekirse?refresh=1). - Yeni: medya varsa
POST /templates/media→POST /templates/validate(fieldile ilgili kutuyu işaretleyin) →POST /templates. - Düzenle:
GET /templates/{id}→edit_limit.editablekapalıysanext_edit_atgösterin →PATCH /templates/{id}. - Durumu olaylarla izleyin; olay kaçarsa
POST /templates/sync.
Meta kuralları: Şablonlar · Bileşenler · Yönetim (düzenle / sil) · API başvurusu · Resumable Upload · Medya türleri
Tüm alanlar: Şablonlar referansı.
