# Forminit - Form Backend API > Forminit is a form backend service that handles submissions, storage, validation, file uploads, and notifications. Build forms in any framework and let Forminit handle the rest. --- ## Quick Start 1. Create a form at app.forminit.com 2. Get your Form ID 3. Submit forms using SDK or direct API ### Installation ```bash npm install forminit ``` Or use CDN: ```html ``` ### Basic Usage ```javascript import { Forminit } from 'forminit'; const forminit = new Forminit(); const { data, redirectUrl, error } = await forminit.submit('YOUR_FORM_ID', formData); ``` --- ## Authentication Modes | Mode | Use Case | API Key Required | |------|----------|------------------| | **Public** | Client-side forms, static sites | No | | **Protected** | Server-side, sensitive data | Yes | ### Public Mode Forms can be submitted directly from the browser without an API key. ### Protected Mode Requires API key in `X-API-KEY` header. Use a backend proxy to keep keys secure. ```javascript const forminit = new Forminit({ proxyUrl: '/api/forminit' }); ``` --- ## Form Blocks Form Blocks are the building blocks of Forminit submissions. Each block represents a field type with specific validation rules. ### Block Types | Type | Description | Validation | |------|-------------|------------| | `sender` | Contact information | Email format, phone E.164 | | `text` | Text content | None | | `email` | Email addresses | RFC 5322 format | | `phone` | Phone numbers | E.164 format (+12025550123) | | `url` | Web addresses | Valid URL format | | `select` | Dropdown single/multi-select | None | | `radio` | Radio button single choice | None | | `checkbox` | Checkbox single/multi-choice | None | | `rating` | 1-5 star ratings | Integer 1-5 | | `date` | Dates | ISO 8601 (YYYY-MM-DD) | | `file` | File uploads | Size/type limits | | `country` | Country codes | ISO 3166-1 alpha-2 | | `number` | Numeric values | Valid number | | `tracking` | UTM parameters | None | ### Field Naming Convention (FormData) Pattern: `fi-{type}-{name}` ```html ``` ### JSON Submission Format ```json { "blocks": [ { "type": "sender", "properties": { "email": "user@example.com", "firstName": "John", "lastName": "Doe" } }, { "type": "text", "name": "message", "value": "Hello world" }, { "type": "select", "name": "subject", "value": "Support" } ] } ``` --- ## API Reference ### Submit Form **Endpoint:** `POST https://forminit.com/f/{formId}` **Headers:** - `Content-Type`: `application/json` or `multipart/form-data` - `X-API-KEY`: Required for protected forms **Success Response (200):** ```json { "hashId": "abc123", "date": "2025-01-01 12:00:00", "blocks": { "sender": { "email": "user@example.com", "firstName": "John" }, "message": "Hello" }, "redirectUrl": "https://forminit.com/thank-you/abc123" } ``` **Error Response:** ```json { "error": "ERROR_CODE", "code": 400, "message": "Human-readable message" } ``` ### List Submissions **Endpoint:** `GET https://forminit.com/api/v1/forms/{formId}/submissions` **Headers:** - `X-API-KEY`: Required **Query Parameters:** - `page`: Page number (default: 1) - `limit`: Items per page (default: 20, max: 100) - `search`: Search term - `status`: Filter by status (unread, read, spam, archived) - `startDate`: Filter from date (YYYY-MM-DD) - `endDate`: Filter to date (YYYY-MM-DD) **Response:** ```json { "data": [...], "pagination": { "total": 100, "page": 1, "limit": 20, "totalPages": 5 } } ``` --- ## Error Codes | Code | Description | |------|-------------| | `FORM_NOT_FOUND` | Form ID doesn't exist | | `FORM_DISABLED` | Form is disabled | | `EMPTY_SUBMISSION` | No fields submitted | | `UNAUTHORIZED` | Invalid or missing API key | | `FI_SCHEMA_FORMAT_EMAIL` | Invalid email format | | `FI_RULES_PHONE_INVALID` | Invalid phone format | | `FI_SCHEMA_RANGE_RATING` | Rating not 1-5 | | `FI_DATA_COUNTRY_INVALID` | Invalid country code | | `TOO_MANY_REQUESTS` | Rate limit exceeded | | `FI_FILE_TOO_LARGE` | File exceeds 10MB | | `FI_FILE_TYPE_NOT_ALLOWED` | File type not permitted | | `FI_SUBMISSION_TOO_LARGE` | Total exceeds 25MB | --- ## File Uploads - Maximum 10MB per file - Maximum 25MB per submission - Maximum 20 files per submission - Supported types: Documents (PDF, DOC, DOCX, TXT), Images (JPG, PNG, GIF, WebP), Audio (MP3, WAV), Video (MP4, WebM), Archives (ZIP, RAR) ### FormData Upload ```html ``` Note: Append `[]` for multiple files. --- ## Email Notifications Configure in Form Settings > Email Notifications. **Options:** - Notification emails (up to 5 recipients) - Email subject template - Reply-to sender option ### Autoresponder Send automatic confirmation emails to form submitters. **Requirements:** - Sender block with email field - Verified sender email domain (or use Forminit's) **Configuration:** - Subject line - Message body (supports variables: {{firstName}}, {{lastName}}, {{email}}) - From name --- ## Spam Protection ### reCAPTCHA v2 ```html
``` Add secret key in Form Settings. ### reCAPTCHA v3 ```javascript grecaptcha.execute('SITE_KEY', {action: 'submit'}).then(token => { formData.append('g-recaptcha-response', token); }); ``` ### hCaptcha ```html ``` ### Honeypot Add hidden field that bots will fill: ```html ``` Enable in Form Settings > Security > Honeypot Protection. --- ## Integrations ### Webhooks Send submission data to your server in real-time. **Configuration:** Form Settings > Integrations > Webhooks **Payload:** ```json { "event": "submission.created", "form": { "id": "...", "name": "..." }, "submission": { "hashId": "...", "date": "...", "blocks": {...} } } ``` **Security:** Verify `X-Forminit-Signature` header using HMAC SHA-256. ### Slack Notifications 1. Create Slack app at api.slack.com 2. Enable Incoming Webhooks 3. Add webhook URL in Form Settings > Integrations > Slack ### Discord Notifications 1. Open Discord channel settings 2. Go to Integrations > Webhooks 3. Create webhook and copy URL 4. Add in Form Settings > Integrations > Discord ### Zapier Connect to 8,000+ apps. Trigger: "New Submission" Popular integrations: - Google Sheets, Airtable, Notion - Slack, Intercom - Salesforce, HubSpot, Zendesk - Mailchimp, ActiveCampaign - Trello, Basecamp --- ## Framework Guides ### HTML / Static Sites ```html ``` ### React ```tsx import { Forminit } from 'forminit'; const forminit = new Forminit(); function ContactForm() { const [status, setStatus] = useState('idle'); async function handleSubmit(e) { e.preventDefault(); setStatus('loading'); const { data, error } = await forminit.submit('FORM_ID', new FormData(e.target)); setStatus(error ? 'error' : 'success'); } return ( ); } ``` ### Next.js (App Router) **API Route (`app/api/forminit/[formId]/route.ts`):** ```typescript import { NextRequest, NextResponse } from 'next/server'; export async function POST(request: NextRequest, { params }: { params: { formId: string } }) { const body = await request.json(); const response = await fetch(`https://forminit.com/f/${params.formId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-KEY': process.env.FORMINIT_API_KEY! }, body: JSON.stringify(body) }); return NextResponse.json(await response.json(), { status: response.status }); } ``` **Client Component:** ```tsx 'use client'; import { Forminit } from 'forminit'; const forminit = new Forminit({ proxyUrl: '/api/forminit' }); ``` ### Nuxt.js **Server Route (`server/api/forminit/[formId].post.ts`):** ```typescript export default defineEventHandler(async (event) => { const formId = getRouterParam(event, 'formId'); const body = await readBody(event); return await $fetch(`https://forminit.com/f/${formId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-KEY': process.env.FORMINIT_API_KEY }, body }); }); ``` ### Node.js / Express ```javascript import express from 'express'; const app = express(); app.use(express.json()); app.post('/api/forminit/:formId', async (req, res) => { const response = await fetch(`https://forminit.com/f/${req.params.formId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-KEY': process.env.FORMINIT_API_KEY }, body: JSON.stringify(req.body) }); res.status(response.status).json(await response.json()); }); ``` ### Astro ```astro --- // For static sites, use client-side submission --- ``` ### WordPress Use Contact Form 7 or WPForms with webhook/API integration, or embed HTML form directly in pages. --- ## Configuration Options ### Redirections Set custom thank you page URL in Form Settings > After Submission > Redirect URL. ### Authorized Domains Restrict submissions to specific domains in Form Settings > Security > Authorized Domains. ### Custom SMTP Use your own email server for notifications: - SMTP Host, Port, Username, Password - From email address - Encryption (TLS/SSL) --- ## Workspace & Team - Create multiple workspaces for different projects - Invite team members with role-based access - Manage forms across workspaces --- ## Pricing Free tier available. Paid plans for higher volumes and additional features. See https://forminit.com/pricing for details. --- ## Support - Documentation: https://forminit.com/docs - Dashboard: https://app.forminit.com - Website: https://forminit.com