# 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.

Published 2026-10-25 · https://ikiform.com/guides/send-form-to-email/multiple-recipients

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

Diagram: One submission, one email per recipient

1. The form posts once to Ikiform.
2. Ikiform builds the recipient list: the members ticked for this form, or the workspace default, plus outside addresses that confirmed.
3. Duplicates are dropped and the list stops at 10.
4. Each recipient gets a separate email, so nobody sees the others' addresses.
5. Addresses still waiting for confirmation, and addresses paused after a bounce, are skipped.

Separate copies mean one person replying doesn't copy in the rest. Decide who answers what before you add five people.

1. Open the form in the dashboard, then **Settings** and **Notifications**. Make sure **Email new submissions** is on.
2. Tick each workspace member who should get email. Only members with a verified address are listed.
3. For anyone outside the workspace, enter their address under **Add someone outside the workspace** and press **Send link**. You can add 5 per form.
4. 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.

> Need more than 10 people, or a team that changes often? Add one shared address, such as a Google Group or a mail alias, as the only recipient and manage who's in it there.

### Members and outside addresses

The two kinds of recipient behave differently, which matters when you decide who to add where:

|   | 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:

`contact.html`:

```html
<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:

`app/api/route-message/route.ts`:

```ts
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.
- `replyTo` keeps **Reply** pointing at the visitor, as Ikiform's own email does.
- `idempotencyKey: event.id` makes a retried delivery send nothing new. Ikiform retries a delivery that doesn't get a `2xx`, with the same id.
- A `502` when 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](https://ikiform.com/docs/webhooks.md) cover retries and the payload. Prefer no code? A [Zapier](https://ikiform.com/blog/form-submissions-to-zapier.md) or [n8n](https://ikiform.com/blog/form-submissions-to-n8n.md) 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

1. Check every recipient row in the form's **Notifications** settings. None should say **Waiting for confirmation**.
2. Fill in the form on your page and submit it. You land on your thank-you page, or Ikiform's hosted one.
3. Each recipient gets their own email. Ask one of them to check the **To** line: it shows only their address.
4. If you route by webhook, submit once per department and check the delivery log under **Webhooks**. Each shows `succeeded`.
5. 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](https://ikiform.com/docs/webhooks.md).

## Questions

### What happens if a recipient's address bounces?

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.

### How many email addresses can one form send to?

Up to 10. That includes workspace members you tick and up to 5 outside addresses, each of which confirms by link first.

### Can the form choose who receives the email?

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.

### Do recipients see each other's addresses?

No. Every recipient gets a separate email addressed only to them.

### Can I send sales and support messages to different people?

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.

## More guides

- [Send a form to your email](https://ikiform.com/guides/send-form-to-email.md): Get every form submission in your inbox without a mail server: why mailto: and PHP mail() fail, and a setup that filters spam and lets you reply.
- [Reply from your inbox](https://ikiform.com/guides/send-form-to-email/reply-to.md): Make Reply on a form notification write to the person who filled in the form: which field names work, when to use _replyto, and why replies go astray.
- [To Gmail](https://ikiform.com/guides/send-form-to-email/gmail.md): Get form submissions in Gmail without mailto: links, app passwords or Apps Script, then label them, keep them out of spam and reply from Gmail.
- [Next.js](https://ikiform.com/guides/send-form-to-email/nextjs.md): Two ways to email a Next.js form with a Server Action: send it yourself with Resend or Nodemailer, or forward it to a form backend, compared honestly.
- [Without PHP](https://ikiform.com/guides/send-form-to-email/without-php.md): Replace a contact.php script that calls mail() with a form that posts to a hosted endpoint, keeping your field names, your thank-you page and replies.
- [EmailJS alternative](https://ikiform.com/guides/send-form-to-email/emailjs-alternative.md): Move a contact form off EmailJS: why browser-side email keys are a risk, what changes in your code, and what you give up, such as the auto-reply.
