Send an HTML form to email
Set your form’s action to a PortForm endpoint and add your access key as a hidden field. Each submission is stored and emailed to the address you verified, and a plain HTML form does it without JavaScript or a server of your own.
Three steps: form, address, endpoint.
Create the form
In the dashboard, create a form and give it the address that should receive the email. That gives you an access key.
Verify the address
Confirm you control the inbox. Email is not sent to an address until you do.
Paste the endpoint
Set the form’s action to the endpoint and add the access key, as below.
<form action="https://app.portform.co/api/submit" method="POST">
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<input type="hidden" name="redirect" value="https://example.com/thanks" />
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<!-- Honeypot: hidden from people, filled in by bots. Leave it here. -->
<input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off" />
<button type="submit">Send</button>
</form>Replace YOUR_ACCESS_KEY with your access key. The redirect field is optional: it sends the visitor to your own thank-you page after they submit, and it must be a full URL starting with https://. Without it the visitor sees the JSON response. Every field name and response is in the docs. What the endpoint does with a request is explained on the form endpoint page.
Verify the address that receives the email.
PortForm sends a confirmation email to the destination address. Until someone clicks it, submissions are still accepted and stored, and the visitor still gets a success, but no notification email is sent to that address.
An address you have already verified in your account is verified for new forms automatically. Verification only gates the notification email: storage and any integrations you connected are unaffected. See destination verification in the docs.
What lands in your inbox.
One email per submission, sent from PortForm’s own domain, so there is no DNS to set up.
- The fields the visitor filled in, in the body of the email.
- Reply-To set to the visitor: a valid replyto field if the form has one, otherwise the email field. Replying writes to them.
- A subject line from the form’s subject template, or “New submission from PortForm” by default. A subject field in your HTML is shown in the body; it does not set the subject line.
- A [TEST] prefix on the subject while the form is in test mode.
- On Pro: CC recipients, and any uploaded files as attachments.
Why mailto: is not a form backend.
A mailto: link hands an address to the visitor’s own email program, which is what MDN documents it as doing (MDN: the anchor element). Nothing in that flow sends a request to a server you control, so nothing is received, stored or filtered on your side.
A form that posts to an endpoint is a different architecture: the browser sends an HTTP request to the URL in action, and the server there handles the data (MDN: sending form data). PortForm is that server. It receives the POST, stores the accepted submission, and then emails you.
After the email: storage and export.
The email is not the only copy. Every accepted submission is written to storage before the email is attempted, kept for 30 days, and exportable as CSV or JSON from the dashboard on every plan.
On Pro you can also forward each submission to Slack, Discord, Telegram, Google Sheets, Notion, Airtable, HubSpot or any webhook. Integration deliveries have their own automatic retries. Details are in the integrations docs, and the form backend page explains the wider model.
If the email does not arrive.
First check whether the submission is in your dashboard. If it is, the form works and the cause is one of these.
- The destination address is not verified.
- The submission is stored and appears in your dashboard, but no email is sent until the address is verified. Verify it from the dashboard.
- The form is in test mode.
- Test submissions still send the email, with [TEST] in the subject, and cost no quota. Look for the prefix, and turn test mode off for real traffic.
- The submission was filtered as spam.
- A filled honeypot field or a spam-like payload is stored as spam, sends no email and does not count against your quota. The visitor still sees a normal success. Check the Spam view in the dashboard, and make sure real visitors never fill the botcheck field.
- The request was rejected.
- A missing or wrong access_key returns 400. Passing your submission limit returns 429. On Pro, a domain restriction that excludes your site returns 403. A rejected request is not stored. With a redirect field the visitor lands on your thank-you URL with ?error=1 added.
- The email send failed.
- PortForm makes an immediate notification-email attempt. A submission with no recorded attempt after 10 minutes can receive one late recovery attempt, and failed sends can be retried manually from the dashboard once the cause is fixed. The submission is stored and marked failed with the error either way, so you can read it there.
Other ways to route form submissions.
Other services also turn a form into email. The comparisons check each one against its own documentation, for example FormSubmit and Web3Forms.
Questions
- How do I send an HTML form to email without a backend?
- Set the form’s action to a PortForm endpoint, add your access key as a hidden field, and verify the destination address. Each submission is then stored and emailed to that address. The form is plain HTML: no server code and no JavaScript are needed. 300 submissions every 30 days are free.
- Can HTML send an email by itself?
- No. A form only sends its data to the URL in its action attribute, and something at that URL has to handle it. A mailto: link works differently: it opens the visitor’s own email program (MDN). Neither one sends mail from your site, which is the job a form backend does.
- Do I need JavaScript to send a form to email?
- No. A plain form with method="POST" and the PortForm endpoint as its action posts natively, and a hidden redirect field sends the visitor on to your thank-you page. JavaScript is only needed if you want to submit without a page load.
- Why am I not receiving my form emails?
- The most common cause is an unverified destination address: PortForm stores the submission but sends no email until that address is verified. Others are test mode (the email arrives with [TEST] in the subject), a filtered spam submission, a rejected request, or a failed send. The dashboard shows which one applies.
- Who receives replies to form submissions?
- The notification email goes to your destination address, and its Reply-To is the visitor. PortForm uses a replyto field if the form has a valid one, otherwise the email field. A form with neither has no Reply-To. Replying to the notification writes to the visitor, not to PortForm.
- What happens if email delivery fails?
- The submission is already stored, so it is not lost. PortForm makes an immediate notification-email attempt. A submission with no recorded attempt after 10 minutes can receive one late recovery attempt, and failed sends can be retried manually from the dashboard. A failure is recorded on the submission with its error.
- Is sending a form to email free?
- Yes, up to 300 submissions every 30 days, with no card. That is a hard cap: past it, submissions are rejected until the window rolls over. Pro raises the cap to 10,000 and adds CC recipients, file attachments and integrations.
Get the submissions in your inbox.
Create a form, verify the address, and paste the endpoint. 300 every 30 days, free, no card. See pricing.