Skip to the page

No-code

Zapier

BlueBot’s Zapier app texts from your own number and starts a Zap when a text comes in, a text changes state or somebody texts STOP. This page lists every trigger, action and search and each of their fields.

The BlueBot app for Zapier joins your number to the apps Zapier connects. A form fills in and the person gets a text from you; a client texts back and the reply goes into your CRM; a text fails and you hear about it in Slack. It has five triggers, eight actions and three searches.

Every trigger is instant. BlueBot posts to Zapier as soon as something happens, so a Zap never waits for a polling interval.

Texts sent through Zapier go through the same sending rules as everything else: pacing, quiet hours, the daily limits and your stop list. A text that can’t go yet is accepted and held, never refused, and the Zap step still succeeds. Each one shows source: "zapier" in BlueBot, so you can tell them apart in the inbox and in your numbers.

Connect your account

The app signs in with an API key. Make one for Zapier alone, so you can revoke it without touching anything else.

Make a key

In BlueBot, open Developers → API keys and press New key. Name it “Zapier” and tick every scope: the triggers need webhooks:manage to subscribe, the contact steps need contacts:read and contacts:write, and the connection test needs account:read. Copy the key. It starts with bb_live_ and is shown once.

Add it in Zapier

Add a BlueBot step to a Zap and press Sign in. Paste the key into API Key and press Yes, Continue to BlueBot. Zapier checks it with GET /v1/me and names the connection after your account’s email address.

Check the connection

You gotIt meansDo next
A connection named after your emailThe key works and can read the account.Pick a trigger or an action.
“That API key isn’t valid”BlueBot doesn’t know the key: mistyped, revoked, or only part of it pasted.Copy the key again, or make a new one. unauthorized
“This key needs the account:read scope”The key was made without account:read.Make a new key with every scope ticked. insufficient_scope

One connection serves every Zap in your Zapier account. To change keys later, open My Apps in Zapier, find BlueBot and press Reconnect. A revoked key makes every Zap that uses it fail with unauthorized until you reconnect.

Triggers

All five are instant. When you turn a Zap on, the app makes a webhook in your BlueBot account that points at the Zap, subscribed to only the events that trigger needs; when you turn the Zap off or delete it, the app deletes that webhook. You can see them under Developers → Webhooks in BlueBot, each described as “Zapier: ” and the Zap’s name. Don’t delete one there while its Zap is on, or the Zap stops hearing anything.

Each trigger’s output is the record as the API returns it (a message, a contact or a sequence enrollment), plus three fields about the event: event_id, event_type and event_timestamp. Zapier flattens nested fields when you map them, so metadata.record_id shows as Metadata Record ID and each file as a line item under Files.

When you press Test trigger, the app reads your three newest matching records from BlueBot, so you map real fields from your own account. If there are none yet, it shows the sample below.

New Incoming Text

Starts when somebody texts your number. Pictures and voice memos come with it as files. BlueBot subscribes the Zap to message.received.

FieldKeyTypeRequiredHelp text
Include Group Chatsinclude_groupsBooleanNoAlso start for texts in group chats. Default: yes.
Only Fromonly_fromStringNoOnly start for texts from this phone number or email address. Leave it empty for everyone.

BlueBot copies the texts of people you’ve texted through it, unless you set Which chats to copy to Everything in Settings → Sending rules. A text from somebody you’ve never texted through BlueBot doesn’t start the Zap until you change that setting.

Sample: New Incoming Text
{
  "id": "msg_4Tz8QvN2pLk7RcYw1HmXe3",
  "object": "message",
  "direction": "in",
  "state": "received",
  "to": "+15555550100",
  "from": "+15555550123",
  "chat_id": null,
  "contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
  "conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
  "text": "Yes, 3 PM works. See you there.",
  "files": [],
  "service": "imessage",
  "source": "mac",
  "metadata": {},
  "reply_to_id": null,
  "received_at": "2026-11-13T19:44:12.000Z",
  "event_id": "evt_7Kd3WnP9xQ2mLc5RvT8bHy",
  "event_type": "message.received",
  "event_timestamp": "2026-11-13T19:44:13.000Z"
}

Text Status Changed

Starts when a text you sent changes state: sent, delivered, read, failed and so on. Use it to write the result back to the record that caused the text, or to hear about failures.

FieldKeyTypeRequiredHelp text
StatesstatesMultiple select: Sent, Delivered, Read, Failed, Unconfirmed, Expired, CanceledYesWhich changes start the Zap. Pick Failed, Unconfirmed and Expired to hear only about texts that didn’t go.
Only With Metadatametadata_keyStringNoOnly start for texts whose metadata has this key, such as record_id, so texts you typed by hand don’t start it.

BlueBot subscribes the Zap to the matching events (message.sent, message.delivered and so on). Delivered and read come only from iMessage, and read only from people who share read receipts, so an SMS goes from sent to nothing more. Message states has the whole picture.

The output is the message as it is after the change, so state, failure and metadata are all there. A failed text carries failure.reason: not_on_imessage, messages_refused or file_unavailable.

New Contact

Starts when a person is added to your contacts: by a first text either way, an import, the API, the website widget, a Text Hook or the dashboard. BlueBot subscribes the Zap to contact.created. It has no fields.

Sample: New Contact
{
  "id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
  "object": "contact",
  "handle": "+15555550123",
  "kind": "phone",
  "first_name": "Maria",
  "last_name": "Lopez",
  "company": null,
  "tags": ["lead"],
  "custom_fields": {},
  "stopped": false,
  "created_via": "widget",
  "created_at": "2026-11-13T19:40:02.000Z",
  "event_id": "evt_2Mx8TqR4vB9nKd1WcY6pLs",
  "event_type": "contact.created",
  "event_timestamp": "2026-11-13T19:40:02.000Z"
}

Contact Stopped

Starts when somebody goes on your stop list: they replied with a stop word, or somebody added them in the dashboard or through the API. Their queued texts are already canceled. Use it to mark them as opted out in your CRM. BlueBot subscribes the Zap to contact.stopped.

FieldKeyTypeRequiredHelp text
Only Repliesonly_repliesBooleanNoOnly start when the person texted a stop word themselves, not when somebody added them. Default: no.

The output is the contact with stopped: true, stopped_at and stop_source (reply, dashboard, api, import or admin).

Sequence Completed

Starts when a person comes to the end of a sequence, or leaves it early because they replied, texted STOP or were taken off. BlueBot subscribes the Zap to sequence.completed.

FieldKeyTypeRequiredHelp text
Sequencesequence_idDropdown of your sequencesNoOnly start for this sequence. Leave it empty for every sequence.
OutcomeoutcomeSelect: Any, Completed, Ended earlyNoDefault: Any.

The output is the enrollment: id (enr_…), sequence_id, contact_id, state (completed, stopped or canceled), stop_reason (replied, stopped, canceled, sequence_archived or failed) and completed_at, plus the contact’s phone number and name as contact_handle, contact_first_name and contact_last_name.

Actions

Every action that sends a text carries an Idempotency-Key made from the Zap’s id and a hash of the step’s inputs. If Zapier runs the step again after a timeout, or you replay the run, BlueBot answers with the text it already accepted instead of sending a second one. The key lasts 24 hours.

That has one effect worth knowing: if the same Zap sends exactly the same words to the same person twice within 24 hours, the second run gets the first text back and nothing new goes. When a Zap should be able to repeat itself, map something unique into Metadata, such as the record’s id or the date.

Send Text

Sends a text from your number now, or as soon as your sending rules allow. The answer is the message, usually state: "queued"; it moves to sent within seconds once your Mac takes it.

FieldKeyTypeRequiredHelp text
TotoStringYes, unless Group Chat is setA mobile number in any format, such as (555) 555-0123; US numbers can leave off the +1. Or an email address the person uses for iMessage.
Group Chatchat_idDropdown of your group chatsNoText an existing group chat instead of one person. Leave To empty. BlueBot can’t start a new group.
TexttextLong textYes, unless Files is setThe words, up to 2,000 characters.
FilesfilesFile, listNoUp to 10 pictures, videos, audio files, PDFs or contact cards (.vcf), each up to 25 MB, sent after the words. The app uploads each one first.
ServiceserviceSelect: Auto, iMessage, SMSNoAuto (the default) uses whatever the newest chat with the person used, else iMessage, and sends an iMessage that never went once more as SMS. iMessage never falls back. SMS needs your iPhone with Text Message Forwarding.
Give Up Atexpires_atDate and timeNoIf the text is still waiting at this time, it expires instead of going late. Default: 24 hours after it’s due (a setting).
MetadatametadataKey and value pairsNoYour own data, kept on the text and sent back on every status change: up to 20 keys of up to 40 characters, values up to 500. Put the record’s id here.

The output is the message. Map id into a later Cancel Scheduled Text, or keep it on your record. If the text is held (quiet hours, your Mac offline, a daily limit), hold.reason and hold.until say why and until when, and the step still succeeds.

A text to somebody on your stop list succeeds as a step but comes back state: "canceled" with cancel_reason: "opted_out", and nothing is sent. Add a Filter after the step on State if later steps should only run for texts that will go.

Send Template

Sends one of your BlueBot templates, filled in with the values you map.

FieldKeyTypeRequiredHelp text
TotoStringYesA mobile number or an iMessage email address, as on Send Text.
Templatetemplate_idDropdown of your templatesYesThe template to send. Its words appear under the field once you pick it.
VariablesvariablesKey and value pairsNoA value for each {{name}} in the template, keyed by the name without braces. A variable you leave out comes from the contact when BlueBot knows it (first_name, last_name, company and custom fields) or from your business name (business), else from the template’s own fallback. One with none of those stops the send, naming it.
ServiceserviceSelect: Auto, iMessage, SMSNoAs on Send Text.
MetadatametadataKey and value pairsNoAs on Send Text.

The output is the message, with the template’s words filled in as text. A variable with no value and no fallback fails the step with invalid_request and the variable’s name, and nothing is sent.

Schedule Text

Schedules a text for a time. Until it’s due it can be changed in BlueBot or canceled with Cancel Scheduled Text. When the time comes it goes through your sending rules like any other text, so a text scheduled inside quiet hours waits for morning.

FieldKeyTypeRequiredHelp text
TotoStringYes, unless Group Chat is setAs on Send Text.
Group Chatchat_idDropdown of your group chatsNoAs on Send Text.
TexttextLong textYes, unless Files is setAs on Send Text.
Send Atsend_atDate and timeYesWhen to send it. Zapier reads times like “tomorrow 9am” in your Zapier time zone.
FilesfilesFile, listNoAs on Send Text. Each file is uploaded when the step runs and kept with the text for up to 30 days, so schedule a text with files at most 30 days ahead.
ServiceserviceSelect: Auto, iMessage, SMSNoAs on Send Text.
Give Up Atexpires_atDate and timeNoDefault: 24 hours after Send At.
MetadatametadataKey and value pairsNoAs on Send Text.

The output is the message with state: "scheduled" and send_at. Keep its id if anything might need to cancel it, such as a booking being moved.

Cancel Scheduled Text

Cancels a text that hasn’t gone yet: one that’s scheduled, or queued and waiting on a hold.

FieldKeyTypeRequiredHelp text
Message IDidStringYesThe msg_ id from the step that scheduled it.

The output is the message with state: "canceled" and cancel_reason: "requested". A text the Mac already took can’t be called back: the step fails with conflict, “Your Mac already took that text, so it can’t be canceled.” Use a Filter on the earlier step’s State if that can happen often.

Create or Update Contact

Finds the person by phone number or email address and updates them, or adds them when BlueBot doesn’t know them.

FieldKeyTypeRequiredHelp text
Phone or EmailhandleStringYesThe person’s mobile number in any format, or an email address they use for iMessage.
First Namefirst_nameStringNo
Last Namelast_nameStringNo
CompanycompanyStringNo
TagstagsString, listNoTags to add. Tags they already have stay.
Custom Fieldscustom_fieldsKey and value pairsNoYour own fields, for templates. A key you send replaces that field; keys you don’t send stay as they were.

A field you leave empty doesn’t clear what BlueBot has. The output is the contact, with created: true when the person was new.

Add Tag

Adds tags to a person, adding them as a contact first if BlueBot doesn’t know them.

FieldKeyTypeRequiredHelp text
Phone or EmailhandleStringYes
TagstagsString, listYesOne or more tags. Tags are matched without regard to case.

The output is the contact with all of its tags.

Enroll in Sequence

Starts a person on one of your sequences. The sequence’s texts go through your sending rules, and by default it stops the moment they reply or text STOP.

FieldKeyTypeRequiredHelp text
Phone or EmailhandleStringYesAdded as a contact if BlueBot doesn’t know them.
Sequencesequence_idDropdown of your sequencesYes
VariablesvariablesKey and value pairsNoValues for the {{name}}s in the sequence’s templates, kept for every step.

A person already in the sequence isn’t started again; the step succeeds and returns the enrollment they’re in. A person on your stop list isn’t enrolled, and the step stops the run as Halted rather than Errored, with BlueBot’s reason. The output is the enrollment: id (enr_…), sequence_id, contact_id, state and the time of the first text.

Remove from Sequence

Takes a person off a sequence. Their texts from it that haven’t gone are canceled.

FieldKeyTypeRequiredHelp text
Phone or EmailhandleStringYes
Sequencesequence_idDropdown of your sequencesNoLeave it empty to take them off every sequence.

The output lists the enrollments that ended. A person in none of them isn’t an error; the list is empty.

Searches

Find Contact

Finds a person by phone number or email address. Turn on Create BlueBot Contact if it doesn’t exist yet? to add them when there’s no match, with the fields of Create or Update Contact.

FieldKeyTypeRequiredHelp text
Phone or EmailhandleStringYesAny format; BlueBot compares numbers in E.164.

Find Conversation

Finds your conversation with a person and its newest text, to check whether they’ve answered before you send something else.

FieldKeyTypeRequiredHelp text
Phone or EmailhandleStringYes

The output is conversation_id, contact_id, last_message_text, last_message_direction (in or out), last_message_at and waiting_on_you, which is true when the newest text came from them.

Check iMessage

Says whether your newest chat with a number used iMessage or SMS. It reads your own Messages history through your Mac and waits up to 15 seconds for it; it calls GET /v1/lookup.

FieldKeyTypeRequiredHelp text
Phone or EmailnumberStringYes

The output is service (imessage, sms or unknown), basis (history, none, device_offline or timeout) and last_seen_at. Apple gives no way to ask about a number you’ve never texted, so a new number answers unknown with basis: "none". You don’t need this step before sending: Service: Auto already tries iMessage and falls back to SMS.

When a step fails

The app turns BlueBot’s error into Zapier’s, with BlueBot’s message, its hint, the error code and the request id, such as “Send to or chat_id. Check the fields named in the message and send it again. (invalid_request, req_1Hq2LxW9cVbN3mKpRtYs0a)”. Quote the request id if you write to support.

BlueBot answersZapier showsWhat to do
invalid_request (400)The step shows as Errored and names the field that didn’t fit.Fix the mapping. A number BlueBot can’t read is the usual cause. More
unauthorized (401)The connection as expired, and an email asking you to reconnect.Reconnect with a working key. More
plan_lapsed (402)The step as Errored.Update the card on the Billing page. More
insufficient_scope (403)The step as Errored, naming the scope.Reconnect with a key that has every scope. More
account_held (403)The step as Errored.Write to support. More
not_found (404)The step as Errored.Check the id you mapped. More
conflict (409)The step as Errored.The record changed first, such as a text already sent. More
rate_limited (429)Nothing at first: the app asks Zapier to try the step again after retry_after seconds.Nothing, unless one key runs many busy Zaps. More
internal, upstream_failed, unavailable (5xx)The step as Errored. With Autoreplay on, Zapier tries again, and the idempotency key keeps that from sending twice.Try again, or replay the run. More

A held text is never an error. A text that fails after it was accepted (Messages refused it, or it was iMessage-only to somebody not on iMessage) isn’t either, because the step already succeeded; catch it with Text Status Changed on Failed.

Your first Zap

Maria runs a cleaning company and keeps new leads in a Google Sheet. This Zap texts each new lead from her own number.

Pick the trigger

Make a Zap with Google Sheets’ New Spreadsheet Row trigger and choose the sheet. Press Test trigger so Zapier loads a row.

Add Send Text

Add a BlueBot step, choose Send Text and pick your connection. Map the row’s phone column into To, and write the text with the row’s name column in it: “Hi Dana, it’s Maria from Sparkle Cleaning. Thanks for asking about a quote. When is a good time to come by?” Map the row number into Metadata under row.

Test it with your own number

Before testing, type your own mobile number into To in place of the mapped column. Press Test step.

You gotIt meansDo next
A message with state: "queued", and the text on your phone a few seconds laterIt works end to end.Map the phone column back into To and turn the Zap on.
state: "queued" with hold.reason: "quiet_hours"It’s inside your quiet hours, so the text waits for morning.Nothing; it goes when quiet hours end. Change them in Settings → Sending rules.
state: "queued" with hold.reason: "device_offline"Your Mac hasn’t checked in for 2 minutes.Wake the Mac and open BlueBot on it. The text goes once it’s back.
invalid_request naming toThe number couldn’t be read.Check what you typed in To.

Turn it on

Turn the Zap on. Each new row now gets a text within seconds, paced 20 seconds apart by default so a big import doesn’t send a burst.

Next, add a second Zap with New Incoming Text that writes each reply back to the sheet, or follow a full walkthrough in A Google Sheets row sends a text. The recipes have one page per app with the exact fields to map.

Using the API directly in a Zap

For anything the app doesn’t have a step for, use Zapier’s Webhooks by Zapier or Code by Zapier with a key and the API. Send Authorization: Bearer <key>, an Idempotency-Key on every POST, and the header BlueBot-Client: zapier so the text shows as sent from Zapier.