# FormsReach Documentation (full) Source: https://formsreach.com/docs/ Generated for agents. Prefer per-page .md URLs for targeted retrieval. --- ## Section: Introduction # Introduction FormsReach is a form backend API for websites. Start with a free account, paste HTML, and deliver submissions by email, WhatsApp, and more. FormsReach is a **contact form API** and form backend. Visitors submit a normal form on your site. You receive the enquiry where you already work - email, WhatsApp, Telegram, Discord, webhooks, or Google Sheets. You do not need your own server or backend code to accept contact form submissions. ## What you get - A public **submit endpoint** per form (authenticated with your form `api_key`) - Delivery **channels**: Email, WhatsApp (Meta Cloud API), Telegram, Discord, Webhooks, Google Sheets - Spam protection (honeypot + time trap), [domain allowlists](/docs/submit-api/domains/), and [custom redirects](/docs/submit-api/redirect/) - Dashboard for [submissions](/docs/dashboard/submissions/), analytics, [workflow rules](/docs/dashboard/workflow-rules/), and billing credits - Stack guides for [HTML](/docs/frameworks/html/), [JavaScript](/docs/frameworks/javascript/), [React](/docs/frameworks/react/), [Vue](/docs/frameworks/vue/), and more Usage for accepted submissions, email, and WhatsApp is metered from a shared monthly credit pool. See [pricing](https://formsreach.com/pricing) for current plans and credit costs. ## How it works 1. Create a form in the [dashboard](https://app.formsreach.com) and copy your API key. 2. Point your form at `https://api.formsreach.com/submit` (HTML POST, JSON, or SDK). 3. Configure channels (start with email if you want notifications). 4. Submissions are stored and dispatched according to your settings. ## Start here **New to FormsReach?** Follow the HTML path - no Node or npm required. 1. [Quickstart](/docs/getting-started/quickstart/) - first working form in minutes 2. [Create a form and API key](/docs/getting-started/create-form-api-key/) - what the key is and where to find it 3. [Your first submission](/docs/getting-started/first-submission/) - how to confirm success 4. [Test your form](/docs/getting-started/test-your-form/) - local and staging checks 5. [Next steps](/docs/getting-started/next-steps/) - email, domains, spam, WhatsApp, frameworks ## Other paths | If you want… | Go to | |---|---| | Your stack (HTML, React, Next, WordPress, …) | [Frameworks overview](/docs/frameworks/overview/) | | Delivery setup (email, WhatsApp, …) | [Channels overview](/docs/channels/overview/) | | Field names, JSON, file uploads | [Submit API overview](/docs/submit-api/overview/) | | Fix a broken form | [Troubleshooting](/docs/help/troubleshooting/) | ## Prerequisites - A free [FormsReach account](https://app.formsreach.com) - Any page where you can paste HTML (static host, CMS, or a local HTML file for testing) --- ## Section: Getting started # Quickstart Create a FormsReach form, paste an HTML snippet, submit a test, and confirm the row in the dashboard in minutes. ## What you will achieve A working contact form that stores submissions in FormsReach - and can email you once you enable the email channel - in under about ten minutes. You only need to paste HTML. No backend, npm, or SDK for this path. ## Prerequisites - A [FormsReach account](https://app.formsreach.com) (free plan is enough to start) - Any page where you can paste HTML (static site, CMS block, CodePen, or a local `.html` file) ## Steps ### 1. Sign in and create a form 1. Open [app.formsreach.com](https://app.formsreach.com) and sign in (or create an account). 2. Create a new form from the dashboard. 3. Open that form so you can see its overview and integration snippets. ### 2. Copy your API key 1. On the form overview or integration panel, copy the form **API key**. 2. Keep it handy for the next step. The key is a public form identifier. It will appear in your page HTML - that is expected. Protect production traffic with a [domain allowlist](/docs/submit-api/domains/) and [spam protection](/docs/submit-api/spam/) after your first test works. More detail: [Create a form and API key](/docs/getting-started/create-form-api-key/). ### 3. Paste a plain HTML form Add this form to your page. Replace `YOUR_ACCESS_KEY` with your real API key. ```html
``` Requirements: - `action` must be `https://api.formsreach.com/submit` - `method` must be `POST` - Hidden input `name="api_key"` must match this form's key - Each field you care about needs a `name` attribute ### 4. Submit a test 1. Open the page in a browser. 2. Fill name, email, and message with obvious test values (for example `Test User`). 3. Click **Submit Form**. You should land on the default thank-you experience, or your [custom redirect](/docs/submit-api/redirect/) if you already configured one. ### 5. Confirm in the dashboard 1. Return to [app.formsreach.com](https://app.formsreach.com). 2. Open the **same** form you used for the key. 3. Open **Submissions**. ## Verify You should see: - A new submission row with the test field values - No need for email or WhatsApp yet - a stored row means the submit path works If the row is missing, continue to [Your first submission](/docs/getting-started/first-submission/) and [Troubleshooting](/docs/help/troubleshooting/). ## Common failures | Symptom | What to check | |---|---| | Nothing in Submissions | Wrong `api_key`, or you are viewing a different form | | Error about missing API key | Hidden input `name="api_key"` missing or misspelled | | Domain denied | Host not on the form [domain allowlist](/docs/submit-api/domains/) - add your site host (and `www` if used) | | Credits / plan error | Monthly credits exhausted - see [pricing](https://formsreach.com/pricing) and billing in the app | | Network error in the browser | Confirm the form `action` URL is exactly `https://api.formsreach.com/submit` | ## Next - [Your first submission](/docs/getting-started/first-submission/) - how to read success and errors - [Test your form](/docs/getting-started/test-your-form/) - local, staging, and production checks - [Email channel](/docs/channels/email/) - get notified when someone submits - Optional later: [programmatic submit](/docs/submit-api/json/) or the [JavaScript](/docs/frameworks/javascript/) guide if you need AJAX-style submit without a full page reload # Create a form and API key What a FormsReach form is, where to copy the public API key, how to rotate it, and when to use multiple forms. ## What you will achieve Understand what a **form** is in FormsReach, copy the correct **API key**, and know how to keep that key safer in production. ## Prerequisites - A [FormsReach account](https://app.formsreach.com) ## What a form is A **form** is one FormsReach endpoint configuration you own. Each form has: - A unique public **API key** used on every submit - Optional [allowed domains](/docs/submit-api/domains/) - Optional [redirect URL](/docs/submit-api/redirect/) after success - Channel settings (email, WhatsApp, Telegram, Discord, webhooks, Google Sheets) - [Workflow rules](/docs/dashboard/workflow-rules/) and [submission history](/docs/dashboard/submissions/) Create a new form when you need a separate endpoint, separate channels, or separate submission history (for example one form per client site). ## Steps ### 1. Create a form 1. Sign in at [app.formsreach.com](https://app.formsreach.com). 2. Create a form from the dashboard home or form switcher. 3. Open the new form so you see its overview. ### 2. Find the API key Look for the key on: - The form overview - The integration / snippet panel (HTML, JavaScript, React, Vue snippets are pre-filled with this form's key) Copy the key exactly. You will paste it into `api_key` (HTML) or your SDK init config. ### 3. Use the key on your site For the HTML path, the key goes in a hidden field: ```html ``` Full paste example: [Quickstart](/docs/getting-started/quickstart/). ## How to think about the API key The API key is a **public form identifier** (similar to a publishable form ID). Anyone who can view your site HTML can see it. That is expected for browser-based contact forms. Treat it like a publishable key, not a secret server password: - Turn on a [domain allowlist](/docs/submit-api/domains/) for production hosts - Add [spam protection](/docs/submit-api/spam/) so bots are less likely to burn credits - Prefer separate forms for separate public sites so you can disable or rotate one without affecting others ## Rotate or replace a key If a key is embedded somewhere you no longer control (old site, public gist, abandoned deploy): 1. Open the form in the dashboard. 2. Use the product control to **rotate** or regenerate the API key (wording may be Rotate / Regenerate in the UI). 3. Update every live form embed and snippet with the new key. 4. Re-test with [Test your form](/docs/getting-started/test-your-form/). Until you update embeds, old HTML still posts with the previous key and will fail once that key is invalidated. ## Multiple forms Use more than one form when: - You run several websites or brands - Different teams need different WhatsApp or email destinations - You want separate analytics or submission lists Do not reuse one key across unrelated production sites if you can avoid it - domain allowlists and channel settings are per form. ## Verify You should be able to: - Point to one form in the dashboard - Copy one API key from that form - Paste it into the Quickstart HTML and get a [first submission](/docs/getting-started/first-submission/) ## Common failures | Symptom | What to check | |---|---| | Snippets work in docs but not on your site | You still have `YOUR_ACCESS_KEY` placeholder text | | Submissions go to the wrong form | Key copied from a different form than the one you are viewing | | Old site still submits after rotate | Deploy still has the previous key | ## Next - [Quickstart](/docs/getting-started/quickstart/) - paste HTML and submit - [Your first submission](/docs/getting-started/first-submission/) - confirm the dashboard row - [Submit API overview](/docs/submit-api/overview/) - endpoint reference # Your first submission Confirm a FormsReach submit succeeded - dashboard row, accepted vs channel delivery, and common first-time errors. ## What you will achieve Know what "success" means after you submit, where to read the data, and how to tell a storage success from a channel delivery issue. ## Prerequisites - You completed the [Quickstart](/docs/getting-started/quickstart/) (or equivalent HTML/JSON submit) - You can open the form in [app.formsreach.com](https://app.formsreach.com) ## Success checklist After you submit, check these in order: 1. **Browser request** - the browser completed a POST to `https://api.formsreach.com/submit` without a network failure (DevTools → Network). 2. **Dashboard row** - a new row appears under that form's **Submissions** list with your field values. 3. **Channels (optional)** - if email, WhatsApp, or other channels are enabled and credits remain, delivery runs after the submission is accepted. A stored row is enough to prove the form path works. You can enable channels after the first successful store. ## Accepted vs delivered | Stage | Meaning | |---|---| | **Accepted** | FormsReach validated the request, stored the submission, and spent submission credits when applicable | | **Delivered** | A channel job succeeded (email sent, WhatsApp message sent, webhook 2xx, and so on) | You can have an accepted submission with a failed or skipped channel (channel misconfigured, destination not verified, or not enough credits for that channel). Fix channels without changing a working HTML form. ## Where to read the submission 1. Open the form in the dashboard. 2. Open **Submissions**. 3. Open the latest row. 4. Confirm `name`, `email`, `message` (or your custom field names) match what you typed. Field names come from your input `name` attributes (HTML) or JSON keys. ## What the browser may show ### Classic HTML form POST Depending on Accept headers and [redirect settings](/docs/submit-api/redirect/), the browser may: - Redirect to your thank-you URL, or - Show a FormsReach success page Either outcome can still mean success if the Submissions row exists. ### JSON clients JSON clients receive a unified envelope on success, for example: ```json { "data": { "id": "…", "ok": true }, "status": "success", "meta": { "requestId": "req_…" } } ``` Failures use `"status": "failure"` with a problem object (`code`, `title`, `detail`). Keep `meta.requestId` if you contact support. Programmatic clients: [JS SDK submit](/docs/submit-api/json/). Field reference: [Submit API overview](/docs/submit-api/overview/). ## Verify You should be able to answer yes to: - I submitted test data I recognize - I see that data on the correct form's Submissions list - I know whether channels are enabled yet (if not, missing email/WhatsApp is expected) ## Common first-time failures | Symptom | Check | |---|---| | Nothing in dashboard | Wrong `api_key`; form inactive; viewing a different form; filtering spam-only views | | 422 / missing API key | Hidden input `name="api_key"` missing | | Domain denied | Origin/referrer host not on the [allowlist](/docs/submit-api/domains/) | | 402 / credits | Plan credits exhausted - see billing in the app and [pricing](https://formsreach.com/pricing) | | CORS on `fetch` | Prefer classic form POST or the official SDK; see [Troubleshooting](/docs/help/troubleshooting/) | | Row exists, no email/WhatsApp | Channel not enabled, destination not verified, or plan gate (WhatsApp is Pro/Agency) | ## Next - [Test your form](/docs/getting-started/test-your-form/) - repeatable checks before go-live - [Next steps](/docs/getting-started/next-steps/) - email, domains, spam, WhatsApp - [Channels overview](/docs/channels/overview/) - turn on delivery - [Troubleshooting](/docs/help/troubleshooting/) - if the row never appears # Test your form Test a FormsReach form before go-live - local HTML, staging hosts, domain allowlist, and dashboard verification. ## What you will achieve A short checklist to prove submit works before you put the form on a production page - and again after every domain or key change. ## Prerequisites - A form and API key ([Create a form and API key](/docs/getting-started/create-form-api-key/)) - The [Quickstart](/docs/getting-started/quickstart/) HTML (or equivalent) on a page you control ## Why test - Catch wrong keys and missing `name` attributes before real visitors submit - Confirm [domain allowlist](/docs/submit-api/domains/) includes every host you actually use - Avoid noisy WhatsApp traffic while you are still wiring the form ## Steps ### 1. Start with dashboard-only success 1. Disable or skip WhatsApp until the HTML path works (WhatsApp is available on Pro/Agency and costs credits per send). 2. Email is optional for the first tests - a **Submissions** row is the source of truth. 3. Submit once with unique text in `message` (for example `test-2026-07-28-a`). ### 2. Use a simple host you control Good early hosts: - A static HTML file on a staging URL - Your site's preview deploy - A CMS draft page that still posts from a real browser origin Open the page over the same kind of URL you will use later (prefer HTTPS for staging and production). ### 3. Watch the network request 1. Open browser DevTools → **Network**. 2. Submit the form. 3. Select the request to `https://api.formsreach.com/submit`. 4. Confirm method `POST` and a non-network-error response. If the request never leaves the browser, fix the form `action` or page JavaScript before debugging FormsReach. ### 4. Confirm the Submissions row 1. Open the form in [app.formsreach.com](https://app.formsreach.com). 2. Open **Submissions**. 3. Find the unique test message. No row means the submit was not accepted (or you are on the wrong form). Use [Your first submission](/docs/getting-started/first-submission/). ### 5. Align domain allowlist with real hosts Your `api_key` is public. When the allowlist is enabled, FormsReach checks the request Origin/Referer host against hosts you configured for that form. Before go-live: 1. List every production host (include both apex and `www` if both serve the form). 2. List every preview or staging host you intentionally test from. 3. Submit again from each host you listed. 4. Prefer HTTPS sites. If a host is missing, you get a domain denied style error. Details: [Domain allowlist](/docs/submit-api/domains/). ### 6. Keep spam fields empty for humans If you added [honeypot / time trap](/docs/submit-api/spam/) fields: - Leave the honeypot empty (real users never see it) - Do not bot-fill spam fields in automated tests unless you intend to create a spam classification ### 7. Add channels only after store works 1. Enable [Email](/docs/channels/email/) and send a test submission. 2. On Pro/Agency, add [WhatsApp](/docs/channels/whatsapp/) and verify destination numbers before relying on it. 3. Treat channel delivery as a second checklist after the Submissions row exists. ## Verify matrix | Result | Meaning | What to do | |---|---|---| | Row in Submissions | Submit path accepted | Safe to harden domains/spam and enable channels | | HTTP error, no row | Rejected or failed request | Read error body; check key, domain, credits | | Row exists, no email/WhatsApp | Channel not delivering | Fix channel config and credits - form HTML may be fine | | Works on staging, fails on production | Host allowlist gap | Add production host (and `www` if needed) | ## Common failures | Symptom | What to check | |---|---| | Works in dashboard preview but not on site | Different host - add site host to allowlist | | Intermittent domain errors | Some pages on `www`, some on apex - allow both | | Duplicate test noise on WhatsApp | Test with dashboard + email first | | Spam-looking rows | Honeypot filled or automated fill too fast - see [Spam](/docs/submit-api/spam/) | ## Next - [Next steps](/docs/getting-started/next-steps/) - production checklist after a green test - [Domain allowlist](/docs/submit-api/domains/) - [Spam and honeypot](/docs/submit-api/spam/) - [Email channel](/docs/channels/email/) # Next steps After your first FormsReach submission - enable email, lock domains, add spam protection, WhatsApp, rules, and frameworks. ## What you will achieve A clear order of upgrades after your first successful test submission - without reading the entire docs site at once. ## Prerequisites - A green test: submission row in the dashboard ([Test your form](/docs/getting-started/test-your-form/)) ## Recommended order Work top to bottom. Stop when the form meets your production needs. ### 1. Enable email notifications Turn on the [Email channel](/docs/channels/email/) so you get a message for each enquiry. Verify recipient addresses in the dashboard when the product asks you to. Email uses credits per notification. See [pricing](https://formsreach.com/pricing). ### 2. Lock production domains Add every real host to the [domain allowlist](/docs/submit-api/domains/) (apex and `www` if both are used). Re-test from the production URL. ### 3. Add spam protection Add honeypot and time-trap fields from [Spam and honeypot](/docs/submit-api/spam/) so bots are less likely to fill Submissions or burn credits. ### 4. Set a thank-you redirect Send visitors to your own page after success with [Redirect and thank-you](/docs/submit-api/redirect/). ### 5. Add WhatsApp (Pro / Agency) If your plan includes WhatsApp, configure [WhatsApp](/docs/channels/whatsapp/), verify destination numbers, and send one test. Visitors do not need WhatsApp to submit - only you receive the notification. WhatsApp is not on Free or Starter. Plan details: [pricing](https://formsreach.com/pricing). ### 6. Route with workflow rules when needed Use [Workflow rules](/docs/dashboard/workflow-rules/) when different answers should hit different channels or destinations (for example city → different WhatsApp number). ### 7. Switch stack package or JSON if the UI needs it Stay on HTML POST if full page reload is fine. If you need in-page success states without reload: - [JavaScript](/docs/frameworks/javascript/) - [React](/docs/frameworks/react/) - [Vue](/docs/frameworks/vue/) - [Programmatic submit](/docs/submit-api/json/) ### 8. Watch submissions and usage - Review history in [Submissions](/docs/dashboard/submissions/) - Watch credit usage in the app billing UI and [pricing](https://formsreach.com/pricing) (unused plan credits do not roll over; delivery stops at 0 credits) ## Verify you are production-ready You should be able to say yes to: - [ ] Test submission appears for the production host - [ ] Domain allowlist includes production hosts - [ ] Spam fields are present and empty for real users - [ ] At least one notification channel is verified (email and/or WhatsApp) - [ ] Thank-you experience matches what you want visitors to see - [ ] You know where to open Submissions when something looks wrong ## Common failures after go-live | Symptom | Likely gap | |---|---| | Works on staging only | Production host missing from allowlist | | Sudden bot traffic | Spam fields not added | | No owner notification | Channel off or unverified destination | | Accept then silence on WhatsApp | Plan gate or credits - see WhatsApp docs and pricing | ## Next - [Channels overview](/docs/channels/overview/) - [Submit API overview](/docs/submit-api/overview/) - [Troubleshooting](/docs/help/troubleshooting/) - [Introduction](/docs/) - back to the docs hub --- ## Section: Submit API # Submit API overview Public FormsReach submit endpoint - URL, authentication via api_key, content types, and response shape. ## Endpoint ``` POST https://api.formsreach.com/submit ``` This host rewrites to the app’s public submit route (`/api/v1/submit`). Use the public URL above in production snippets. ## Authentication Include your form API key as field **`api_key`** in the body (JSON, urlencoded, or multipart). No Bearer token is required for public website forms. ## Content types | Content-Type | Use | |---|---| | `application/x-www-form-urlencoded` | Classic HTML forms | | `multipart/form-data` | HTML forms with [file uploads](/docs/submit-api/file-uploads/) | | `application/json` | SPAs, mobile, server-to-server | ## Field rules - **`api_key`** - required - Any other field names are accepted as submission data (subject to max field limits) - Reserved spam fields: `_gotcha`, `_ts` - see [Spam protection](/docs/submit-api/spam/) - File fields use multipart only ## Success and errors Successful accepts return success envelope (JSON) or redirect/HTML for browsers. Typical problem codes include validation failures, inactive form, domain denied, rate limits, and insufficient credits. For the full machine-readable API surface (including authenticated dashboard routes), use the [OpenAPI explorer](https://app.formsreach.com/api/docs). ## Guides in this section - [HTML form POST](/docs/submit-api/html/) - [Programmatic submit (JS SDK)](/docs/submit-api/json/) - [File uploads](/docs/submit-api/file-uploads/) - [Redirect and thank-you](/docs/submit-api/redirect/) - [Domain allowlist](/docs/submit-api/domains/) - [Spam and honeypot](/docs/submit-api/spam/) # HTML form POST Point a classic HTML contact form at FormsReach with method POST and your api_key - no backend required. ## Minimal form ```html
``` ## Requirements - `method="POST"` - `action` = public submit URL - Hidden `api_key` - Every field you care about needs a `name` attribute ## Tips - Prefer **HTTPS** on your site so browsers do not warn on submit. - Use full-page POST for simplest CORS-free behavior on static hosts. - For in-page success states without reload, use the [JavaScript guide](/docs/frameworks/javascript/) or [programmatic submit](/docs/submit-api/json/). ## Related - [Spam protection](/docs/submit-api/spam/) - [Custom redirect](/docs/submit-api/redirect/) - [Domain allowlist](/docs/submit-api/domains/) # Programmatic Submission Submit form fields to FormsReach with the official @formsreach/js SDK - submitForm, npm, and CDN - without hand-written fetch. ## What you will achieve Send submission data from JavaScript (SPA, custom UI, or server-side Node) using the official SDK instead of building your own `fetch` to the submit endpoint. ## Prerequisites - A form and API key - [Create a form and API key](/docs/getting-started/create-form-api-key/) - Node/npm for the package, or any page for the CDN script ## Install ```bash npm install @formsreach/js ``` Package details: [GitHub SDK](https://github.com/formsreach/sdk/tree/main/packages/js). ## Programmatic submit with `submitForm` ```js import { submitForm } from "@formsreach/js"; const { id, redirectUrl } = await submitForm({ apiKey: "YOUR_ACCESS_KEY", data: { name: "Ada Lovelace", email: "ada@example.com", message: "Hello from the JS SDK", }, }); console.log(id, redirectUrl); ``` - `apiKey` - your form public API key - `data` - field map (same names you would use as HTML `name` attributes) - Return value includes submission `id` and optional `redirectUrl` when a [custom redirect](/docs/submit-api/redirect/) is configured ### Error handling Wrap `submitForm` in `try/catch`. Failures surface status and problem details (validation, domain allowlist, credits, and so on). For a full field reference and response shape, see [Submit API overview](/docs/submit-api/overview/). ## CDN (browser) If you are not using a bundler: ```html ``` Mark classic forms with `data-formsreach` after `FormsReach.init` if you want automatic intercept - see [JavaScript](/docs/frameworks/javascript/). ## When to use HTML instead Prefer a classic [HTML form POST](/docs/submit-api/html/) when you do not need SPA-style handling and a full page submit is fine. ## Related - [JavaScript](/docs/frameworks/javascript/) - [React](/docs/frameworks/react/) - [Vue](/docs/frameworks/vue/) - [Submit API overview](/docs/submit-api/overview/) # File uploads Accept file fields on FormsReach forms using multipart/form-data. ## HTML Use `enctype="multipart/form-data"` and `input type="file"`: ```html
``` ## Notes - JSON bodies cannot carry raw file bytes - use multipart for uploads. - Size and type limits apply at the API (oversized payloads return **413**). - Files appear on the submission detail in the dashboard when accepted. ## Related - [HTML form POST](/docs/submit-api/html/) - [Submit API overview](/docs/submit-api/overview/) # Redirect and thank-you Send visitors to your own thank-you URL after a successful FormsReach submission. ## Custom redirect In the dashboard form settings, enable redirect and set a full HTTPS URL (your thank-you page). After a successful browser form POST, FormsReach redirects the visitor to that URL. ## Default experience If redirect is disabled, browsers receive FormsReach’s default success handling (hosted thank-you / HTML success). ## Tips - Redirect applies to successful accepts - validation errors should redisplay your form (use SDK/JSON for in-page errors). - Keep thank-you pages free of the API key in query strings. ## Related - [Quickstart](/docs/getting-started/quickstart/) - [HTML form POST](/docs/submit-api/html/) # Domain allowlist Restrict which website origins can submit to your FormsReach form. ## Why allowlist Your `api_key` is public in HTML. Domain allowlisting reduces abuse from random third-party sites posting to your endpoint. ## How it works Configure allowed hosts in the form settings (dashboard). Submit requests include Origin/Referer host checks against that list (plus platform-allowed hosts for dashboard previews). If the host is not allowed, the API returns a domain denied / required style error. ## Recommendations - In production, list every production domain (and `www` if used) - Include preview domains you intentionally test from - Prefer HTTPS sites ## Related - [Spam protection](/docs/submit-api/spam/) - [Troubleshooting](/docs/help/troubleshooting/) # Spam and honeypot Reduce bot submissions with FormsReach honeypot and time-trap fields. ## Built-in signals FormsReach supports lightweight anti-spam fields recognized by the public submit API: | Field | Purpose | |---|---| | `_gotcha` | Honeypot - must stay empty for humans | | `_ts` | Time trap - timestamp set on page load; too-fast posts are treated as spam | Spam submissions can be recorded separately so they do not flood primary workflows the same way as legitimate leads. ## HTML example ```html
``` ## Also use - [Domain allowlist](/docs/submit-api/domains/) - Dashboard spam tools on individual submissions ## Related - [HTML form POST](/docs/submit-api/html/) --- ## Section: Frameworks # Frameworks overview Install FormsReach on HTML, React, Vue, Next.js, Nuxt, WordPress, and more - pick the guide that matches your stack. ## What you will achieve Find the right how-to for your website stack. Each guide is a step-by-step install with a copy-paste snippet and a verify checklist. Marketing comparison pages live at [/integrations/](/integrations/). **These docs pages are the how-to source of truth.** ## Choose a path | If you build with… | Start here | Pattern | |---|---|---| | Plain HTML / static site | [HTML](/docs/frameworks/html/) | Form POST | | Vanilla JS (CDN) | [JavaScript](/docs/frameworks/javascript/) | `@formsreach/js` | | React | [React](/docs/frameworks/react/) | `@formsreach/react` | | Next.js | [Next.js](/docs/frameworks/nextjs/) | `@formsreach/react` + Client Component | | Vue | [Vue](/docs/frameworks/vue/) | `@formsreach/vue` | | Nuxt | [Nuxt](/docs/frameworks/nuxt/) | `@formsreach/vue` | | WordPress | [WordPress](/docs/frameworks/wordpress/) | HTML in Custom HTML block | More stacks (Astro, Svelte, Webflow, Shopify, and others) ship in later docs waves. Until then, use the closest pattern above or the matching [/integrations/](/integrations/) page. ## Official packages | Package | Install | Guide | |---|---|---| | `@formsreach/js` | npm or CDN | [JavaScript](/docs/frameworks/javascript/) · [Programmatic submit](/docs/submit-api/json/) | | `@formsreach/react` | `npm i @formsreach/react` | [React](/docs/frameworks/react/) · [Next.js](/docs/frameworks/nextjs/) | | `@formsreach/vue` | `npm i @formsreach/vue` | [Vue](/docs/frameworks/vue/) · [Nuxt](/docs/frameworks/nuxt/) | Source: [github.com/formsreach/sdk](https://github.com/formsreach/sdk) CDN for browser drop-in: ``` https://unpkg.com/@formsreach/js/dist/formsreach.min.js ``` ## When to use a package vs plain HTML - **HTML form POST** - simplest path; full page submit is fine - **JS / React / Vue packages** - AJAX submit, loading and error helpers, no full reload ## After the form works 1. [Email channel](/docs/channels/email/) 2. [Domain allowlist](/docs/submit-api/domains/) 3. [Spam protection](/docs/submit-api/spam/) 4. [WhatsApp](/docs/channels/whatsapp/) on Pro / Agency ## Next - New here? [Quickstart](/docs/getting-started/quickstart/) - Pick a guide from the table above # HTML Point a plain HTML contact form at FormsReach with method POST and your API key - no backend required. ## What you will achieve A working contact form on any static page using classic HTML form POST - no npm, no SDK. ## Prerequisites - A [FormsReach form and API key](/docs/getting-started/create-form-api-key/) - A page where you can paste HTML ## Steps ### 1. Create a form and copy the API key Sign in at [app.formsreach.com](https://app.formsreach.com), create a form, and copy the API key. ### 2. Paste the form ```html
``` Replace `YOUR_ACCESS_KEY` with your real key. ### 3. Submit a test Open the page, fill the fields, and submit. ## Verify - A new row appears under the form's **Submissions** in the dashboard - Field values match what you typed ## Common failures | Symptom | Check | |---|---| | Nothing in dashboard | Wrong key or wrong form in the app | | Missing API key error | Hidden input `name="api_key"` missing | | Domain denied | Add your host to the [domain allowlist](/docs/submit-api/domains/) | ## Next - [Test your form](/docs/getting-started/test-your-form/) - [Email channel](/docs/channels/email/) - [JavaScript](/docs/frameworks/javascript/) if you need AJAX without full page reload - Marketing landing: [/integrations/html/](/integrations/html/) # JavaScript Add FormsReach with the @formsreach/js CDN or npm package - data-formsreach forms and programmatic submit. ## What you will achieve A contact form that submits without a full page reload using the official JavaScript SDK. ## Prerequisites - A [FormsReach form and API key](/docs/getting-started/create-form-api-key/) - A page that can load a script (or a bundler for npm) ## Steps ### 1. Drop in the CDN (fastest) ```html
``` `FormsReach.init` sets the default API key. Forms marked with `data-formsreach` are intercepted after init. ### 2. Or install with npm ```bash npm install @formsreach/js ``` Programmatic submit (custom UI): ```js import { submitForm } from "@formsreach/js"; const { id, redirectUrl } = await submitForm({ apiKey: "YOUR_ACCESS_KEY", data: { name: "Ada Lovelace", email: "ada@example.com", message: "Hello from JS", }, }); ``` More detail: [Programmatic submit](/docs/submit-api/json/). ## Verify - Submit once from the browser - Confirm the row in **Submissions** for that form ## Common failures | Symptom | Check | |---|---| | Form does a full navigation | Missing `data-formsreach` or `init` not called | | Empty payload | Inputs need `name` attributes | | Script 404 | CDN URL must be `formsreach.min.js` as above | ## Next - [React](/docs/frameworks/react/) or [Vue](/docs/frameworks/vue/) for framework apps - [Email channel](/docs/channels/email/) - Marketing landing: [/integrations/javascript/](/integrations/javascript/) # React Add a React contact form with useFormsReach from @formsreach/react - no custom API route required. ## What you will achieve A React contact form that posts to FormsReach from the browser using the official hook. ## Prerequisites - A [FormsReach form and API key](/docs/getting-started/create-form-api-key/) - A React app that can install npm packages ## Steps ### 1. Install ```bash npm install @formsreach/react ``` ### 2. Use the hook ```tsx import { useFormsReach } from "@formsreach/react"; export function ContactForm() { const { submit, submitting, error } = useFormsReach("YOUR_ACCESS_KEY"); return (
``` Replace `YOUR_ACCESS_KEY` with your real key. You can also place the same markup in a child theme template or a reusable block pattern. ### 3. Publish and test Publish the page, submit once from the live (or preview) URL, open **Submissions**. ## Verify - The form tags and `api_key` field are still present when you view page source - Dashboard shows the test row - Theme CSS can style the form (snippet is unstyled by design) ## Common failures | Symptom | Check | |---|---| | Form tags removed | Use **Custom HTML**, not a text paragraph; some builders strip raw HTML | | Missing api_key | Editor stripped the hidden input - re-paste and recheck source | | Caching oddities | Classic form POST works with most caches; avoid minifiers that strip form attributes | | Domain denied | Add your WordPress host (and `www` if used) to the [allowlist](/docs/submit-api/domains/) | ## Next - [Test your form](/docs/getting-started/test-your-form/) - [Email channel](/docs/channels/email/) - [HTML guide](/docs/frameworks/html/) for non-WordPress static sites - Marketing landing: [/integrations/wordpress/](/integrations/wordpress/) --- ## Section: Channels # Channels overview Deliver FormsReach submissions by email, WhatsApp, Telegram, Discord, webhooks, or Google Sheets from one form. ## What is a channel? A **channel** is a delivery destination attached to a form. After a submission is accepted, FormsReach dispatches to enabled channels (subject to workflow rules and credits). ## Available channels | Channel | Summary | Credits (typical) | |---|---|---| | [Email](/docs/channels/email/) | Notify recipients by email | 1 per notification (plan rules apply) | | [WhatsApp](/docs/channels/whatsapp/) | Official Meta Cloud API to your numbers | Country-band costs on Pro/Agency | | [Telegram](/docs/channels/telegram/) | Platform bot → your private chats | 1 per successful chat send | | [Discord](/docs/channels/discord/) | Incoming webhook embed | 1 per successful send | | [Webhooks](/docs/channels/webhooks/) | HTTP POST to your URL | 0 | | [Google Sheets](/docs/channels/google-sheets/) | Append rows to a spreadsheet | Plan rules; free on supported plans | Exact credit pricing: [formsreach.com/pricing](https://formsreach.com/pricing). ## Configuration Open a form in the dashboard → channel section → enable and configure each destination. Test actions where available (for example Discord test embeds) may not consume credits. ## Multi-channel You can enable several channels on the same form. Each successful billable action debits the shared monthly pool independently. ## Related - [Workflow rules](/docs/dashboard/workflow-rules/) - [Usage and credits](https://formsreach.com/pricing) # WhatsApp Receive website form submissions on WhatsApp via the official Meta WhatsApp Business API. ## Overview WhatsApp delivery sends formatted submission notifications to phone numbers you verify in the dashboard. Visitors do **not** need WhatsApp to submit - only you receive the message. FormsReach uses the **official Meta WhatsApp Business API** (not unofficial clients). ## Setup (dashboard) 1. Open your form → WhatsApp channel. 2. Add and verify destination numbers (OTP flow as shown in the app). 3. Ensure your plan includes WhatsApp (Pro / Agency; Free does not include WhatsApp delivery). 4. Submit a test form and confirm the WhatsApp message. ## Credits WhatsApp sends consume credits by **country band** per destination number. See [pricing](https://formsreach.com/pricing) for current Low / Standard / High / Default bands. ## Tips - Keep numbers verified and active - Pair with [Email](/docs/channels/email/) if you want an inbox archive - Use [workflow rules](/docs/dashboard/workflow-rules/) to route by field values when needed ## Related - [Channels overview](/docs/channels/overview/) - [Quickstart](/docs/getting-started/quickstart/) # Email Email notification channel for FormsReach form submissions, including recipient verification where required. ## Overview Email delivers submission notifications to addresses you configure on the form. Free plans include email delivery metered by credits. ## Setup 1. Form → Email channel in the dashboard. 2. Add recipients. Some flows require **OTP verification** before a recipient is active. 3. Submit a test and check the inbox (and spam folder on first send). ## Credits Email notifications typically cost **1 credit** per send when billed - confirm on [pricing](https://formsreach.com/pricing). ## Related - [Channels overview](/docs/channels/overview/) - [Spam protection](/docs/submit-api/spam/) # Telegram Get FormsReach submission alerts in Telegram private chats via the platform bot. ## Overview Telegram delivery uses a **platform-operated bot**. You generate a deep link, open it in Telegram, then **confirm** the chat in the FormsReach dashboard. Verified private chats receive HTML-formatted submission dumps with a link back to the dashboard. ## Setup 1. Form → Telegram channel → create link. 2. Open `t.me/?start=` on your phone/desktop. 3. In the dashboard, confirm the pending chat. 4. Submit a test form. ## Limits and credits - Up to **5** chats per form (pending + verified) - **1 credit per chat** after a successful `sendMessage` - Private chats only ## Related - [Channels overview](/docs/channels/overview/) - [Discord](/docs/channels/discord/) # Discord Post FormsReach submissions to Discord with an Incoming Webhook and rich embeds. ## Overview Paste a Discord **Incoming Webhook** URL for the channel you want. FormsReach POSTs a rich embed on each accepted submission. ## Setup 1. In Discord: channel settings → Integrations → Webhooks → New Webhook → copy URL. 2. In FormsReach: form → Discord channel → paste URL and save. 3. Use **Send test** (free) to verify the embed. 4. Submit a real form test. ## Security The webhook URL is **write-only** after save (not returned again). Treat it like a secret. ## Credits **1 credit** per successful live send after Discord returns 2xx. Test posts do not consume credits. ## Related - [Webhooks](/docs/channels/webhooks/) - [Channels overview](/docs/channels/overview/) # Webhooks Receive an HTTP POST to your URL for every accepted FormsReach submission - zero credit cost. ## Overview Webhooks push submission payloads to your HTTPS endpoint so you can sync CRMs, automation tools, or custom backends. ## Setup 1. Form → Webhooks channel. 2. Enter your HTTPS endpoint URL. 3. Submit a test and verify your server receives the POST. ## Credits Webhooks cost **0 credits**. ## Implementation tips - Respond quickly with 2xx; do heavy work asynchronously - Verify authenticity using any signing/secret options exposed in the dashboard if enabled - Log non-2xx responses for retry design on your side ## Related - [Discord](/docs/channels/discord/) (specialized webhook embed) - [Programmatic submit (JS SDK)](/docs/submit-api/json/) # Google Sheets Append FormsReach submissions as rows in a Google Spreadsheet via account Google connection. ## Overview Connect a Google account once, then enable Google Sheets on a form. FormsReach auto-creates a spreadsheet named like `{Form Name} - Submissions` and appends rows for new submissions (`Submitted At`, `Submission ID`, plus dynamic field columns). ## Setup 1. In the form channel dialog, connect Google when prompted (OAuth / link identity). 2. Enable the Google Sheets channel for the form. 3. Submit a test and open the created spreadsheet from the dashboard UI. ## Notes - Connection is **per user account** (not per form OAuth dance every time) - Spreadsheet is auto-created in v1 (picker selection is a follow-up) - Failures are logged; treat Sheets as best-effort export alongside the dashboard source of truth ## Related - [Channels overview](/docs/channels/overview/) - [Submissions](/docs/dashboard/submissions/) --- ## Section: Dashboard # Submissions View, search, and inspect form submissions in the FormsReach dashboard. ## Where to find them Open a form → **Submissions**. Each accepted submission stores field data, timestamps, and related delivery context. ## What you can do - Search and filter recent submissions - Open detail for full field values and files - Use spam tools when a row looks automated - Jump from channel notifications (Telegram/Discord embeds include dashboard links when available) ## Source of truth The dashboard holds the canonical submission record. Channels (email, WhatsApp, Sheets, …) are delivery side-effects. ## Related - [Your first submission](/docs/getting-started/first-submission/) - [Workflow rules](/docs/dashboard/workflow-rules/) # Workflow rules Overview of FormsReach workflow rules for conditional routing and processing of submissions. ## Overview **Workflow rules** let you express conditions on submission fields and control how channels fire (for example, route certain cities to different WhatsApp numbers). Configure rules in the form’s rules UI in the dashboard. ## Mental model 1. Submission accepted and stored 2. Rules evaluated against field data 3. Matching channel actions dispatch Exact operators and actions are defined in the product UI - use the dashboard as the live reference while iterating. ## Related - [Channels overview](/docs/channels/overview/) - [WhatsApp](/docs/channels/whatsapp/) --- ## Section: Help # Troubleshooting Fix common FormsReach integration issues - missing submissions, domain errors, CORS, and channel delivery. ## No submission in the dashboard - Confirm `api_key` matches the form you are viewing - Confirm the form is active / API enabled - Check browser network tab for non-2xx responses - Ensure you are not filtering spam-only views if the post was classified as spam ## Domain denied - Add your site host to the form [domain allowlist](/docs/submit-api/domains/) - Include both apex and `www` if both are used - Preview deploy URLs must be listed if you test from them ## CORS / fetch failed - Prefer classic form POST or the official SDK - Avoid random third-party origins without CORS intent - Inspect preflight OPTIONS failures in DevTools ## Channel not notifying - Channel enabled and destinations verified (email OTP, WhatsApp numbers, Telegram chat confirm) - Credits remaining for billable channels - Check plan gates (WhatsApp on Pro/Agency) - Webhook URL still valid (Discord/custom) ## Wrong fields in delivery - Inputs need `name` attributes - JSON keys must match the fields you expect ## Still stuck? Email [hello@formsreach.com](mailto:hello@formsreach.com) with the form id, approximate time, and `meta.requestId` from the JSON response if available. # FAQ Frequently asked questions about FormsReach form API, WhatsApp delivery, credits, and frameworks. ## Is FormsReach a form builder or a form API? FormsReach ships as a **form API / form backend** first. You point your own HTML or framework forms at our endpoint. A visual form builder is part of the longer-term product story. ## Do visitors need WhatsApp? No. Only you (the form owner) receive WhatsApp notifications when that channel is enabled. ## Is WhatsApp official? Yes - Meta WhatsApp Business API. FormsReach is not affiliated with or endorsed by Meta; WhatsApp is a trademark of Meta Platforms, Inc. ## Does Free include WhatsApp? No. Free includes email, webhooks, and workflow rules with a monthly credit pool. WhatsApp is on Pro and Agency. Details: [pricing](https://formsreach.com/pricing). ## Can I use React / Next / Vue? Yes - official packages plus plain HTML. See [Frameworks](/docs/frameworks/overview/). ## Where is the full OpenAPI? [app.formsreach.com/api/docs](https://app.formsreach.com/api/docs) for the live explorer. Public website integration focuses on the [Submit API](/docs/submit-api/overview/). --- ## Section: Agents # Coding agents Use FormsReach docs with AI coding agents - Copy as Markdown, raw .md URLs, llms.txt, and the installable skill. ## Copy as Markdown Every docs page has **Copy as Markdown** in the header. Paste into Claude, Cursor, ChatGPT, or any agent chat. ## Raw `.md` URLs Append `.md` to a guide path: - HTML: `https://formsreach.com/docs/channels/whatsapp/` - Markdown: `https://formsreach.com/docs/channels/whatsapp.md` Home: [https://formsreach.com/docs/index.md](/docs/index.md) ## llms.txt - Curated index: [/llms.txt](/llms.txt) - Full corpus: [/llms-full.txt](/docs/llms-full.txt) ## Agent skill Install the FormsReach skill for Claude Code / Cursor-style agents: - Marketing guide: [formsreach.com/skills](https://formsreach.com/skills) - GitHub: [github.com/formsreach/skills](https://github.com/formsreach/skills) ```bash npx skills add formsreach/skills ``` ## Accuracy rules for agents - Prefer these docs and the dashboard snippets over inventing field names - Public submit: `https://api.formsreach.com/submit` - Public field: `api_key` - SDK packages: `@formsreach/js`, `@formsreach/react`, `@formsreach/vue`