Apollo setup guide
| Status | Kind | How you connect |
|---|---|---|
| Coming soon | Outreach | A Zap or the bubbl3 API with your key |
This guide is coming soon: bubbl3 is still checking it end to end. It shows how Apollo will send leads to bubbl3, with nothing to install.
What it does
Apollo's Zapier app starts a Zap when a contact is created or updated in Apollo. With one Code step, the Zap sends each contact to a bubbl3 lead source, where it becomes (or updates) a bubbl3 contact and can start the source's workflow. If you already read Apollo from your own code, you can add the contacts to bubbl3 with the bubbl3 API instead.
Apollo contacts come from outbound prospecting, so bubbl3 treats them as cold: see the sending rules below.
Before you start
- A bubbl3 Lead URL for Apollo: in Settings, Integrations, under Lead sources, add a Lead URL source, set its labels, owner, consent setting and workflow, and copy its id (
src_...) and signing secret, which is shown once. - A Zapier account that can use Code by Zapier steps.
- Contacts in Apollo with a phone number. A lead needs one.
Setup
With Zapier
- In Zapier, create a Zap with the Apollo trigger New Contact.
- Add a Code by Zapier step (Run JavaScript) and paste the code below.
- In the step's Input Data, add
source_idandsource_secret(from your lead source),toolset toapollo,record_idmapped to the Apollo contact's id, andphone,first_name,last_nameandemailmapped to the contact's fields. - Test the step. The lead shows on the source as received, and the contact in Contacts.
- Turn the Zap on.
With the bubbl3 API
From your own code, find each contact with GET /v1/contacts (by phone), then update it with PATCH /v1/contacts/{id} or create it with POST /v1/contacts, with a label such as apollo and an Idempotency-Key made from the Apollo contact's id. Contacts added this way keep the consent you give them, and one whose consent is unknown can be texted unless the workspace is set to text only opted-in contacts: turn that setting on for outbound lists, or send consent_status and a real consent_source only for people who agreed. The Java and Go samples show the same steps, and the Node SDK has them as methods.
Templates
The Zap's Code step
Zap templates are made in Zapier's own editor, so this is a recipe: add a Code by Zapier step (Run JavaScript) after your Apollo trigger, map the Input Data names in the code's first lines, and paste this code. It signs the lead and sends it to your lead source, with Apollo's record id as the idempotency key.
// Code by Zapier (JavaScript): sends one lead to a bubbl3 lead source, signed with its secret.
// Input Data: source_id, source_secret, tool, record_id, phone, first_name, last_name, email.
const crypto = require('crypto');
// Without the record id every later lead would look like a duplicate, so stop instead.
if (!inputData.record_id) throw new Error("Map record_id to the trigger's record id");
const lead = {
event_id: `${inputData.tool}-${inputData.record_id}`,
phone: inputData.phone,
first_name: inputData.first_name,
last_name: inputData.last_name,
email: inputData.email,
};
const body = JSON.stringify(lead);
const t = String(Math.floor(Date.now() / 1000));
const v1 = crypto
.createHmac('sha256', inputData.source_secret)
.update(`${t}.${body}`)
.digest('hex');
const res = await fetch(`https://api.bubbl3.com/v1/inbound/leads/${inputData.source_id}`, {
method: 'POST',
headers: {
'content-type': 'application/json',
'bubbl3-signature': `t=${t},v1=${v1}`,
'Idempotency-Key': lead.event_id,
},
body,
});
if (!res.ok) throw new Error(`bubbl3 refused the lead (${res.status}): ${await res.text()}`);
output = { received: true, event_id: lead.event_id };
Data shared
From Apollo to bubbl3: each contact's name, phone, email and Apollo id, through the Zap or your code.
From bubbl3 to Apollo: nothing.
Sending rules that still apply
Apollo never texts anyone itself. Its contacts come from outbound lists: they haven't asked to hear from you, which makes them the riskiest texts for a line's health. Every text to them goes through the same checks as a text you send from bubbl3, and nothing in Apollo can turn them off.
- Cold contacts. Contacts that arrive from Apollo are cold contacts. They share each line's normal limit for new contacts below, like everyone else, unless your workspace sets a lower daily limit for cold contacts in compliance settings. When you add or update a contact through the bubbl3 API, send
"outreach_class": "cold"to mark it. On the lead source in bubbl3, tick "Leads come from an outbound tool", so every lead it gets is marked cold. See cold outreach. - Consent. bubbl3 never texts a contact who opted out. Contacts Apollo adds through the bubbl3 API keep the consent you give them: one whose consent is unknown can be texted, unless the workspace is set to text only opted-in contacts. Record each contact's real consent (
consent_statuswith itsconsent_source) when you have it. When you create a lead source, you confirm that everyone you send to bubbl3 has agreed to receive texts from you, so its leads can be texted straight away. - Opt-out. Replying STOP opts a contact out at once.
- Quiet hours. No texts from 8:00 PM to 9:00 AM in the contact's own time zone (from the phone's area code). A text due then waits until the morning.
- Pacing. Each line texts at most 15 new contacts an hour and 50 a day (fewer while a new line warms up), and spaces texts 20 to 90 seconds apart. A big import or batch is queued and sent as the limits allow, never dropped.
- First messages. Until a contact replies, a text can't include links, photos or files, phone numbers or email addresses, must be 300 characters or fewer, and at most 3 texts go out.
What Apollo is told when bubbl3 doesn't send
Apollo isn't told when bubbl3 doesn't send a text: the reason shows on the message in bubbl3, and in the message.status webhook if you use one.
| Reason | Code | What you see |
|---|---|---|
| A link before the contact replies | pre_reply_link_blocked | Not sent: "Links can't be sent until the contact replies" |
| A photo or file before the contact replies | pre_reply_media_blocked | Not sent: "Photos and files can't be sent until the contact replies" |
| A phone number before the contact replies | pre_reply_phone_blocked | Not sent: "Phone numbers can't be sent until the contact replies" |
| An email address before the contact replies | pre_reply_email_blocked | Not sent: "Email addresses can't be sent until the contact replies" |
| A first message that is too long | pre_reply_too_long | Not sent: "First messages must be 300 characters or fewer" |
| Too many texts without a reply | pre_reply_message_limit | Not sent: "Already sent 3 texts without a reply. Wait for the contact to reply" |
| The same text to too many people today | identical_text_limit | Not sent: "This exact text went to 20 people from this line today" |
| The line is paused after unanswered texts | unanswered_streak_limit | Not sent: "This line is paused after too many unanswered texts" |
| The contact opted out | contact_opted_out | Not sent: "The contact opted out of texts" |
| The workspace texts only opted-in contacts | consent_required | Not sent: "This workspace only texts contacts who opted in" |
| No line can reach the contact | line_unavailable | Not sent: "bubbl3's line for this contact isn't available" |
| Quiet hours | quiet_hours | Held: "Scheduled for 9:00 AM America/Chicago, quiet hours" |
| The line's daily limit | daily_new_contact_cap | Held: "Scheduled for Oct 15, 9:00 AM America/Chicago: today's limit for this line is reached" |
| The line's hourly limit of new contacts | hourly_new_contact_cap | Held: "Scheduled for 2:00 PM America/Chicago: this hour's limit of new contacts for this line is reached" |
The numbers are the default limits; a line's own limits change them. bubbl3's other checks (no phone number, a number that doesn't match) have their own plain reasons.
Limits and known gaps
- Zapier's Apollo New Contact trigger can fire up to 30 minutes after a contact is created, while Apollo checks the contact's details.
- A contact without a phone number is refused with "A lead needs a phone number".
- Sending to lead sources is how these contacts enter a workflow; nothing in the Zap texts anyone itself.
Troubleshooting
- The Code step fails with
403. Check the source id and secret, that the source isn't paused, and that the Zap's clock isn't far off (signatures last five minutes). - Contacts arrive but nobody is texted. Check the source's workflow, and whether the line has reached its daily limit for new contacts.