A static site has no server. A form needs one thing that runs.
Every static plan on this site is sold as 'no server'. None of them says what happens when a visitor needs to send something. This page does.
One word, three jobs
Who owns each one.
- 1
The fields on the page
What you ask a visitor to fill in. A briefed change adds, removes, or renames a field — it is your form to design.
Owned by You - 2
The endpoint that catches the POST
A small managed endpoint that receives the submission. A static site has no server of its own to catch it — this is the one thing a static plan needs briefed in.
Owned by CustomHosted - 3
The destination the submission lands in
An inbox, a database row, a file, or an outside service. The endpoint decides where a submission goes; see where a submission can end up below.
Owned by You
Hop by hop
The last hop hands off to Email — this page stops where delivery starts.
- 1
A visitor submits the form
YouThe browser sends the fields to the endpoint. Nothing here holds a secret — see the four things a form must not do below.
- 2
The endpoint checks the request
CustomHostedMethod, field length, and a hidden field a human never fills in. This site's own defences are the worked artifact below.
- 3
The endpoint writes to the destination
CustomHostedA message handed to the mail relay, a row written to a database, or a file saved to storage, depending what the form is for.
- 4
The relay takes it from there
CustomHostedOnce a message reaches the relay, Email owns the rest of the hop: delivery, signing, and bounces.
By hosting shape
| Shape | Plan | Catches it | Detail |
|---|---|---|---|
| Static alone | Static Starter | Nothing | A static site has no server standing by to catch a POST. A form on the page with no endpoint behind it does nothing at all. |
| Static plus a briefed endpoint | Static Starter or Static Pro | A small managed endpoint | Briefed once, then it runs on its own. The site stays a static site — there is no application server to add, and no tier to climb to take an enquiry. |
| Dedicated | Dedicated M | The app itself | Your own running application catches the request directly — no separate endpoint to brief. |
| Dedicated plus a database | Dedicated M + DB Standard | The app, writing to a database row | The same app, with somewhere durable to put what it catches. Both sit on the rate card. A shape that outgrows it is quoted as Custom. See Databases for how a schema change to hold a submission ships. |
Four rules, plainly
No secret in the page
Every file shipped to a visitor's browser can be read by that visitor. A value baked in at build time is public the moment it ships — not hidden, only unlabelled. A form on a static page can hold no secret value — see Configuration for the full rule.
No mailto: link as a form
A mailto link opens the visitor's own mail app, if they have one configured, and shows your address in the page source either way. It is not a form.
No unbounded field
Every field needs a hard length limit, or a message field becomes a place to paste anything at all. See the field caps in the worked artifact below.
No trust in the browser's own validation
A required attribute in the page's markup stops a normal visitor, not a script posting straight to the endpoint. The endpoint has to check again.
Four destinations, briefed once
An inbox someone already reads
The common case — a submission arrives as mail, sent onward through the relay. See Email.
A database row
A submission saved for later, queried instead of read one message at a time. See Databases.
An outside service
A support desk, a CRM, a spreadsheet tool — anywhere a submission can be handed off to over its own API. See Outside services.
A file
An attachment saved to storage rather than a database. A static site has no writable disk, so a static plan alone has nowhere to put one. See Files.
What a visitor with JavaScript off sees
This site's own form posts with JavaScript. With JavaScript off, this site's own quote form does nothing at all when the button is pressed. A form that also posts without JavaScript is quoted work, briefed like any other change — not a setting to switch on.
This site's own quote form
Every row below is a real check in this repository, not a hypothetical one.
- This page's own quote form runs on the exact shape above: a static site, with a briefed endpoint behind it.
- A configuration handed off from the estimator or the selector fills a spec plate on the form. A visitor never retypes what they already chose.
- A composed change brief fills the message field the same way. A visitor arrives with a ready-to-send request, not a blank box. See Brief a change.
Defences on the endpoint
Reused in full from Under attack.
POST only
Any other request method is refused outright.
A browser on another site can't post to it
A form on someone else's page cannot submit through this endpoint from a visitor's browser. A script that is not a browser is not stopped by this one — the checks below are what handle that.
A hidden field a human never sees
A field real visitors never fill in. A submission that fills it gets a cheerful "sent" response while nothing is actually sent.
Every field capped in length
A name, an email address, and a message all have a hard length limit, so a multi-megabyte message is not a thing.
A real address, checked
The email address has to look like an address or the request is refused.
Request logs kept 90 days
Every request to the form is logged for 90 days, not kept forever and not thrown away immediately.
The caps themselves
A field longer than its cap is cut to the cap, not refused. The submission still arrives, with the overflow dropped.
- Name200 chars max
- Email320 chars max
- Company200 chars max
- Workload100 chars max
- Message5000 chars max
- Configuration (spec plate)800 chars max
- Estimate40 chars max
A plan, plus a briefed endpoint
A static plan plus a briefed endpoint
Static Starter or Static Pro, plus the endpoint briefed once as a change. No separate line item for the endpoint itself.
A form does not push you onto dedicated compute
Static hosting starts at $5/mo. Dedicated compute starts at $29/mo. A form on a static plan is the cheaper shape because it adds an endpoint, not a server.
No per-submission meter
A form does not bill by the message. Ten submissions a month or ten thousand cost the same, up to the fair-use transfer allowance the plan already carries.
Agentic iteration — CodeHerder
$25/mo. Changing a field, adding a destination, or tightening a check later is a briefed change, not a new project. Quoted flat within one business day if the first brief itself needs pricing.
Four ways, and the route out
Who hears about each, and when, is Monitoring's own escalation ladder — reused whole below.
The endpoint refuses the request
Owner: OursA required field is missing, the address is malformed, or the method is wrong. The endpoint answers with an error and sends nothing. An over-long field is not one of these cases — see the caps in the worked artifact above.
Refused by the relay
Owner: OursThe relay itself rejects the request before the message goes anywhere — a configuration problem on the sending side.
It bounces once delivered
Owner: Your dataThe destination address no longer exists. See Email for the rest of that failure mode.
Nobody reads the destination
Owner: YouThe submission arrived. Nobody reads the inbox, spreadsheet, or database any more. Monitoring watches whether the endpoint itself is up — not whether a human reads what lands.
| Tier | What counts | What happens first | Who hears |
|---|---|---|---|
| Auto-handled | A known, safe failure with an established fix — a crashed process, a failed health check, a stuck deploy | Restart, retry, or redeploy the last known-good version, done automatically | No one, unless it recurs — it goes in the log, not a message to you |
| You hear from us | Something that touched the app and needs a person to pick the right response, not just a retry | A human looks at it and decides what to do — revert, restore, or a fix in code | You, in writing, on the same quote channel as everything else — business hours for anything that isn’t urgent |
| Outage handling | The site or a core function is down, or badly degraded, for real users | Worked ahead of the routine queue | You, as soon as there is something to say, with priority handling; out-of-hours response is best effort, not a staffed round-the-clock desk |
The honest limits
No drag-and-drop form builder
A field, a destination, or a check is a briefed change to the endpoint's own code, not a setting in a dashboard.
This site's own form posts with JavaScript
With JavaScript off, this site's own quote form does nothing at all when the button is pressed. A form that also posts without JavaScript is quoted work, briefed like any other change — not a setting to switch on.
Deliverability is never guaranteed
Whether a message lands in an inbox, a spam folder, or nowhere at all depends on the receiving side's own filtering and your own sending reputation. Inbox placement is not something measurable from here, and nobody can promise it. See Email for the full deliverability picture once a submission is handed to the relay.
No file upload by default
A field that accepts an attachment is real work we can build — quoted flat, the same as any other custom infrastructure request, not something switched on by asking.
Form questions
The questions that come up once a static site has to receive something.
Can a static site really take a contact form?
Yes. A static plan plus a briefed endpoint — the same shape this site's own quote form runs on. See what catches a submission by hosting shape above.
What stops a bot from spamming the form?
A hidden field a human never fills in, every field capped in length, and the request checked before it reaches the destination — see the worked artifact above for this site's own defences.
Does the form work with JavaScript off?
This site's own quote form does not. A form that posts without JavaScript is quoted work — see the JavaScript-off section above.
Can the form take a file attachment?
Not by default. A field that accepts an upload is real work we can build, quoted flat — see the honest limits above.
Where does a submission actually go?
An inbox, a database row, an outside service, or a file — you choose when the endpoint is briefed. See where a submission can end up above.
Is a form on a static plan slower than one on a dedicated instance?
No. The endpoint runs on its own, separate from the static files — the plan a visitor's browser downloads is unchanged either way.
What forms connects to
- Logins
A different kind of form: one that starts a session instead of catching a one-off submission.
- Email
Everything that happens once a submission reaches the relay — signing, bounces, and deliverability.
- Under attack
The defences this page's worked artifact reuses whole, and the rest of the perimeter around them.
- Static
The flagship product this page answers the first practical question about: can it take a form?
- Custom
The bigger, bespoke workloads a form is not one of.
- Databases
What holds a submission saved as a row instead of sent as mail.
- Files
What holds a file a form has to accept as an attachment.
Have something for a form to catch?
Tell us the fields and where the submission should land — one fixed monthly rate, in writing.