Forms on a static site, without running a server

A static host will serve your HTML but it will not accept a POST. SubmitHarbor gives the form somewhere to go: one endpoint that validates the fields, drops obvious bots, and keeps every submission in a private inbox you can read, search, and export.

A form that works on any static host

This is ordinary HTML. No build step, no client library, no JavaScript needed — it works the same on Netlify, GitHub Pages, Cloudflare Pages, S3, or a folder served by nginx.

index.html
<form action="https://www.submitharbor.com/api/submit/sh_your_project_key" method="POST">
  <label>
    Your email
    <input type="email" name="email" required />
  </label>
  <label>
    Message
    <textarea name="message" required></textarea>
  </label>

  <!-- Bots fill this in. People never see it. -->
  <input type="text" name="website" tabindex="-1" autocomplete="off" hidden />

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

Swap the key in the action for your own and the form is live. A native form post sends application/x-www-form-urlencoded; a fetch call can send JSON instead. The endpoint reads both.

Try the endpoint before you wire anything up

There is nothing to install and nothing to sign up for first. The demo key below is the same route the product uses.

Run this now — the shared demo key is open and answers immediately
curl -i -X POST https://www.submitharbor.com/api/submit/demo_contact_7x2p \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","message":"Testing the demo endpoint."}'

The shared demo key validates a submission and echoes it back, then discards it. It never writes to the database, because a stored demo submission would leave a stranger's details in an inbox nobody owns. Create your own endpoint to keep what arrives.

What the endpoint checks

Validation happens on the server, so it still applies when someone posts around your page. Every rejection comes back as a plain sentence you can show the visitor.

FieldRule
emailRequired. Must contain a name, an @, and a dotted domain.
messageRequired. At least 3 characters after trimming.
Any other fieldOptional. Stored as sent, trimmed, up to 5,000 characters.
website, _gotchaHoneypots. If either is filled the submission is accepted and discarded.
_redirectOptional. A URL on the submitting origin or the allow-list to return the browser to.

Spam controls that do not ask your visitors to prove anything

No puzzle, no third-party widget, no tracking script. Three server-side controls do the work.

A honeypot field
Add a hidden website input. People never see it, so they never fill it. When it arrives populated the endpoint answers 200 and quietly discards the submission, which keeps a bot from learning it was caught.
An origin allow-list
List the sites permitted to use the endpoint and a post from anywhere else is refused with 403. Browsers always send an Origin header on a cross-site form post, so this stops another site from pointing at your endpoint. It is not authentication: a direct server request that sends no Origin is not blocked by it.
A rate limit
20 submissions per minute, per address, per endpoint. Past that the endpoint answers 429 with a Retry-After header instead of filling your inbox.

The submission log

Every stored submission lands in a private inbox scoped to the endpoint that received it and the account that created it.

Read what arrived
The exact captured payload, field by field, with the sending origin and the time received. Unread submissions are marked until you open them.
Search and export
Filter across every field, then export what you are looking at as CSV. The export contains exactly the rows on screen, and spreadsheet formula characters in submitted text are neutralised.
Reply and delete
Open a reply to the sender in your own mail client, or delete a submission outright. Deleting an endpoint deletes the submissions attached to it.
Get told when one arrives
Set a notification address on the project and each stored submission is emailed to it. Email is only sent when the delivery credentials are configured; the response tells you whether it went.

What SubmitHarbor does not do

Worth reading before you build on it. These limits apply today.

  • The shared signed-out demo validates and echoes a preview; durable endpoints, storage, and notifications require a configured signed-in project.
  • SubmitHarbor does not promise an uptime SLA, attachments, CAPTCHA providers, webhooks, CRM integrations, or unlimited submissions.
  • Origin checks and honeypots reduce common abuse but do not replace a complete security and privacy review for sensitive forms.

Questions about static site forms

Do I need a server or a build step?

No. The form is plain HTML posting to a hosted URL, so it works on any static host. A JavaScript submission is supported but never required.

Where do submissions go on a static site?

To the endpoint, then to the private inbox for that project. Nothing is stored on your host, so a static deploy stays static.

Can I test it without creating an account?

Yes. The shared demo key accepts submissions and shows you the validated payload. It does not store anything, so create your own endpoint once you want to keep what arrives.