Formlar (WhatsApp Flows), müşterinin sohbetten çıkmadan doldurduğu çok ekranlı arayüzlerdir: başvuru, randevu, anket, iletişim formu. Form tasarımı Meta'nın Flow JSON biçimindedir. Müşteri formu gönderdiğinde yanıt flow.completed olayıyla gelir.
#Akış
POST /flowsile formuDRAFTolarak oluşturun.validation_errorsboş değilsePUT /flows/{flow_id}/jsonile düzeltin.- Taslağı kendinize
POST /messagesveflow.mode: "draft"ile göndererek deneyin. POST /flows/{flow_id}/publishile yayınlayın. Yayınlanan form değiştirilemez.- Müşteriye form mesajı ya da form butonlu şablon gönderin.
- Yanıtı
flow.completedolayıyla alın.
Formlar işletme hesabı (WABA) düzeyindedir; phone_number_id ile numaranızın WABA'sı seçilir. Form yönetimi kredi düşmez; form mesajı normal mesaj gibi 1 kredidir. Gerekli kapsamlar: flows:read, flows:write.
#Form oluşturun
curl -X POST https://api.verimerkezi.app/wa/flows \
-H "Authorization: Bearer $VM_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"phone_number_id": "1234567890",
"name": "Teklif formu",
"categories": ["LEAD_GENERATION"],
"flow_json": { "version": "7.2", "screens": [] }
}'const form = await vm.createFlow('1234567890', 'Teklif formu', ['LEAD_GENERATION'], flowJson);
console.log(form.flow_id, form.validation_errors);form = vm.create_flow('1234567890', 'Teklif formu', ['LEAD_GENERATION'], flow_json)
print(form['flow_id'], form['validation_errors'])<?php
$form = $vm->createFlow('1234567890', 'Teklif formu', ['LEAD_GENERATION'], $flowJson);
echo $form['flow_id'];{ "ok": true, "flow_id": "1234567890123456", "status": "DRAFT", "validation_errors": [] }categoriesen az bir değer içermelidir:SIGN_UP,SIGN_IN,APPOINTMENT_BOOKING,LEAD_GENERATION,CONTACT_US,CUSTOMER_SUPPORT,SURVEY,OTHER.flow_jsonnesne ya da JSON metni olabilir; en fazla 10 MB.- Form yazma uçları test anahtarıyla çalışmaz (
403 test_mode_unsupported).
examples/flows/teklif-formu.flow.json.#Koşullu alanlar (If) — Meta kuralları
Meta'nın If bileşeninde (condition) == ve != için iki taraf aynı türde olmalıdır. Metin değişmezi tek tırnakla ('2'), sayı tırnaksız yazılır. >, >=, <, <= yalnız sayılarla çalışır. İç içe If en fazla 3 seviyedir (Meta: If bileşeni).
Canlı Meta testlerinde (14.10.2026) ek kısıtlar gözlendi:
- Bir ifadede tek eşitlik.
(${form.arac} == '2') || (${form.arac} == '3')reddedilir. Meta bunu((${form.arac} == '2') || ${form.arac}) == '3'diye çözer veType mismatch in an equality operationhatası verir. - Çalışan biçimler: tek karşılaştırma (
${form.arac} == '2'), mantıksal değerle birleşim (${form.onay} || (${form.arac} == '2')), sayısal aralık ((${form.yas} > 2) || (${form.yas} < 1)). - Birden çok değeri kontrol etmek için koşulu iç içe If'lere bölün (en fazla 3 seviye) ya da her değer için ayrı bir If yazın.
- Switch bileşeni aynı testlerde
Cannot read property 'type'hatası verdi. Şimdilik If kullanın.
Meta bu hatayla reddettiğinde yanıta hint ve hint_message eklenir. Başarılı yanıtta (validation_errors) bu alanlar üst düzeyde, 422 meta_flow_failed yanıtında ise error içinde yer alır. Flow JSON'unuz değiştirilmez.
hint | Anlamı |
|---|---|
flow_chained_equality | Bir ifadede birden fazla eşitlik var. Koşulu bölün. |
crm_update_required | İstek bir Sigorta CRM hizmetine bağlı anahtardan geldi. CRM yazılımını güncel sürüme yükseltin. |
#Form mesajı gönderin
{
"phone_number_id": "1234567890",
"to": "905550000000",
"type": "flow",
"flow": {
"flow_id": "1234567890123456",
"flow_token": "crm-basvuru-42",
"cta": "Formu Aç",
"body": "Teklif için formu doldurun.",
"screen": "WELCOME"
}
}| Alan | Açıklama |
|---|---|
flow_id ya da flow_name | Yalnız biri. |
flow_token | Kendi eşleştirme anahtarınız (en fazla 191 bayt). Verilmezse üretilir ve yanıtta döner. |
cta | Buton metni; en fazla 20 karakter, emoji yok. |
body | Gövde; en fazla 1024 karakter. header ve footer isteğe bağlı, en fazla 60 karakter. |
mode | published (varsayılan) ya da draft. |
action | navigate (varsayılan) ya da data_exchange (yalnız Endpoint'li formlar). |
screen, data | Açılış ekranı ve başlangıç verisi (navigate için). |
Serbest mesaj kuralları geçerlidir: 24 saat penceresi kapalıyken form butonlu bir şablon kullanın.
#Şablonla gönderin
Şablonu POST /templates ile FLOW butonuyla oluşturun. Gönderimde buton parametresi:
{ "type": "button", "sub_type": "flow", "index": 0,
"parameters": [ { "type": "action", "flow_token": "crm-basvuru-42", "flow_action_data": { "ad": "Ahmet" } } ] }#Yanıtı alın
Müşteri formu gönderdiğinde flow.completed olayı gelir. Aynı mesaj ayrıca message.received (type: interactive) olarak da gelir.
{
"event": "flow.completed",
"data": {
"event_id": "flow_7f3c2a91",
"phone_number_id": "1234567890",
"from": "905550000000",
"flow_token": "crm-basvuru-42",
"flow_id": "1234567890123456",
"response": { "flow_token": "crm-basvuru-42", "ad": "Ayşe Yılmaz", "brans": "trafik" },
"media": [],
"timestamp": "1791619800"
}
}response, form tasarımınızdaki alan adlarıyla ayrıştırılmış yanıttır.- Formdaki fotoğraf ve belgeler sunucumuzda indirilir;
media[].media_idileGET /media/{media_id}üzerinden alınır. data.event_idaynı yanıt için sabittir; yinelenenleri bununla ayıklayın.flow.completedveflow.status_changedolayları*aboneliğine dahil değildir; açıkça seçin.
#Yönetim
| İşlem | Uç |
|---|---|
Listele (limit ≤ 200, next_cursor / has_more) | GET /flows?phone_number_id=... |
| Ayrıntı | GET /flows/{flow_id} |
| JSON güncelle (yalnız DRAFT) | PUT /flows/{flow_id}/json |
| Yayınla | POST /flows/{flow_id}/publish |
| Kullanımdan kaldır | POST /flows/{flow_id}/deprecate |
| Sil (yalnız DRAFT) | DELETE /flows/{flow_id} |
| Önizleme bağlantısı | GET /flows/{flow_id}/preview |
| Metrikler (Endpoint'li formlar) | GET /flows/{flow_id}/metrics |
Meta'nın yönetim arayüzünde oluşturduğunuz formlar için {flow_id} uçlarına ?phone_number_id= ekleyin; form hesabınıza bağlanır.
data_exchange) özelliğini kullanan formlarda şifreli Endpoint trafiğini Veri Merkezi karşılamaz; kendi sunucunuz karşılar.Tüm alanlar: Formlar referansı.
