Collect form submissions
Point an HTML form’s action at deploybase and every submission is stored, scored for spam, and emailed to your team. There is no backend to run, no JavaScript required, and the form does not have to be on a site we host.
Set one up
Section titled “Set one up”Open a project, go to the Forms tab, and create a form. Then point a form at the endpoint it gives you:
<form action="https://api.deploybase.eu/f/0123456789abcdef" method="POST"> <input type="email" name="email" /> <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" /> <button>Send</button></form>No JavaScript and no API key are involved. The endpoint accepts requests from any origin, so the form can live anywhere.
0123456789abcdef is deliberately fake. Every form has its own id, shown on the form’s page in the dashboard, and a real one is random rather than a tidy run of hex.
Opening the endpoint in a browser shows a live-check page that renders your own snippet back at you, which is the quickest way to confirm you have the right id before wiring it into a real page.
Submit with JavaScript instead
Section titled “Submit with JavaScript instead”Send Accept: application/json and you get a JSON response rather than a redirect:
const res = await fetch("https://api.deploybase.eu/f/0123456789abcdef", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify({ email: "jane@example.com", message: "Hello" }),});
const { ok, id } = await res.json();Success is 200 {"ok": true, "id": "..."}. Without that header the same request gets a 303 redirect instead, which is what makes a plain HTML form post work.
Content types we accept
Section titled “Content types we accept”| Content type | Notes |
|---|---|
application/x-www-form-urlencoded |
A standard HTML form post |
multipart/form-data |
Fields only. A file part returns 422 FILES_NOT_SUPPORTED |
application/json |
An object. Nested values are stored as they arrive |
A submission can carry up to 100 fields and 256 KB.
Reserved field names
Section titled “Reserved field names”A small set of field names is reserved, matching Formspree’s. Migrating from Formspree is usually a matter of changing the action URL.
| Field | What it does |
|---|---|
_gotcha |
Honeypot. Keep it in the markup, hidden with CSS. Arriving filled in means a bot, and the submission is quarantined silently while the sender still sees success. Rename it per form under Settings → Honeypot field |
_replyto |
Sets Reply-To on the notification email. Falls back to a field named email |
_subject |
Overrides the notification subject, up to 200 characters |
_next |
Where to send the browser afterwards. Must be on the submitting site’s origin or one of your project’s verified domains, which is an open-redirect guard. Anything else is ignored |
_cc |
Accepted for Formspree compatibility. Not currently used |
Reserved fields are stripped before the submission is stored or exported, so they never appear in your inbox data.
Redirects
Section titled “Redirects”After a non-JSON submission the browser is redirected with 303 See Other, so refreshing the destination does not resubmit. The target is the first of these that applies:
- The
_nextfield, if present and valid - The form’s redirect URL, set in Settings
- A hosted deploybase thank-you page
How spam is filtered
Section titled “How spam is filtered”No CAPTCHA, no Akismet, no reCAPTCHA. Five layers, in order:
- Honeypot (
_gotcha). Filled in means bot, quarantined silently - Origin allow-list, configurable per form. Empty accepts any origin
- Per-IP rate limit of 20 requests a minute per form, the only case that gets an explicit
429 - Per-form flood limit of 120 submissions a minute. Anything over is still accepted, just quarantined, so a genuine traffic spike does not cost you leads
- Duplicate absorption. Identical submissions inside a one-minute window are absorbed rather than stored twice
Nothing is deleted. Everything quarantined lands in the form’s Spam tab, and marking one “Not spam” restores it to the inbox. Quarantined submissions never send a notification and never count against your quota, and the sender never learns which verdict they got.
Privacy and GDPR
Section titled “Privacy and GDPR”- Submissions are stored in the EU, in Paris
- Raw IP addresses are never stored or logged. By default a truncated form is kept,
203.0.113.x, and a per-form setting turns off even that - Retention: keep submissions indefinitely, or purge automatically after 30, 90 or 365 days. Changing the window applies to existing submissions, not only new ones
- Erasure: owners and admins can hard-delete every submission matching an email address, from Forms → privacy tools or over the API. API keys act as Member and cannot make this call, so it needs a signed-in user’s token:
curl -X DELETE "https://api.deploybase.eu/api/v1/teams/form-submissions?email=jane@example.com" \ -H "Authorization: Bearer $DEPLOYBASE_TOKEN"Each erasure is written to an audit trail, recording a hashed email, the number of submissions removed and who asked, so you have a record to show.
Notifications
Section titled “Notifications”Each submission emails the form’s notify addresses: verified team members, plus any external recipients who have confirmed.
Above 30 submissions an hour, notifications collapse into one hourly digest rather than one email each. If you pass your plan’s monthly allowance you get a single “notifications paused” notice for that billing period rather than a stream. Teams can opt out entirely in notification preferences.
Send notifications outside your team
Section titled “Send notifications outside your team”To get submissions to a client, a contractor or a shared inbox, add an external recipient in Forms → form → Settings.
- An owner or admin adds the address
- One confirmation email goes out. Until the link is clicked the recipient sits at Pending and receives nothing
- After confirming, they receive every new submission. Anything that arrived while they were pending is not backfilled, and stays in the inbox
- Every notification carries an unsubscribe link. Unsubscribing stops mail immediately and permanently, until an admin removes and re-adds the address, which starts a fresh confirmation
Limits keep this from becoming a way to email strangers: five recipients per team awaiting confirmation at once, across every form, ten confirmation emails per team per day, and one confirmation per address per hour, so Resend has an hour of cooldown. Confirmation links are single use and expire.
Team member addresses are rejected here deliberately. Tick them in the notify list instead, which needs no confirmation.
When delivery fails
Section titled “When delivery fails”Two more statuses can appear on a recipient row, and both mean deploybase has stopped sending on its own:
- Bounced: mail failed permanently, usually a typo or a mailbox that no longer exists
- Complained: the recipient marked one of our emails as spam. Sending to that address stops for good
Mail providers judge a sender by how much undeliverable and unwanted mail it sends, so continuing would degrade delivery for every other recipient on the platform. Honouring a spam complaint permanently is standard practice across email providers.
There is no button to switch a suppressed recipient back on. If you have fixed whatever caused a bounce, remove the recipient and add the address again to start a fresh confirmation. For a complaint, only re-add the address if the person asks you to.
The same applies to your team’s notification email under Settings → Notifications. If that address bounces or reports us, notifications stop and the page says so.
What counts against your plan
Section titled “What counts against your plan”Forms themselves are unlimited on every plan. The limit is on verified, non-spam submissions per month, and the current allowance is on the pricing page.
Spam and quarantined submissions never count. Past the allowance, submissions keep being stored and are marked uncounted, notifications pause, and your site is not affected. There is no overage charge.
Export and automate
Section titled “Export and automate”Export a form’s inbox as CSV or JSON from the dashboard, or over MCP, which exposes list_forms, list_form_submissions, export_form_submissions and the spam-marking tools to an AI assistant.
Not supported yet
Section titled “Not supported yet”- File uploads
- Outbound webhooks and Slack notifications
- Autoresponders back to the submitter