Zoho Forms looks like a Typeform clone with a CRM connector. For a contact-us page, fine. For a multi-step demo request, an event registration, or a partner application, you need to know what the docs do not tell you.
1. CRM push happens once. Edits do not re-sync.
If a respondent edits their submission via the Forms edit link, Forms updates its own record. CRM does not get a second webhook. To fix, switch the integration mode from “Push on Submit” to “Push on Update too” and select the field-level merge strategy. Most teams want “Forms wins” for contact info and “CRM wins” for owner and stage.
2. File uploads need the WorkDrive bridge
A file upload field does not push the actual file to CRM Attachments. It pushes a Forms URL. When you delete the form three years later, the attachment dies. Configure the form to drop files into a specific WorkDrive folder, then store the WorkDrive permalink in a CRM URL field. Permalinks survive form deletion.
3. Conditional logic does not transmit through
If your form shows Field B only when Field A equals “Enterprise”, the CRM record gets Field B as blank for SMB respondents. That blank overwrites existing data on update. Use a default value of __SKIP__ in hidden conditional fields and a Workflow Rule that ignores updates equal to __SKIP__.
4. Spam protection is your job
Forms has reCAPTCHA but it is off by default. Worse, the integration creates a CRM Lead before reCAPTCHA verifies. Turn on “Verify before push” in the integration tab. Add a honeypot field. For high-value forms, gate with email verification before CRM creation.
5. The Deluge tab inside Forms is more powerful than people use
You can run server-side logic on submit, before CRM sync, with full access to Zoho APIs. Use it for enrichment, dedupe, and routing.
// On Submit script inside Zoho Forms
domain = input.Email.subString(input.Email.indexOf("@") + 1);
if(domain.containsIgnoreCase("gmail") || domain.containsIgnoreCase("yahoo"))
{
input.Lead_Quality = "Personal_Email";
}
existing = zoho.crm.searchRecords("Contacts","(Email:equals:" + input.Email + ")");
if(existing.size() > 0)
{
// Update Contact instead of creating Lead
zoho.crm.updateRecord("Contacts", existing.get(0).get("id"), {"Last_Form":input.Form_Name});
input.Skip_CRM_Push = true;
}
Bonus: payment forms and CRM amount fields
If you collect payment via Forms, the integration writes the payment status but not the amount in the local currency you expect. Multi-currency setups need a Deluge step that converts and writes to CRM Amount in base currency.
What to do this week: pick your highest-volume form, add the on-submit Deluge for dedupe, and switch file uploads to WorkDrive so submissions outlive the form.