Documentation

FormFlux accepts standard multipart/form-data and application/x-www-form-urlencoded posts. There is no SDK to install and no key to embed in your markup.

Zero-config email mode

Fastest way to start. The first submission emails you a one-time verification link; after you click it, submissions are delivered.

<form action="https://api.formflux.online/email/[email protected]" method="POST">
  <input type="text" name="name" required />
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>

  <!-- bots fill this in; humans never see it -->
  <input type="text" name="_honey" style="display:none" tabindex="-1" autocomplete="off" />

  <button type="submit">Send</button>
</form>
Before going live, switch to the UUID endpoint. The zero-config URL contains your real email address, so scrapers can read it from your page source. A dashboard form gives you /f/<uuid> instead, which exposes nothing — the same protection as an invisible or aliased address.

Dashboard mode

Create a form in the dashboard to get a UUID endpoint plus settings for redirects, webhooks, autoreply, captcha, retention, and validation.

<form action="https://api.formflux.online/f/YOUR_FORM_ID"
      method="POST"
      enctype="multipart/form-data">
  <input type="text" name="name" required />
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>
  <input type="file" name="attachment" />

  <input type="text" name="_honey" style="display:none" tabindex="-1" autocomplete="off" />
  <input type="hidden" name="_subject" value="New website enquiry" />
  <input type="hidden" name="_next" value="https://example.com/thanks" />

  <button type="submit">Send</button>
</form>

AJAX / JSON mode

Send Accept: application/json (or _format=json) and FormFlux replies with JSON instead of redirecting.

const response = await fetch("https://api.formflux.online/f/YOUR_FORM_ID", {
  method: "POST",
  headers: { Accept: "application/json" },
  body: new FormData(document.querySelector("form")),
});

const result = await response.json();
// { success: true, submissionId: "..." }

Special fields

Hidden inputs that change behaviour for a single submission. They are stripped before the submission is stored or emailed.

_replyto

Sets the Reply-To header so replying goes straight to the sender.

<input type="hidden" name="_replyto" value="[email protected]" />
_next

Redirects this one submission somewhere else, overriding the form's default redirect.

<input type="hidden" name="_next" value="https://example.com/thanks" />
_subject

Overrides the notification email's subject line.

<input type="hidden" name="_subject" value="New lead from pricing page" />
_cc

Comma-separated extra recipients on the notification email.

<input type="hidden" name="_cc" value="[email protected], [email protected]" />
_blacklist

Comma-separated phrases (20 max). A match silently marks the submission as spam — the sender still sees success.

<input type="hidden" name="_blacklist" value="viagra, casino, free money" />
_captcha

Set to "false" to say this submission has no captcha. Ignored when the form owner requires hCaptcha.

<input type="hidden" name="_captcha" value="false" />
_honey

Honeypot. If a bot fills it, the submission is dropped silently. _honeypot works too.

<input type="text" name="_honey" style="display:none" />
_autoresponse

Custom autoreply body for this submission, overriding the saved template. Supports {{field}} placeholders.

<input type="hidden" name="_autoresponse" value="Thanks {{name}}!" />
_template

Email layout: "table" (default) or "plain".

<input type="hidden" name="_template" value="plain" />
_webhook

Fires an extra webhook to this URL with a { "form_data": {...} } body, alongside your configured destinations.

<input type="hidden" name="_webhook" value="https://example.com/hook" />
_format

Set to "json" (or send Accept: application/json) to get a JSON response instead of a redirect.

<input type="hidden" name="_format" value="json" />

Limits and behaviour

File uploads
10MB total per submission across all files, up to 10 files. Stored in R2 with download links in the email.
Rate limiting
Rolling one-hour window per IP and per form, default 100 submissions per hour, configurable per form.
Spam
Honeypot drops silently. Blacklist and heuristic matches are stored with is_spam = true and skip email and webhooks. A failed captcha is rejected outright.
Webhooks
Delivered in parallel. Non-2xx responses retry with exponential backoff up to five attempts, and every attempt is logged.
Retention
A daily job deletes submissions older than each form's retention window, including their uploaded files.
Archive
Search your entire submission history from the dashboard with no call limit — it's your own database.