Apollo ships a first-party bi-directional Salesforce integration, configured as separate Pull and Push settings. Push is real time; pull runs on a schedule. Most of what goes wrong is not the connection but the org: restricted picklists reject Apollo's values, and the Lead versus Contact choice determines whether you accumulate duplicate people.
What already exists
The integration is first-party and covers Contacts, Leads, Accounts, Deals and Activities, with activities spanning emails, tasks, notes, meeting summaries and calls, each configurable separately. Pull and Push are configured independently, which is genuinely useful because it lets you take data in without writing back while you validate mappings. Push is documented as real time, firing as records are requested or updated. The initial sync can take several hours depending on CRM size.
The detail
Contacts, Leads, Accounts, Deals and Activities, bi-directionally
Activities cover emails, tasks, notes, meeting summaries and calls, each toggled separately
Pull and Push are configured independently, so you can read without writing back
Default mappings ship for standard fields such as First Name, Last Name and Company
Fields Apollo can enrich are marked with a refresh icon in the mapping interface
Apollo writes a default value of 'Apollo' to Lead Source on new contacts and leads
Custom Salesforce fields can be linked to custom Apollo fields, with matching data types required
In practice
Restricted picklists reject Apollo's values, and record types make it worse
This is the dominant failure. Apollo sends a value, Salesforce rejects it with INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST or a bad value error. What makes it genuinely hard is that picklist options vary by record type, so a value that is valid for one record type is rejected for another. An org with several record types will see the integration succeed for some records and fail for others with no obvious pattern, which is why it is usually misdiagnosed as intermittent.
Apollo: access the Salesforce integration error log and picklist errorsThe Lead versus Contact choice generates duplicate people
Push settings let you decide whether new records land as Leads or as Contacts. Salesforce models these as separate objects, so the same person can exist as both without either object considering it a duplicate. This is a classic Salesforce problem rather than an Apollo defect, but Apollo's push settings are where the decision gets made, often without anyone realising a decision was being made.
Apollo: configure Salesforce push settings, Lead versus ContactPaired custom fields with mismatched data types fail on write
Apollo's own guidance is to select the same or a similar data type on both sides to prevent sync errors. In practice the mismatch is usually a text field in Apollo paired to a number, date or picklist in Salesforce. The mapping saves without complaint and fails at write time, which puts the error a long way from its cause.
Apollo: link custom Salesforce fields to custom Apollo fieldsFailures accumulate in a log nobody is watching
Apollo maintains a Salesforce integration error log with the ability to retry from the log after fixing mappings, which is genuinely well designed. The problem is that it is a pull rather than a push: nothing alerts you. Teams typically discover a month of failed records when someone eventually opens it, by which point the gaps are in reporting too.
Apollo: access the Salesforce integration error log and picklist errorsWhen not to hire anyone
The native integration handles standard Lead, Contact, Account and Opportunity sync with activity logging well, and if your org has unrestricted picklists or a single record type, and Apollo is your only CRM-connected prospecting tool, you do not need anyone to build anything. That is a real and common setup. It stops being enough in multi-record-type orgs with restricted picklists where values need transforming before they are safe to write, in orgs that need Apollo alongside another CRM, where assignment rules or duplicate rules have to interact with inbound records, or where the Lead and Contact split needs deliberate reconciliation rather than a setting.
How we build it
We map the picklists first, because that is where the failures are. That means enumerating the allowed values per record type, deciding what Apollo values map onto them, and transforming values before they reach Salesforce rather than discovering the rejection afterwards.
We make the Lead versus Contact decision explicitly and write it down. Which object a new person lands on, what promotes a Lead to a Contact, and what happens when the same person arrives through both paths are business rules, not integration settings, and they need answering before the integration encodes an answer by default.
Where the native constraints bind, particularly the one-CRM limit or field-level conditional logic, we drive Apollo's API through n8n instead. That means owning the sync ourselves, which is more work and is only worth it when the constraint is real.
We put monitoring in front of the error log so failures alert rather than accumulate, and we watch daily API consumption so this integration does not quietly starve the org's other ones. The first version will not have every picklist mapped. What matters is that the rejections are visible the same day rather than the same quarter.
Three to four weeks is typical, and the variable is almost entirely the org's configuration history. A clean single-record-type org is quick; one with years of accumulated record types, validation rules and restricted picklists is not. See how we scope and price this work.
Sources
Related integrations
If you are weighing whether to build this in house or have it built, read what a build like this costs, or see worked examples from real engagements. The vocabulary behind all of this is in the B2B GTM and automation glossary.
Get in touch
Give us some context and we'll come to the conversation prepared. No generic pitch. No obligation.
We review every inquiry personally and respond within one business day.