# Bir istek oluşturmak

Formun alan anahtarlarını keşfedin, ardından önceden doldurulmuş değerler, kilitli alanlar ve bağlam ile bir istek oluşturun.

## Bir istek oluşturmak

İki API çağrısı: forma neyin söylenebileceğini sorun, ardından zaten bildiğiniz değerlerle formu bir kişiye atayın.

<h2 id="start-in-the-share-sheet">Paylaş panelinden başlayın</h2>

<p>
  Yayınlanmış formunuzu açın, <strong>Paylaş</strong>'a tıklayın ve <strong>İstekler</strong> sekmesini seçin. Oradaki kart, ilk çağrıyı
  yapmak için ihtiyacınız olan her şeyi verir:
</p>

<ul>
  <li>
    Kopyalama düğmesiyle birlikte <strong>form kimliği</strong>.
  </li>
  <li>
    Formunuzun gerçek alan anahtarlarından oluşturulmuş bir <strong>curl</strong> parçacığı ve bir <strong>MCP</strong> istemi — örnek zaten
    bu formun gerçekten sahip olduğu alanlara adreslenmiştir.
  </li>
  <li>
    Bir isteği elle oluşturan <strong>Manuel</strong> sekmesi, ve orada doldurduklarınızı <a href="#test-mode">test modunda</a> bir isteğe
    çevirip bağlantısını size veren <strong>Kendin dene</strong>.
  </li>
  <li>
    Bu forma göre filtrelenmiş <a href="/tr/requests/managing-requests">İstekler sayfasına</a> bir bağlantı.
  </li>
</ul>

> ⚠️ **Önce yayınlayın**
> <p>
>     Yayınlanmamış bir form için istek oluşturulamaz ve siz yayınlayana kadar parçacıklar devre dışı kalır. Alan anahtarları ilk yayında
>     dondurulur — bu da otomasyonunuzun bir yıl sonra hâlâ <code>company_name</code> adresine adreslenebilmesini sağlayan şeydir. Bkz.{' '}
>     <a href="/tr/requests/field-keys">Alan anahtarları</a>.
>   </p>

<h2 id="discover-fields">Adım 1 — Alanları keşfedin</h2>

<p>
  <code>fields.list</code>, formun geçerli yayınlanmış sürümündeki her alanı, adreslemek için kullanılacak anahtarla, aldığı değer biçimiyle
  ve ait olduğu grupla birlikte döndürür.
</p>

```
curl -X POST https://api.formstep.io/api/v1 \
  -H "Authorization: Bearer $FORMSTEP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method":"fields.list","params":{"formId":"j57..."}}'
```

```
{
  "ok": true,
  "data": {
    "published": true,
    "items": [
      { "key": "company_name", "type": "text", "title": "Company", "required": true, "prefillable": true },
      {
        "key": "company_size", "type": "select", "title": "Company size", "required": false, "prefillable": true,
        "options": [
          { "key": "1_50", "label": "1–50" },
          { "key": "51_200", "label": "51–200" }
        ]
      },
      { "key": "case_id", "type": "hidden", "title": "Case", "required": false, "prefillable": false, "context": true },
      { "key": "total", "type": "number", "title": "Total", "required": false, "prefillable": false, "calculated": true },
      { "key": "signature", "type": "signature", "title": "Sign here", "required": true, "prefillable": false }
    ],
    "hasMore": false
  }
}
```

<ul>
  <li>
    <code>context: true</code> gizli bir alanı işaretler. Değeri her zaman <code>context</code> içine gider, asla <code>prefill</code> içine
    değil; bir gizli alanın anahtarı <code>prefill</code> içinde bulunursa <code>UNKNOWN_FIELD_KEY</code> hatasıyla reddedilir.
  </li>
  <li>
    <code>calculated: true</code>, hesaplanan bir alanı işaretler. Formun kendisi değerini hesaplar, dolayısıyla kimse bir değer gönderemez;
    değeri <code>answers</code> içinde kendi anahtarı altında geri okursunuz.
  </li>
  <li>
    <code>prefillable: false</code>, kimsenin değer sağlayamayacağı bir alanı işaretler: dosya yükleme, imza, ödeme, randevu ayırma ve
    Belgeler blokları. Alıcı soruları kendisi doldurur. Gizli alanlar ve hesaplanan alanlar da <code>prefillable: false</code> olarak
    görünür: gizli alanlar <code>context</code> alır, hesaplanan alanlar ise hiçbir şey almaz.
  </li>
  <li>
    <code>options</code>, bir seçim sorusunun seçeneklerini listeler. Etiketi değil, seçeneğin <strong>anahtarını</strong> gönderin; etiket
    yalnızca bildiğiniz seçimi kendi anahtarına eşlemeniz için orada. Bir matris de <code>rows</code> ve <code>columns</code>'unu aynı
    şekilde listeler.
  </li>
  <li>
    Tekrarlayan gruplar, <code>type: "group"</code>, <code>repeating: true</code> ve bir <code>members</code> listesiyle tek bir girdi
    olarak döner.
  </li>
</ul>

<h2 id="create">Adım 2 — İsteği oluşturun</h2>

```
curl -X POST https://api.formstep.io/api/v1 \
  -H "Authorization: Bearer $FORMSTEP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method":"requests.create","params":{
        "formId":"j57...",
        "recipient":{"email":"ada@acme.com","name":"Ada"},
        "context":{"case_id":"CASE-9"},
        "prefill":{"company_name":"Acme","company_size":"51_200"},
        "readonly":["company_name"],
        "delivery":"email",
        "externalId":"run-42",
        "callbackUrl":"https://automation.example/webhook/resume-abc",
        "idempotencyKey":"run-42"}}'
```

```
{
  "ok": true,
  "data": {
    "id": "kd7...",
    "status": "pending",
    "url": "https://form.formstep.io/r/rq_...",
    "deliveryStatus": "queued",
    "expiresAt": 1794787200000,
    "createdAt": 1789379200000,
    "externalId": "run-42",
    "deduplicated": false
  }
}
```

<p>
  Formstep daveti e-postayla gönderdiğinde <code>deliveryStatus</code> <code>"queued"</code>, bağlantıyı kendiniz teslim ettiğinizde ise{' '}
  <code>"not_requested"</code> olur.
</p>

<h2 id="three-buckets">Önceden doldurma, kilitli alanlar ve bağlam</h2>

<p>Bir isteğe üç farklı şey eklenebilir ve bunları karıştırmak en yaygın ilk hatadır.</p>

<h3 id="prefill">Prefill</h3>

<p>
  Görünür sorular için başlangıç yanıtları — böylece alıcı sıfırdan yazmak yerine gözden geçirip düzeltir. Onlar hakkında zaten bildiğiniz
  her şey burada yer alır — CRM'deki şirket adı, faturadaki tutar, geçen yılın yanıtları.
</p>

<h3 id="locked-fields">Kilitli alanlar</h3>

<p>
  Önceden doldurulmuş bir anahtarı <code>readonly</code> içine ekleyin, alıcı değeri görür ama değiştiremez. Bunu, alıcının sağladığı değil
  onayladığı gerçekler için kullanın — sözleşme numarası, üzerinde anlaşılan fiyat. Kilitleme istek bazlıdır: formun kendisi dokunulmamış
  kalır ve aynı alan bir sonraki istekte özgürce düzenlenebilir.
</p>

<p>
  Kilitli her anahtar aynı zamanda önceden doldurulmuş olmalıdır ve kilitli bir <em>zorunlu</em> alan boş olmayan bir değerle doldurulmuş
  olmalıdır — aksi takdirde alıcı asla gönderemeyeceği bir formla karşı karşıya kalır ve Formstep bu tuzağı oluşturmak yerine çağrıyı
  reddeder.
</p>

<h3 id="context">Context</h3>

<p>
  Formun <a href="/tr/building-forms/hidden-fields">gizli alanları</a> için güvenilir değerler — bir dosya numarası, bir workflow çalışma
  kimliği, bir tutar. Context, değişkenleri, koşullu mantığı, hesaplanan alanları ve e-posta metnini besler, geri çağırmada değişmeden döner
  ve alıcı bunu değiştiremez. Herkesin sorgu dizesini düzenleyebildiği genel bir bağlantıda URL üzerinden bir gizli alan besleme yönteminden
  farkı budur; istek bağlantıları URL sorgu parametrelerini tamamen yok sayar. Context değerleri bir metin dizesi, sayı veya boolean
  olmalıdır.
</p>

<p>
  Context serbest biçimli değildir: her anahtar formun yayınlanmış sürümünde bir gizli alan olmalıdır, bunun dışındaki her anahtar{' '}
  <code>UNKNOWN_FIELD_KEY</code> ile reddedilir. Gizli alanı olmayan kayıt bilgileri, örneğin bir yürütme kimliği,{' '}
  <a href="#metadata">metadata</a>'ya aittir.
</p>

<p>
  Gizli alanlar formda gösterilmez, ama bir context değeri alıcı için gizli değildir. Alıcı bunu, formun veya davetin gösterdiği her yerde
  görür: form içeriğinde veya e-posta metninde <a href="/tr/building-forms/answer-piping">anıldığında</a>, ya da görünür bir sorunun o gizli
  alanı kendi <a href="/tr/building-forms/field-configuration#default-values">varsayılan değeri</a> olarak kullanmasında. Bu son durumda,
  alıcı context değerini o soruda önceden doldurulmuş görür ve yanıtı düzenleyebilir. Context değerinin kendisi değişmeden kalır. O sorunun
  kendi anahtarı için bir <code>prefill</code>, varsayılana göre önceliklidir.
</p>

<h3 id="metadata">Metadata</h3>

<p>
  Kendi kayıt tutma bilgileriniz — bir yürütme kimliği, bir CRM kayıt kimliği. Bu hiçbir zaman forma ulaşmaz, dolayısıyla metne aktarılamaz
  veya mantık tarafından okunamaz; sadece yolculuğa eşlik eder ve her geri çağırmada ve durum okumasında geri döner.
</p>

<h2 id="value-shapes">Değer biçimleri</h2>

<p>
  Değerleri <code>fields.list</code>'ten gelen <code>type</code>'ın istediği biçimde gönderin. Yanlış bir biçim, anahtarı, beklenen türü ve
  — seçim soruları için — kabul edilecek değerleri belirten bir doğrulama hatası olarak döner.
</p>

<h2 id="documents">Belgeler</h2>

<p>
  Bir <a href="/tr/building-forms/documents-block">Belgeler bloğu</a>, yanıtlayıcıya dosya verir. Hazırlanmış dosyaları herkes için aynıdır
  ve her zaman kalır; bir istek, kendi tek alıcısı için dosyaları bunların altına ekler — müşterinin kendi kira sözleşmesi, kontrol edilecek
  bir kimlik fotokopisi. Baytlar hiçbir zaman API çağrısının kendisinden geçmez: önce yükleyin, sonra referans verin.
</p>

```
"documents": [
  { "documentId": "kn7...", "name": "Your lease contract" },
  { "documentId": "kn8..." }
]
```

<p>
  <code>name</code>, yüklemeyle kaydedilen görünen adı geçersiz kılar. Formda birden fazla Belgeler bloğu varsa hedefi <code>field</code>
  ile, yani bloğun alan anahtarıyla belirtin (<code>fields.list</code> bunu, her yanıtlayanın zaten aldığı hazır belgelerle birlikte
  listeler). Dosyalar bu hazır belgelerin altında yer alır: bir istek dosya ekler, hiçbir zaman birini değiştirmez. Bir yükleme, istediğiniz
  kadar çok istek tarafından referans gösterilebilir — bir kez yüklenen bir fiyat listesi beş yüz isteğe hizmet eder.
</p>

<p>
  Sınırlar: yalnızca PDF ve görseller, belge başına 25 MB, istek başına 100 MB (<code>DOCUMENTS_TOO_LARGE</code>) ve hazırlanmış belgeler
  dahil blok başına en fazla 20 belge (<code>DOCUMENTS_TOO_MANY</code>). Dosyalar çalışma alanı depolama alanınıza sayılır ve onlara
  referans veren istekler formun saklama penceresinin dışına çıktığında serbest bırakılır. Gönderim, alıcının bloğun alan anahtarı altında
  gördüğü listeyi kaydeder, böylece geri çağırma size bu kişiye tam olarak hangi dosyaların verildiğini söyler.
</p>

<h2 id="options">Kalan seçenekler</h2>

<h3 id="test-mode">Test modu</h3>

<p>
  Gerçek bir çalıştırmadan önce tüm yapıyı denemek için <code>test: true</code> geçirin. Bir test isteği, bağlantı açısından önemli olan her
  şekilde gerçektir: bağlantı açılır ve tamamlanabilir, <a href="/tr/requests/callbacks">geri çağırma</a> her zamanki gibi tetiklenir ve{' '}
  <code>requests.get</code> yanıtları döndürür. Asla yapmadığı şey, sonradan temizlemeniz gereken birine veya bir şeye ulaşmaktır:
</p>

<ul>
  <li>
    <code>delivery</code> ne derse desin, ne davet ne de hatırlatma gönderilir. <strong>Hatırlatma gönder</strong> bunun üzerinde reddedilir
    ve aylık kotanızdan hiçbir şey harcamaz.
  </li>
  <li>
    Geri çağırma <code>"test": true</code> taşır, böylece workflow’unuz buna göre dallanabilir veya onu yok sayabilir.
  </li>
  <li>
    Gönderim saklanır ama sayılmaz: ne aylık kotanıza karşı (kota tükenmiş olsa bile bir test tamamlanır), ne de formun gönderim
    sayılarında, gönderimler sekmesinde, dışa aktarımlarda veya entegrasyonlarınızda görünür. Kimse bilgilendirilmez.
  </li>
  <li>
    İstek, <strong>Test isteklerini göster</strong>'in arkasında <a href="/tr/requests/managing-requests">İstekler sayfasından</a> gizlenir,
    Analytics'teki istek hunisinden dışlanır ve <code>includeTest: true</code> geçirmediğiniz sürece <code>requests.list</code>'ten
    dışlanır.
  </li>
  <li>
    <code>expiresAt</code> daha uzun bir süre istese bile bağlantı 24 saat içinde kapanır; yanıttaki <code>expiresAt</code> ne zaman
    olduğunu söyler. Free'de bir workspace günde 10 test isteği oluşturabilir. Sonraki istek <code>RATE_LIMITED</code> ve{' '}
    <code>TEST_REQUEST_LIMIT_REACHED</code> nedeniyle başarısız olur, <code>retryAfterMs</code> ise ne zaman tekrar deneyebileceğinizi
    söyler. Pro ve Business'ta günlük sınır yoktur.
  </li>
</ul>

<p>
  Paylaş panelindeki <strong>Kendin dene</strong>, bu modu tek tıkla çalıştırır: Manuel sekmesinin taslağını — önceden doldurma, kilitler,
  bağlam, geri çağırma, süre dolumu — alır, isteği kendi hesabınıza adresler, hiçbir e-posta göndermez ve size kendinizin açacağı bağlantıyı
  verir.
</p>

<h3 id="allowance">Bir isteğin maliyeti</h3>

<p>
  Her planda, her iki kanalın paylaştığı tek bir <strong>aylık kota</strong> vardır: bir paylaşım bağlantısı gönderimi bir birim harcar,
  oluşturduğunuz her istek de öyle — alıcı yanıtlasın, yok saysın veya siz iptal edin, fark etmez. Bir isteğin topladığı gönderim zaten
  ödenmiştir ve hiçbir yerde sayılmaz. Ücretsiz plan ayda 1.000 birim içerir, Pro ve Business 50.000; sayaç her ayın 1’inde, UTC olarak
  sıfırlanır. Kotaya ulaşıldığında <code>requests.create</code>, <code>UPGRADE_REQUIRED</code> hatasıyla ve{' '}
  <code>MONTHLY_ALLOWANCE_REACHED</code> nedeniyle başarısız olur; zaten oluşturduğunuz istekler yanıtlanabilir kalmaya devam eder.
</p>

<p>
  Ücretsiz planda, <code>"delivery": "email"</code> ile oluşturulan bir istek ayrıca hesabın{' '}
  <a href="/tr/subscription-billing/limits-quotas#free-invitations">10 ücretsiz davetinden</a> birini harcar. Bunlar asla sıfırlanmaz;
  bittiklerinde e-posta teslimatı <code>UPGRADE_REQUIRED</code> hatasıyla ve <code>FREE_INVITATIONS_USED</code> nedeniyle başarısız olur.
</p>

<h3 id="idempotency">Idempotency (aynı sonuç garantisi)</h3>

<p>
  Aynı gövdeyle aynı <code>idempotencyKey</code>'i geçirin, <code>deduplicated: true</code> ile birlikte orijinal isteği ve orijinal
  bağlantıyı geri alırsınız — ikinci bir istek yok, ikinci bir e-posta yok. Anahtarı <em>farklı</em> bir gövdeyle yeniden kullanırsanız
  Formstep, hangisini kastettiğinizi tahmin etmek yerine <code>IDEMPOTENCY_CONFLICT</code> ile reddeder. Anahtarlar çalışma alanına
  kapsamlıdır ve 30 gün boyunca geçerlidir; bu sürenin ardından aynı anahtar yeni bir istek başlatır.
</p>

<p>
  Bir workflow aracında, yürütme kimliği doğal anahtardır: bir ağ kesintisinden sonra yeniden denenen bir çalışma, zaten oluşturduğu isteği
  devralır.
</p>

<h3 id="rate-limit">Hız sınırı</h3>

<p>
  <code>requests.create</code> ve <code>documents.create</code>, API tokeni başına (tokensiz yapılan bir çağrı için kullanıcı başına)
  sayılan, dakikada <strong>60 çağrılık</strong> bir bütçeyi paylaşır. Boşalttığınız bir birikim kendi hızını ayarlamalıdır; bütçeyi aşan
  bir patlama reddedilir ve yeniden denenebilir.
</p>

<h3 id="custom-domains">Özel alan adları</h3>

<p>
  Form zaten özel <a href="/tr/branding-domains/custom-domains">alan adlarınızdan</a> birinde yayınlanmışsa, istek bağlantıları orada
  otomatik olarak oluşturulur — <code>https://forms.yourcompany.com/r/rq_…</code>. Form birden fazla alan adında yayınlanmışsa{' '}
  <code>domainId</code>'yi açıkça belirtin. Alan adı, formla aynı çalışma alanına ait olmalıdır.
</p>

<h2 id="what-the-recipient-sees">Alıcı ne görür</h2>

<p>
  Tam olarak yazdığınız form — aynı tema, aynı logo, aynı dil — değerleri yerinde, kilitli alanlar salt okunur ve çözülecek bir captcha yok.
  Gönderdiklerinde, teşekkür sayfanızı görürler. Daha sonra bağlantıya geri dönerlerse, boş bir form yerine sonuç sayfasını görürler.
</p>

<p>
  Sayfada otomasyonunuzdan bir mesaj yoktur. Alıcının bilmesi gereken her şey formun kendisinde yer almalıdır; burada bir bağlam değerini
  veya önceden doldurulmuş bir alanı <a href="/tr/building-forms/answer-piping">anarak</a> kişiselleştirebilirsiniz.
</p>

<p>
  Bir AI ajanı, <code>fields_list</code> ve <code>request_create</code> ile aynı iki adımı, aynı seçeneklerle — documents ve{' '}
  <code>domainId</code> dahil — çalıştırır. Bkz. <a href="/tr/developers/mcp-server#requests">MCP sunucusundaki İstekler</a>.
</p>

<div class="not-prose grid gap-3 sm:grid-cols-2">
  - [Alan anahtarları](/tr/requests/field-keys) — Bu anahtarların nereden geldiği ve nasıl kararlı tutulacağı.
  - [Geri çağırmalar ve imzalama](/tr/requests/callbacks) — Alıcı işini bitirdiğinde ne gelir.
  - [Sorun giderme](/tr/requests/troubleshooting) — Her reddedilme nedeni ve ne yapılması gerektiği.
  - [API referansı](/tr/developers/rest-api) — Her istek metodu için tam parametre listesi.
</div>
