İstekler
Tek çağrıda bir form ve bir istek oluşturun
Bir müşteriyle telefonda konuşan bir ajan, müşterinin hâlâ iki maaş bordrosu yüklemesi, 40 EUR’luk bir ücret ödemesi ve bir görüşme ayarlaması gerektiğini öğrenir. Formu ve isteği aynı çağrıda gönderir; gerisini Formstep halleder.
Ne zaman kullanılır
Bir istek normalde birinin düzenleyicide oluşturup yayınladığı bir formu gösterir. Sorular duruma bağlı olduğunda çağıran onları isteğin
içinde gönderir: requests.create, formId yerine form alır. Formstep bloklardan sıradan bir form
oluşturur, onu yayınlar ve isteği tek adımda oluşturur; böylece ya ikisi birden oluşur ya da hiçbiri. Buna satır içi form
(inline form) diyoruz.
Aynı biçimde birçok kişiye gönderdiğiniz ve düzenleyicide elle tasarlamak istediğiniz bir form için formId kullanmaya devam
edin. Neyin sorulacağına bir otomasyon karar verdiğinde form kullanın.
Çağrı
curl -X POST https://api.formstep.io/api/v1 \
-H "Authorization: Bearer $FORMSTEP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"method":"requests.create","params":{
"form":{
"name":"Documents and fee for your mortgage application",
"logo":{"type":"image","url":"https://acme.example/logo.png"},
"cover":{"type":"color","color":"#0f4c81"},
"emoji":"🏦",
"blocks":[
{"type":"paragraph","content":"Upload the two documents and pay the processing fee."},
{"type":"file","key":"payslips","title":"Your last two payslips","maxFiles":2},
{"type":"payment","key":"fee","title":"Processing fee","amount":40,"currency":"EUR"},
{"type":"scheduleAppointment","key":"call","title":"Pick a time for our call","eventType":"15 min call"}]},
"recipient":{"email":"ada@example.com","name":"Ada"},
"delivery":"email",
"idempotencyKey":"call-8841"}}'İsteğin geri kalanı anlamını korur: recipient, prefill, context, readonly,
delivery, hatırlatmalar, son kullanma tarihi, callbackUrl, test ve idempotencyKey,
yeni forma göre tıpkı elle oluşturulmuş bir forma göre olduğu gibi denetlenir. Yanıt ayrıca formu ve formun yanıtlarının hangi
anahtarlarla döneceğini içerir:
{
"id": "kd7...",
"status": "pending",
"url": "https://form.formstep.io/r/rq_...",
"form": {
"id": "j58...",
"name": "Documents and fee for your mortgage application",
"reused": false,
"fields": [
{ "key": "payslips", "type": "file" },
{ "key": "fee", "type": "payment" },
{ "key": "call", "type": "schedule-appointment" }
]
}
}Aynı çağrıda bir seçim sorusunu önceden doldurmak için, her formda olduğu gibi seçenek anahtarlarını gönderin. Bir seçeneğin anahtarı
etiketinden türetilir; Self-employed, self_employed olur. Anahtar yerine etiket gönderilirse çağrı
INVALID_PREFILL_VALUE ile başarısız olur ve hata geçerli anahtarları listeler.
Form nesnesi
| Alan | Ne yapar |
|---|---|
| name | Zorunlu, 1 ile 100 karakter arası. Panoda ve tarayıcı sekmesinde görünen ad; her alıcı için aynıdır. Kişiselleştirmeyi adla değil, her zaman prefill ve context ile yapın. |
| blocks | Zorunlu, formun gösterdiği sırayla 1 ile 200 arasında blok. Bir satırın sütunlarındaki bloklar ve bir tekrarlanan grubun alanları da sayılır. |
| language | Formun arayüz dili. Varsayılan: İngilizce. |
| logo, cover, emoji | Her istekle gönderilen markanız. logo: { "type": "icon", "name": "HeartIcon" } veya { "type": "image", "url": "https://…" }. cover: { "type": "color", "color": "#0f4c81" } veya { "type": "image", "url": "https://…", "offsetY": 50 }. emoji: adın yanında tek bir emoji. Aşağıya bakın. |
| theme | Her renk modu için bir görünüm: { "light": "solarized-light", "dark": "dracula" }. Her mod, her planda ücretsiz olan bir hazır tema kimliği ya da MCP aracı formTheme_set’in aldığı biçimde tam bir tema nesnesi alır; tema nesnesi Pro planı gerektirir. |
| settings | Ayarlar sayfasının belirlediği form davranışı: Formstep markası, doğrulanmış bir e-posta alan adı (emailDomainId), sahibe ve yanıtlayana giden e-postalar ve metinleri, hatırlatma planı, davet e-postası, yönlendirme ve saklama süresi. Anahtara göre alanlar: respondentNotificationTo bir e-posta sorusunun anahtarıdır, redirectQueryParams bir parametreyi bir alan anahtarına eşler. E-posta metni {{key}} yer tutuculu düz metindir. Parola veya oturum açma engeli yoktur, bot koruması ya da gönderimden sonra düzenleme gibi bir paylaşım bağlantısı ayarı da yoktur: bir istek kendi bağlantısını taşır. Diğer her anahtar reddedilir. |
| translations | Formun başka dillerdeki hâli; alıcı için bir dil seçiciyle birlikte: { "de": { "Your name": "Ihr Name" } }. Formun her metni, blokların yazdığı hâliyle anahtarlanır. Aşağıya bakın. |
Bloklar
Bir blok, MCP sunucusundaki eşleşen editor_insert* aracının parametrelerini
formId ve after olmadan alır; bunlara ek olarak isteğe bağlı bir key alır. Anahtar verilmezse
başlıktan türetilir; böylece “Full name”, full_name olur. Bloğun tanımadığı bir parametre atlanmaz, reddedilir.
| Grup | Türler |
|---|---|
| Sorular | text, contact, number, date, time, radio, checkbox, select, switch, rating, linearScale, matrix, ranking, pictureChoice, file, signature, decision |
| Belgeler | documents; alıcının okuduğu veya imzaladığı dosyaları göstermek için |
| Ödemeler ve randevular | payment, scheduleAppointment |
| İçerik | header, paragraph, image (src URL’si), embedded, table (cells doldurur), list, row (columns: her sütunun blokları, 2 ile 6 sütun; widths: yüzde olarak genişlikler). İsteğe bağlı bir key, mantığın bloğu göstermesini veya gizlemesini sağlar. |
| Yapı | pageDivider, repeatingGroup (fields: grubun soruları, her biri kendi anahtarıyla bir blok olarak), hiddenField (key zorunludur: bağlam anahtarıdır), calculatedField (name değeri anahtarıdır), logic |
Başlık (header) ve paragraf (paragraph) metni, liste öğeleri ve tablo hücreleri bold, italic,
, struck<u>underlined</u>, , code$$equation$$,
text, düzenleyici araç çubuğunun renk, yazı tipi ve boyutlarıyla
<span color=“red” background=“yellow” font=“font-georgia” size=“1.25”>…</span> ve o anahtara sahip alanın
değerini gösteren {{key}} biçimlerini okur. Biçimler iç içe geçebilir; eşi olmayan bir işaret düz metin olarak kalır. Bir
satırın sütunu pageDivider, logic, hiddenField, calculatedField, repeatingGroup, row ve scheduleAppointment dışında her bloğu alabilir.
Bir decision bloğu title değerini ve onay, ret ve değişiklik için labels değerlerini formun dilinde
alır.
Bloklar birbirine öğe kimliğiyle değil, her zaman anahtarla başvurur: bir logic bloğu rule değerini
editor_insertLogic gibi alır; kimlik beklenen yerlerde alan anahtarlarını, koşul değeri olarak seçenek etiketlerini ve
setNextPage için sayfa adlarını kullanır.
Ödemeler
Bir payment bloğu amount ve currency alır ya da amountFromField alır: bir gizli alanın
veya bir sayı sorusunun anahtarı. Gizli alanla her istek kendi tutarını context içinde gönderir; böylece tek bir form her
müşteriden kendi tutarını tahsil eder:
{
"form": {
"name": "Pay your invoice",
"blocks": [
{ "type": "hiddenField", "key": "invoice_total" },
{ "type": "payment", "key": "invoice", "title": "Invoice", "currency": "EUR", "amountFromField": "invoice_total" }
]
},
"recipient": { "email": "ada@example.com" },
"context": { "invoice_total": 1200 }
}Tutarı belirleyen bir sayı sorusu zorunlu olmalı ve 0’dan büyük bir min değerine sahip olmalıdır; böylece kimse checkout
adımına boş, sıfır ya da negatif bir tutarla ulaşmaz.
Form, çalışma alanının varsayılan Stripe hesabı ya da connection ile belirtilen hesap üzerinden ödeme alır. Stripe’ı
çalışma alanı için bir kez bir kişi bağlar; bir otomasyon bağlayamaz.
Kullanılabilir bir hesap yoksa çağrı başarısız olur ve hesabı nerede bağlayacağınızı söyler.
Randevular
Bir scheduleAppointment bloğu eventType alır: çalışma alanının Cal.com
bağlantısındaki bir etkinlik türünün başlığı veya kimliği. Çalışma alanında birden fazla bağlantı varsa connection da alır.
Formstep etkinlik türünü istek oluşturulurken arar. prefill: { name, email }, yanıtları randevu bilgilerini dolduran
soruları belirtir.
Markanız
Bir otomasyon görünümünüzü kendisi uyduramaz; bu yüzden onu bir kez verirsiniz ve otomasyon her istekle gönderir: blokların yanında
logo, cover ve emoji, renkler ve yazı tipleri için de theme.
| Alan | Ne alır |
|---|---|
| logo | Oluşturucudaki bir simge, { "type": "icon", "name": "HeartIcon" }, ya da kendi görseliniz, { "type": "image", "url": "https://…/logo.png" }. |
| cover | Düz bir renk, { "type": "color", "color": "#0f4c81" }, ya da bir görsel, { "type": "image", "url": "https://…/cover.jpg", "offsetY": 50 }; 0 ile 100 arasındaki offsetY, uzun bir görselin hangi kısmının görüneceğini seçer. |
| emoji | Form adının yanında gösterilen tek bir emoji. |
Bir görsel bloğunun src değeri dahil her görsel, herkese açık bir JPEG, PNG veya WebP olmalıdır. Formstep her birini form
oluşturulurken bir kez indirir ve kendi kopyasını saklar; böylece form ve gönderimlerinin PDF’leri kaynaktan daha uzun yaşar.
İndirilemeyen bir URL, alanı belirten INLINE_FORM_IMAGE_UNREACHABLE ile çağrıyı başarısız kılar. Marka olmadan form, panodan
oluşturulmuş yeni bir form gibi görünür.
Çeviriler
translations, formu aynı anda başka dillerde de yayınlar ve alıcı, çevrilmiş bir formun sahip olduğu dil seçiciyi alır:
{ "de": { "Your name": "Ihr Name", "Order for **{{customer}}**": "Bestellung für **{{customer}}**" } }. Formun her metni,
tam olarak blokların yazdığı hâliyle anahtarlanmış olarak bulunmalıdır: soru başlıkları, seçenekler, yer tutucular, başlıklar,
paragraflar, liste öğeleri, tablo hücreleri, grup adları ve düğme etiketleri. Biçimlendirme ve {{key}} kaynaktaki gibi
kalır. Eksik bir metin, eklenecek metinleri listeleyen INLINE_FORM_TRANSLATION_MISSING ile çağrıyı başarısız kılar. E-posta
metinleri çevrilmez.
Bir tanım, bir form
Aynı form nesnesiyle yapılan sonraki bir çağrı aynı formu yeniden kullanır ve yanıt “reused”: true içerir. Tek
bir tanımla yapılan yüz istek tek bir form oluşturur ve dışa aktarılacak tek bir yanıt kümesi olur. Bir bloğu, adı, markayı veya bir
çeviriyi değiştirmek yeni bir form oluşturur; daha önce gönderilmiş istekler oluşturuldukları formu korur. Kapatılan veya yayından
kaldırılan bir form yeniden kullanılmaz: aynı tanımla yapılan sonraki çağrı yeni bir form oluşturur.
Kişiselleştirmeyi prefill ve context ile yapın
Müşterinin adını, fatura numarasını veya tutarı form adına, bir başlığa ya da sabit bir tutara değil, her zaman prefill ve
context içine koyun. Müşteriye göre değişen bir tanım, her müşteri için yeni bir form oluşturur. Her soruya
key verin: türetilen anahtar başlığı izler, bu yüzden başlığı değişen bir soru yeni bir anahtarla yanıtlanır. Bir çalışma
alanı günde en fazla 300 yeni satır içi form oluşturur; bundan sonra yeni form oluşturacak bir çağrı RATE_LIMITED ile
başarısız olur, bir formu yeniden kullanan çağrılar ise çalışmaya devam eder.
Açık bir satır içi form aynı blok türlerini aynı sırayla içerdiği hâlde bir çağrı yeni bir form oluşturursa, yanıt o formu
form.similarForm içinde belirtir. Bunun nedeni genellikle değişen bir ad veya başlıktır. Bir satır içi formun tüm yanıtlarını
okumak için her isteği tek tek okumak yerine gönderimlerini listeleyin.
Panoda
Satır içi bir form isteğine aittir; bu yüzden Formlar sayfasında değil, isteğin sayfasında yer alır. Sayfa yanıtları alan anahtarına göre
listeler ve Önizle, formu alıcının gördüğü gibi, yanıtlarıyla doldurulmuş olarak açar. Satır içi bir formun
düzenleyicisine veya gönderimlerine giden bir bağlantı, bunun yerine o forma göre filtrelenmiş İstekler sayfasını açar. Ajanlar satır içi
formları form_list içinde görmeye devam eder ve API bunları değiştirmeyi reddeder.
Satır içi bir formun paylaşım bağlantısı yoktur ve eklenemez: ona yalnızca istekleri üzerinden ulaşılır ve geri çağırma her yanıtı taşır. Entegrasyonu da yoktur.
Kendi sayfası olmadığı için satır içi bir form asla elle silinmez. Son isteğiyle birlikte gider: bir isteği sildiğinizde ya da formun saklama süresi onu aldığında ve başka hiçbir istek formu hâlâ kullanmıyorsa, form da silinir.
Çağrı reddedildiğinde
Her ret, otomasyonunuzun details.reason değerine göre dallanabileceği bir VALIDATION_ERROR hatasıdır. Hiçbir şey
oluşturulmaz.
| Neden | Ne yapmalı |
|---|---|
| FORM_SOURCE_MISSING / FORM_SOURCE_AMBIGUOUS | formId ve form alanlarından tam olarak birini gönderin. |
| INLINE_FORM_INVALID | Bir blok veya form nesnesinin bir alanı şemasına uymuyor. details.issues her birini belirtir. |
| INLINE_FORM_DUPLICATE_KEY | İki blok aynı anahtara çıkıyor. Bunlardan birine kendi anahtarını verin. |
| INLINE_FORM_UNKNOWN_KEY | Bir mantık kuralı, amountFromField veya bir randevu ön doldurması, hiçbir blokta olmayan bir anahtarı belirtiyor. |
| INLINE_FORM_AMOUNT_MISSING | Tutar alanı için context içinde pozitif bir sayı gönderin. |
| INLINE_FORM_CONNECTION_MISSING | Stripe veya Cal.com bağlı değil. details.connectUrl, bir kişinin hizmeti bağlamak için bir kez açtığı sayfadır. |
| INLINE_FORM_EVENT_TYPE_NOT_FOUND | Hiçbir Cal.com etkinlik türü eşleşmiyor. Hata, mevcut olanları listeler. |
| INLINE_FORM_IMAGE_UNREACHABLE | Bir görsel URL’si herkese açık bir JPEG, PNG veya WebP değil. details.field onu belirtir. Herkesin açabileceği bir URL kullanın ya da görseli çıkarın. |
| INLINE_FORM_TRANSLATION_MISSING | Bir çeviride formun sahip olduğu metinler eksik. details.missing bunları bloklarda yazıldığı hâliyle listeler. |
| INLINE_FORM_PUBLISH_ISSUES | Yayınlama formu reddetti; örneğin formdan randevu alınamayan bir etkinlik türü nedeniyle. |
Bir ajandan
MCP sunucusunda request_create aynı form nesnesini alır. Ödeme veya randevu içeren bir form oluşturmadan önce
ajan workspaceConnection_list aracını okur: bu araç bağlı Stripe ve Cal.com hesaplarını ve biri eksikse bir kişinin bir kez
açması gereken sayfanın adresini gösterir. scheduler_listEventTypes bir randevunun belirtebileceği etkinlik türlerini
listeler, paymentConnection_setDefault ise varsayılan Stripe hesabını değiştirir. REST API’de bu üçü
connections.list, scheduler.listEventTypes ve paymentConnections.setDefault metodlarıdır.