Admins / Architects / Developers

Sending Emails With Apex: setTargetObjectId() vs. setToAddresses()

By Anand Dosapati

In Salesforce, sending emails through Apex can be achieved using two primary methods: setTargetObjectId() and setToAddresses(). Both methods serve the purpose of specifying the recipients of an email, but they have distinct use cases and advantages.

This article explores these methods, their advantages, and practical scenarios where one might be more beneficial than the other.

Setting the Scene

Imagine you’re a Salesforce Developer tasked with sending congratulatory emails to sales representatives whenever an opportunity is closed. As you dive into Salesforce’s email functionalities, you come across two methods: setTargetObjectId() and setToAddresses(). Understanding the nuances between these methods can help you make an informed decision and leverage Salesforce’s capabilities more effectively.

The Basics

setTargetObjectId(): This method sets the Target Object ID of the recipient, which must be a Salesforce user, contact, lead, or person account. It uses the ID to fetch the email address and other related information of the recipient.

setToAddresses(): This method directly sets the email addresses of the recipients as a list of strings. It does not require the recipients to be Salesforce records.

Deep Dive into setTargetObjectId()

Automatic Linking to CRM Records

  • When using setTargetObjectId(), the email is automatically associated with the recipient’s Salesforce record. This creates a complete activity history, enhancing CRM data quality.
  • Example: Sending an email to the owner of a closed opportunity links the email to the opportunity and the owner’s contact record.

Ease of Use

  • You don’t need to manually handle email addresses. Simply pass the record ID (e.g. User ID, Contact ID), and Salesforce handles the rest.
  • Example: email.setTargetObjectId(opp.OwnerId); automatically resolves the owner’s email address.

Enhanced Personalization

  • Emails sent using this method can leverage Salesforce’s merge fields to include dynamic data directly from the recipient’s record.
  • Example: Personalized greetings using the contact’s first name.

Practical Scenario

You’re managing a large sales team, and you want to send personalized congratulatory emails to sales reps when they close opportunities. By using setTargetObjectId(), you ensure each email is recorded in the rep’s activity history, providing valuable insights into communications and interactions.

Exploring setToAddresses()


  • This method allows you to send emails to any valid email address, not limited to Salesforce records.
  • Example: Sending emails to external partners or customers who are not in your Salesforce database.

Bulk Email Capabilities

  • Easily send emails to multiple recipients by providing a list of email addresses.
  • Example: Announcing a product update to a list of external stakeholders.

Decoupled from Salesforce Records

  • Ideal for scenarios where the recipient does not need to be a Salesforce record or when the email address is dynamic or retrieved from an external system.
  • Example: Sending order confirmations to customer email addresses stored in a separate system.

Practical Scenario

You’re running a marketing campaign, and you need to send promotional emails to a list of prospects whose email addresses are stored outside of Salesforce. Using setToAddresses(), you can target these recipients without creating records for each email address.

Comparing the Two Methods

Association with Salesforce Records

  • setTargetObjectId(): Strong association with Salesforce records, automatically logged as activities.
  • setToAddresses(): No automatic association, suitable for external or non-Salesforce recipients.

Ease of Use

  • setTargetObjectId(): Simplifies personalization and record-keeping.
  • setToAddresses(): Offers flexibility in recipient selection.

Use Case Suitability

  • setTargetObjectId(): Best for internal communications or CRM-centric workflows.
  • setToAddresses(): Ideal for external communications or bulk emails to non-Salesforce contacts.

Apex Code: Leveraging Both Methods

public class SendOpportunityClosedEmails {
    public static void sendEmails() {
        // Query for opportunities closed today
        List<Opportunity> closedOpportunities = [SELECT Id, Name, OwnerId, Owner.Email 
                                                 FROM Opportunity 
                                                 WHERE CloseDate = TODAY AND StageName = 'Closed Won' LIMIT 1];
        // Debug statement to display the number of closed opportunities
        System.debug('Number of closed opportunities today: ' + closedOpportunities.size());
        // Prepare to send emails using setTargetObjectId()
        List<Messaging.SingleEmailMessage> emailsWithTargetObjectId = new List<Messaging.SingleEmailMessage>();
        for (Opportunity opp : closedOpportunities) {
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setSubject('Congratulations on Closing Opportunity: ' + opp.Name);
            email.setPlainTextBody('Congratulations on successfully closing the opportunity ' + opp.Name + ' today!');
        // Send emails using setTargetObjectId()
        if (!emailsWithTargetObjectId.isEmpty()) {

        // Prepare to send emails using setToAddresses()
        List<Messaging.SingleEmailMessage> emailsWithToAddresses = new List<Messaging.SingleEmailMessage>();
        for (Opportunity opp : closedOpportunities) {
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setToAddresses(new String[] { opp.Owner.Email });
            email.setSubject('Congratulations on Closing Opportunity: ' + opp.Name);
            email.setPlainTextBody('Congratulations on successfully closing the opportunity ' + opp.Name + ' today!');
        // Send emails using setToAddresses()
        if (!emailsWithToAddresses.isEmpty()) {


Limits: Two emails were sent, yet the daily limit consumed is only one.

Received Emails:


Both setTargetObjectId() and setToAddresses() are powerful tools in a Salesforce Developer’s arsenal, each with its own set of advantages. Understanding when and how to use each method can significantly enhance your email-sending strategies, ensuring you leverage Salesforce’s capabilities to the fullest.

By carefully choosing the appropriate method based on your specific use case, you can streamline your processes, improve data quality, and enhance communication efficiency within your Salesforce environment.

The Author

Anand Dosapati

Anand Dosapati is a Salesforce Solution Architect with a passion for helping businesses optimize their CRM.


    July 04, 2024 8:17 pm
    So which one consumed the sending limit?
    July 05, 2024 2:34 pm
    Haha I was wondering the same
    July 05, 2024 2:37 pm
    Emails sent using 'setTargetObjectId()' set against the User object do not count against the 'SingleEmailMessage' limit. That means Contact/Lead - does count against limitation, user doesn't. All emails sent by setToAddresses() count

Leave a Reply