A broken form can stop in the browser, be rejected by configuration, or be stored even though an email did not arrive immediately. The fastest route to the cause is to test the flow in order: page code, submission response, ZoraForms dashboard, and only then notification delivery.
Start with the form on the published page
Open the production URL, not only a local preview, and inspect the form element. It needs method="POST" and an action containing the form’s current public identifier. Every field that should be stored needs a name. An id helps JavaScript and labels, but does not make a data key for a regular POST.
If you use fetch, inspect the request address, response status, and error body in browser developer tools. Do not show success just because someone clicked the button. Plain HTML can redirect after success, but a custom script must handle the response itself.
<form action="https://forms.example.com/f/YOUR_PUBLIC_ID" method="POST">
<input name="email" type="email" required />
<textarea name="message" required></textarea>
<button>Send</button>
</form>Compare the page with the form configuration
In the dashboard, check that the website and form are available and that the account has an active license. Compare the allowed origin with the page address: protocol, host, and any port must match. The www version is a different host. ORIGIN_NOT_ALLOWED means source configuration is wrong, not that a field label is wrong.
On Free, check the domain’s DNS TXT proof. Until control of the public domain is verified, new submissions will not be accepted. Also check monthly usage: once the limit is reached, later submissions are rejected, and deleting old records does not restore usage.
- Website and form are available.
- Origin exactly matches the sending page.
- Free has a verified DNS TXT record.
- The monthly limit has not been reached.
Refresh protection code
When you enable CAPTCHA, a honeypot, or a minimum completion time, action alone is insufficient. Download the complete code from Integration after every configuration change and replace the page code. It contains the CAPTCHA token or protection fields the server expects. An old snippet can look correct but still lead to rejection.
For CAPTCHA, also check the credential and key domain. Verification is server-side; an invalid token, provider timeout, or mismatched hostname rejects the submission. This intentional fail-closed behavior is why you should test in a browser on the real domain.
- Save protection configuration in the dashboard.
- Copy a fresh HTML or fetch variant.
- Deploy it to the domain for which the key was created.
- Send a new test; do not reuse an old token.
Separate submission storage, notification, and delivery
If the submission appears in the dashboard, form intake worked. A missing notification email is then a separate delivery, conversation-setting, or receiving-mailbox issue. The dashboard confirms storage; do not assume that a missing inbox message means no submission exists.
With custom SMTP, begin with its connection test. It confirms connectivity and login, not delivery. Conversation history distinguishes queued, sent, and failed messages; “sent” means the mail server accepted it, not that it reached an inbox. Check that status, the sender address, and spam filtering. Customer replies are received through an IMAP mailbox configured by the operator and Reply-To, not by attaching your receiving mailbox.