How to add a contact in a sequence in Apollo via API?

Table of Contents

08 Oct 2023

Been struggling with making this work for the last couple days - adding contacts to a sequence in Apollo via API.

As my contacts originate from my own database, I understand I need first to create them in Apollo, to get the contact ID, and then add them to the sequence.

doc

Using this doc:

https://apolloio.github.io/apollo-api-docs/?python#add-contacts-to-sequence

code

Here is my code:

email_account_id = "642**********ed86" # verified as correct

class Lead:
    def __init__(self, first=None, last=None, email=None, title=None, company=None, linkedin=None):
        self.first = first
        self.last = last
        self.email = email
        self.title = title
        self.company = company
        self.linkedin = linkedin

    def __str__(self):
        attributes = ["first", "last", "email", "title", "company", "linkedin"]
        output = ""
        for attr in attributes:
            value = getattr(self, attr, None)
            if value is not None:
                output += f"{attr}: {value}\n"
        return output


# FUNCTIONS

# Get all campaigns IDs and names

def get_dict_campaigns():

    url = "https://api.apollo.io/v1/emailer_campaigns/search"

    data = {
        "api_key": APOLLO_API_KEY,
        # "q_name": "Nic Test 1"
    }

    headers = {
        'Cache-Control': 'no-cache',
        'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, json=data)

    data = response.json()

    campaigns = data['emailer_campaigns']

    dict_campaign_name_id = {
        campaign['name']: campaign['id']
        for campaign in campaigns
    }

    # pp.pprint(dict_campaign_name_id)

    return dict_campaign_name_id


campaigns = get_dict_campaigns()


# Create a contact in Apollo

def create_contact(lead):

    url = "https://api.apollo.io/v1/contacts"

    data = {
        "api_key": APOLLO_API_KEY,
        "first_name": lead.first,
        "last_name": lead.last,
        "title": lead.title,
        "organization_name": lead.company,
        "email": lead.email,
    }

    headers = {
        'Cache-Control': 'no-cache',
        'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, json=data)

    contact = response.json()['contact']

    contact_id = contact['id']

    if verbose:
        print(f"\nℹ️  apollo.create_contact: {lead.email} created with ID {contact_id}\n")

    return contact_id


# Add contact to sequence

def add_contact_to_sequence(apollo_sequence_name, lead_list): # lead_list is a list of Apollo Contact IDs
    global campaigns
    global email_account_id

    try:
        campaign_id = campaigns[apollo_sequence_name]

    except KeyError:
        print(f"\n\n❌ ERROR with campaign name '{apollo_sequence_name.upper()}' does not exist.\n\n")
        campaign_id = None

        return False

    if campaign_id:

        if verbose:
            print(f"\nℹ️  apollo.add_contact_to_sequence: adding {len(lead_list)} leads ({lead_list}) to {apollo_sequence_name} (ID: {campaign_id})\n")

        url = f"https://api.apollo.io/v1/emailer_campaigns/{campaign_id}/add_contact_ids"

        data = {
            "api_key": APOLLO_API_KEY,
            "async": False,
            "contact_ids": lead_list,
            "emailer_campaign_id": campaign_id,
            "send_email_from_email_account_id": email_account_id,
            "sequence_active_in_other_campaigns": False, # Whether to still sequence the contact if he/she is active or paused in another sequence  
            "sequence_no_email": False, # Whether to still sequence the contact if he/she does not have an email address    
            "sequence_finished_in_other_campaigns": False # Whether to still sequence the contact if he/she already finished another sequence   
        }

        headers = {
            'Cache-Control': 'no-cache',
            'Content-Type': 'application/json'
        }

        response = requests.request("POST", url, headers=headers, json=data)

        pp.pprint(response.json())

        return True

## TEST 1

# new_lead = create_contact(Lead
#                             (
#                                 first="Paul", 
#                                 last=f"Atreides {ts_db}", 
#                                 email="test@test.com", 
#                                 title="Mua'dib", 
#                                 company="The Sand Company", 
#                                 )
#                             )

# # add_contact_to_sequence("Nic Test 1", [new_lead,])

## TEST 2

add_contact_to_sequence("Nic Test 1", ["651d8c8ee7b4d10001d37d23",]) # https://app.apollo.io/#/contacts/651d8c8ee7b4d10001d37d23

output

response.json():

ℹ️  apollo.add_contact_to_sequence: adding 1 leads (['651d8c8ee7b4d10001d37d23']) to Nic Test 1 (ID: 651c699754e81b00a3f85017)
{   'contacts': [],
    'emailer_campaign': {   'ab_test_step_ids': [],
                            'active': True,
                            'archived': False,
                            'bcc_emails': '',
                            'bounce_rate': 0.0,
                            'cc_emails': '',
                            'click_rate': 0.0,
                            'contact_email_event_to_stage_mapping': {},
                            'contact_statuses': {   'active': 0,
                                                    'bounced': 0,
                                                    'failed': 0,
                                                    'finished': 0,
                                                    'hard_bounced': 0,
                                                    'not_sent': 0,
                                                    'paused': 0,
                                                    'spam_blocked': 0},
                            'create_task_if_email_open': False,
                            'created_at': '2023-10-03T19:20:55.045Z',
                            'creation_type': 'ai_generated',
                            'days_to_wait_before_mark_as_response': 40,
                            'demo_rate': 0.0,
                            'email_open_trigger_task_threshold': 3,
                            'emailer_schedule_id': '6426675b43030601320ded88',
                            'excluded_account_stage_ids': [   '6426675a43030601320ded16',
                                                              '6426675a43030601320ded17',
                                                              '6426675a43030601320ded18',
                                                              '6426675a43030601320ded19'],
                            'excluded_contact_stage_ids': [   '6426675a43030601320ded13',
                                                              '6426675a43030601320ded12',
                                                              '6426675a43030601320ded0e',
                                                              '6426675a43030601320ded0f'],
                            'folder_id': None,
                            'hard_bounce_rate': 0.0,
                            'id': '651c699754e81b00a3f85017',
                            'is_performing_poorly': False,
                            'label_ids': [],
                            'last_used_at': '2023-10-08T08:05:46.777+00:00',
                            'loaded_stats': True,
                            'mark_finished_if_click': False,
                            'mark_finished_if_interested': True,
                            'mark_finished_if_reply': True,
                            'mark_paused_if_ooo': True,
                            'max_emails_per_day': None,
                            'name': 'Nic Test 1',
                            'num_contacts_email_status_extrapolated': 0,
                            'open_rate': 0.0,
                            'opt_out_rate': 0.0,
                            'permissions': 'team_can_use',
                            'prioritized_by_user': None,
                            'remind_ab_test_results': False,
                            'reply_rate': 0.0,
                            'same_account_reply_delay_days': 30,
                            'same_account_reply_policy_cd': None,
                            'sequence_by_exact_daytime': None,
                            'sequence_ruleset_id': None,
                            'spam_block_rate': 0.0,
                            'starred_by_user_ids': [],
                            'underperforming_touches_count': 0,
                            'unique_bounced': 0,
                            'unique_clicked': 0,
                            'unique_delivered': 0,
                            'unique_demoed': 0,
                            'unique_hard_bounced': 0,
                            'unique_opened': 0,
                            'unique_replied': 0,
                            'unique_scheduled': 0,
                            'unique_spam_blocked': 0,
                            'unique_unsubscribed': 0,
                            'user_id': '6426675b43030601320ded86'},
    'emailer_steps': [   {   'ab_test_details': {},
                             'auto_skip_in_x_days': None,
                             'counts': {   'active': 0,
                                           'bounced': 0,
                                           'finished': 0,
                                           'hard_bounced': 0,
                                           'not_sent': 0,
                                           'paused': 0,
                                           'spam_blocked': 0},
                             'emailer_campaign_id': '651c699754e81b00a3f85017',
                             'exact_datetime': None,
                             'id': '651c699754e81b00a3f8501b',
                             'max_emails_per_day': None,
                             'note': '',
                             'position': 1,
                             'priority': None,
                             'type': 'auto_email',
                             'wait_mode': 'day',
                             'wait_time': 100},
                         {   'ab_test_details': {},
                             'auto_skip_in_x_days': None,
                             'counts': {   'active': 0,
                                           'bounced': 0,
                                           'finished': 0,
                                           'hard_bounced': 0,
                                           'not_sent': 0,
                                           'paused': 0,
                                           'spam_blocked': 0},
                             'emailer_campaign_id': '651c699754e81b00a3f85017',
                             'exact_datetime': None,
                             'id': '651c699754e81b00a3f85020',
                             'max_emails_per_day': None,
                             'note': '',
                             'position': 2,
                             'priority': None,
                             'type': 'auto_email',
                             'wait_mode': 'day',
                             'wait_time': 3},
                         {   'ab_test_details': {},
                             'auto_skip_in_x_days': None,
                             'counts': {   'active': 0,
                                           'bounced': 0,
                                           'finished': 0,
                                           'hard_bounced': 0,
                                           'not_sent': 0,
                                           'paused': 0,
                                           'spam_blocked': 0},
                             'emailer_campaign_id': '651c699754e81b00a3f85017',
                             'exact_datetime': None,
                             'id': '651c699754e81b00a3f85025',
                             'max_emails_per_day': None,
                             'note': '',
                             'position': 3,
                             'priority': None,
                             'type': 'auto_email',
                             'wait_mode': 'day',
                             'wait_time': 3}],
    'emailer_touches': [   {   'bounce_rate': None,
                               'click_rate': None,
                               'demo_rate': None,
                               'emailer_step_id': '651c699754e81b00a3f8501b',
                               'emailer_template_id': '651c699754e81b00a3f8501d',
                               'generic_personalized_opener': None,
                               'hard_bounce_rate': None,
                               'has_personalized_opener': None,
                               'id': '651c699754e81b00a3f8501e',
                               'include_signature': False,
                               'open_rate': None,
                               'opt_out_rate': None,
                               'personalized_opener_fallback_option': None,
                               'reply_rate': None,
                               'spam_block_rate': None,
                               'status': 'approved',
                               'type': 'new_thread',
                               'unique_bounced': 0,
                               'unique_clicked': 0,
                               'unique_delivered': 0,
                               'unique_demoed': 0,
                               'unique_hard_bounced': 0,
                               'unique_opened': 0,
                               'unique_replied': 0,
                               'unique_scheduled': 1,
                               'unique_spam_blocked': 0,
                               'unique_unsubscribed': 0},
                           {   'bounce_rate': None,
                               'click_rate': None,
                               'demo_rate': None,
                               'emailer_step_id': '651c699754e81b00a3f85020',
                               'emailer_template_id': '651c699754e81b00a3f85022',
                               'generic_personalized_opener': None,
                               'hard_bounce_rate': None,
                               'has_personalized_opener': None,
                               'id': '651c699754e81b00a3f85023',
                               'include_signature': True,
                               'open_rate': None,
                               'opt_out_rate': None,
                               'personalized_opener_fallback_option': 'send_without_opener',
                               'reply_rate': None,
                               'spam_block_rate': None,
                               'status': 'approved',
                               'type': 'reply_to_thread',
                               'unique_bounced': 0,
                               'unique_clicked': 0,
                               'unique_delivered': 0,
                               'unique_demoed': 0,
                               'unique_hard_bounced': 0,
                               'unique_opened': 0,
                               'unique_replied': 0,
                               'unique_scheduled': 0,
                               'unique_spam_blocked': 0,
                               'unique_unsubscribed': 0},
                           {   'bounce_rate': None,
                               'click_rate': None,
                               'demo_rate': None,
                               'emailer_step_id': '651c699754e81b00a3f85025',
                               'emailer_template_id': '651c699854e81b00a3f85027',
                               'generic_personalized_opener': None,
                               'hard_bounce_rate': None,
                               'has_personalized_opener': None,
                               'id': '651c699854e81b00a3f85028',
                               'include_signature': True,
                               'open_rate': None,
                               'opt_out_rate': None,
                               'personalized_opener_fallback_option': 'send_without_opener',
                               'reply_rate': None,
                               'spam_block_rate': None,
                               'status': 'approved',
                               'type': 'reply_to_thread',
                               'unique_bounced': 0,
                               'unique_clicked': 0,
                               'unique_delivered': 0,
                               'unique_demoed': 0,
                               'unique_hard_bounced': 0,
                               'unique_opened': 0,
                               'unique_replied': 0,
                               'unique_scheduled': 0,
                               'unique_spam_blocked': 0,
                               'unique_unsubscribed': 0},
                           {   'bounce_rate': None,
                               'click_rate': None,
                               'demo_rate': None,
                               'emailer_step_id': '651c699754e81b00a3f8501b',
                               'emailer_template_id': '651d887f6ef23700bc309a13',
                               'generic_personalized_opener': None,
                               'hard_bounce_rate': None,
                               'has_personalized_opener': None,
                               'id': '651d887f6ef23700bc309a15',
                               'include_signature': True,
                               'open_rate': None,
                               'opt_out_rate': None,
                               'personalized_opener_fallback_option': 'send_without_opener',
                               'reply_rate': None,
                               'spam_block_rate': None,
                               'status': 'to_be_reviewed',
                               'type': 'new_thread',
                               'unique_bounced': 0,
                               'unique_clicked': 0,
                               'unique_delivered': 0,
                               'unique_demoed': 0,
                               'unique_hard_bounced': 0,
                               'unique_opened': 0,
                               'unique_replied': 0,
                               'unique_scheduled': 0,
                               'unique_spam_blocked': 0,
                               'unique_unsubscribed': 0}],
    'signals_hash': None,
    'team': {'id': '6426675a43030601320ded0a', 'sequences_finder_empty': False}}

Issue is that an empty list is returned as contacts, and the contact is not added to the sequence.

tried

  • creating a new Contact, getting its ID, and adding it to the sequence AND passing the ID of an existing Contact in Apollo
  • with & without passing async, sequence_active_in_other_campaigns, sequence_no_email & sequence_finished_in_other_campaigns
  • with & without sequence being active
  • adding to different sequences

links

social