Instantly setup guide
| Status | Kind | How you connect |
|---|---|---|
| Coming soon | Outreach | A Make template, an n8n template or a Zap |
This guide is coming soon: bubbl3 is still checking it end to end. It shows how Instantly will send leads to bubbl3, with nothing to install.
What it does
Instantly posts a webhook when something happens in a campaign, such as a reply. Make, n8n or Zapier takes that webhook, signs it with your bubbl3 lead source's secret and sends the lead on, so each lead who replies becomes (or updates) a bubbl3 contact and can start the source's workflow, for example to tell your team or follow up by text.
Instantly's leads come from cold email lists, so bubbl3 treats them as cold: see the sending rules below.
Before you start
- Instantly webhooks, on Instantly's Hyper Growth plan or above.
- A bubbl3 Lead URL for Instantly: 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. - Phone numbers on your Instantly leads. Instantly's webhook sends a lead's phone only when the lead has one, and a lead needs one.
Setup
With Make or n8n
- Import the Make blueprint or the n8n workflow below, and paste the source id and secret where the template says.
- Copy the address of the template's first step (Make: the Webhooks module; n8n: the Webhook node's production URL).
- In Instantly, open Integrations, Webhooks, choose Add Webhook, paste the address, choose the Reply received event and the campaigns, (with n8n) add a header matching the Webhook node's Header Auth credential under Add headers, and save.
- Send a test event from Instantly. The lead shows on the source as received. The template's Lead fields step maps Instantly's
phone,firstName,lastName,lead_emailandcompanyName; check them against the test. - Turn the scenario on (Make) or activate the workflow (n8n).
With Zapier
- In Zapier, create a Zap with Webhooks by Zapier, Catch Hook, and paste its address into Instantly's webhook as above.
- Add a Code by Zapier step (Run JavaScript) with the code below. In Input Data, add
source_id,source_secret,toolset toinstantly,record_idmapped to the event'scampaign_idandlead_email, andphone,first_name,last_nameandemailmapped from the event. - Test the step, then turn the Zap on.
Templates
Each template takes Instantly's webhook, sets the lead's fields, signs the lead with your lead source's secret and sends it to bubbl3, with Instantly's record id as the idempotency key, so a retry is the same lead. It never texts anyone itself: your lead source's consent setting and workflow decide what happens next.
- Make blueprint: in Make, create a scenario, open the … menu, choose Import Blueprint and pick the file.
- n8n workflow: in n8n, open a new workflow, open the … menu, choose Import from File and pick the file.
In the n8n workflow's Webhook node, replace the path replace-with-a-long-random-value with a long random value (a new UUID is fine) before you activate it. Anyone who knows the address can post to it, and the workflow would sign what they post, so the path must be one nobody can guess. The node also checks a header: create a Header Auth credential with a header name (such as X-Webhook-Key) and a long random value, choose it on the node (it's named "bubbl3 webhook header"), and have Instantly send that header, as the Setup steps say. Make's webhook address is random already.
After importing, replace PASTE_THE_SOURCE_ID with your lead source's id and PASTE_THE_SOURCE_SECRET with its signing secret. Anyone who can edit the scenario or workflow can read the secret, so share it only with people who could manage the lead source; rotate the secret in bubbl3 if it leaks.
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 Instantly 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 Instantly'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 Instantly to bubbl3: each event's lead email, name, company, phone (when the lead has one) and campaign.
From bubbl3 to Instantly: nothing.
Sending rules that still apply
Instantly 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 Instantly can turn them off.
- Cold contacts. Contacts that arrive from Instantly 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. 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. When you connect Instantly or create a lead source, you confirm that everyone you send to bubbl3 has agreed to receive texts from you, so its contacts can be texted straight away. bubbl3 never texts a contact who opted out, and a workspace set to text only opted-in contacts texts only them.
- 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 Instantly is told when bubbl3 doesn't send
Instantly 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
- One lead per campaign and lead email and event: a repeat of the same event is the same lead.
- A reply without a phone number is refused with "A lead needs a phone number".
- Instantly doesn't sign its webhooks, and the template signs whatever reaches it. Make's webhook address is random; in n8n, give the Webhook node a long random path and keep its header check on. Keep either address private.
Troubleshooting
403from bubbl3. Check the source id and secret, and that the source isn't paused.- Nothing arrives. Check the webhook's event and campaigns in Instantly, and that the scenario or workflow is on.