Whats the best process for converting leads with external ids?

I have an integration where I need to convert leads. The conversion needs to happen on an external id. I can't pass in the Salesforce id, that would be too easy. The best thing I've thought of is to write a webservice that takes a list of lead external ids, creates Database.LeadConvert objects for all the relevant, non converted leads, and then converts them.

This comes at a price though: If I convert leads in the same list, under the same account, I get a "Duplicate Id list" exception thrown.

Here's a code snippet of the web service:

List<Database.LeadConvert> leadConversions = new List<Database.LeadConvert>();
    for(Lead l : 
            External_Id__c in :externalIds 
            and External_Id__c != null 
            and IsConverted=false
         Limit 100]){
        Database.LeadConvert lc = new Database.LeadConvert();

List<LeadConversionResult> lcr = new List<LeadConversionResult>();
Integer i=0;
for(Database.LeadConvertResult r : Database.convertLead(leadConversions,false)){
        new LeadConversionResult(
            r.getErrors().isEmpty() ? null : r.getErrors().get(0).getMessage(),

There is a soap convertLead call I can make, and that DOES handle leads under the same account properly. However, it only takes an Id instead of also external ids. Is there a best practice approach for integrating lead conversions like this, or am I on the right track?

  • Wonder if your leads should be deduped based on external Id perhaps by making it unique do that you only have one instance of a lead. Apr 9, 2013 at 22:22
  • @techtrekker - The external id is unique, and the leads are deduped already. That's not the issue. Most of these leads are under a single account, and when converted in apex, that throws a "Duplicate id in list" exception. Apr 10, 2013 at 14:15

2 Answers 2


Seems like you're pretty close, just need to break up Leads with the same accountId into different batches. You'll want to do some data analysis to see what your worst case scenario is for the number of leads related to the same account and ensure that you won't exceed the max number of DML statements.


Map<Id, List<Database.LeadConvert>> leadConvertMap = new Map<Id, List<Database.LeadConvert>();
for(Lead l : [
  ... query ...
]) {
  Database.LeadConvert lc = new Database.LeadConvert();
  ... set lead convert params ...

  // organize by accountId
  Id accountId = l.contact__r.accountId;
  if(!leadConverMap.containsKey(accountId)) {
    leadConvertMap.put(accountId, new List<Database.LeadConvert>());

// group into batches guaranteeing no dupe accounts
while(true) {
  List<Database.LeadConvert> toConvert = new List<Database.LeadConvert>();
  for(Id accountId : leadConvertMap.keySet()) {
    List<Database.LeadConvert> convertList = leadConvertMap.get(accountId);
    if(!convertList.isEmpty()) {
  if(toConvert.isEmpty()) break;
  Database.convertLead(toConvert, false);

I solved the issue by a series of calls in my integration.

  1. Added the converted leads to a custom object "queue"
  2. Called a custom web service on the target org to get lead ids by external id.
  3. Called convertLead on the target org via the partner wsdl (convertLead supports multiple leads under the same account).
  4. Called custom web service on the source org to remove successful lead converts from the queue

I wrote a blog post about it here: http://codequirk.blogspot.com/2013/04/lions-tigers-and-lead-conversion-oh-my.html

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .