https://forms.codeaddon.com/s/abc123.action attribute. Submit the form — a new row appears in your sheet.Field name attributes become your sheet's column headers. _gotcha is a hidden honeypot field — leave it empty and hidden.
<form action="https://forms.codeaddon.com/s/your-form-id" method="POST"> <input type="text" name="name" placeholder="Your name"> <input type="email" name="email" placeholder="Your email"> <textarea name="message" placeholder="Message"></textarea> <input type="text" name="_gotcha" style="display:none"> <button type="submit">Send</button> </form>
Send Accept: application/json and the endpoint responds with JSON instead of redirecting. CORS is open (*) so this works from any origin.
fetch(endpoint, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(r => r.json());
// { "status": "success" }
Every field's name attribute maps to a column, matched exactly (case-insensitively) against your header row. New field names become new columns automatically. A Timestamp column is added automatically as the first column when your sheet is empty.
Add a hidden field named _gotcha. Real users never fill it in because it's hidden with CSS; bots that fill every field trip it. When _gotcha is non-empty, the submission is silently dropped — the visitor still sees a normal success response, but nothing is written to your sheet.
By default, visitors are redirected to /thanks/:formId — a plain "Submission received" page. On paid plans you can:
The "Powered by CodeAddon Forms" footer is removed on all paid plans.
All emails send from notify@mail.codeaddon.com with your chosen display name. Reply-To is set to your own email, so replies land in your inbox — the from address itself is always ours (needed for deliverability; user-supplied From addresses would fail sender authentication).
Alerts and auto-responses share one monthly pool per account: Essential 500/mo, Pro 2,000/mo. Over quota, sends are skipped silently — submissions themselves are never affected.
Auto-response supports up to 5 rules: "if field X equals/contains Y → send template B." Rules are checked top to bottom; the first match wins. If nothing matches, the default template is used.
Use {{fieldName}} anywhere in a subject or body to insert a submitted value, e.g. Hi {{name}}, we got your message. Unknown tags are replaced with nothing.
Every auto-response includes a small "Delivered by CodeAddon Forms" footer line, on all plans — this is separate from the "no branding" promise, which covers thank-you pages only.
Set an HTTPS webhook URL and every submission is POSTed there as JSON, 5-second timeout, no retries:
{
"formId": "abc123",
"formName": "Contact form",
"submittedAt": "2026-07-08T09:14:00.000Z",
"data": { "name": "Ada", "email": "ada@example.com" }
}
Free plan: submissions go only to your Google Sheet. We store nothing beyond small counters used for your usage stats.
Paid plans: Cloud Backup keeps a searchable copy of every submission on our servers — 30 days on Essential, 90 days on Pro. From the add-on you can browse it, export it as CSV, or run Restore to sheet, which writes all backed-up submissions into a new tab in your spreadsheet (your live tab is never touched).
| Free | Essential | Pro | |
|---|---|---|---|
| Forms | 3 | Unlimited | Unlimited |
| Submissions/month | 300 | 2,000 | 10,000 |
| Included emails/month | 0 | 500 | 2,000 |
| Cloud Backup | — | 30 days | 90 days |
| Analytics chart | 7 days | 30 days | 90 days |
Usually means the service-account editor was removed from your sheet. Re-create the form link from the add-on sidebar to re-add it.
File uploads aren't supported. Remove enctype="multipart/form-data" from your form tag.
Submissions are rejected with a clear message until your usage resets on the 1st of the month, or until you upgrade.
Check that the submission includes a field with "email" in its name and a valid email value, and that you haven't hit your monthly email quota.