# Forms (https://coss.com/products/forms)

> coss.com Forms is a form backend. Point any HTML form at an endpoint, and every submission is screened for spam and sent to webhooks, email and contacts.

## How it works

Create a form, point your HTML at its endpoint, and handle accepted submissions in a webhook. coss.com does the rest.

```ts twoslash
import { Coss } from "coss";
const coss = new Coss();
// ---cut---
const { data: form } = await coss.forms.create({
  name: "Contact us",
  allowed_origins: ["https://www.example.com"],
  fields: [
    { name: "email", type: "email", required: true },
    { name: "message", type: "textarea", max_length: 5000 },
  ],
  notifications: { recipients: ["support@example.com"] },
});
// form?.endpoint: https://…/f/form_01k…
```

```html
<form action="https://…/f/form_01k…" method="post">
  <input type="email" name="email" required>
  <textarea name="message"></textarea>
  <!-- The honeypot: people leave it empty, bots fill it in. -->
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
  <button>Send</button>
</form>
```

An accepted submission sends `form.submission.received` to your [webhooks](/docs/webhooks) with what was submitted, emails the form's recipients and, if you like, adds the submitter to your contacts. See the [Forms guide](/docs/forms) and the [API reference](/docs/api-reference/forms/create-form).

## Everything a form needs

Collect, screen and deliver submissions from plain HTML, a script, or a page coss.com hosts.

### Any HTML form
The endpoint takes the URL-encoded and multipart posts browsers send, and JSON. Define `fields` to validate types, required values and options, or leave them out and take any field. Redirects go to `_next` or the form's `redirect_url`. See [HTML forms](/docs/forms/html-forms).

### Submits without a page load
`attachForm` from `coss/forms` takes over a form's submit, posts it with a [`coss/device`](/docs/risk/devices) token for Risk and gives you per-field errors. It never throws, and the form still works as plain HTML without JavaScript. See [JavaScript](/docs/forms/javascript).

### Hosted pages
Turn on `hosted` and the endpoint also serves the form as a page, rendered from its fields, to link to or embed. Pages can't ask for passwords, codes or card numbers, and live pages are screened for phishing when published. See [hosted pages](/docs/forms/hosted-pages).

### Spam stays out
A honeypot, then a [Risk](/docs/risk) assessment with your own rules and lists, a content check for spam, phishing, malware and fraud, and an optional Turnstile or hCaptcha. Risk's reviews wait as `held`; release a false positive and Risk learns from it. See [spam filtering](/docs/forms/spam-filtering).

### Delivered where you work
Accepted submissions go to webhooks, to up to 5 notification recipients that can reply straight to the submitter, and into your [contacts](/docs/email/contacts) with their audiences, topics and properties. Each destination retries on its own. See [destinations](/docs/forms/destinations).

### Confirmed addresses
`submitter.verify` holds a submission until the submitter clicks the link emailed to them, and contacts can need double opt-in. File uploads take attachments into `file` fields, served only as downloads. See [double opt-in](/docs/forms/double-opt-in) and [file uploads](/docs/forms/file-uploads).

## Specifications

The limits a submission is checked against. The docs list each one in context.

- Encodings: URL-encoded, multipart, JSON
- Fields per submission: 100, 10,000 characters a value
- Text per submission: 64 KB
- Files: 3 by default, up to 10, 10 MB each
- Files per submission: 25 MB in all
- Notification recipients: up to 5
- Allowed origins: up to 10, https
- Confirmation links: valid for 7 days
- Submissions per form: 10 a second, bursts of 50
- Accepted submissions kept: 90 days
- Spam and unconfirmed kept: 14 days

## Pricing

You pay per accepted live submission, and for the files it carries. Spam, held and unconfirmed submissions cost nothing unless you release them or the submitter confirms.

| Product | Rate | |
| --- | --- | --- |
| Form submissions | $1.00 per 1,000 submissions | |
| Form uploads | $0.25 per 1,000 MB | The files of accepted submissions, kept 90 days; rounded up to the MB per submission |

The Free plan includes 1,000 form submissions a month and 1,000 MB of form uploads a month. Notification and confirmation emails sent from your own domain are billed like any email; notifications sent "via coss.com" are not. See [pricing](/pricing) for the plans.

## Test it in a sandbox

Sandbox forms screen, store and deliver submissions like live ones, and bill nothing.

Forms made with a sandbox (`coss_test_…`) key work end to end, and can allow `http://localhost` while you develop. Notification and confirmation emails go to the sandbox's fake provider, where the dashboard shows them with their links. Risk's test inputs show each outcome: a filled `_gotcha` is `spam`, text with `[coss-test:spam]` fails the content check, and the captcha tokens `test-pass` and `test-fail` pass or fail. See [testing forms](/docs/forms/testing).

## Frequently asked questions

### How do I add a form to a static site without a backend?

Create a form with coss.forms.create() or in the dashboard, then set your HTML form's action to its endpoint. coss.com stores each submission, screens it for spam and sends accepted ones to your webhooks, your team's inbox and your contacts. No server code is needed.

### How does coss.com filter form spam?

A hidden honeypot field catches simple bots at once. Every other submission is a Risk assessment of the submitter's email, IP address, browser and the text they wrote, with your own Risk rules and lists, plus a content check for spam, phishing, malware and fraud and an optional Turnstile or hCaptcha. Spam is answered exactly like a success, so bots learn nothing.

### Can a form send me an email for each submission?

Yes. Up to 5 recipients get an email per accepted submission with every field, replying to the submitter. In live environments, recipients must be members of your organization or addresses on its verified domains.

### Can form submitters be added to my mailing list?

Yes. With contacts turned on, the submitter becomes a contact of the environment, added to the audiences and topics you choose, with fields mapped to contact properties. Double opt-in can make new contacts confirm their address first.

### Do I need to write HTML for a form?

No. Turn on a hosted page and coss.com renders the form from its field definitions, with a honeypot and an optional captcha, at a link you can share or embed in an iframe. It needs no JavaScript.

### Can forms accept file uploads?

Yes. Turn on files and the form takes multipart posts with attachments, 3 files of up to 10 MB each by default and 25 MB per submission. HTML, SVG, scripts and executables are always refused, and files are served only as downloads.
