Retool setup guide
| Status | Kind | How you connect |
|---|---|---|
| Coming soon | Other | The bubbl3 API with your key |
This guide is coming soon: bubbl3 is still checking it end to end. It shows how Retool will send leads to bubbl3, with nothing to install.
What it does
A Retool REST API resource can call the bubbl3 API from your internal apps and workflows: look up a contact by phone number, add one, or update its name, email and labels, with a key you make for Retool.
Before you start
- A bubbl3 API key just for Retool, made in Developers, API keys. The read scope covers looking contacts up; add admin to create or update them. Use a test key (
b3_test_...) while you build. - A Retool account that can create resources.
Setup
With the bubbl3 API
- In Retool, open Resources, Create new, REST API. Set the base URL to
https://api.bubbl3.com, and add a headerAuthorizationwith the valueBearerand your key. Keep the key in the resource, not in app code. - Find a contact: a query on the resource with
GET /v1/contactsand the URL parameterphone. The answer'sdatalist has the contact if bubbl3 has it. - Add one: a query with
POST /v1/contacts, a JSON body withphone,first_name,last_name,emailandlabels, and anIdempotency-Keyheader made from your record's id, so running it twice doesn't add the contact twice. - Update one: a query with
PATCH /v1/contacts/{id}and the fields to change. - Run each query once with a test phone number before you wire it to a button or a workflow step.
Data shared
From Retool to bubbl3: the fields your queries send.
From bubbl3 to Retool: each query's answer: contacts, with their consent status and labels.
Sending rules that still apply
Retool reaches bubbl3 only through the public API with your key. Every text it asks for goes through the same checks as any API send, and POST /v1/messages/check tells you first why one wouldn't go. No setting turns a check off.
- Consent. bubbl3 never texts a contact who opted out. Contacts Retool 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. - 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 Retool is told when bubbl3 doesn't send
Retool sees bubbl3's answer in the query's result. A refused call answers with an error code and a plain message.
| 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
- Every query counts against your API key's rate limit; a
429says how long to wait. - A contact Retool adds keeps the consent it's given; one whose consent is unknown can be texted unless the workspace is set to text only opted-in contacts. Send
consent_statusand a realconsent_sourceonly for people who agreed to texts. - Updating a contact never changes their consent or opt-out: those come from the contact themselves and your compliance settings in bubbl3.
Troubleshooting
401. The header's value must beBearerand the key, with a space between.403on add or update. The key needs the admin scope to change contacts.409on add. bubbl3 already has a contact with that phone number: find it and update it instead.