Skip to content
FormSubmit

Sending submissions

Endpoint reference

How the FormSubmit endpoint accepts submissions, what it returns, and every error code.

Every form has one endpoint:

text
POST https://formsubmit.app/f/{formId}

Accepted content types

Content-TypeTypical sourceNotes
application/x-www-form-urlencodedPlain HTML forms (default)Repeated keys and name[] become arrays.
multipart/form-dataForms with enctype="multipart/form-data", FormData in JSRequired for file inputs. About 4.5 MB per request.
application/jsonfetch with JSON.stringifyBody must be a JSON object. Nested values are stored as-is.
text/plainenctype="text/plain", sendBeaconParsed as key=value lines.

Up to 200 fields are stored per submission and each value is capped at 100,000 characters. Field names starting with _ are reserved for control fields and are not stored as data.

Responses

FormSubmit decides between a redirect and JSON:

  • JSON is returned when the body is JSON, the Accept header asks for application/json (without text/html), X-Requested-With: XMLHttpRequest is sent, or the form includes _format=json.
  • Otherwise the response is a 303 See Other redirect.

Success

json
{ "ok": true, "id": "r8T2kLm0Qa9zXc1V", "message": "Thanks! Your submission has been received." }

id is null for forms set to "don't store" and for submissions silently discarded by the honeypot. The message is your form's custom success message if you set one.

For HTML forms the redirect goes to, in order of priority:

  1. The redirect URL in your form settings.
  2. A _redirect (or _next) field in the submission — must match your domain allowlist if one is set.
  3. The hosted thank-you page at https://formsubmit.app/thanks.

Errors

json
{ "ok": false, "error": { "code": "captcha_failed", "message": "Captcha verification failed. Please try again." } }

HTML forms are redirected to a friendly error page instead.

CodeHTTPMeaning
form_not_found404The form id doesn't exist (or was deleted).
form_inactive403The form is paused — manually or because your plan's form limit was reduced.
domain_not_allowed403The Origin/Referer isn't on the form's allowlist.
rate_limited429Too many submissions from one IP (20/min per form) or to one form (600/min).
captcha_failed400Missing or invalid captcha token.
bad_request400The body couldn't be parsed (e.g. invalid JSON).
file_too_large413A file exceeds your plan's per-file limit.
payload_too_large413The whole request exceeds the ~4.5 MB body limit. Use direct uploads.
storage_quota_exceeded507The form owner's file storage is full.
uploads_unavailable503File uploads are temporarily unavailable.
internal_error500Something went wrong on our side. Safe to retry.

CORS

The endpoint answers OPTIONS preflight requests. With no allowlist, any origin may submit. With an allowlist, only matching origins receive Access-Control-Allow-Origin.

Monthly limits

If you're over your plan's monthly submissions, the endpoint still returns success and stores the submission — it is locked until you upgrade or the month resets. Visitors never see an error because of your quota. See limits and plans.

GET requests

Opening the endpoint in a browser shows a short explanation page. Only POST creates submissions.