Gravity SMTP 2.3.3 fixes Zoho delivery problems involving non-US datacenters, CC, BCC, additional To recipients, and expired access tokens. It also repairs email logging for long multibyte subjects and several header shapes. A single test email to the primary mailbox will miss most of these failure modes.
Use this for sites sending customer notifications, store receipts, form alerts, multilingual subjects, regional Zoho accounts, shared inboxes, compliance copies, blind copies, and custom code that adds headers to wp_mail.
Quick answer
Use synthetic mailboxes in each To, CC, and BCC position and a Zoho account in the site's actual datacenter. Send plain ASCII and long multibyte subjects, string and array headers, plus messages before and after token expiry. Record one message marker in the subject and body. Reconcile the WordPress send result, Gravity SMTP log, Zoho API response, provider sent folder, every recipient inbox, duplicate count, and header privacy. The BCC address must receive the message without appearing to other recipients.
Test scenarios to run
Run the same controlled fixture across these branches. Write down the expected result before testing so a surprising response is easy to identify.
| Scenario | Fixture | Expected result |
| Regional account | EU or IN datacenter | Correct API host |
| Multiple recipients | To plus CC plus BCC | Each receives once |
| Expired token | Refresh allowed | One retry, then sent |
| Multibyte subject | Long translated text | Log remains readable |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence | Verification |
| Map the Zoho region | Record Gravity SMTP version, Zoho account region, API base URL, sending identity, token expiry, WordPress locale, mail headers, recipient positions, and the message marker. | To, CC, BCC, and additional recipients each receive exactly one message with the expected headers. |
| Build recipient fixtures | Test one To, multiple To, CC, BCC, additional recipients, reply-to, string headers, array headers, ASCII subject, long accented subject, and non-Latin subject. | The provider host matches the Zoho account datacenter and no cross-region fallback hides an error. |
| Test token failure | Repeat with a valid token, an expired access token with a valid refresh path, a revoked grant, provider throttling, and a network timeout after provider acceptance. | Expired and revoked token branches fail or recover as written without duplicate mail. |
| Reconcile provider evidence | Compare Gravity SMTP email log, Zoho API status, sent folder, provider trace, each inbox, spam folder, message ID, recipient privacy, and retry count. | Long multibyte subjects and string or array headers remain readable in logs and delivered messages. |
What to check first
- Record Gravity SMTP version, Zoho account region, API base URL, sending identity, token expiry, WordPress locale, mail headers, recipient positions, and the message marker.
- Test one To, multiple To, CC, BCC, additional recipients, reply-to, string headers, array headers, ASCII subject, long accented subject, and non-Latin subject.
- Repeat with a valid token, an expired access token with a valid refresh path, a revoked grant, provider throttling, and a network timeout after provider acceptance.
- Compare Gravity SMTP email log, Zoho API status, sent folder, provider trace, each inbox, spam folder, message ID, recipient privacy, and retry count.
- Confirm failures stay visible and actionable; do not mark delivery complete from wp_mail returning true or from one recipient receiving the message.
Field notes
- Write the pass condition before changing anything and keep one repeatable synthetic fixture for the full test window.
- Record exact versions and UTC timestamps because deployments, caches, retries, scheduled actions, and background jobs can change the evidence.
- Test the public path and the stored server-side result, not only an admin preview, isolated command, or API response.
- Repeat verification after the relevant cache, queue, cron, webhook, and observation window has completed.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
$headers = ['Cc: qa-cc@example.test', 'Bcc: qa-bcc@example.test', 'Reply-To: support@example.test'];
wp_mail(['qa-to@example.test', 'qa-second@example.test'], 'SMTP233-ZOHO-001 test', 'Synthetic delivery test', $headers);
Why this usually happens
- An integration assumes every Zoho account uses the US API endpoint.
- Additional recipients are serialized in a shape the provider ignores.
- The plugin refreshes an expired token but repeats a message already accepted.
- Byte length and character length are confused when logging a multibyte subject.
Decision rule
Approve Zoho delivery only when the correct regional endpoint is used, every intended recipient gets exactly one message, BCC remains private, token recovery is bounded, and logs preserve multilingual subjects.
Production verification checklist
- To, CC, BCC, and additional recipients each receive exactly one message with the expected headers.
- The provider host matches the Zoho account datacenter and no cross-region fallback hides an error.
- Expired and revoked token branches fail or recover as written without duplicate mail.
- Long multibyte subjects and string or array headers remain readable in logs and delivered messages.
Safe fix order
Use a sequence that makes each result easy to prove. Stop when new evidence changes the scope or owner of the problem.
- Map the Zoho region
- Build recipient fixtures
- Test token failure
- Reconcile provider evidence
- Verify privacy and retries
Mistakes to avoid
- Changing production before recording exact versions, UTC timestamps, a stable fixture, the expected result, and a tested rollback point.
- Treating one successful screen as proof while stored records, logs, queues, caches, emails, APIs, and downstream systems remain unchecked.
- Testing only as an administrator instead of using the role, device, locale, cache state, payment state, and failure branch that customers reach.
- Leaving temporary exclusions, debug output, test accounts, broad permissions, or one-off repair code active after verification.
Questions teams ask during testing
Can I run this directly in production?
Begin with read-only evidence and use staging for package, database, checkout, form, permission, or security changes. If a production canary is necessary, make it identifiable, reversible, monitored, and unable to expose personal data or charge a customer.
How do I avoid a false positive?
Repeat the same fixture with the same versions, role, URL, locale, cache state, and integrations. Compare browser, stored, API, and log evidence instead of relying on one screen.
What should the evidence packet contain?
Keep UTC time, exact versions, synthetic record ID, expected result, actual result, relevant log lines, change made, rollback point, owner, and final verification. Redact secrets and personal data.
When is the test complete?
Close the work when the primary path passes, failure branches are understood, stored and downstream records reconcile, temporary changes are removed, and monitoring covers the next update.
What to tell the client or owner
Give the owner a concise packet with the affected workflow, exact versions, UTC test time, fixture ID, expected result, actual result, key logs, change made, rollback point, final result, unresolved risks, owner, and next review date. Remove credentials and personal data before sharing it.
When HandL WP should help
Bring in help when this affects leads, checkout, search visibility, security, paid media reporting, or a client production site. HandL WP can trace the issue through WordPress, hosting, cache, tracking, and Search Console, then verify the workflow after the technical fix.
If this is active on a production site, have HandL WP test WordPress email delivery.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references