Send a form to your email6 min read
Send one form to several email addresses
Email one form to your whole team, or route each message to the right person by topic, without letting the form itself pick who gets the mail.
Add each person as a recipient of the form in the dashboard: workspace members by ticking them, and anyone else by a confirmation link, up to 10 addresses. Everyone gets their own copy of every submission. To send sales questions to one person and support to another, route by a field in a webhook instead.
What's different here
Old PHP scripts and some form services let the form name its own recipients, with a hidden to or cc field. That's convenient, and it's also how contact forms become spam relays: a bot changes the hidden field and your server mails whoever it likes, from your domain. Ikiform has no recipient field. Who gets email is set in the dashboard, and anyone outside your workspace has to confirm first.
That leaves two different jobs, and they're solved in different places:
| You want | Where it's done | Limit |
|---|---|---|
| Everyone gets every submission | Recipients in the form's Notifications settings | 10 addresses per form |
| Each submission goes to the right person | A webhook that reads a field and emails one team | 3 webhook endpoints per workspace |
Send every submission to the whole team
- The form posts once to Ikiform.
- Ikiform builds the recipient list: the members ticked for this form, or the workspace default, plus outside addresses that confirmed.
- Duplicates are dropped and the list stops at 10.
- Each recipient gets a separate email, so nobody sees the others' addresses.
- Addresses still waiting for confirmation, and addresses paused after a bounce, are skipped.
- Open the form in the dashboard, then Settings and Notifications. Make sure Email new submissions is on.
- Tick each workspace member who should get email. Only members with a verified address are listed.
- For anyone outside the workspace, enter their address under Add someone outside the workspace and press Send link. You can add 5 per form.
- Ask them to confirm. Until they do, their row says Waiting for confirmation and they get nothing.
Outside recipients see the submission's fields and an unsubscribe link; they don't get a dashboard link, because they have no account. Members get a View submission button. If someone leaves, remove their row; if they unsubscribe, their row goes too.
Members and outside addresses
The two kinds of recipient behave differently, which matters when you decide who to add where:
| Item | Workspace member | Outside address |
|---|---|---|
| Added by | Ticking them on the form | Send link, then their confirmation |
| Sees in the email | Fields and a View submission button | Fields and an unsubscribe link |
| Can open the dashboard | Yes | No |
| Stops getting email when | You untick them, or they leave the workspace | You remove the row, or they unsubscribe |
| Counts toward | The 10-address limit | The 10-address limit and the 5 outside addresses per form |
Give the people who answer messages a seat in the workspace, so they can see past submissions and spam. Use outside addresses for people who only need to know, such as a manager or a shared inbox.
Route each submission by topic
Recipients can't depend on what the visitor picked. For that, add a field that names the team, and let a small webhook handler choose the address. Here's the form:
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="department">Who should read this?</label>
<select id="department" name="department" required>
<option value="sales">Sales</option>
<option value="support">Support</option>
<option value="billing">Billing</option>
</select>
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Send</button>
</form>Define department as a select field in the dashboard, so a post can only carry sales, support or billing. A bot that sends anything else gets 422 validation_failed and never reaches your handler.
Then the handler. It verifies the signature, picks the team from department, and sends through your own email provider, here Resend. Because you send the email, you choose its subject too:
import { Resend } from "resend";
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
const resend = new Resend(process.env.RESEND_API_KEY);
const TEAMS: Record<string, string[]> = {
sales: ["sales@example.com"],
support: ["support@example.com", "oncall@example.com"],
billing: ["accounts@example.com"],
};
export async function POST(request: Request) {
const payload = await request.text();
try {
const event = await verifyWebhook({
payload,
headers: request.headers,
secret: process.env.IKIFORM_WEBHOOK_SECRET!,
});
if (event.type !== "submission.created") return new Response(null, { status: 204 });
const fields = event.data.fields;
const department = String(fields.department ?? "support");
const { error } = await resend.emails.send(
{
from: "Website <forms@example.com>",
to: TEAMS[department] ?? TEAMS.support,
replyTo: typeof fields.email === "string" ? fields.email : undefined,
subject: `[${department}] ${String(fields.name ?? "New message")}`,
text: Object.entries(fields)
.map(([key, value]) => `${key}: ${String(value)}`)
.join("\n"),
},
{ idempotencyKey: event.id },
);
if (error) return new Response(error.message, { status: 502 });
return new Response(null, { status: 204 });
} catch (error) {
if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
throw error;
}
}- The addresses live in your code, not in the form. A visitor chooses a team name, never an address.
replyTokeeps Reply pointing at the visitor, as Ikiform's own email does.idempotencyKey: event.idmakes a retried delivery send nothing new. Ikiform retries a delivery that doesn't get a2xx, with the same id.- A
502when the provider fails tells Ikiform to retry later, so a short outage doesn't lose a message. - Unknown or missing departments fall back to support rather than dropping the message.
Add the URL under Webhooks in the dashboard and copy its whsec_ secret into IKIFORM_WEBHOOK_SECRET. The webhooks docs cover retries and the payload. Prefer no code? A Zapier or n8n flow with a filter per department does the same.
Keep Ikiform's own email on for one person as a backstop, or switch off Email new submissions so nobody gets the message twice.
Check it works
- Check every recipient row in the form's Notifications settings. None should say Waiting for confirmation.
- Fill in the form on your page and submit it. You land on your thank-you page, or Ikiform's hosted one.
- Each recipient gets their own email. Ask one of them to check the To line: it shows only their address.
- If you route by webhook, submit once per department and check the delivery log under Webhooks. Each shows
succeeded. - Post with the honeypot filled in,
_gotcha=bot. It still gets a success answer, but the submission is stored as spam and sends no email or webhook.
Gotchas
- No CC or BCC. Each recipient gets a separate message, so there's no shared thread. Agree who replies, or route by topic.
- The cap counts submissions, not recipients. Past 50 submissions an hour on one form, every recipient gets the digest instead.
- Membership changes. When someone leaves the workspace, they stop getting email at once. Check the form's recipients after a team change, so the form isn't left emailing nobody.
- A bounced address is paused. The row shows Emails bounced with a date, and email to it resumes after that. Fix the address or remove it.
- Nothing goes to the visitor. Ikiform doesn't email the person who fills in the form. Notification emails go to you and your team only, so there is no autoresponder, confirmation email or double opt-in. Send those from your email tool, triggered by a webhook.
Questions
Ikiform pauses email to that address for a while and marks the row Emails bounced in the form's settings. Other recipients aren't affected. Fix the address or remove it.
Up to 10. That includes workspace members you tick and up to 5 outside addresses, each of which confirms by link first.
No, and that's deliberate. A recipient field would let anyone use the form to send mail to any address. Route by a select field in a webhook instead, with the addresses kept in your own code.
No. Every recipient gets a separate email addressed only to them.
Yes, with a webhook. Add a department select to the form, then let a small handler or an automation tool pick the address and send the email.
Stuck on a step, or want a guide for your situation? Email hello@ikiform.com.