# API reference

> The FormDoc submit API: endpoint, content types, reserved fields, limits, responses and every error code.

## Endpoint

`POST https://api.formdoc.dev/v1/submit`

Accepted content types: `application/x-www-form-urlencoded`, `multipart/form-data` and `application/json`. Cross-origin requests are allowed from any site (`Access-Control-Allow-Origin: *`); credentials are never used.

## Reserved fields

These fields control FormDoc and are not stored with the submission. Only `access_key` is required.

| Field | Purpose |
| --- | --- |
| `access_key` | Your form’s public key (`fd_` + 24 characters). Required. |
| `subject` | Email subject |
| `from_name` | Sender display name |
| `redirect` | Where to send the visitor after an HTML post. Must be a full `http` or `https` address. |
| `botcheck` | Honeypot. Must be empty. |
| `cf-turnstile-response`, `h-captcha-response`, `g-recaptcha-response` | Captcha tokens, when the form has a captcha turned on |
| `replyto` | Reply-To address for the notification email |
| `ccemail` | Extra CC for this submission (paid plans; only addresses that confirmed for the form) |
| `_autoresponse` | Set to `off` to skip the autoresponder for this submission (paid plans) |

Fields with the same name, such as a group of checkboxes, are joined with `,` .

## Limits

-   64 KB of text, 50 fields and 10,000 characters per field.
-   10 submissions a minute per visitor per form, 120 a minute per form, and 60 a minute per visitor across all forms.
-   Monthly submissions depend on your [plan](https://www.formdoc.dev/pricing/).

## Responses

**JSON** (when you send JSON or `Accept: application/json`):

JSON

```json
{ "success": true, "message": "Submission received", "submission_id": "01J..." }
```

**HTML form posts** get a `303` redirect: to your `redirect` field, then the form’s redirect setting, then FormDoc’s hosted thank-you page.

Submissions caught by the honeypot or spam scoring get the same success response, so bots learn nothing. They’re stored as spam and you’re not emailed.

## Errors

JSON

```json
{ "success": false, "error": { "code": "invalid_key", "message": "..." } }
```

HTML form posts are redirected to the form’s error page setting, or to a hosted page that explains the problem.

| Code | HTTP | Meaning |
| --- | --- | --- |
| `invalid_request` | 400 | The body couldn’t be read |
| `unsupported_media_type` | 415 | Not one of the three supported content types |
| `payload_too_large` | 413 | Over the size, field or character limits |
| `invalid_key` | 400 | `access_key` is missing or unknown |
| `key_unverified` | 403 | The recipient email address isn’t confirmed yet |
| `form_inactive` | 403 | The form is paused or suspended |
| `origin_not_allowed` | 403 | The website isn’t in the form’s trusted domains (paid plans) |
| `rate_limited` | 429 | Too many submissions; wait for the time in `Retry-After` |
| `captcha_failed` | 400 | The captcha token is missing or invalid |
| `quota_exceeded` | 429 | The monthly limit (plus 10% grace) is reached |
| `files_not_allowed` | 403 | Files were sent but this form can’t accept them |
| `internal_error` | 500 | Our fault. Please try again later. |
