How a form works
A form is ordinary HTML whose action is a literal path on the same origin:{name}is the form name: lowercase letters, digits, and hyphens (contact,quote-request). The build scans the source for/_cactal/forms/{name}literals; a name that is not in the deployed source is rejected withunknown_form, so write the path as a literal string rather than computing it. A site can have up to 20 forms.- The endpoint accepts
application/x-www-form-urlencoded,multipart/form-data(file parts are rejected), andapplication/json. Repeated field names become arrays. _redirectis the only reserved field: a same-site path to redirect to after a successful browser submission.- The first email field (
type="email"or a field named likeemail) becomes the submitter address and the reply-to of the notification; the firstname,full_name, orfirst_namefield becomes the submitter name. - Limits: 50 fields, 10 KB per value, 64 KB per submission.
Responses
The endpoint answers according to how it was called:
Error codes:
validation (400, with per-field fields), unknown_form (404), payload_too_large (413), rate_limited (429, with Retry-After), limit_reached (403, the Free plan monthly allowance is used up), suspended (451), unavailable (503).
Submissions from the draft preview host are accepted and stored as test submissions (source: "draft"); they never count toward limits and appear under the Test filter.
To also send submissions to a CRM or another service, add a form server function. It runs after spam screening for every accepted submission and never changes what the visitor sees.
Notifications
Every accepted submission is emailed fromYour site via Cactal <forms@cactalforms.com> with the submitter as reply-to, so replying from any mail client reaches the visitor. Each form has its own list of recipients:
- A new form starts by notifying the organization owners. Removing every recipient stops the emails; submissions still land in the Forms tab, and
POST /v1/websiteSourceCode/head/checkreturns a note for each such form unless the website has aformserver function. - An address that belongs to an organization member or website editor receives submissions immediately.
- Any other address must click a confirmation link first (valid for 7 days). Every email carries a link the recipient can use to stop future submissions.
- An address that bounces permanently or complains is marked failing and stops receiving mail; owners are notified. A temporary bounce, such as a full mailbox, does not stop it.
- After 10 immediate emails in an hour, further submissions to the site are batched into one hourly digest per recipient, so a busy form or a bot that slips past the filters never floods an inbox. The Forms tab always shows every submission as it arrives.
Spam
Spam filtering is invisible to visitors: there is no CAPTCHA. Rate limits, a page-load signal, duplicate detection, and link density run on every submission. Every Cactal page sets the page-load signal in the visitor’s browser, so a published submission without it was sent by a script, not from the website, and goes straight to the Spam folder; submissions from framed pages and the draft preview, where browsers block the signal, are exempt. A classifier moves the remaining spam to Spam, with a second model reviewing the submissions it is unsure about. A submission is emailed only after the classifier has screened it: if screening is briefly unavailable, the submission still appears in the Forms tab right away and its email waits for the next hourly retry, and one that still cannot be screened is announced in the hourly digest without its content. Spam never triggers an email, stays for 30 days, and can be restored with Not spam, which sends the missed notification.Plans
Free websites accept 50 published submissions per month, with warnings to owners at 80 percent and at the limit; further submissions receivelimit_reached until the month resets. Pro websites are unlimited. See Plans and limits.
API
GET /v1/websites/{websiteId}/formslists forms with counts, on-site status, recipients, and monthly usage. A form is listed as soon as the draft or published build contains it, so recipients can be set before the first submission.GET /v1/websites/{websiteId}/forms/submissionspages submissions newest first; filter withform,status(inboxorspam), andsource(publishedordraft).PATCHandDELETE /v1/websites/{websiteId}/forms/submissions/{submissionId}mark spam or not spam, and delete.POST /v1/websites/{websiteId}/forms/{formName}/recipientsandDELETE .../recipients/{recipientId}change who a form emails;POST /v1/websites/{websiteId}/forms/recipients/{recipientId}/resendreissues a confirmation.
websiteForms.view capability (content editors and above); recipients need websiteForms.manage (full editors and above). Submission data is personal information: never render it on the public website.