--- name: forminit-nodejs description: Integrates Forminit headless form backend into Node.js applications using the npm SDK with server-side API key. Submits forms with typed blocks (sender, text, email, phone, file, rating, date, select, radio, checkbox, country, number). Use when handling form submissions from Node.js, Express, Fastify, or any server-side JavaScript. Do not use for Next.js (use forminit-nextjs), Nuxt.js (use forminit-nuxtjs), or client-side HTML (use forminit-html). metadata: author: forminit version: "1.0" --- # Forminit — Node.js Integration > Forminit is a headless form backend API. You build the form UI, Forminit handles submission, validation, storage, and notifications. This skill uses the npm SDK on the server side. ## Constraints - Server-side only. API key must be in environment variables, never in client code. - User must set authentication mode to "Protected" in Form settings before creating an API token. - All field names use prefix pattern: `fi-{type}-{name}` - Sender block: max 1 per form. Use for submitter's contact info. - Default to `fi-sender-firstName` + `fi-sender-lastName`. Use `fi-sender-fullName` only if user wants a single name field. - For non-submitter emails/phones/countries, use field blocks: `fi-email-invitee`, `fi-phone-emergency`, `fi-country-shipping` - File uploads require FormData (not JSON) - Max 50 blocks per form, max 25 MB total files ## Install ```bash npm install forminit@latest ``` ## Environment Variable ```bash # .env FORMINIT_API_KEY="YOUR-SECRET-API-TOKEN" ``` ## Basic Submission (JSON) ```js import { Forminit } from 'forminit'; const forminit = new Forminit({ apiKey: process.env.FORMINIT_API_KEY, }); const { data, error } = await forminit.submit('FORM_ID', { blocks: [ { type: 'sender', properties: { firstName: 'Jane', lastName: 'Doe', email: 'jane@example.com', }, }, { type: 'text', name: 'message', value: 'Hello from Node.js' }, ], }); if (error) { console.error(error.message); } else { console.log('Submitted:', data.hashId); } ``` Replace `FORM_ID` with the form ID from https://app.forminit.com. ## Express Example ```js import express from 'express'; import { Forminit } from 'forminit'; const app = express(); app.use(express.json()); const forminit = new Forminit({ apiKey: process.env.FORMINIT_API_KEY, }); app.post('/submit', async (req, res) => { const { data, error } = await forminit.submit('FORM_ID', { blocks: req.body.blocks, }); if (error) return res.status(error.code).json({ error: error.message }); res.json({ id: data.hashId }); }); app.listen(3000); ``` ## FormData Submission (for file uploads) ```js import { Forminit } from 'forminit'; const forminit = new Forminit({ apiKey: process.env.FORMINIT_API_KEY, }); const formData = new FormData(); formData.append('fi-sender-email', 'jane@example.com'); formData.append('fi-text-message', 'Hello'); formData.append('fi-file-resume', fileBuffer, 'resume.pdf'); const { data, error } = await forminit.submit('FORM_ID', formData); ``` ## Form Blocks Reference ### Sender Block — `fi-sender-{property}` One per form. Collects submitter info. At least one property required. ``` fi-sender-email fi-sender-firstName fi-sender-lastName fi-sender-fullName fi-sender-phone fi-sender-company fi-sender-position fi-sender-title fi-sender-userId fi-sender-address fi-sender-city fi-sender-country ``` ### Field Blocks — `fi-{type}-{name}` Each name must be unique. Up to 50 total blocks. ``` text fi-text-{name} e.g. fi-text-message number fi-number-{name} e.g. fi-number-quantity email fi-email-{name} e.g. fi-email-invitee phone fi-phone-{name} e.g. fi-phone-emergency Validation: E.164 (+12025550123) url fi-url-{name} e.g. fi-url-website date fi-date-{name} e.g. fi-date-appointment Validation: ISO 8601 (YYYY-MM-DD) rating fi-rating-{name} e.g. fi-rating-satisfaction Validation: integer 1-5 select fi-select-{name} e.g. fi-select-plan Supports multi-select (string[]) radio fi-radio-{name} e.g. fi-radio-priority Single choice (string) checkbox fi-checkbox-{name} e.g. fi-checkbox-features Supports multi-choice (string[]) file fi-file-{name} e.g. fi-file-resume Add [] for multiple: fi-file-photos[] country fi-country-{name} e.g. fi-country-shipping Validation: ISO 3166-1 alpha-2 ``` ## SDK Response ```js const { data, redirectUrl, error } = await forminit.submit(formId, payload); ``` Success: `data.hashId` (submission ID), `data.date`, `data.blocks` (submitted values), `redirectUrl` (thank-you page URL). Error: `error.error` (code like `FI_SCHEMA_FORMAT_EMAIL`), `error.code` (HTTP status), `error.message` (human-readable). ## Common Mistakes - Using `name="email"` instead of `fi-sender-email` — all fields must use the `fi-` prefix or the submission will be empty. - Using `fi-sender-name` — there is no `name` property on sender. Use `fi-sender-firstName` + `fi-sender-lastName` or `fi-sender-fullName`. - Putting the API key in client-side code — the key must stay on the server. - Setting form authentication to "Public" instead of "Protected" — Node.js integration requires Protected mode. - Sending phone without E.164 format — `5551234567` will be rejected, must be `+15551234567`. - Using JSON with file uploads — files only work with FormData. ## Documentation - Full guide: https://forminit.com/docs/nodejs/ - SDK reference: https://forminit.com/docs/sdk/ - Form blocks: https://forminit.com/docs/form-blocks/ ## Spam Protection (only if user requests) - reCAPTCHA: https://forminit.com/docs/recaptcha/ - hCaptcha: https://forminit.com/docs/hcaptcha/