FormThunder isn't open yet. This site describes the service as it will run at launch. Find out more

FormThunder
Menu

Forms, updated

Submit API and fields

The submit API is one endpoint: POST https://formthunder.com/submit, or POST https://formthunder.com/submit/{formId} with the key in the path. It accepts JSON, URL-encoded and multipart bodies, CORS is open, and the field names match Web3Forms. Any field that isn't reserved is forwarded as-is, and a field's name is its label in the email.

Request

bash
curl -X POST https://formthunder.com/submit \
  -H "Content-Type: application/json" \
  -d '{"access_key":"YOUR_ACCESS_KEY","name":"Priya","email":"priya@example.com","message":"Hello"}'

The access key is the form's ID. It's public by design, because it can only send to recipients you've verified.

Reserved fields

FieldWhat it does
access_keyIdentifies the form. Required unless the ID is in the URL.
subjectEmail subject. Overrides the form's setting.
from_nameSender name shown in the inbox.
replytoReply-to address.
emailThe visitor's address. Stored as the sender and used for replies and the autoresponder.
ccemailCC addresses, comma-separated. They must be verified linked emails. Pro.
redirectAbsolute URL to send a plain HTML form post to.
botcheckHoneypot. Any value other than false or off marks the submission as spam.
webhookHTTPS URL to post this one submission to. Pro.
attachmentFiles, or upload IDs from the uploader. Pro.
h-captcha-responsehCaptcha token.
cf-turnstile-responseTurnstile token. Pro.
g-recaptcha-response, recaptcha_responsereCAPTCHA token. Pro.
preheaderPreview text in the email.

A field name ending in [] is treated as a list, so colors[] arrives as colors.

Response

A JSON or fetch request gets JSON back.

json
{
  "success": true,
  "message": "Your message was sent.",
  "submission_id": "8f14e45f-...",
  "body": { "data": { "name": "Priya", "message": "Hello" }, "message": "..." }
}

A plain HTML form post gets a 303 to redirect, or to the default success page. If it fails, the 303 goes to /submit/error with the reason. A failed JSON request gets success: false, a message and sometimes a hint. A successful one may also carry warnings, for things like ignored files.

Status codes

CodeMeaningWhat to do
200Stored. Deliveries are queued.Nothing.
303Stored. Redirecting a plain form post.Nothing.
400Bad request: missing key, bad JSON, failed captcha.Read message.
403The form is paused, or the origin isn't on its allowed domains.Add the domain or resume the form.
413Too large.Bodies stop at 6 MB and direct files at 5 MB. Use the uploader.
429Over 30 requests a minute from this IP to this form.Wait a minute.
503We couldn't store it. Sent with Retry-After.Retry after that many seconds.

Limits

A submission can hold up to 100 fields, and each value up to 50,000 characters. Longer values are trimmed.

What happens next

The submission and its delivery jobs are written to Postgres in one transaction before you get a success reply. A background worker then sends the email and any webhooks or chat messages, and retries failures for up to 24 hours. See how that's built.