What This Is
This is a one-directional, write-oriented integration. Propensity pushes qualifying account and contact records, along with a defined set of standard and custom fields, into Apollo via its bulk REST endpoints, using per-user bearer-token authentication and idempotent create/update semantics.
When To Use This
Use this technical reference when you need to understand exactly what data Propensity writes to Apollo, how authentication works, or how to troubleshoot sync behavior for this integration.
This integration pushes qualifying accounts and contacts into Apollo whenever a configured alert condition fires (an account visits the customer's website, a contact visits the site, or a lead's warmth score becomes "hot"). Each Propensity workspace can configure one or more alerts targeting Apollo, each with its own trigger type and optional "ICP Only" filter that restricts the sync to accounts matching the customer's Ideal Customer Profile.
The single read operation involved is a metadata lookup of Apollo's custom field schema, used to map Propensity's data correctly into the customer's existing Apollo custom fields. It does not pull Apollo record data back into Propensity.
Authentication
Each sync run authenticates to Apollo using a bearer token tied to the specific Propensity user and workspace that owns the alert (Authorization: Bearer <token>, Content-Type: application/json). The token is retrieved from Propensity's stored credential store per user/workspace pair rather than a single shared key, so API activity in Apollo can be attributed back to the Propensity user who configured the alert. If a workspace has no valid Apollo credential on file, that workspace's Apollo alerts are skipped for the run.
API Endpoints Used
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/v1/fields?source=custom | Reads Apollo's custom contact field definitions (field ID, type, picklist options) so Propensity can map its own data points to the correct Apollo field IDs before writing. |
| POST | /api/v1/accounts/bulk_create | Creates or resolves existing Apollo accounts by domain, in batches of up to 100. |
| POST | /api/v1/contacts/bulk_create | Creates or resolves existing Apollo contacts (run_dedupe: true), in batches of up to 100. |
| POST | /api/v1/contacts/bulk_update | Writes standard and custom field values onto existing Apollo contacts, in batches of up to 100. |
The only read call in this integration is the custom-fields lookup, and it reads Apollo's field schema (labels, IDs, types), not contact or account records. No Apollo contact/account/activity data is pulled back into Propensity's own systems as part of this process. The data flow is a one-way push from Propensity into Apollo.
What Triggers a Sync
A sync runs per workspace, per configured alert, and sources candidate accounts/contacts from Propensity's data based on the alert's trigger type:
Website Visit: accounts that visited the customer's website within the lookback window, expanded to their associated buying-circle contacts.
Contact Website Visit: specific contacts identified in contact-level website tracking data.
Lead Becomes Hot: contacts/accounts whose Propensity warmth score changed to "hot" within the lookback window, using either account-centric or contact-centric scoring depending on the alert configuration.
In all three cases, candidates are excluded if they lack a work email, have already been pushed for that specific alert, are on the workspace's suppression/opt-out list, are marked as an existing customer or have an open opportunity (website-visit trigger only), or fall outside the ICP filter when "ICP Only" is enabled on the alert configuration in Propensity.
Data Written to Apollo
Accounts
For each unique company domain among eligible contacts, Propensity submits:
| Apollo field | Source |
|---|---|
| name | Company name (title-cased) |
| domain | Company website domain |
bulk_create is idempotent. Apollo returns both newly created and already-existing accounts, and Propensity uses the returned account ID to link new contacts to the correct account.
New accounts are only created in Apollo if Propensity doesn't find an existing account with the same domain value as the contacts the integration is attempting to sync.
Contacts - standard fields
Contacts are created via bulk_create, then matched back to the created/existing Apollo record (first by email, falling back to a company + first name + last name match) for the subsequent update pass. On create, and only when the corresponding field is currently blank on the Apollo contact, Propensity writes:
| Apollo field | Source |
|---|---|
| first_name | Contact first name (title-cased) |
| last_name | Contact last name (title-cased) |
| title | Job title (title-cased) |
| organization_name | Company name (title-cased) |
| website_url | Company website |
| present_raw_address | City, region, country (concatenated) |
| mobile_phone | Mobile phone |
| direct_phone | First available phone number |
Email is used only as a match key to find/create the Apollo contact. It is not overwritten on existing records by this job.
Contacts - custom fields
Propensity looks up each of the following by label against Apollo's custom-field schema (via the GET /fields call) and, if a matching contact-modality field exists in the customer's Apollo instance, writes a typed value via typed_custom_fields on bulk_update:
| Apollo custom field label | Source | Written on |
|---|---|---|
| Existing Customer | Propensity CRM match | Website Visit / Contact Website Visit alerts |
| Open Opportunity | Propensity CRM match | Website Visit / Contact Website Visit alerts |
| Last Website Visit | Most recent visit date | Website Visit / Contact Website Visit alerts |
| Warmth | Propensity warmth score | Lead Becomes Hot alerts |
| Warmth Reason | Most recent warmth-change reason | Lead Becomes Hot alerts |
| Warmth Change Date | Date warmth score changed | Lead Becomes Hot alerts |
Values are type-coerced to match each field's Apollo type before sending: dates/datetimes to ISO-8601, booleans to Apollo's yes/true/1 convention, numeric/currency values stripped of non-numeric characters, and picklist values matched to the corresponding Apollo option ID by label. If a required custom field isn't found in the customer's Apollo instance (e.g., it hasn't been created there, or is misnamed), that value is simply omitted from the update rather than failing the whole request.
Batching, Rate Limits, and Error Handling
All bulk operations (account create, contact create, contact update) are chunked into batches of 100 records to stay within Apollo's bulk endpoint limits. Propensity checks each response and handles Apollo's documented error codes: 401 (invalid/expired API key), 403 (insufficient permissions), 422 (invalid payload), and 429 (rate limited). On a 429, the current alert's processing stops for the remainder of that run so it doesn't compound the rate limit. Any records already successfully created or updated up to that point are retained, and the rest are picked up on the next scheduled run.