formpit

Docs

Formpit is an endpoint you POST a form to. Everything below is optional except the action.

Quick start

Create a form in the dashboard and copy its endpoint. Then:

<form action="https://formpit.com/f/YOUR_FORM_ID" method="POST">
  <input type="text"  name="name"  placeholder="Your name" required>
  <input type="email" name="email" placeholder="Your email" required>
  <textarea name="message" placeholder="Message" required></textarea>
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
  <button type="submit">Send</button>
</form>

That's it. Submissions are emailed to the addresses on the form and stored in your dashboard. The hidden _gotcha input is a spam trap: real browsers leave it empty, bots fill it.

Field names

Any name you use becomes a column in the dashboard and a row in the email. Use clear names like email, company, budget. Checkboxes and multi-selects with the same name are joined with commas. Fields are capped at 50 per submission and 20,000 characters each.

If you include a field named email, the notification's reply-to is set to it, so replying to the notification replies to the visitor.

Special fields

Fields starting with an underscore are instructions to Formpit and aren't stored.

FieldWhat it does
_redirectURL to send the visitor to after submitting. Overrides the form's redirect setting.
_subjectSubject line for the notification email.
_replytoReply-to address, if your email field isn't called email.
_gotchaHoneypot. Keep it hidden and empty; any value marks the submission as spam.
<input type="hidden" name="_subject" value="New quote request">
<input type="hidden" name="_redirect" value="https://yoursite.com/thanks">

Switching from another service? Formpit also understands their control fields, so you can usually change just the action URL: _next (Formspree, FormSubmit) and redirect (Web3Forms) work as redirects; _honey, botcheck and bot-field work as honeypots; and access_key, the Netlify form-name input and FormSubmit options like _template and _captcha are ignored and never stored. See the alternatives pages for step-by-step switching.

JavaScript / fetch

Send Accept: application/json (or a JSON body) and you get JSON back instead of a redirect. CORS is open, so this works from any origin.

const res = await fetch("https://formpit.com/f/YOUR_FORM_ID", {
  method: "POST",
  headers: { "Content-Type": "application/json", "Accept": "application/json" },
  body: JSON.stringify({ email: "a@b.com", message: "Hello" })
});
const data = await res.json();   // { ok: true, id: 123 }  or  { ok: false, error: "..." }

You can also post a FormData object directly; just set the Accept header. File fields work too on Pro (see file uploads).

Testing & debugging

Click Send test submission on a form's page to drop a sample message into its inbox (it skips the captcha). To check your own form before going live, use the free tools, which work with any form backend:

  • Form submission debugger: paste your form's HTML to find problems such as fields without a name, a missing method="post", or a file input without enctype="multipart/form-data", and see exactly what will be sent.
  • Echo endpoint: temporarily set your form's action to https://formpit.com/tools/echo and submit it. You get back a page (or JSON, if you ask for it) listing every field and file that arrived. Nothing is stored.
  • Form endpoint tester: send a test submission as a normal form post, JSON or multipart to any URL and see the status, timing and response.
  • Spam protection tester: check whether a message would be filed as spam, and score your form's defences.
  • HTML form generator and contact form templates if you'd rather start from working code.

Thank-you page & redirects

After submitting, visitors see Formpit's thank-you page: a short confirmation with a button back to your site and no Formpit navigation. Customise its heading and message per form under Settings → Thank-you page (each settings section has its own Save changes button); {{name}} becomes the visitor's first name and {{email}} their address (leftover punctuation is tidied if the form doesn't collect them).

To make the page match your website, pick an icon (or paste an https link to your logo) and turn on Use my own colours to set the page background, card, text and button colours. Start from a preset or type your own hex values; the preview updates as you change them. The button text switches to black or white automatically so it stays readable. On Pro you can also tick Hide “Form powered by Formpit” to remove the credit under the card.

To use your own page instead, set a redirect URL in the same section, or add a hidden _redirect field to send a particular form somewhere else. Redirect URLs must start with http:// or https://. Pro accounts can remove the small “powered by Formpit” line.

Spam & captcha

Every form gets, with no setup: a honeypot (_gotcha), a per-IP rate limit (10 submissions per 10 minutes per form), and content checks for link floods, known spam phrases, empty bodies and garbage text. Flagged entries go to the form's Spam tab, where you can mark them "not spam".

Add your own blocked words per form in Settings → Spam protection; any submission containing one goes straight to Spam.

Adding a captcha

For stricter protection, turn on Require a captcha in the form's Settings → Spam protection, choose a provider, paste the provider's secret key into Formpit (it is stored encrypted), and add the provider's widget to your form with the matching site key. On every submission Formpit sends the widget's token and the visitor's IP to the provider for verification; anything without a valid token is rejected with "Captcha failed" and never stored. Each provider gives you both keys when you register your site:

  • hCaptcha: sign up at hcaptcha.com → Sites → New site (add your domain, copy the site key) → Settings (the secret key is at the top of that page).
  • Google reCAPTCHA: open the admin console, register your domain with the v2 checkbox (or v3 score-based) type, and copy both keys from the confirmation screen. For v3, Formpit requires a score of 0.5 or more.
  • Cloudflare Turnstile: in the Cloudflare dashboard open Turnstile → Add widget, add your hostname, and copy both keys. Your site does not need to be on Cloudflare.

Then drop the widget inside your <form>:

<!-- hCaptcha -->
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<div class="h-captcha" data-sitekey="YOUR_SITE_KEY"></div>

<!-- Google reCAPTCHA v2 -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>

<!-- Cloudflare Turnstile -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>

If you submit with JavaScript instead of a plain form post, read the token from the widget (h-captcha-response, g-recaptcha-response or cf-turnstile-response) and include it in your request body under that same name. The dashboard's "Send test submission" button skips the captcha so you can test delivery before wiring up the widget.

reCAPTCHA v3 works too: send the token as g-recaptcha-response; scores under 0.5 are rejected.

Domain lock

Under Settings → Spam protection, set Only accept from domain to yoursite.com and Formpit rejects submissions whose Origin or Referer is another site (subdomains are allowed). Requests with no origin header at all, such as curl, are still accepted, so this is a nuisance filter rather than a security boundary.

The inbox

Every non-spam submission lands in the form's inbox as New. Open one to see all fields, reply, tag it, or leave a private note.

  • Reply sends an email from Formpit with reply-to set to you and the visitor's message quoted underneath. It always goes to the address the visitor submitted, the reply is saved on the submission, and the status becomes Replied. Needs an email field on your form. Up to 30 replies a day on Free, 500 on Pro.
  • Saved replies (Account → Saved replies, up to 25) store answers you send often. Pick one from the reply box and {{name}}, {{email}} and {{form}} are filled in for that visitor. Tick “Save this reply as a template” when sending to turn a real reply into one; the visitor's details become placeholders automatically.
  • Remind me snoozes a submission until tomorrow, in three days, next Monday or a date you pick. You get an email at 08:00 UTC that day; snoozed submissions show a ⏰ in the inbox.
  • Mark replied / Close / Reopen change status without sending anything, for messages you handled elsewhere.
  • Tags are free-form (lead, support, press); notes are only visible to you.
  • Search looks across every field, your notes and tags. Export gives you CSV or JSON of the whole form at any time.
  • Reminders and digest Pro: a submission still New after 48 hours triggers one email nudge (snoozed ones are skipped), and a Monday digest summarises the week. Switch either off on your Account page.

File uploads Pro

Add enctype="multipart/form-data" to your form and one or more <input type="file"> fields. Files are stored with the submission, shown on its page, listed in the webhook payload, and attached to the notification email when they total under 8 MB (above that the email links to them instead).

<form action="https://formpit.com/f/YOUR_FORM_ID" method="POST" enctype="multipart/form-data">
  <input type="email" name="email" required>
  <input type="file" name="resume" accept=".pdf,.doc,.docx">
  <input type="file" name="photos" accept="image/*" multiple>
  <button>Send</button>
</form>

Limits: 5 files per submission, 10 MB per file, 25 MB total. Allowed types: images, PDF, Office documents, CSV, text, zip, and common audio/video. A submission that breaks a limit is rejected with a plain error so the visitor can fix it. On the Free plan, file fields are ignored and the rest of the submission still goes through. With fetch(), send a FormData object and don't set a Content-Type header.

Webhooks Pro

Set a webhook URL on a form and Formpit POSTs JSON to it for every non-spam submission, in parallel with the email:

{
  "form": "abc123",
  "id": 456,
  "created_at": "2026-10-25T10:30:00.000Z",
  "data": { "name": "Priya", "email": "priya@example.com", "message": "Hi!" },
  "attachments": [ { "filename": "brief.pdf", "size": 230400, "mime": "application/pdf", "url": "https://formpit.com/forms/abc123/submissions/456/files/1" } ]
}

Paste a Zapier, Make or n8n webhook URL to pipe submissions into a CRM, a spreadsheet, anything. The URL must be public: addresses on private or internal networks are refused. Requests time out after 10 seconds, redirects aren't followed, and deliveries aren't retried yet, so treat the dashboard or an export as the source of truth.

Slack

  1. Go to api.slack.com/apps → Create New App. Under “From scratch” choose Pick features, name it “Formpit” and pick your workspace.
  2. On the scopes step, switch to the Bot scopes tab and add incoming-webhook. Leave events empty and click Create and Install.
  3. Slack asks which channel the app may post to; choose one and click Allow.
  4. Click Go to App Settings, then Incoming Webhooks in the left sidebar, and copy the URL from the table (https://hooks.slack.com/services/…).
  5. Paste it into the Webhook URL field under Settings → Automations and click Save changes.

Formpit recognises Slack URLs and sends a plain message (“New submission to Contact page”, the fields, and a link to the submission) rather than the JSON payload. Each submission's Deliveries list shows whether Slack accepted it. To post to a second channel later, use Add New Webhook to Workspace on the same page.

Discord

Channel settings → Integrations → Webhooks → New Webhook → copy the URL and paste it as the form's Webhook URL. Same readable format.

Telegram Pro

On the form's Integrations tab, press Connect in Telegram app (or Use Telegram Web on a computer without the app). Press Start in the Formpit bot and the chat is linked to that form automatically; the Formpit page updates by itself. For a group, use “add the bot to a group”. Every submission then arrives as a message with its fields and an “Open in Formpit” link. Uploaded files follow as documents threaded under that message, and the result shows in the submission's Deliveries list.

If the automatic link doesn't happen within a few seconds, the bot's reply includes your chat ID and the manual field opens: paste it in and press “Save & send test”.

Autoresponder Pro

Set a subject and body under Settings → Automations and Formpit emails the visitor a confirmation when they submit (requires an email or _replyto field). Replies to that email go to your first notification address.

Google Sheets Pro

Every submission is appended as a row to a sheet you own. No OAuth: you share the sheet with Formpit's service account, like sharing with a colleague.

  1. Open the form's Integrations tab and copy the service account email shown there.
  2. In your Google Sheet, click Share and add that email as an Editor.
  3. Paste the sheet URL into Formpit and save. Add #gid=… (from the tab's URL) to write to a specific tab; otherwise the first tab is used.
  4. Click Test Sheets connection. You should see the sheet's title and tabs.

Formpit writes a header row (Submitted at, Submission ID, Form, then your field names) and extends it when new field names appear. Don't rename those header cells; add your own columns to the right of them instead.

Notion Pro

Every submission becomes a page in a Notion database.

  1. Go to notion.so/my-integrations, create an internal integration, and copy its Internal Integration Secret.
  2. Open the target database, click ··· → Connections, and add your integration.
  3. In the form's Integrations tab, paste the secret and the database URL, save, and click Test Notion connection.

Mapping: the database's title property gets the visitor's name (or email). Any field whose name matches a property (case-insensitive) is written by type: text, email, phone, URL, number, checkbox, select, multi-select, date. A date property named Submitted at, a property named Form, and a URL property named Formpit link are filled automatically. Every field is also written into the page body, so nothing is lost if a property doesn't exist. The secret is stored encrypted.

Email templates Pro

In Settings → Notification email you can set the sender name, the subject and the body of the notification. Placeholders: {{name}} or any {{field}}, {{all}} (every field, one per line), {{form}}, {{id}}, {{link}}. The same placeholders work in the autoresponder, so Hi {{name}}, thanks for writing! does what you'd expect. You can also hide the “Open in Formpit” footer.

Each submission's page has a Deliveries list showing whether the email, autoresponder, webhook, Sheets row and Notion page succeeded, with the provider's error message if not.

Frameworks

Step-by-step guides for each platform, including Lovable, Bolt, WordPress, Shopify, Wix and Squarespace, live on the Integrations page.

React / Next.js

function Contact() {
  const [state, setState] = useState("idle");
  async function onSubmit(e) {
    e.preventDefault();
    setState("sending");
    const r = await fetch("https://formpit.com/f/YOUR_FORM_ID", {
      method: "POST", headers: { "Accept": "application/json" },
      body: new FormData(e.target)
    });
    setState(r.ok ? "sent" : "error");
  }
  return (
    <form onSubmit={onSubmit}>
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button disabled={state === "sending"}>{state === "sent" ? "Sent!" : "Send"}</button>
    </form>
  );
}

Framer

Add a Form component, open its settings, choose Custom as the destination and paste your endpoint. Set the method to POST. Use the field names you want in your inbox.

Webflow

Select the form element, open Settings, set Action to your endpoint and Method to POST. Webflow's own form handling is bypassed.

Astro, Hugo, Eleventy, Jekyll, plain HTML

Use the quick-start snippet as-is. Nothing to install.

Carrd

Carrd forms can't change their action, but you can embed the quick-start HTML in an Embed element.

Limits

FreePro
Emailed submissions / month5005,000
Stored submissionsUnlimited, kept until you delete them
FormsUnlimited
Notification recipients per form15
Rate limit10 submissions per IP per form per 10 minutes
Fields / field size50 fields · 20,000 characters each
File uploadsIgnored5 files · 10 MB each · 25 MB total
Replies from the inbox30 / day500 / day
Saved replies25 per account

The monthly quota counts submissions, not emails: one submission is one, however many notifications, autoresponders or Telegram messages it triggers. Over the quota, submissions are still accepted and stored; only notifications pause until the 1st. Notifications also stay paused until you've verified your account email (link sent at sign-up).