Skip to content

Form blocks

Form blocks are the typed building blocks of every Forminit submission. Combine them to capture exactly what your form needs: contact details, file uploads, ratings, choices, anything.

  • Server-side validation, no setup. email, phone, url, country, rating, and date are validated automatically. Bad data never reaches your dashboard or webhooks.
  • A consistent schema for every submission. Every block is typed, so CSV exports, webhooks, and integrations always get the same shape. No garbage data breaking automations.
  • sender and tracking are built in. Use sender to identify who submitted the form. tracking is auto-captured by the JS SDK so you always know where the visitor came from.
  • Compose anything. Up to 50 blocks per submission, named however you like with the pattern fi-{blockType}-{name}. Same backend whether you’re collecting a contact request, a 12-question survey, or a file-upload portal.

Form Block Example


Every input name follows the same pattern: fi-{blockType}-{name}. That’s the only rule.

The example below packs every block type into a single submission, shown four ways so you can grab whichever fits your stack: HTML loads the SDK from the CDN (browser, no API key needed), Node.js posts plain fetch with an X-API-KEY header (server, no SDK), React uses the npm SDK inside a component, and Python uses the official Python SDK. Each tab is independently runnable. Most forms only need a handful of these blocks, so copy the tab you want and delete the ones that don’t apply to your form.

<!-- Load the SDK from the CDN -->
<script src="https://forminit.com/sdk/v1/forminit.js"></script>

<form id="contact-form">

  <input type="text"  name="fi-sender-firstName" placeholder="First name" />
  <input type="text"  name="fi-sender-lastName"  placeholder="Last name" />
  <!-- Single-field alternative to firstName/lastName -->
  <input type="text"  name="fi-sender-fullName"  placeholder="Full name" />
  <input type="email" name="fi-sender-email"     placeholder="Email" />
  <input type="text"  name="fi-sender-phone"     placeholder="Phone" />
  <input type="text"  name="fi-sender-title"     placeholder="Title (Mr., Ms., Dr.)" />
  <input type="text"  name="fi-sender-company"   placeholder="Company" />
  <input type="text"  name="fi-sender-position"  placeholder="Job title" />
  <input type="text"  name="fi-sender-address"   placeholder="Address" />
  <input type="text"  name="fi-sender-address2"  placeholder="Address line 2 (apt, suite, etc.)" />
  <input type="text"  name="fi-sender-city"      placeholder="City" />
  <input type="text"  name="fi-sender-postcode"  placeholder="Postcode / ZIP" />
  <input type="text"  name="fi-sender-country"   placeholder="Country (ISO 3166-1 alpha-2, e.g. US)" />
  <input type="hidden" name="fi-sender-userId"   value="ext_12345" />

  <!-- text: free-form answer, no validation -->
  <textarea name="fi-text-message" placeholder="Message"></textarea>

  <!-- number: any numeric value -->
  <input type="number" name="fi-number-budget" placeholder="Budget" />

  <!-- email: a second email beyond the sender's -->
  <input type="email" name="fi-email-invitee" placeholder="Invitee email" />

  <!-- phone: a second phone beyond the sender's, E.164 format -->
  <input type="text" name="fi-phone-emergency" placeholder="Emergency contact" />

  <!-- url: validated as a URL -->
  <input type="url" name="fi-url-website" placeholder="Your website" />

  <!-- select: single or multi choice -->
  <select name="fi-select-plan">
    <option value="basic">Basic</option>
    <option value="pro">Pro</option>
    <option value="enterprise">Enterprise</option>
  </select>

  <!-- radio: single choice from a group -->
  <label><input type="radio" name="fi-radio-priority" value="low"  /> Low</label>
  <label><input type="radio" name="fi-radio-priority" value="high" /> High</label>

  <!-- checkbox: one or more choices, same name = array -->
  <label><input type="checkbox" name="fi-checkbox-features" value="api" />     API</label>
  <label><input type="checkbox" name="fi-checkbox-features" value="support" /> Support</label>

  <!-- rating: integer between 1 and 5 -->
  <input type="range" name="fi-rating-satisfaction" min="1" max="5" step="1" value="3" />

  <!-- date: ISO 8601 date or date-time -->
  <input type="date" name="fi-date-appointment" />

  <!-- file: requires multipart/form-data (FormData uses it by default) -->
  <input type="file" name="fi-file-resume" />

  <!-- country: ISO 3166-1 alpha-2 code. Full list: https://gist.github.com/ssskip/5a94bfcd2835bf1dea52 -->
  <select name="fi-country-shipping">
    <option value="US">United States</option>
    <option value="GB">United Kingdom</option>
  </select>

  <!-- tracking: auto-captured by the SDK from URL params and referrer -->

  <button type="submit">Send</button>
  <p id="form-status"></p>
</form>

<script>
  const forminit = new Forminit();
  const form = document.getElementById('contact-form');
  const status = document.getElementById('form-status');

  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    status.textContent = '';

    const { data, error } = await forminit.submit('YOUR_FORM_ID', new FormData(form));

    if (error) {
      status.textContent = 'Error: ' + error.message;
      return;
    }

    status.textContent = 'Thanks! Your submission was received.';
    form.reset();
  });
</script>

Every block you can submit. sender and tracking each appear at most once per submission and hold a fixed set of properties. The rest are blocks you define yourself. Pick a type, give it any name, and Forminit validates the value server-side. The naming pattern is always fi-{blockType}-{name}.

| Form block | Description | |---|---| | sender | Who submitted the form. Appears at most once per submission. Properties: email, firstName, lastName, fullName, phone, title, company, position, address, address2, city, postcode, country, userId. At least one of userId, email, phone, firstName, lastName, or fullName is required. FormData fields use fi-sender-{property} (e.g. fi-sender-email). | | text | Free-form answer for messages, comments, or any string. No validation. | | number | Any numeric value (budget, quantity). Validated as a valid number. | | email | A second email beyond the sender’s (invitee, backup contact). Validated as a valid email format. For the submitter’s own email, use sender.email. | | phone | A second phone beyond the sender’s (emergency contact). E.164 format, e.g. +12025550123. For the submitter’s own phone, use sender.phone. | | url | A URL (website, LinkedIn). Validated as a valid URL format. | | select | Dropdown choice. Single value, or an array of values for multi-select. | | radio | Single choice from a group sharing the same name. | | checkbox | One or more choices. Multiple checkboxes with the same name produce an array. | | rating | Integer between 1 and 5. Use for satisfaction scores, reviews, or any 1–5 scale. | | date | ISO 8601 date or date-time (2025-01-15 or 2025-01-15T10:30:00Z). | | file | File upload. Requires multipart/form-data; JSON submissions cannot include files. See the File upload guide for size and MIME limits. | | country | ISO 3166-1 alpha-2 code (e.g. US, GB, DE). Full list. For the submitter’s own country, use sender.country. | | tracking | Marketing attribution. Appears at most once per submission. Properties: UTM params (utmSource, utmMedium, utmCampaign, utmTerm, utmContent), referrer, and ad click IDs (gclid, fbclid, msclkid, ttclid, twclid, li_fat_id, amzclid, mc_cid, mc_eid, wbraid, gbraid). Auto-captured on the client by the JS SDK; set manually for server-side submissions. |


| Limit | Value | |---|---| | Maximum custom blocks per submission | 50 | | Maximum custom blocks of the same type | 20 | | Built-in blocks per submission (sender, tracking) | 1 each |


| Block | Rule | |---|---| | sender.email, email | Valid email format | | sender.phone, phone | E.164 format (e.g. +12025550123) | | sender.country, country | ISO 3166-1 alpha-2 code | | url | Valid URL format | | rating | Integer 1–5 | | date | ISO 8601 date or date-time | | number | Valid number | | file | multipart/form-data only |


After your first submission, your blocks become your form’s schema. From Form Settings → Blocks you can:

  • Rename labels so the dashboard reads naturally (e.g. Budget instead of fi-number-budget)
  • Reorder how blocks appear in the submission view
  • Hide blocks you don’t want to see