Skip to the page

Concepts

Templates

Save a text once with variables in it, then send it by id from the API, MCP, broadcasts, sequences and keyword replies, filled in for each person.

A template is a text you save once and send many times, with {{variables}} where each person’s details go. Dana’s team sends the same showing reminder a dozen times a week, so she saved it:

Text
Hi {{first_name|there}}, see you at {{time}} at {{address}}.

Make templates on the Templates page or with POST/v1/templates. Each has a name, unique among your templates, and an id that starts tpl_.

Variables

A variable is a name in double braces. When a template is sent, each one is filled from the first of these that has a value:

  1. What the sender passed for this send: variables on POST/v1/messages, a column of a broadcast’s CSV, or a field a Text Hook received.
  2. The person’s contact: first_name, last_name, full_name, company, phone, email, and any custom field by its name ({{showing}}, or {{custom.showing}} to be explicit).
  3. business: your business name from Settings (business_name on GET/v1/settings). Until you set one it has no value, so use a fallback such as {{business|us}} or set the name first.

{{name|fallback}} gives the words to use when a variable has no value. Hi {{first_name|there}} reads “Hi Maria” for Maria and “Hi there” for somebody with no name on file.

A variable with no value and no fallback is left out, with the space before it when punctuation follows, so Hi {{first_name}}, … reads “Hi, …”. A broadcast, a sequence or a keyword reply sends it that way. A send through the API or MCP refuses instead, so your code finds out before anybody gets a text with a gap in it.

Sending one from the API

Send template_id in place of text, and variables for anything the contact doesn’t already have:

POST/v1/messagesSend a text →
curl -X POST "https://usebluebot.com/api/v1/messages" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: showing-48213-reminder" \
  -d '{
    "to": "+15555550123",
    "template_id": "tpl_1Hq2LxW9cVbN3mKpRtYs0a",
    "variables": {
      "time": "3 PM",
      "address": "412 Oak St"
    }
  }'

The text is filled in when BlueBot accepts it, so the answer carries the finished words, and source_ref is the template’s id. Changing the template afterwards doesn’t change texts already sent or scheduled. Send a text has every field of a send.

You gotIt meansDo next
201The template was filled in and the text accepted.Read text in the answer to see the words that will go.
400 invalid_request naming variables.timeThe template needs time, and neither your variables nor the contact had it.Send it in variables, or add a fallback such as {{time|soon}}.
400 invalid_request naming template_idYou sent text and template_id together.Send one of them.
404 not_found naming template_idNo template of yours has that id, or it was deleted.List yours with GET /v1/templates.

Where else templates are used

  • The inbox. The composer’s template menu fills one in for the person you’re texting, and you edit it before sending.
  • Broadcasts, sequences and keyword replies can each send a template in place of their own words, filled in for each person. Sequences and keyword replies read the template each time they send, so an edit changes their next text. A broadcast copies the template’s words when you make it.
  • MCP. send_template fills one in for an AI assistant, with the same rules as the API. MCP tools

Keeping them

A template is your own content, so BlueBot keeps it for as long as you do, unlike the words of a sent text, which go after 30 days. Data retention