# Form endpoint reference

> The SiteBackend form endpoint in detail - request formats, field rules, special fields, responses, status codes and CORS.

Source: https://sitebackend.com/docs/reference/form-endpoint · Updated: 2026-09-28

Every form has one endpoint. It accepts submissions from any page on an allowed origin.

```txt
POST https://api.sitebackend.com/forms/YOUR_FORM_ID
```

## Which request formats are supported?

| `Content-Type`                      | Typical source                                                     | Notes                           |
| ----------------------------------- | ------------------------------------------------------------------ | ------------------------------- |
| `application/x-www-form-urlencoded` | A plain HTML `<form>`                                              | The default for HTML forms.     |
| `multipart/form-data`               | `<form enctype="multipart/form-data">` or `FormData` in JavaScript | Required for file uploads.      |
| `application/json`                  | `fetch` with `JSON.stringify`                                      | The body must be a JSON object. |

Anything else is rejected with `400 Unsupported content type`.

## How are fields stored?

- Every field is stored under its `name`.
- A name used more than once (checkboxes, multi-selects) is stored as a list: `tags=a&tags=b` becomes `["a", "b"]`.
- **Fields whose name starts with `_` are never stored.** Use them for control fields such as the honeypot.
- Captcha tokens (`cf-turnstile-response`, `h-captcha-response`, `g-recaptcha-response`) are checked, then discarded.
- A submission with no stored fields is rejected with `400 Submission is empty`.
- Size limits: at most 200 fields, 64 KB per field and 256 KB of field data in total. Without file uploads, the whole request can be up to 512 KB.

## Which fields have special meaning?

| Field     | Purpose                                                                                                        |
| --------- | -------------------------------------------------------------------------------------------------------------- |
| `email`   | Used to create a contact and show who wrote in. Configurable per form (**Settings → Contacts → Email field**). |
| `name`    | Used as the contact's name when a new contact is created.                                                      |
| `_gotcha` | The default honeypot. If it has any value, the submission is treated as spam. Configurable per form.           |

## What does the endpoint respond with?

The response depends on how you send the request.

**HTML form posts** get a `303` redirect:

- on success, to your form's redirect URL, or to the SiteBackend thank-you page if none is set;
- on error, to the thank-you page with the error message.

**JSON requests** (when the request's `Content-Type` is JSON or its `Accept` header includes `application/json`) get JSON back:

```json
{ "ok": true, "id": "cmuhalcxn0008kcitf4c9oyk7" }
```

```json
{ "ok": false, "error": "Too many submissions, try again shortly" }
```

Submissions caught as spam still return `{ "ok": true, "id": null }`, so bots can't tell they were filtered.

## Status codes

| Status | When                                                                                                       |
| ------ | ---------------------------------------------------------------------------------------------------------- |
| `200`  | Accepted (JSON requests).                                                                                  |
| `303`  | Accepted or rejected (HTML form posts); follow the redirect.                                               |
| `400`  | Unsupported content type, invalid JSON, empty submission, too many fields, or captcha verification failed. |
| `403`  | The form is paused or archived, or the request's origin isn't allowed.                                     |
| `404`  | No form with that ID.                                                                                      |
| `413`  | The submission is too large: see the size limits above, or the file limits for forms with uploads.         |
| `429`  | More than 5 submissions a minute from the same visitor, on the same form.                                  |

## What about the monthly limit?

The endpoint never refuses a submission because of your plan. On Free, submissions past the monthly limit are accepted like any other (`200` or the redirect), saved, and hidden in the dashboard until you upgrade. See [plans and limits](https://sitebackend.com/docs/workspace/plans-and-limits).

## CORS

For `fetch` requests from the browser, the endpoint answers `OPTIONS` preflight requests and sends `Access-Control-Allow-Origin`:

- `*` when the form has no allowed origins;
- the request's own origin when it's on the allowed list.

Allowed headers are `Content-Type` and `Accept`.
