# FormBlade — Complete AI Reference # https://formblade.com # This file provides comprehensive documentation for AI coding assistants. ## Product FormBlade is a form backend service (like Formspree). Users create forms in a dashboard, get a hosted form page or endpoint URL, POST HTML form data to it. The system stores submissions, sends notifications (email, Telegram, Slack, Discord, Viber, Teams), and provides a dashboard for management. ## Key URLs - Homepage: https://formblade.com - Documentation: https://formblade.com/docs - API reference: https://formblade.com/docs/api - OpenAPI spec: https://formblade.com/api/openapi.json - Widget docs: https://formblade.com/docs/widget - Getting started: https://formblade.com/docs/getting-started - Platform guides: https://formblade.com/docs/platforms - Pricing: https://formblade.com/pricing - Sign up: https://formblade.com/app/register - Code examples: https://github.com/znxltd/formblade-examples ## Quick Start 1. Sign up at formblade.com/app/register (free, no credit card) 2. Create a form — pick from 9 templates (contact, feedback, newsletter, booking, etc.) 3. Copy the widget snippet, HTML snippet, or share the hosted link 4. Submissions arrive in email, Telegram, Slack, Discord, Viber, or Teams --- ## HTML Form Integration Point any HTML form at your FormBlade endpoint: ```html
``` FormBlade reads the `name` attributes from your form fields. You can use any field names. ### With file upload ```html ``` ### Custom redirect after submission ```html ``` --- ## Widget Embed (Recommended) One script tag adds a floating contact button with a slide-in form panel: ```html ``` ### Widget options (data-* attributes) - data-form — Endpoint ID (required) - data-label — Button text (default: "Contact Us") - data-color — Button color (default: #6366f1) - data-emoji — Animated emoji before label (e.g. "👋") - data-emoji-animation — "bounce", "wave", "pulse", "tada" - data-open — Trigger: "click" (default), "time", "scroll", "exit" - data-open-value — For time: ms delay. For scroll: percentage 0-100 - data-show-once — "true" to hide after visitor closes - data-hide-after-submit — "true" (default) to hide after submission, "false" to keep showing - data-dot — "true" for pulsing notification dot ### JS API - FormBlade("open") / FormBlade("close") — control widget from JS - FormBlade("set", {field: "value"}) — pre-fill form fields - Supports command queue: calls before script loads are queued - Redirect URL navigates parent page, not the iframe ### Auto-open after 5 seconds ```html ``` ### Open at 50% scroll ```html ``` ### Exit intent ```html ``` --- ## AJAX Submission (JavaScript) ```javascript const form = document.querySelector('form'); form.addEventListener('submit', async (e) => { e.preventDefault(); const data = new FormData(form); const res = await fetch('https://formblade.com/f/YOUR_ENDPOINT_ID', { method: 'POST', body: data, }); if (res.ok) alert('Sent!'); }); ``` --- ## REST API Base URL: https://formblade.com/api OpenAPI spec: https://formblade.com/api/openapi.json Auth: Bearer token in Authorization header ### Authentication ``` Authorization: Bearer fb_sk_your_api_key_here ``` Create API keys from the dashboard at /app/api-keys. Personal plan: read-only keys. Pro+: full access keys. ### List forms ``` GET /api/forms ``` Returns array of form objects. ### Create form (Pro+) ``` POST /api/forms Content-Type: application/json {"name": "Contact Form", "notify_email": "you@example.com"} ``` ### Generate form with AI ``` POST /api/forms/ai-generate Content-Type: application/json {"prompt": "A job application form with name, email, resume upload, position dropdown with Engineering/Design/Marketing, and cover letter"} ``` Returns a complete form object with AI-generated fields, name, and theme. Prompt must be 10-1000 characters and cannot contain URLs. Limits: 3/month (free), 50/month (pro), unlimited (business). ### Get form ``` GET /api/forms/{form_id} ``` ### Update form (Pro+) ``` PATCH /api/forms/{form_id} Content-Type: application/json {"name": "Updated Name", "is_active": false} ``` ### Delete form (Pro+) ``` DELETE /api/forms/{form_id} ``` ### Categories Group forms in the dashboard (all plans). Assign a form by sending category_id on PATCH /api/forms/{id}. ``` GET /api/categories → list of { id, name, color, sort_order } POST /api/categories → create { name, color? } PATCH /api/categories/{id} → update { name?, color?, sort_order? } DELETE /api/categories/{id} → delete (forms are kept; their category_id is cleared) ``` ### Form object fields - id: uuid - name: string (3-64) - endpoint_id: string (6-12) — used in /f/{endpoint_id} URL - category_id: uuid | null — category for grouping forms in the dashboard (see Categories) - notify_email: string | null - redirect_url: string | null - is_active: boolean - honeypot_field: string | null (default: _fb_hp) - js_honeypot: boolean (default: true) - captcha_type: "none", "math", "hcaptcha", "recaptcha_v2", "recaptcha_v3", "turnstile", "geetest_v4" - captcha_site_key: string | null - captcha_min_score: float | null (reCAPTCHA v3, 0.0-1.0) - form_theme: "minimal", "corporate", "glass", "dark", "warm", "compact" - form_fields: array | null - auto_respond: boolean (Pro+) - consent_required: boolean (requires _fb_consent field in submissions, rejects 422 if missing) - consent_message: string | null (custom label for consent checkbox) - privacy_url: string | null (linked from consent checkbox) - compliance_region: "gdpr" | "uk_gdpr" | "ccpa" | "lgpd" | "pipeda" | "popia" | "pdpa" | "appi" | "dpdpa" | "pipl" | "pipa" | "ndsg" | "kvkk" | "apa" | "nzpa" | null (applies preset: https://formblade.com/docs/compliance) - ip_anonymize: boolean (last IP octet zeroed before storage) - store_ip: boolean - store_user_agent: boolean - data_retention_days: integer | null (auto-purge after N days) - telegram_bot_token: string | null - telegram_chat_id: string | null - slack_webhook_url: string | null - discord_webhook_url: string | null - teams_webhook_url: string | null - viber_bot_token: string | null - viber_receiver_id: string | null - blocked_emails: string[] | null (Pro+ — wildcard patterns like "*@spam.com") - email_routing_rules: array | null (Pro+ — [{field, operator, value, email}]) - notion_config: object | null (Pro+ — {api_key, database_id, field_mapping}) - airtable_config: object | null (Pro+ — {api_key, base_id, table_name, field_mapping}) - trello_config: object | null (Pro+ — {api_key, token, list_id}) - github_config: object | null (Pro+ — {token, repo, labels, title_field}) - mailchimp_config: object | null (Pro+ — {api_key, list_id, email_field, merge_fields}) - freshdesk_config: object | null (Pro+ — {api_key, domain, email_field, subject_field}) - zendesk_config: object | null (Pro+ — {api_token, email, subdomain, email_field, subject_field}) - weekly_digest: boolean (Monday summary email per form) - view_count: integer (read-only) - submission_count: integer (read-only) - created_at: ISO 8601 (read-only) - updated_at: ISO 8601 (read-only) ### List submissions ``` GET /api/forms/{form_id}/submissions?page=1&per_page=25&spam=false ``` Response: ```json { "items": [ { "id": "uuid", "data": {"name": "Jane", "email": "jane@example.com", "message": "Hello!"}, "files": null, "ip_address": "203.0.113.42", "country": "US", "device": {"device_type": "desktop", "browser": "Chrome 145", "os": "Windows 10"}, "is_spam": false, "spam_flags": null, "referrer_page": "https://example.com/pricing", "created_at": "2026-03-23T11:02:05Z" } ], "total": 42, "page": 1, "per_page": 25 } ``` ### Export submissions ``` GET /api/forms/{form_id}/submissions/export?format=csv ``` Formats: csv, json, xlsx (xlsx requires Pro+) ### Toggle spam flag (Pro+) ``` PATCH /api/forms/{form_id}/submissions/{id}/spam ``` ### Delete submission (Pro+) ``` DELETE /api/forms/{form_id}/submissions/{id} ``` ### Download file ``` GET /api/forms/{form_id}/submissions/{id}/files/{stored_name} ``` ### Dashboard stats ``` GET /api/forms/stats ``` Returns: total_forms, total_submissions, submissions_today, submissions_this_month, spam_count, storage_used_mb, storage_limit_mb, submissions_limit, forms_limit, plan, recent_submissions, top_forms. --- ## Webhooks (Pro+) When a form receives a submission, FormBlade sends a POST request to your webhook URL with a signed JSON payload. ### Payload ```json { "event": "submission.created", "form_id": "uuid", "form_name": "Contact Form", "endpoint_id": "contact", "submission_id": "uuid", "created_at": "2026-03-26T14:30:00Z", "data": { "name": "Jane Doe", "email": "jane@example.com", "message": "Hello!" }, "files": null, "ip_address": "203.0.113.42", "country": "US", "device": {"device_type": "desktop", "browser": "Chrome 145", "os": "Windows 10"} } ``` ### Headers - Content-Type: application/json - User-Agent: FormBlade-Webhook/1.0 - X-FormBlade-Event: submission.created - X-FormBlade-Delivery: unique-delivery-id - X-FormBlade-Signature: sha256=hex-digest (if signing secret set) ### Verify signature (Node.js) ```javascript const crypto = require('crypto'); function verify(body, signature, secret) { const expected = crypto.createHmac('sha256', secret).update(body).digest('hex'); return signature === `sha256=${expected}`; } ``` ### Verify signature (Python) ```python import hmac, hashlib def verify(payload_bytes, signature, secret): expected = hmac.new(secret.encode(), payload_bytes, hashlib.sha256).hexdigest() return hmac.compare_digest(f"sha256={expected}", signature) ``` --- ## Notifications Submissions trigger notifications on all configured channels: - Email — to the notify_email address - Telegram — via bot token + chat ID - Slack — via Incoming Webhook URL (Block Kit format) - Discord — via webhook URL (rich embed) - Viber — via bot token + receiver ID (plain text) - Microsoft Teams — via Incoming Webhook URL (Adaptive Card) Spam-flagged submissions do NOT trigger any notifications. ### Monthly integration limits - Personal (free): 50 messages/month - Pro: 3,000 messages/month - Business: unlimited --- ## Data Integrations (Pro+) Native integrations push submission data to third-party services. Configure via dashboard Integrations page or API. - Google Sheets — append row to a spreadsheet (requires Google OAuth connection) - Brevo Contacts — create/update CRM contacts - Notion — insert row into a database (API key + database ID) - Airtable — add record to a base (API key + base ID + table name) - Trello — create card on a board (API key + token + list ID) - GitHub Issues — create issue from submission (personal access token + repo) - Mailchimp — subscribe to audience (API key + audience ID) - Freshdesk — create support ticket (API key + domain) - Zendesk — create support ticket (API token + email + subdomain) Configure via: POST /api/forms/{form_id}/integration/{provider}/configure Test via: POST /api/forms/{form_id}/integration/{provider}/test Providers: notion, airtable, trello, github, mailchimp, freshdesk, zendesk Google Sheets and Brevo Contacts use dedicated endpoints instead: POST /api/forms/{form_id}/sheets/configure and POST /api/forms/{form_id}/brevo-contacts/configure ## Email Features - Email blocklist (Pro+): Block email patterns. blocked_emails field on form, supports wildcards (*@spam.com). - Conditional email routing (Pro+): Route notifications to different emails based on field values. email_routing_rules: [{field, operator, value, email}]. Operators: equals, contains, starts_with, ends_with. - Weekly digest: Monday summary email with submission counts per form. Enable per form with weekly_digest: true. ## Spam Protection Built-in layers (all free): - FormShield — automated bot protection combining honeypot field (_fb_hp) and JS verification (_fb_js) - Math challenge — simple math question - Email blocklist (Pro+) — block patterns like *@spam.com Captcha providers: - hCaptcha (free on all plans) - reCAPTCHA v2, v3 (Pro+) - Cloudflare Turnstile (Pro+) - GeeTest v4 (Pro+) --- ## Form Fields Array The form_fields array defines the hosted form layout: ```json [ {"type": "heading", "name": "heading", "label": "Contact us"}, {"type": "text", "name": "name", "label": "Name", "placeholder": "Your name", "required": true}, {"type": "email", "name": "email", "label": "Email", "placeholder": "you@example.com", "required": true}, {"type": "textarea", "name": "message", "label": "Message", "rows": 4, "required": true}, {"type": "select", "name": "priority", "label": "Priority", "options": ["Low", "Medium", "High"]}, {"type": "file", "name": "resume", "label": "Resume"}, {"type": "submit", "name": "", "label": "Send message"} ] ``` Field types: heading, text, email, textarea, select, checkbox, radio, date, phone, number, url, file, separator, submit. --- ## Pricing - Personal: Free forever — 300 subs/mo, 10 forms, email + Telegram + Slack/Discord/Viber/Teams (50/mo) - Pro: $14/mo or $12/mo yearly — 3,000 subs/mo, 100 forms, webhooks, auto-responder, whitelabel - Business: $49/mo or $39/mo yearly — 50,000 subs/mo, unlimited integrations, domain restrictions, 10 team members ## Platform Support Works with: WordPress, Wix, Squarespace, Webflow, Shopify, React, Next.js, Vue, Angular, static HTML, any website. ## Code Examples Full examples for React, Next.js, HTML, AJAX, and more: https://github.com/znxltd/formblade-examples ## Machine-readable resources - OpenAPI 3 spec: https://formblade.com/api/openapi.json - Sitemap: https://formblade.com/sitemap.xml - Robots.txt: https://formblade.com/robots.txt - Blog RSS feed: https://formblade.com/blog/feed.xml - LLM short summary: https://formblade.com/llms.txt - LLM full reference (this file): https://formblade.com/llms-full.txt