> ## Documentation Index
> Fetch the complete documentation index at: https://apidoc.mailercloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect forms to your audience

> Grow lists from your website: Mailercloud webforms, or wire any third-party form (Wix, WordPress, custom) to the contacts API.

There are two ways to feed website signups into Mailercloud.

## Option 1 — Mailercloud webforms (no code)

Build a form in the app under **Audience → Webforms**, style it, and embed the generated snippet on your site. Submissions land directly in the connected list — no API work needed. You can list your forms programmatically with [Webform list](/api-reference/webforms/webform-list).

## Option 2 — Any third-party form via the API

If your form lives in Wix, WordPress, Framer, or your own code, point its submit handler (or the form platform's webhook) at a small endpoint on your server that forwards to Mailercloud:

```javascript Node.js form handler theme={null}
app.post("/newsletter-signup", async (req, res) => {
  await fetch("https://cloudapi.mailercloud.com/v1/contacts/upsert", {
    method: "POST",
    headers: {
      Authorization: process.env.MAILERCLOUD_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      email: req.body.email,
      first_name: req.body.name,
      list_id: process.env.LIST_ID,
      tags: ["signup-website"],
    }),
  });
  res.redirect("/thanks");
});
```

<Warning>
  Always call the Mailercloud API from your **server**, never from browser JavaScript — your API key must not be exposed to visitors, and the API does not support CORS requests by design.
</Warning>

Use **upsert** (not create) so repeat submissions update the existing contact instead of failing, and add a `tags` value per form so you can tell your signup sources apart — see [Sync contacts in real time](/guides/contact-sync).
