# Xodia Forms: connect a form

URL: https://docs.xodia.ai/content/forms
Last updated: 2026-11-08

Xodia Forms receives the forms on your site for you. Turn it on for a form in the Settings panel, and every message reaches your team by email and waits in the Content tab, checked for spam, wherever your site is hosted.

_Picture: A contact form selected on the Xodia canvas, with Send to Xodia Forms turned on in the design panel: this month's submissions and See messages, the form's name, two members and an address waiting for confirmation who get emails, an email for each message, Show a message after sending with the success and error text, the fields Xodia keeps, and the form's address and method set by Xodia Forms._

Xodia Forms comes with every plan, within its monthly submissions. Every plan It works on React sites, such as the Xodia template, and on plain HTML sites.

## Connect a form

1. Select the form on the canvas

   Click the form itself, not a field inside it; the breadcrumbs or the Navigator help you pick it. To add a new one, open Add elements and choose a form or a form section from the Forms category: Xodia offers to turn on Send to Xodia Forms as soon as it is on the page.
2. Name each field

   Xodia keeps the fields that have a name, such as name, email and message. Select a field and set its name in Settings if it has none.
3. Turn on Send to Xodia Forms

   In the Settings panel's Form section, turn on Send to Xodia Forms. Xodia writes the form's address and a hidden spam trap into your code, and Fields Xodia keeps lists the names it found.
4. Choose who gets emails

   Under Who gets emails, add a member of your workspace or type any address. An address outside your workspace gets an email first, and messages go to it once its owner confirms. If nobody gets emails, messages still show in the Content tab.
5. Save and publish

   The form's new address is a change like any other edit: update your live site on Xodia hosting, or publish it to your own host. Until then, the live site still sends the form wherever it did before.

> **Tip:** Test the form from your live site or its Preview. Your form only accepts messages from your site's own addresses: its xodia.site address and custom domains on Xodia hosting, or the address of the host you connected in Xodia and its deploys. If visitors on your own host are told the form can only be sent from its own website, connect the host your site is on.

## Form settings

| Setting | What it does |
| --- | --- |
| Name | The form's name in the Content tab and in emails, such as Contact or Class booking. |
| Who gets emails | Members of your workspace, and other addresses once they confirm. Each one gets an email for every message, and replying goes to the visitor when the form has an email field. |
| Notifications | Each message sends an email as each message comes in. Daily digest sends one email a day with the previous day's messages. |
| After a visitor sends it | Show a message in place of the form, or go to a page on your site, such as /thanks. |
| Success and Error | The text visitors see when their message was sent, or when it couldn't be. |
| Fields Xodia keeps | The field names Xodia stores. After you add, rename or remove a field, choose Refresh to read them again. Fields not on this list are dropped. |
| Bot check | Checks that a person sent the form, usually with no puzzle to solve. See [Bot check](https://docs.xodia.ai/content/forms#bot-check). |
| Webhooks | Addresses that get each message as JSON. See [Webhooks](https://docs.xodia.ai/content/forms#webhooks). |

While the form is connected, its Action and Method are set by Xodia Forms. To send a form somewhere else, leave Send to Xodia Forms off and set them yourself.

Turn the switch off and the form's own address comes back; the messages it already got stay in the Content tab.

A form inside a component is connected inside the component, so every copy of it on your site sends to the same form.

## Read and export messages

_Picture: Xodia's Content tab on the Forms group: All forms with 8 messages from a bakery's Contact, Class booking and Newsletter forms, unread ones marked, with search, a form picker, dates, Inbox, Unread and Spam, Export CSV and this month's submissions against the plan._

Open the Content tab: the Forms group under your collections lists All forms and each form, with its unread count. Choose one to see its messages.

- Search messages, pick a form, and set From and To to narrow by the day they were sent.
- Inbox shows messages that aren't spam, Unread the ones nobody opened yet, and Spam the ones the checks caught.
- Tick messages to Mark read, Mark unread, mark them as Spam or Delete them.
- Open a message to see every field, the page it came from and when it was sent, with Reply by email when it has an address.
- Export CSV downloads what the list shows, with one column for each field.

## Spam

_Picture: A message Xodia Forms marked as spam, open in the Content tab: the note says no email was sent, because it was sent too fast for a person and had too many links, with Not spam and Delete._

Each message is checked as it arrives: a hidden trap field that people never fill in, how fast the form was sent, how often one visitor sends, too many links, and the same message sent again. Spam goes to the Spam view with the reasons it was caught, no email goes out for it, and it doesn't count toward your monthly submissions. Choose Not spam to move a message back to the inbox.

## Bot check

_Picture: The contact form's Form section in the design panel, scrolled down: the fields Xodia keeps, Bot check turned on under Spam, and under Webhooks one address whose last send worked, with Send test and Remove, and a field to add another._

Bot check, under Spam in the Form section, makes sure a person sent the form before the message reaches you. It runs in the background on Xodia's forms address and only asks a visitor to tick a box when something looks off. A message that fails the check isn't kept, and the visitor sees your error text.

- New forms have it on by default on paid plans. On Free it starts off, and you can turn it on.
- The spam checks above run either way, with Bot check on or off.
- Without JavaScript, the visitor sees a short check page, and the message is sent after it.

## Webhooks

A webhook sends each message to another app as it comes in, such as a CRM, a spreadsheet or your own server. Under Webhooks in the Form section, type the address and choose Add.

1. Add the address

   Use a public https address. Local, private and Xodia addresses can't receive webhooks.
2. Copy the signing secret

   Xodia shows the webhook's signing secret once, right after you add it. Keep it in your app's settings. To get a new one, remove the webhook and add it again.
3. Send a test

   Send test posts a sample message with your form's own field names, and the row tells you whether it worked or why it didn't.

Each row shows the address, a switch to turn it off and on, and how its last send went, with Send test and Remove. Spam is never sent to a webhook. If your app doesn't answer, Xodia tries again a little later; a webhook that keeps failing is turned off, and the workspace owners and admins get an email. Fix the address or your app, then turn it on again.

Webhooks count for the whole workspace: 1 on Free, 3 on Starter and no set limit on Pro and Agency. See [pricing](https://xodia.ai/pricing).

Each send is a POST with a JSON body like this:

Webhook body:

```json
{
  "event": "submission",
  "id": "sub_8fQ2",
  "form": { "id": "frm_7Kq2", "name": "Contact" },
  "project": { "id": "prj_3Lm9", "name": "Bakery" },
  "page": "/visit",
  "fields": {
    "name": "Ana",
    "email": "ana@example.com",
    "message": "Do you bake for weddings?"
  },
  "createdAt": "2026-11-05T09:30:00.000Z"
}
```

A test has `"event": "test"`. The `X-Xodia-Event` header says the same, and `X-Xodia-Delivery` carries an id that stays the same when a send is tried again.

To check that a request came from Xodia, read the `X-Xodia-Signature` header. It looks like `t=1793872200,v1=5d41...`: `t` is the time in Unix seconds, and `v1` is the hex HMAC-SHA256 of the time, a dot and the raw body, keyed with the webhook's signing secret. Work out the same value in your app, compare the two, and refuse requests whose time is more than a few minutes old.

Check a signature (Node.js):

```js
import { createHmac, timingSafeEqual } from "node:crypto";

// header: the X-Xodia-Signature value
function fromXodia(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(
    header.split(",").map((part) => part.split("=")),
  );
  const expected = createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  return (
    fresh &&
    expected.length === v1.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
  );
}
```

## Notifications and the daily digest

Under Notifications, choose how the people under Who gets emails hear about new messages:

- **Each message:** an email as each message comes in. Replying goes to the visitor when the form has an email field.
- **Daily digest:** one email a day with the previous day's messages, and a link to the rest in the Content tab when there are many.

A workspace that sends a very large number of notification emails in a month switches every form to the daily digest until the month ends, and the Form section says so. Messages still reach the Content tab as usual.

## Templates with working forms

Fernbook, Northwind, Atelier Nine, Rye and Ember, Mara Lind and Stillwater Physio connect their contact form to Xodia Forms when you make a project from them. You are the one who gets emails at first; add your team under Who gets emails. Publish the site and the form works. See [templates](https://xodia.ai/templates).

## Forms and your AI

When you [connect your own AI](https://docs.xodia.ai/ai), it can work with Xodia Forms over MCP as a member of your workspace:

- `list_forms` lists the site's forms with their settings, unread and kept messages, and anything in the code that stops messages arriving, with the fix.
- `connect_form` connects a form in your code, the same as turning on Send to Xodia Forms, as an edit you review and save. Who gets emails, Bot check, notifications and webhooks stay in the Settings panel.
- `list_submissions` reads your forms' messages, newest first, a page at a time. It only reads: it never marks a message read, changes or deletes it, and spam is left out unless your AI asks for it.

When your AI runs the links check, it warns about forms that send nowhere and forms that open an email app with `mailto:`, and suggests turning on Send to Xodia Forms instead.

## Limits and how long messages are kept

| Plan | Submissions a month | Kept for |
| --- | --- | --- |
| Free | 50 | 30 days |
| Starter | 500 | 1 year |
| Pro | 2,500 | 2 years |
| Agency | 10,000 | 2 years |

Submissions count for the whole workspace, and you can have as many forms as you like. Spam is kept for 7 days. Workspace owners get an email as you near the limit. Past it, new messages are still kept for a while, but emails pause until the next month; upgrade to get them again. See [pricing](https://xodia.ai/pricing).

## If a form won't connect

- **This form has its own submit code:** the form runs code when it is sent, which would stop the message reaching Xodia. Choose Remove the submit code when Xodia offers it, or ask your AI to connect the form.
- **This form has no fields with a fixed name:** give each field a name in its settings, then turn the switch on again.
- **Not kept, followed by a field name:** Xodia Forms never accepts passwords, card numbers or similar fields such as bank account or ID numbers. Remove the field, or use a service built for payments or sign-in.

## Your visitors' data

For each message, Xodia stores the fields your form sends, the page it came from, when it was sent, the visitor's browser details and a one-way code made from their IP address, used for rate limits. Raw IP addresses are never stored. You decide what your forms collect, so mention them in your own site's privacy policy. How Xodia handles this data is in the [privacy policy](https://xodia.ai/privacy) and the [data processing addendum](https://xodia.ai/dpa).

Deleted messages leave the Content tab straight away and are erased within 30 days. Turning Xodia Forms off for a form keeps its messages; deleting the project deletes its forms and their messages. For CMS collections, see [CMS collections](https://docs.xodia.ai/content).
