Zoho Campaigns
Add or unsubscribe Zoho Campaigns contacts from your forms, with answers mapped to their contact fields.
Zoho is an add-on for Forms. Each form gets a Zoho panel where you add actions. An action adds the person who submitted to a Zoho Campaigns mailing list, or unsubscribes them from one. It works with Zoho Campaigns lists only, not Zoho CRM, Desk or Books.
Connect Zoho
Zoho doesn't use a simple API key. You create an app in Zoho's API Console, then approve it once for the whole site.
In WordPress, open XPAC → Integrations → Zoho. Under Create a Zoho app, copy the redirect URL.
In the Zoho API Console, click Add Client and choose Server-based Applications. Enter a Client Name and your site address as the Homepage URL, paste the copied URL into Authorized Redirect URIs, and click Create.
On the app's Client Secret tab, copy the Client ID and Client Secret into Client ID and Client Secret in WordPress.
Set Zoho data center to match the domain you sign in to Zoho with, such as Europe (.eu) for zoho.eu. It starts on United States (.com).
Click Authorize with Zoho → and approve access. The screen then reads Connected to Zoho Campaigns.
Click Test connection. It reads your lists and names the first one it finds. It sends nothing.
The Client ID and Client Secret stay visible to admins on this screen. A wrong data center usually fails with The authorization code is invalid or expired. Re-authorize; a mismatched data center is usually why.
Keep the connection working
Connected to Zoho Campaigns means Zoho answered for this site in the last 12 hours. After that the screen reads Connected, not checked since a date: opening the screen starts a check in the background, or click Test connection. If Zoho refuses the connection, the screen reads Not connected with Zoho's reason, and every admin screen shows a notice until the connection works again.
Under Connection details:
- Renew token gets a new access token from Zoho now.
- Re-authorize with Zoho approves the saved app again. Use it after a refused connection.
- Disconnect clears the saved keys and the webhook URL, and asks Zoho to revoke this site's access. On a copy of the site that shares the live site's keys, this cuts off the live site too.
If you change the Client ID or data center on a connected site, the new values are saved only once Zoho approves them. Back out of Zoho's screen and the old connection keeps working.
Unsubscribes and bounces
This is optional. Click Show webhook URL and add it in Zoho Campaigns under
Settings → Developer Space → Webhooks: one webhook per event, sending the
contact's email as contact_email, with the URL ending in &event=unsubscribe or
&event=bounce. Keep the URL private. After a disconnect, show the URL again and
update it in Zoho.
The site keeps the last 200 addresses Zoho reports. They change nothing until you turn on Don't re-add reported contacts. Then an address Zoho reported as unsubscribed or bounced isn't added to a list again, and the delivery notes it.
Add it to a form
Edit the form, open the Zoho panel in the sidebar and click Add Zoho action.
- Action: Add contact, which also updates existing contacts, or Remove contact, which unsubscribes the address from the list and leaves an address that isn't on it alone.
- List: one of your Zoho Campaigns lists.
- Field mapping: pair each Form field with a Zoho field. Contact Email is required and the rest are optional. Remove contact uses only the email address.
Save the action, then save the form. Save stays off until you pick a list and map a form field to Contact Email. Make that form field required.
Zoho's contact fields belong to your account, so every list offers the same ones. Answers are sent as text, and several ticked answers are joined with commas. File uploads aren't offered. If you rename or delete a mapped field in Zoho, the row is flagged in the editor, and deliveries can fail naming that field until you pick it again. Lists and fields are read when you open the form, so reload the editor to see ones you just made in Zoho.
Each row in the panel shows the action and its list. Use the switch to turn an action off without deleting it. With Forms' conditional logic, an action can run only when the answers match. The add-on sends no confirmation email of its own, so ask for consent on the form. The XPAC Agent can also connect a form to a list for you.
When a send fails
Sends run in the background a moment after the submission is saved, so the visitor never waits. Each one shows on XPAC → Forms → Deliveries:
| Status | What it means |
|---|---|
| Waiting | Queued, or waiting for its next automatic try. |
| Delivered | Zoho accepted it. The Notes column lists anything left out. |
| Skipped | There was nothing to send. The Error column says why. |
| Failed | It didn't go through. The Error column has the reason. |
| Dismissed | You dismissed it, or the submission is in spam or the trash. |
What Zoho outcomes look like:
- An empty email answer is Skipped. If another action in the same submission went through, the delivery is Delivered with a note instead.
- Adding someone already on the list, or removing someone not on it, is Delivered.
- A contact kept off by Don't re-add reported contacts is Delivered with a note.
- An address Zoho refuses, such as an invalid one or a group address like info@, is Failed and isn't retried.
- If the site isn't authorized, or Zoho refuses the connection, the delivery is Failed with a message asking you to re-authorize.
A timeout, a rate limit or a server error is retried on its own after about 1, 5, 30 and 120 minutes, up to five tries. Other failures stay Failed until you act. Fix the cause, then click Retry now on the delivery, or Retry all failed. A retry sends with the form's current settings and the connection saved now. Actions that already went through aren't sent again unless you've changed them since.
If 5 deliveries in a row fail on one form, XPAC pauses Zoho Campaigns on that form and emails the site admin. A refused address, an empty email answer and a rate limit don't count toward this. While it's paused, submissions are still saved but show as Failed, and XPAC tries one submission an hour. If that one goes through, sending starts again on its own. To start sooner, fix the cause and click Resume and retry on the Deliveries screen.
For developers
| Hook | Type | What it does |
|---|---|---|
xpac_zoho_webhook | Action | A webhook call was accepted: $event (unsubscribe, bounce, spam or subscribe), $email, $params. |
xpac_zoho_contact_suppressed | Action | A reported contact was not sent: $email, $item, $submission. |
xpac_zoho_suppress_reported_contacts | Filter | Whether a reported contact is kept off the list: $suppress, $email, $record. Default: the Don't re-add reported contacts setting. |
xpac_zoho_typed_contact_fields | Filter | Send dates and numbers in Zoho's own field types instead of text: $typed, $item. Default false. |
xpac_zoho_date_format | Filter | Date format used when typed values are on: $format, $uiType. Default m/d/Y. |
xpac_zoho_request_timeout | Filter | Seconds to wait for Zoho. Default 10. |