Canned responses and macros — the reply library model
The reply library is the set of pre-authored content agents send from the inbox. It has two levels, and distinguishing them is the first modeling decision:- A canned response is a named template blob — one reusable message body stored under a shortcut. It is content only: a shortcut like
/hours, a title, a body, and an optional channel scope. When an agent types the shortcut in the composer, the stored body replaces it. - A macro is a canned response plus more: an ordered chain of steps — send a message, add or remove contact tags, assign the conversation, set its status or priority, snooze it, schedule a follow-up, create a task, or escalate to an AI agent. The message step of a macro carries variable placeholders (
{{contact.first_name}},{{agent.signature}}) that resolve against the live conversation when the macro runs.
Scoping — who can see and run each
The two levels carry different scoping rules. Canned responses are one org-wide library. Owners and admins manage the entries through the settings endpoints; every agent in the workspace can use any entry from the composer. There is no personal canned response — the personalization lever on this level is the channel scope, not visibility. An entry with achannel value is offered only on conversations of that channel; an entry with no channel (or the literal all) is offered everywhere. That filtering happens server-side — the inbox composer requests only the active channel’s subset instead of shipping the whole library to client-filter — and the list endpoint clamps any limit you pass to a 500-row maximum.
Macros carry a real access model, the same shape as saved views and routing rules elsewhere in the workspace:
- Personal macros belong to the agent who created them. Only the creator (or an owner/admin) can edit, delete, or run them, and nobody else sees them in the palette or the list.
- Team (shared) macros are created by owners and admins and are readable by everyone in the workspace. Optionally the creator narrows a shared macro to one or more team ids; then only active members of the listed teams see it in their palette. Owners and admins bypass the narrowing and always see the full library.
How resolution works at send time
A macro’s message body is stored with its placeholders unresolved. Resolution happens at run time in a fixed order:- Lookup. Running a macro loads the stored definition, which is the placeholder map against the current conversation.
- Variable interpolation.
{{contact.*}}fields resolve from the contact profile,{{agent.*}}from the running agent’s saved signature and name,{{conversation.*}}from the conversation the macro runs against. Anything that does not resolve renders as an empty string — a typo shows up as a missing word, not as a literal{{...}}in a customer-facing message. - Locale selection. A message step can carry one body per language. The run picks the body matching the conversation’s detected language, falls back to the contact’s stored language, then to English (the required fallback body). One “refund policy” macro serves a multilingual queue.
- Preview before commit. Multi-step macros render every step against the live conversation — variables interpolated, relative times converted to exact timestamps — with zero side effects until the operator confirms. Once fired, re-running the same macro against the same conversation inside 30 seconds is debounced, so a double click cannot double-send.
Where the library appears
The same two libraries surface in three places:- Inbox — the operator picker. The macro palette attached to the composer lists the macros visible to the current agent, grouped by folder, ranked by their own recent run count. Canned responses are reachable through the slash shortcut typed into the composer text. Both are the day-to-day surface.
- Campaigns — the template step. A campaign that needs a reusable body references a carrier-reviewed template by id; a canned response is not a campaign object. The distinction matters: campaigns go through the template lifecycle because they send at scale, while inbox replies go through the reply library because agents send them one conversation at a time.
- Flows — automation steps that send messages resolve the same way a macro’s message step does: either reference an approved template or carry an inline body on a platform-only channel.
A worked example
Create an org-wide canned response scoped to SMS:201 returns the generated id (cr_...) and created_at; a bad shape gets a 422. From then on, every agent can type /refund-sms into the composer of an SMS conversation and have the body replace the shortcut.
The Inbox-use walkthrough for a macro: an agent opens a conversation, presses /, picks Refund policy from the filtered list, and sees the preview — the resolved message body, the tag, the snooze target rendered as an exact time, the disposition label. They confirm, and the chain runs atomically; if the send fails, the reversible steps that already ran (tag, snooze, disposition) roll back, so a half-applied macro never leaves the conversation tagged and snoozed around a message that never went out.
A team-scope example: the support team lead publishes the refund macro as shared, narrowed to the support team. Support members see it in the palette; sales members do not; the owner can still edit the wording after legal review because admins bypass the narrowing. An agent who wants the same chain only for themselves creates it as a personal macro instead — visible and runnable by that agent alone.
See also
- Macros and canned responses guide — the operator walkthrough for building, organizing, and applying both libraries
- Template lifecycle and approval semantics — the carrier-review model macro message steps reference on approval-required channels
- Settings API reference — the canned-response CRUD contract