# Stylo Documentation (Complete)
Stylo is an AI-powered customer support platform that helps teams generate grounded replies, configure workflow-based responses, and increase automation deliberately.
This file is a machine-readable export of the documentation corpus. Each page section includes its title, canonical path, optional description, and processed page text.
---
# Analytics and Operations
URL: /analytics-and-operations
Type: concept
Description: See what your workflows did, find and diagnose failed runs, and handle anything waiting for human review.
Keywords: analytics, operations, execution history, runs, metrics, logs, approvals
Once your workflows are running, you'll want to know what they did, catch anything that failed, and clear anything waiting on a person. Stylo gives you three views for that — **Logs**, a per-workflow **Execution History**, and **Execution Detail** — plus an **Approvals** queue for steps that pause for review.
{/* TODO(docs): screenshot — Logs page with the run table and an Execution Detail panel open. Tracked in public/images/README.md. */}
Find a recent run: Logs [#find-a-recent-run-logs]
The **Logs** page is the fastest way to see everything that ran across your workspace. Start here when you know something happened recently but not which workflow or run to look at.
You can:
* Search runs and filter by status
* Scan the workflow name, trigger, duration, and start time
* Open any run in a side-by-side detail view
Focus on one workflow: Execution History [#focus-on-one-workflow-execution-history]
Every workflow has its own **Execution History**. Use it when you want to look at a single workflow — compare its recent runs, or check whether a change you made affected how it behaves.
Diagnose a run: Execution Detail [#diagnose-a-run-execution-detail]
Open a run to see its full record. Depending on what happened, you'll see:
* A success summary, or a failure message and error code
* Whether it's queued, in progress, or waiting for approval
* Timing details and the run's event timeline
{/* TODO(docs): GIF — opening a run from Logs and inspecting its detail. Tracked in public/images/README.md. */}
What a run's status means [#what-a-runs-status-means]
| Status | What it means |
| ------------------------ | ------------------------------------------------------------------ |
| **Pending** | The run is queued and hasn't started. |
| **Running** | Work is in progress. |
| **Waiting for approval** | A person needs to approve the next step before it continues. |
| **Succeeded** | The workflow finished without error. |
| **Failed** | The run ended with an error — open it to see the message and code. |
Clear human-review steps: Approvals [#clear-human-review-steps-approvals]
When a workflow pauses for a person to weigh in, that handoff lands in **Approvals**. Check it when:
* A workflow is waiting for review
* A backlog run produced items to approve
* A higher-risk action needs sign-off before it runs
Execution Detail will tell you a run is waiting for approval, but you act on it in the Approvals queue.
A good order for investigating an issue [#a-good-order-for-investigating-an-issue]
Start in **Logs** and find the run.
Open its **Execution Detail** and read the status, summary, error code, and timeline.
If it's waiting on a person, go to **Approvals**.
If one workflow keeps failing, open that workflow's **Execution History** to see the pattern.
A dedicated analytics dashboard isn't available yet — today's review tools are
Logs, Execution History, Execution Detail, and Approvals.
Related [#related]
* [Workflow testing and execution history](/response-workflows/testing-and-history) for testing and reviewing a single workflow
* [Backlog runs](/response-workflows/backlog-runs) for bulk runs that feed into Approvals
* [Troubleshooting](/troubleshooting) for fixing common failures
---
# Assist Sidebar Layout
URL: /assist-sidebar-layout-settings
Type: reference
Description: Control which blocks appear in the Assist sidebar, in what order, and which ones agents can't hide.
Keywords: assist sidebar layout, copilot layout, assist, layout, sidebar blocks, blocks
Assist Sidebar Layout controls which blocks appear in the Assist sidebar and in what order. Use it to put the most useful information first, remove blocks your team doesn't use, and keep required blocks visible for every agent.
{/* TODO(docs): Screenshot of the Assist Sidebar Layout settings page showing the block list, drag handles, and Enabled and Locked switches. Tracked in public/images/README.md. */}
What this setting controls [#what-this-setting-controls]
The page configures which blocks appear in the Zendesk agent sidebar. For each block, you can:
* Drag to reorder it
* Turn it on or off
* Mark it as locked
Locked blocks can't be hidden by individual agents.
Where to find it [#where-to-find-it]
Open **Org Settings**.
Go to **Settings**.
Open **Assist Sidebar Layout** in the settings sidebar, alongside **General** and **Members**.
Reorder blocks [#reorder-blocks]
Drag the handle on the left of a block row to move it up or down. The order you save is the order agents see in the sidebar.
Enable or disable a block [#enable-or-disable-a-block]
Each block has an **Enabled** switch.
* Turn it **on** to keep the block in the layout.
* Turn it **off** to remove it from the active layout.
Disabled blocks appear dimmed in the settings list until you turn them back on.
Lock a block [#lock-a-block]
Each enabled block also has a **Locked** switch. Lock a block when it should always stay visible for agents, even if an individual agent would otherwise hide it.
* A locked block stays required at the organization level.
* A disabled block can't be locked.
* Locking only applies to enabled blocks.
Blocks you can configure [#blocks-you-can-configure]
The sidebar blocks include:
* **Ticket Summary**
* **Knowledge Base**
* **Similar Tickets**
* **Macros**
* **Shopify Orders**
* **Workflow Suggestions**
* **Workflow Execution**
The settings list groups them by category — **Core**, **Integration**, and **AI**.
Save changes [#save-changes]
After you reorder or toggle blocks, select **Save Changes**. Only admins can update the organization's sidebar layout; if someone without that access tries to save, Stylo rejects the change.
Recommended setup [#recommended-setup]
1. Keep core blocks like ticket context and knowledge visible.
2. Move the most-used blocks higher in the list.
3. Hide blocks your team doesn't use regularly.
4. Lock the blocks that should stay consistent for every agent.
5. Revisit the layout after major workflow or integration changes.
Limits and failure modes [#limits-and-failure-modes]
* Layout settings currently apply to the Zendesk agent sidebar.
* Ordering is done through the saved list on this screen.
* Locked blocks prevent individual agents from hiding required blocks.
Related [#related]
* [Workspace Overview](/workspace-overview) for the full navigation model
* [Assist](/assist) for how the sidebar is used during agent work
---
# Assist
URL: /assist
Type: concept
Description: AI-powered response suggestions that help agents reply faster and more consistently.
Keywords: assist, copilot, sidebar, suggestions, draft, write reply
Assist is Stylo's real-time AI assistant. It lives in the sidebar of your helpdesk and generates response suggestions for every ticket your agents work on.
Agents stay in control. Assist drafts a response, but a person reviews, edits,
and sends every reply.
The sidebar [#the-sidebar]
When an agent opens a ticket, the Stylo sidebar provides:
* **Summary** — A concise summary of the ticket conversation so agents can quickly understand the context
* **Knowledge Base** — Relevant articles from your knowledge base, searchable and linkable
* **Write Reply** — Generates a full draft response based on the ticket context, customer data, knowledge base, and your brand settings
The sidebar has two tabs:
Summary and knowledge base articles for the current ticket.
Response Workflows available for this ticket type.
Writing a reply [#writing-a-reply]
Click "Write Reply" or use the Reply tab to generate a response. Stylo considers:
* The full ticket conversation (all customer and agent messages)
* Customer information (name, email, account details)
* Your knowledge base articles (automatically searched for relevant content)
* Your [brand settings](/brand-settings) (voice, tone, guidelines, banned phrases)
* Connected tools (Shopify orders, Stripe subscriptions, etc.)
The generated response appears as a draft. Agents can:
* **Paste into the editor** — Click "Paste Into Text Editor" to insert the response into the helpdesk's reply composer
* **Edit before sending** — Modify the response in the composer as needed
* **Provide feedback** — Rate the suggestion to help improve future responses
Adding context [#adding-context]
Sometimes the AI needs a hint. The Reply tab includes an input area where agents can add context before generating:
* Brief notes about the situation ("customer wants a refund for order #1234")
* Key details the AI should include ("mention the 30-day return policy")
* Specific instructions ("keep it short, just confirm the refund")
Stylo incorporates this context into the generated response, combining the agent's knowledge with AI fluency. You don't need to write full sentences — bullet points and shorthand work fine. Stylo handles greetings, tone, and formatting based on your brand settings.
Adjusting a reply [#adjusting-a-reply]
After generating a response, use the **Adjust** tab to refine it without starting over:
* Type specific adjustments ("make it shorter", "add a link to our FAQ", "more empathetic tone")
* The AI modifies the existing response based on your feedback
* Navigate between versions using the arrow controls to compare drafts
Adjustments are useful when the initial response is close but needs a tweak — a different tone for a frustrated customer, additional details for a complex issue, or a more concise version for a chat channel.
How Assist uses your knowledge base [#how-assist-uses-your-knowledge-base]
When generating a response, Assist automatically searches your knowledge base for articles relevant to the customer's question. These articles ground the response in your actual policies and documentation, reducing hallucination and ensuring accuracy.
You can also manually search and reference knowledge base articles from the Resources tab. Click the arrow icon next to any article to inject it as context for the next generated response.
Assist suggestions [#assist-suggestions]
When [Response Workflows](/response-workflows) are configured with background automation in cache mode, pre-generated suggestions appear in the sidebar automatically. These are more structured than free-form Assist responses — they follow your specific workflow instructions and pull data from connected tools.
Agents see suggestions ranked by confidence and can use them alongside or instead of free-form Assist responses. See [Assist suggestions](/response-workflows/assist-suggestions) for details.
Translation [#translation]
The Translate tab lets agents translate responses into different languages. Stylo detects the customer's language automatically and can generate responses in that language, or agents can manually select a target language.
Tips [#tips]
Even if you need to edit, starting from an AI-generated response is faster than writing from scratch.
A few words of guidance dramatically improve response quality for non-standard situations.
If the response is 80% right, use Adjust to fix the remaining 20% rather than generating a completely new response.
If responses consistently miss the mark on tone or style, the fix is usually in [Brand Settings](/brand-settings), not in per-ticket adjustments.
Related [#related]
---
# Brand Settings
URL: /brand-settings
Type: reference
Description: Configure the voice, tone, language, and guidelines Stylo applies to every AI-generated response.
Keywords: brand, voice, tone, guidelines, banned phrases, response language, multi-brand
Brand Settings control how Stylo's AI communicates on your behalf. Every response generated by [Assist](/assist), [Response Workflows](/response-workflows), and background automation is shaped by these settings. The page is split into three tabs — **Voice & tone**, **Instructions**, and **Language** — and each field is documented below with its type, default, and effect.
Only members who can manage brand settings can change these values. Changes
take effect on the next response Stylo generates.
Voice & tone [#voice--tone]
| Field | Type | Default | Effect when set |
| ------------------- | ------------- | ---------- | ---------------------------------------------------------------------------------------------------------- |
| **Company name** | text | empty | Names the company Stylo represents in the response instructions. |
| **Industry** | text | empty | Adds the company's industry to the context to steer domain wording. |
| **Greeting** | text | empty | Suggested opener. Applied contextually, not as a fixed template — Stylo adapts it to the conversation. |
| **Sign-off** | text | empty | Suggested closer, applied contextually like the greeting. |
| **Tone of voice** | enum | `Balanced` | Sets the register of every response. See the options below. |
| **Response length** | enum | `Balanced` | Sets how long responses run. See the options below. |
| **Emoji** | toggle | Off | When on, Stylo "may use emoji where appropriate." When off, responses contain no emoji. |
| **Comment author** | Zendesk agent | empty | The Zendesk agent Stylo posts comments as for this brand. Leave empty to inherit the organization default. |
| **Banned phrases** | list | empty | Words or phrases Stylo is instructed never to use in a response. |
Tone of voice options [#tone-of-voice-options]
| Value | Behavior |
| ---------------------------------- | ------------------------------------------------------------- |
| **Friendly** | Warm, approachable, encouraging; conversational style. |
| **Balanced** *(default)* | Helpful and clear; balances warmth and professionalism. |
| **Professional** | Polished, confident, businesslike; formal register. |
| **Matter-of-fact** | Direct, plainspoken, concise; focused on facts and solutions. |
Response length options [#response-length-options]
| Value | Behavior |
| ---------------------------------- | ---------------------------------------------------------- |
| **Concise** | Brief and focused; short paragraphs, gets to the point. |
| **Balanced** *(default)* | Thorough but not verbose; covers the key points. |
| **Detailed** | Comprehensive; includes context, examples, and next steps. |
**Banned phrases** are enforced by instruction, not a hard post-filter. Stylo
is told never to use the listed phrases; treat it as strong guidance rather
than a guarantee. Good candidates are competitor names, internal jargon, and
legal terms you want to avoid ("guarantee", "promise").
Instructions [#instructions]
| Field | Type | Default | Effect when set |
| ----------------------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Custom instructions** | list | empty | Individual rules applied to every response, listed as bullets in the instructions. Each entry has a soft 120-character limit — longer rules belong in Response guidelines. |
| **Response guidelines** | long text | empty | Free-form guidance for nuanced or detailed rules that don't fit as short bullet rules. |
Use **custom instructions** for short, discrete rules ("Always offer a next step"). Use **response guidelines** for longer, narrative guidance. Both are injected into the instructions Stylo follows when drafting.
Language [#language]
| Field | Type | Default | Effect when set |
| ------------------------------------ | -------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Response language** | enum | `Auto-detect (match customer)` | `Auto` detects the customer's language and replies in it. Any specific language forces every reply into that language regardless of the customer's. |
| **Summary & internal note language** | enum | `Same as response language` | Language for internally generated notes and summaries. Defaults to whatever the response language resolves to. |
| **Background translation** | toggle | Off | Intended to automatically translate incoming customer messages before processing. {/* TODO(docs): the translation pipeline that consumes this flag was not located in the brand-settings instruction path — confirm where backgroundTranslationEnabled is enforced before describing the runtime effect. */} |
| **Translation glossary** | glossary | empty | A shared glossary assigned to this brand to keep term translations consistent. Glossaries are created once and shared across brands. {/* TODO(docs): glossary enforcement during translation was not located in code — confirm before documenting the runtime effect. */} |
**Response language** offers auto-detect plus a fixed set of languages, including English, Spanish, French, German, Portuguese, Italian, Dutch, Russian, Swedish, Danish, Finnish, Norwegian, Polish, Turkish, Ukrainian, Vietnamese, Thai, Arabic, Japanese, Chinese, and Korean.
Multi-brand support [#multi-brand-support]
If your organization operates multiple brands (common with Zendesk multi-brand), each brand can have its own brand settings.
How brand resolution works:
* Stylo keeps one **global default** row plus an optional row per brand.
* For a ticket, Stylo resolves the brand from the Zendesk brand and uses that brand's row, **falling back to the global default for any field the brand row leaves unset.**
* Text and number fields inherit from the global default when the brand row is empty; a **Response language** of `Auto` on a brand row also means "inherit the global setting."
* Toggle fields (emoji, background translation) always use the brand row's own value.
Limits and failure modes [#limits-and-failure-modes]
* Greeting and sign-off are applied **contextually**, not as fixed strings — Stylo may adapt or omit them when they don't fit the conversation.
* Banned phrases are instruction-level guidance, not a guaranteed block.
* A brand-specific row only overrides the global default for the fields you set on it; everything else inherits.
Related [#related]
* [Assist](/assist)
* [Voice Intelligence](/voice-intelligence)
* [Context Engine Settings](/context-engine-settings)
---
# Context Engine Settings
URL: /context-engine-settings
Type: reference
Description: Control which sources — knowledge, solved tickets, and macros — Stylo draws on when building response context, globally or per brand.
Keywords: context engine, retrieval, sources, grounding, knowledge, solved tickets, macros
Context Engine Settings control which sources Stylo can draw from when assembling the context behind a response. The page is organized into three sections — **Knowledge**, **Tickets**, and **Templates** — and applies either to the whole workspace (the **Global Settings** tab) or to one brand (a brand tab).
Members who can view brand settings can view this page; only members who can
manage brand settings can save changes. Changes save per selected tab, not
across every brand at once.
{/* TODO(docs): screenshot — Context Engine page (Global Settings tab, brand tabs, Knowledge/Tickets/Templates sections). Tracked in public/images/README.md. */}
Knowledge [#knowledge]
| Field | Type | Default | Effect when toggled |
| ---------------------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Analyze Knowledge Base** | toggle | On | When **off**, Stylo skips knowledge-base retrieval entirely — no articles are searched and no knowledge is added to context. |
| **Include Private Articles** | toggle | Off | When **on**, private (non-public) help-center articles are eligible for retrieval. When off, only public articles are searched. Disabled in the UI while *Analyze Knowledge Base* is off. |
| **Share KB Between Brands** | toggle | Off | When **on**, knowledge from other brands can be retrieved for this brand's tickets. When off, retrieval is scoped to the ticket's own brand. Disabled while *Analyze Knowledge Base* is off. |
These three controls are enforced at retrieval time — turning a knowledge toggle off changes what Stylo searches for the affected scope.
Tickets [#tickets]
| Field | Type | Default | Range | Effect |
| -------------------------- | ------ | ------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Analyze Solved Tickets** | toggle | On | — | Intended to control whether previously solved tickets inform responses. |
| **Lookback Period (days)** | number | `30` | 1–90 | Intended to bound how far back solved-ticket history is considered. Applies only when *Analyze Solved Tickets* is on. |
| **Analyze Internal Notes** | toggle | On | — | When **off**, internal (non-public) notes are filtered out of the conversation before Stylo processes it. Enforced during message preprocessing. |
**Analyze Solved Tickets** and **Lookback Period** are stored and editable,
but the current solved-ticket retrieval path does not yet read these values —
so toggling them may not change behavior today.
{/* TODO(docs): searchConversations (conversation-resolver.ts / rewrite.ts) is invoked without analyzeSolvedTickets or solvedTicketsDays. Confirm whether enforcement has shipped before promising behavior. */}
**Analyze Internal Notes** is enforced.
Templates [#templates]
| Field | Type | Default | Effect |
| ------------------ | ------ | ------- | --------------------------------------------------------------------------------- |
| **Analyze Macros** | toggle | On | Intended to control whether macros and support templates are included in context. |
**Analyze Macros** is stored and editable, but no enforcement hook was found
in the response-generation path — toggling it may not change behavior today.
{/* TODO(docs): analyzeMacros has no consumer in the assist/retrieval pipeline. Confirm whether macro retrieval honors this flag before documenting an effect. */}
Global settings and brand settings [#global-settings-and-brand-settings]
Stylo keeps one **global** Context Engine settings row for the workspace, created automatically the first time the page loads. If your organization uses brand-specific brand settings, matching brand tabs can be created so each brand can use different context rules.
* Use **Global Settings** when the same rules should apply across the workspace.
* Use a **brand tab** when one brand needs different context behavior — for example, a different solved-ticket lookback or different knowledge handling.
A brand row overrides the global default for that brand. The global row cannot be deleted; it is the base configuration for the workspace.
How to update Context Engine Settings [#how-to-update-context-engine-settings]
Open **Context Engine** from the workspace sidebar.
Select **Global Settings** or the brand you want to edit.
Adjust the **Knowledge**, **Tickets**, and **Templates** controls.
Select **Save Changes**. The selected tab is saved on its own — other brands are unchanged.
How this relates to knowledge base settings [#how-this-relates-to-knowledge-base-settings]
Context Engine Settings is not the same as the settings for an individual knowledge base.
* Use **Context Engine Settings** to tune source behavior at the workspace or brand level.
* Use a **Knowledge Base** settings tab to configure one specific knowledge base — whether it's enabled, whether it includes private articles, and which brands it serves.
Related [#related]
* [Knowledge Base](/knowledge-base)
* [Workspace Overview](/workspace-overview)
* [Brand Settings](/brand-settings)
---
# Documentation Strategy
URL: /documentation-strategy
Type: concept
Description: How Stylo documentation is organized for customers, operators, and machine-readable retrieval.
Keywords: documentation, strategy, llms.txt, retrieval, style guide
Use this page to understand how the Stylo docs are structured and what they are meant to do. This is the orientation page for the documentation system itself, not a product setup guide.
What the docs are for [#what-the-docs-are-for]
The Stylo docs have three jobs:
1. Help a new customer set up the product in a practical order
2. Help operators and admins run Stylo safely once workflows are live
3. Give retrieval systems and other AI tooling a stable, machine-readable product corpus
That means the docs are part of the product surface. They are not only reference material. They also guide rollout, operational review, and AI-safe configuration.
Who the docs are written for [#who-the-docs-are-written-for]
The current docs are designed for three main reader groups:
* Support leaders and workspace admins who configure integrations, knowledge, access, and automation
* Agents and reviewers who need to understand how assist, approvals, and response workflows behave
* Retrieval systems and AI tooling that consume the docs through stable pages and text exports
How the docs are organized today [#how-the-docs-are-organized-today]
The docs corpus is structured around the main customer workflows in Stylo:
* **Getting Started** for first-run workspace setup
* **Using Stylo** for assist, settings, integrations, and knowledge
* **Response Workflows** for response automation
* **Workflow Builder** for broader workflow automation
* **Operations** for execution review and diagnostics
* **Trust** for access, credentials, and content handling
* **Supporting Guides** for troubleshooting and shared terminology
This structure is meant to help customers move from setup to controlled automation without jumping between unrelated concepts on the same page.
What good Stylo docs should do [#what-good-stylo-docs-should-do]
Each page should help the reader answer a real operational question quickly.
Good pages in this docs set should:
* Start with the outcome or task the feature supports
* Stay focused on one main concept or workflow
* Use the real product terms consistently
* Show where a feature appears in the product
* Explain boundaries, failure cases, or escalation paths when they matter
* Link to the next useful page when the follow-up step is clear
What the machine-readable outputs provide [#what-the-machine-readable-outputs-provide]
The docs app currently exposes two machine-readable exports:
* [`/llms.txt`](/llms.txt) for a navigable page index with recommended starting pages
* [`/llms-full.txt`](/llms-full.txt) for a single-file export of the full docs corpus
These exports matter because Stylo documentation is also meant to work well for retrieval systems, crawlers, and other AI tools that need a cleaner text representation than the rendered site alone.
How `llms.txt` is organized [#how-llmstxt-is-organized]
The current `llms.txt` route includes:
* A short corpus description
* A list of recommended starting pages
* A full page index
* Links to both machine-readable exports
Today, the recommended starting pages are:
* [Getting Started](/getting-started)
* [Assist](/assist)
* [Brand Settings](/brand-settings)
* [Knowledge Base](/knowledge-base)
* [Response Workflows](/response-workflows)
* [Documentation Strategy](/documentation-strategy)
How `llms-full.txt` is organized [#how-llms-fulltxt-is-organized]
The `llms-full.txt` route exports the full page corpus as one text file.
Each page section includes:
* The page title
* Its canonical path
* Its description when available
* The processed page text
This makes the corpus easier to ingest for systems that prefer one complete document instead of a page-by-page crawl.
Writing standards for this docs set [#writing-standards-for-this-docs-set]
The authoritative rules for voice, structure, terminology, components, and
frontmatter live in the **docs style guide** (`apps/docs/STYLEGUIDE.md`). Every page is held to it, and CI enforces the mechanical parts. In short, Stylo docs follow a consistent pattern:
* Lead with the user outcome in the first paragraph
* Prefer short sections and strong headings
* Keep examples concrete and support-oriented
* Avoid vague feature claims that are not grounded in the product
* Preserve stable slugs and titles where possible
* Avoid duplicate pages that compete for the same topic
Current operating principle [#current-operating-principle]
Stylo documentation should stay close to the product that exists today. If a behavior is unclear, the docs should not guess. They should wait for product confirmation or carry a clear docs clarification note until the behavior is confirmed.
Related [#related]
* [Getting Started](/getting-started)
* [Glossary](/glossary)
* [Troubleshooting](/troubleshooting)
---
# Getting Started
URL: /getting-started
Type: tutorial
Description: Set up a new Stylo workspace end-to-end so your agents see AI-drafted reply suggestions in their helpdesk.
Keywords: getting started, setup, onboarding, first run, rollout, assist, first workflow
By the end of this tutorial, an agent who opens a ticket sees a reply already drafted for them in the Stylo sidebar. Getting there takes four things: your helpdesk connected, your brand voice set, your knowledge connected, and one Response Workflow that drafts replies. It takes about 20 minutes.
**Before you start**, you need an **admin** role in Stylo and the ability to
connect your helpdesk (Zendesk).
Set up your workspace [#set-up-your-workspace]
Connect your helpdesk [#connect-your-helpdesk]
Stylo reads and replies to tickets through your helpdesk, so connect it first.
1. Go to **Integrations**.
2. Find **Zendesk** and start the connection. You'll sign in to Zendesk and authorize Stylo.
3. When you return, Zendesk shows a **Connected** status.
**You're done when:** Zendesk appears with a **Connected** status on the Integrations page.
See [Integrations](/integrations) for the full list of tools you can connect.
Set your brand voice [#set-your-brand-voice]
Tell Stylo how your team sounds, so the very first draft already reads like you. Open **Tone & Instructions** and set, at a minimum:
* **Tone of voice** — friendly, balanced, professional, or matter-of-fact
* **Response length** — concise, balanced, or detailed
* **Company name** and **industry**, for context
**You're done when:** your tone is saved. Every reply Stylo drafts from now on follows it.
See [Brand Settings](/brand-settings) for every option and what it changes.
Connect knowledge [#connect-knowledge]
Give Stylo the content it should answer from — your help center, docs, or uploaded files — so replies cite your real policies instead of guesses.
1. Open **Knowledge**.
2. Connect a documentation source, or upload files.
**You're done when:** your first knowledge base appears and finishes syncing.
No knowledge yet? You can still continue and add it later — but connect it
before you trust drafts on policy questions like refunds or shipping.
See [Knowledge Base](/knowledge-base) and [Knowledge sync and documents](/knowledge-sync-and-documents).
Create a Response Workflow [#create-a-response-workflow]
This is the step that puts a draft in front of your agents. A [Response Workflow](/response-workflows) writes a contextual reply for a ticket; set it to draft into the sidebar and your agents review and send with one click.
1. Go to **Response Workflows** and select **New workflow**. Stylo opens the editor.
2. Give it a clear **name** and fill in **Use this when…** — describe, in plain language, the tickets it should handle (for example, "the customer asks where their order is"). Stylo uses this to match the workflow to incoming tickets.
3. Write the **response template** — what the reply should say.
4. Set the workflow to **draft suggestions into the agent sidebar** for review, rather than send on its own.
5. Choose what triggers a draft — for example, **when a customer replies**.
6. **Enable** the workflow. New workflows start off, so this last step is what makes it run.
**You're done when:** the workflow is enabled and set to draft into the sidebar.
Start with one narrow, predictable request rather than every support process at
once. See [Creating a workflow](/response-workflows/creating-a-workflow) for the
full walkthrough and [Response modes](/response-workflows/response-modes) for the
difference between template and guided drafting.
See it working [#see-it-working]
Open a real ticket that matches your **Use this when…** description. Stylo's sidebar shows a drafted reply your agent can review, edit, and send.
As drafts add up, your Home page starts reporting how often agents accept them — your first signal of whether the workflow is pulling its weight.
**You're done when:** a draft appears on a matching ticket.
Where to go from here [#where-to-go-from-here]
Your Home page doubles as a live health check once you're running — it surfaces pending approvals, failed runs, and knowledge bases with sync errors, so it's worth a glance each day.
When a workflow consistently produces replies your agents send unchanged, you can let it send on its own. Move there deliberately, one workflow at a time — see [Progressive Automation](/response-workflows/progressive-automation).
Next steps [#next-steps]
---
# Glossary
URL: /glossary
Type: reference
Description: Definitions for the main Stylo terms used across setup, assist, knowledge, integrations, and automation docs.
Keywords: glossary, terms, definitions, terminology
Quick definitions for the Stylo terms you'll meet across these docs. When a word is used two ways in the wider world, this page says which meaning Stylo uses.
Overloaded and retired terms [#overloaded-and-retired-terms]
A few terms used to drift across the product and docs. These are the canonical resolutions.
Assist vs. Workflow Builder [#assist-vs-workflow-builder]
**Assist** is the agent-facing sidebar that drafts and adjusts replies inside the helpdesk. The **Workflow Builder** is the block-based editor where admins author multi-step **Workflows**. They are different surfaces — Assist is where agents work a ticket; the Workflow Builder is where automations are built.
Response Workflow vs. Workflow Builder [#response-workflow-vs-workflow-builder]
These are two separate surfaces under the **Workflows** area of the navigation:
* A **Response Workflow** generates a contextual reply for a ticket.
* The **Workflow Builder** is where you author **Workflows** — broader, multi-step, block-based automations that can do more than generate a reply.
The word "automation" is the general concept and not a named surface — prefer the specific term. In particular, **background automation** and **progressive automation** are concepts that belong to *Response Workflows* (an execution mode and a rollout strategy), not to the Workflow Builder.
Copilot (retired) [#copilot-retired]
"Copilot" is no longer used in Stylo docs. It was overloaded across agent assist and workflow authoring, which confused both customers and AI tools. Use **Assist** for the agent-assist sidebar, and **Assist suggestion** for a pre-generated reply surfaced for review (formerly "Copilot suggestion"). If you arrived here searching for "Copilot," see [Assist](#assist).
Core workspace terms [#core-workspace-terms]
Workspace [#workspace]
The Stylo environment your team uses to manage settings, knowledge, integrations, and workflows.
Member [#member]
A person who has access to a Stylo workspace.
Viewer [#viewer]
A workspace role for someone who needs visibility without broader operational control.
Agent [#agent]
A workspace role for someone doing day-to-day support work with Stylo.
Admin [#admin]
A workspace role for someone who manages workspace settings, access, and operational configuration.
Owner [#owner]
The highest workspace role. Ownership is not assigned through the standard invite or join-link flows.
Invitation [#invitation]
A direct email-based access path for adding one person to a workspace with a selected role.
Join link [#join-link]
A shareable access link that lets anyone with the link join a workspace with a preset role while the link remains active.
AI assistance terms [#ai-assistance-terms]
Assist [#assist]
The agent-facing Stylo sidebar inside the helpdesk that drafts, adjusts, and translates AI-generated replies. Agents review, edit, and send every response. (Formerly sometimes called "Copilot.")
Assist suggestion [#assist-suggestion]
A reply that Stylo pre-generates from a Response Workflow and surfaces in the Assist sidebar for an agent to review. (Formerly "Copilot suggestion.")
Draft [#draft]
An AI-generated response suggestion that a human can review, edit, approve, or send depending on the workflow.
Grounding [#grounding]
Using connected knowledge and system data so an AI response is based on real source information instead of unsupported guesses.
Brand Settings [#brand-settings]
The workspace settings that define tone, response rules, banned phrasing, and language behavior for AI outputs.
Context Engine [#context-engine]
The retrieval and context assembly behavior that determines what information Stylo feeds into AI generation.
Knowledge terms [#knowledge-terms]
Knowledge base [#knowledge-base]
A collection of connected or uploaded content that Stylo can search and use for grounded responses.
Document [#document]
An indexed record inside a knowledge base that Stylo can search and retrieve.
File [#file]
A raw uploaded asset, such as a PDF, DOCX, or TXT file, that can be processed into searchable knowledge.
Sync [#sync]
The process of pulling or refreshing content from a connected source into a knowledge base.
Sync Status [#sync-status]
The current state of a knowledge base sync, shown as idle, syncing, or error in the product.
Query Mapping [#query-mapping]
The review workflow for turning real support conversations into stronger retrieval mappings.
Integration terms [#integration-terms]
Integration [#integration]
A connection between Stylo and another system your team uses, such as Zendesk, Shopify, Stripe, Slack, or Linear.
Managed API [#managed-api]
An API-backed integration that is configured and maintained inside Stylo for workflow use.
MCP server [#mcp-server]
An integration endpoint that exposes tools and capabilities to Stylo through the Model Context Protocol.
Connection status [#connection-status]
The current health state of an integration, such as connected, degraded, auth expired, disconnected, or error.
OAuth [#oauth]
A connection method where you sign in to an external provider and grant Stylo access through that provider’s authorization flow.
API key [#api-key]
A secret value entered into Stylo to connect certain integrations directly.
Workflow terms [#workflow-terms]
Response Workflow [#response-workflow]
An AI-powered response template and decision layer that generates contextual replies for support work.
Workflow [#workflow]
An automation built in the broader workflow builder. Workflows can run multi-step logic beyond response generation.
Workflow Builder [#workflow-builder]
The Stylo block-based editor for building Workflows from blocks, variables, and connected systems.
Trigger [#trigger]
The event or starting condition that causes a workflow or execution to begin.
Execution [#execution]
A recorded run of a workflow.
Execution History [#execution-history]
The view that lists recorded runs for one workflow.
Execution Detail [#execution-detail]
The detailed record for one workflow run, including status, summary, errors, and event timeline.
Approval [#approval]
A human review step that pauses a workflow until someone approves or rejects the next action.
Backlog run [#backlog-run]
A bulk run that applies a response workflow across a backlog of matching tickets instead of a single live event.
Escalation rule [#escalation-rule]
A rule that prevents Stylo from responding automatically when a human should take over.
Automation and rollout terms [#automation-and-rollout-terms]
Copilot suggestion (retired) [#copilot-suggestion-retired]
Renamed to [Assist suggestion](#assist-suggestion). "Copilot" is no longer used in Stylo docs.
Background automation [#background-automation]
An execution mode where Stylo generates, checks, and sends responses without agent involvement.
Progressive automation [#progressive-automation]
The rollout approach of starting with review-heavy workflows and increasing automation only after the workflow proves reliable.
Voice Intelligence [#voice-intelligence]
The Stylo feature area related to Zendesk call processing and voice-specific operational workflows.
Related [#related]
* [Getting Started](/getting-started)
* [Workspace Overview](/workspace-overview)
* [Response Workflows](/response-workflows)
* [Security and Data Handling](/security-and-data-handling)
* [Troubleshooting](/troubleshooting)
---
# Stylo Documentation
URL: /
Type: concept
Description: Learn how to roll out Stylo, configure grounded AI responses, and scale toward safe automation.
Keywords: overview, introduction, stylo, docs home
Customer Support AI Docs
Stylo helps support teams answer faster with grounded AI, reusable workflows, and a controlled rollout path from agent assist to automation. Use these docs to set up your workspace, connect the systems your team relies on, and define how Stylo should respond.
{/* TODO(docs): Screenshot of the docs home page highlighting the setup path for new admins. Tracked in public/images/README.md. */}
Start with setup [#start-with-setup]
If you are setting up Stylo for a new workspace, start here:
1. [Getting Started](/getting-started) to understand the initial rollout path
2. [Integrations](/integrations) to review connected systems and add the ones your workflows need
3. [Knowledge Base](/knowledge-base) to connect help center content, docs, or uploaded files
4. [Brand Settings](/brand-settings) to define tone, voice, and response rules
5. [Response Workflows](/response-workflows) to standardize repeated support work
This setup path matches the onboarding checklist inside the Stylo workspace. It is the fastest way to move from initial configuration to a useful live workflow.
Follow the first-run path for a new workspace and understand what to
configure first.
Choose the right path [#choose-the-right-path]
Learn where admins and agents work in Stylo and what each area of the
product is for.
See how agents review drafts, adjust responses, and work with grounded
suggestions.
Improve answer quality by connecting reliable content and keeping it up to
date.
Build repeatable response logic with instructions, conditions, guardrails,
and actions.
Who these docs are for [#who-these-docs-are-for]
* Admins and operators who set up integrations, knowledge, brand guidance, and workflows
* Support leaders who want a safer rollout path from assist to more automation
* Agents who need to understand how Stylo drafts responses and when manual review still matters
What you can do in Stylo [#what-you-can-do-in-stylo]
* Connect the external systems your team uses in support operations
* Ground AI responses in your help center, internal docs, and uploaded files
* Define brand rules so responses match your team’s tone and constraints
* Build workflows for repeated ticket patterns
* Review results before you expand automation further
Related [#related]
* [Members and Access](/members-and-access) to invite teammates and manage workspace access
* [Managed APIs](/managed-apis) to connect API-backed tools used in workflows
* [MCP Servers](/mcp-servers) to configure MCP-based integrations
* [Query Mapping](/query-mapping) to improve retrieval using real support conversations
LLM access [#llm-access]
Machine-readable exports are available at
/llms.txt{" "}
and
/llms-full.txt. These are intended for
crawlers, retrieval systems, and other AI tooling that need a cleaner
representation of the docs.
---
# Integrations
URL: /integrations
Type: concept
Description: Connect your tools so Stylo can pull customer data and take actions across your stack.
Keywords: integrations, zendesk, shopify, stripe, slack, connect
Integrations let Stylo access data from your existing tools — order details from Shopify, subscription info from Stripe, customer records from HubSpot — and use it when generating responses. They also enable workflows to take actions in external systems, like creating a Jira ticket or sending a Slack notification.
Available integrations [#available-integrations]
E-commerce [#e-commerce]
| Integration | What it provides |
| --------------- | ----------------------------------------------------------------- |
| **Shopify** | Order details, customer history, fulfillment status, product info |
| **WooCommerce** | Orders, customers, store data |
| **Stripe** | Payment history, subscription status, invoices, refund info |
CRM & Support [#crm--support]
| Integration | What it provides |
| -------------- | --------------------------------------------------------------------------------------- |
| **Zendesk** | Ticket management, user lookup, search — connected automatically when you install Stylo |
| **HubSpot** | Contacts, deals, tickets, company data |
| **Intercom** | Conversations, customer data |
| **ServiceNow** | Incidents, requests, service catalog items |
Project Management [#project-management]
| Integration | What it provides |
| -------------- | ------------------------------------------------- |
| **Jira** | Create and track issues from support interactions |
| **Linear** | Create and sync issues with engineering teams |
| **Monday.com** | Manage boards and items from workflows |
Communication [#communication]
| Integration | What it provides |
| --------------------- | ---------------------------------------------------- |
| **Slack** | Send messages and notifications to channels or users |
| **Gmail** | Send and receive emails from workflows |
| **Microsoft Outlook** | Connect email and calendar via Microsoft 365 |
| **Resend** | Send transactional emails from workflows |
Content & Knowledge [#content--knowledge]
| Integration | What it provides |
| ------------ | --------------------------------------------------- |
| **Notion** | Sync pages and databases for knowledge context |
| **Google** | Access Sheets, Docs, and Drive for data and content |
| **Webflow** | CMS content and form submissions |
| **Typeform** | Form responses and survey data |
Developer [#developer]
| Integration | What it provides |
| ------------- | -------------------------------------------------- |
| **GitHub** | Pull context from repos, issues, and pull requests |
| **Firecrawl** | Web scraping and crawling for knowledge ingestion |
Connecting an integration [#connecting-an-integration]
1. Go to **Integrations** in the Stylo sidebar navigation
2. Find the integration you want to connect
3. Click **Connect**
4. Follow the authentication flow:
* **OAuth integrations** (most integrations) — A popup opens where you sign in and grant Stylo access. Tokens are managed automatically, including refreshes.
* **API key integrations** (Stripe, Linear, WooCommerce, Firecrawl, Resend) — Paste your API key or secret in the dialog. Keys are stored encrypted.
Once connected, the integration is available to all Response Workflows and general Workflows in your organization.
Using integrations in Response Workflows [#using-integrations-in-response-workflows]
Response Workflows use integrations through **tools**. When creating or editing a workflow, you select which tools to enable. For example, enabling the Shopify tool lets the workflow look up order details when generating a response.
The AI uses tool data in two ways:
* **Template placeholders** — In template mode, tool data fills specific placeholders in your response template
* **AI context** — In guided mode, tool data is provided as context so the AI can reference it naturally in the response
See [Creating a Workflow](/response-workflows/creating-a-workflow) for setup details.
Using integrations in Workflows [#using-integrations-in-workflows]
General Workflows have dedicated blocks for each integration. For example:
* A **Zendesk / Get Ticket** block fetches ticket details
* A **Shopify / Get Order** block retrieves order data
* A **Slack / Send Message** block posts a notification
* A **Linear / Create Issue** block creates a bug report
These blocks can be chained together to build multi-step automations. The output of one block flows into the next as input.
Integration status [#integration-status]
Each connected integration shows its current status:
| Status | Meaning |
| ---------------- | ------------------------------------------------------------- |
| **Connected** | Working normally |
| **Auth expired** | OAuth token needs to be refreshed — click to re-authenticate |
| **Error** | Connection failed — check credentials or integration settings |
| **Disconnected** | Not yet connected |
Managing integrations [#managing-integrations]
From the integration detail page, you can:
* **Re-authenticate** — Refresh expired OAuth tokens or update API keys
* **Disconnect** — Remove the integration entirely. This does not delete data already used in responses, but workflows that depend on this integration will no longer be able to fetch data from it.
Tips [#tips]
* **Connect e-commerce integrations first.** Shopify, Stripe, and WooCommerce provide the richest data for support responses — order status, shipping info, payment details.
* **Start with what your agents look up manually.** If agents regularly switch to another tool to find information, that's an integration worth connecting.
* **Use Slack for visibility.** Connect Slack to get notifications when workflows execute, when drafts are waiting for review, or when escalations happen.
Related [#related]
* [Managed APIs](/managed-apis)
* [MCP Servers](/mcp-servers)
* [Security and Data Handling](/security-and-data-handling)
* [Getting Started](/getting-started)
---
# Knowledge Base
URL: /knowledge-base
Type: concept
Description: Connect your documentation so Stylo can ground AI responses in your actual policies and information.
Keywords: knowledge base, articles, grounding, sources
Stylo's knowledge base is how you give the AI access to your company's documentation, policies, and procedures. When generating responses, Stylo searches your knowledge base for relevant articles and uses them to ground the response in accurate, up-to-date information.
Why it matters [#why-it-matters]
Without a knowledge base, the AI generates responses based on general knowledge and the ticket context alone. With a connected knowledge base, responses reference your specific policies, pricing, procedures, and product details. This dramatically reduces hallucination and increases response accuracy.
What makes good knowledge base content [#what-makes-good-knowledge-base-content]
The best articles for AI-grounded responses are:
* **FAQ-style content** — clear questions with direct answers
* **Policy documents** — return policies, SLAs, warranty terms
* **Process guides** — step-by-step instructions for common issues
* **Product documentation** — feature descriptions, pricing tiers, specifications
* **Troubleshooting guides** — known issues and their resolutions
Content to avoid or exclude [#content-to-avoid-or-exclude]
Some content doesn't help (and can hurt) response quality:
* **Outdated articles** — old pricing, deprecated features, expired promotions
* **Blog posts and marketing content** — promotional language doesn't belong in support responses
* **Internal-only documentation** — content not meant for customer-facing use
* **Duplicate articles** — multiple versions of the same information confuse the search
How Stylo uses your knowledge base [#how-stylo-uses-your-knowledge-base]
When a response is generated (via Assist, Response Workflows, or background automation):
1. **Search** — Stylo embeds the customer's question and searches your knowledge base using semantic similarity (not just keyword matching)
2. **Rank** — The most relevant articles are ranked and selected
3. **Ground** — The AI uses the article content as context when generating the response, citing specific policies and information
4. **Cite** — Relevant articles appear in the sidebar's Resources tab so agents can reference them directly
Managing your knowledge base [#managing-your-knowledge-base]
Adding content [#adding-content]
You can populate your knowledge base by:
* **Connecting Zendesk Help Center** — Automatically imports and syncs your published articles
* **Uploading documents** — PDF, DOCX, and other document formats can be uploaded directly
Selecting knowledge bases for workflows [#selecting-knowledge-bases-for-workflows]
Each Response Workflow can be configured to search specific knowledge bases. This is useful when different workflows need different documentation — a billing workflow searches your pricing docs, while a product support workflow searches your technical docs.
Tips [#tips]
* **Quality over quantity.** A smaller knowledge base with accurate, well-written articles produces better responses than a large one full of outdated or irrelevant content.
* **Keep articles focused.** One topic per article. An article that covers both "return policy" and "shipping times" is harder for the AI to use precisely than two separate articles.
* **Update regularly.** When policies change, update the knowledge base. Stale articles lead to incorrect responses.
* **Review what the AI cites.** Check the Resources tab in the sidebar to see which articles are being used. If irrelevant articles keep appearing, consider removing or restructuring them.
Related [#related]
* [Knowledge Sync and Documents](/knowledge-sync-and-documents)
* [Query Mapping](/query-mapping)
* [Context Engine Settings](/context-engine-settings)
---
# Knowledge Sync and Documents
URL: /knowledge-sync-and-documents
Type: concept
Description: Understand how Stylo syncs knowledge content, what document and file states mean, and how to keep a knowledge base healthy.
Keywords: sync, documents, files, sync status, indexing
After you connect or upload content, Stylo turns it into a searchable knowledge base — but only the content that finishes syncing and indexing is actually used in replies. This page shows you how to tell what's current, what's still processing, and what Stylo is really drawing on.
How knowledge bases are created [#how-knowledge-bases-are-created]
The current knowledge base wizard supports these source types:
* **Zendesk**
* **Notion**
* **URL**
* **File Upload**
The wizard walks through three steps:
1. Choose a name and source.
2. Configure the selected source.
3. Review the summary and choose whether **Auto-sync** should be enabled.
This matters because document behavior depends on the source type you chose. A file-upload knowledge base behaves differently from a connected Zendesk, Notion, or URL source.
What you can monitor [#what-you-can-monitor]
Inside a knowledge base, Stylo gives you separate views for:
* **Overview** for sync status and source summary
* **Documents** for indexed content
* **Files** for uploaded file management
* **Settings** for knowledge-base-specific behavior
{/* TODO(docs): Screenshot of a knowledge base detail page showing the Overview, Documents, Files, and Settings tabs. Tracked in public/images/README.md. */}
Read the sync status first [#read-the-sync-status-first]
The **Overview** tab includes a **Sync Status** card. This is the fastest way to tell whether your knowledge base is current or stuck.
Stylo shows three main sync states:
* **Idle** when the knowledge base is not actively syncing
* **Syncing** when documents are being processed
* **Error** when the sync failed
When a sync is running, Stylo also shows:
* Progress through the document count
* How many documents have been processed
* How many failed during the run
If a sync has completed before, Stylo also shows **Last synced** time.
Know what auto-sync means [#know-what-auto-sync-means]
Each knowledge base is created with an **Auto-sync** choice in the setup wizard.
* When auto-sync is enabled, Stylo is set up to keep that source updated automatically
* When auto-sync is disabled, changes in the source may not appear until a sync is triggered
This matters most for connected sources like Zendesk, Notion, or URL-based knowledge bases. It is less important for one-time file uploads.
Understand the difference between files and documents [#understand-the-difference-between-files-and-documents]
Stylo separates uploaded files from indexed documents.
* **Files** are the raw uploaded assets, such as PDF, DOCX, or TXT files
* **Documents** are the indexed records Stylo searches and uses for retrieval
This distinction matters because a file can exist before processing finishes, while documents represent the content that is actually available for search and grounding.
File uploads and processing states [#file-uploads-and-processing-states]
For a **File Upload** knowledge base, the **Files** tab lets you upload:
* `.pdf`
* `.docx`
* `.txt`
After upload, each file gets a processing state:
* **Pending** when the file has been accepted but not started
* **Processing** when Stylo is actively working on it
* **Completed** when the file finished processing
* **Error** when processing failed
If a file fails, Stylo surfaces the processing error in the file row.
{/* TODO(docs): Screenshot of the Files tab showing pending, processing, completed, and error file states. Tracked in public/images/README.md. */}
For non-file-upload knowledge bases, the files view is not the main way content enters Stylo. In those cases, the sync process pulls content from the connected source instead.
When to use the Documents tab [#when-to-use-the-documents-tab]
Use the **Documents** tab when you want to inspect what Stylo has indexed, not just what was uploaded.
The Documents view lets you:
* Browse indexed documents
* Expand a document to preview its content
* Search within the knowledge base
* Filter documents by type
* Edit document labels and content tags
This is the best place to verify whether important content is present and whether it looks usable for retrieval.
Source documents and Q&A documents [#source-documents-and-qa-documents]
The Documents tab supports three filters:
* **All**
* **QA**
* **Source**
These filters matter because Stylo stores more than one document type in the same knowledge base:
* **Source** documents are the original synced or uploaded content
* **QA** documents are AI-generated question-and-answer pair documents
If you want to audit the original source material, use **Source**. If you want to review the generated Q\&A layer, use **QA**.
The search box on the Documents tab searches within that knowledge base and returns scored results. This is a practical way to verify that the content you expect is actually retrievable.
Editing labels and content tags [#editing-labels-and-content-tags]
From the Documents tab, you can edit:
* **Labels**
* **Content Tags**
Use these when you want to improve how a document is categorized or described for your team.
{/* TODO(docs): label/content-tag edits don't trigger an immediate re-embed, so they may not affect retrieval right away. Confirm the timing before documenting it as a search-quality control. */}
Delete carefully [#delete-carefully]
Stylo lets you delete both files and entire knowledge bases.
* Deleting a **file** removes the file and deletes the indexed document created from that file
* Deleting a **knowledge base** removes its documents and files
This is useful for cleanup, but it is also destructive. Use deletion when content is outdated, duplicated, or should no longer be searchable.
Practical health checks [#practical-health-checks]
Use this sequence when response quality drops or a sync looks wrong:
1. Open the knowledge base **Overview** and check **Sync Status**.
2. If the status is **Error**, review the error before assuming the content is current.
3. Open **Files** to confirm uploaded files finished processing.
4. Open **Documents** to confirm the expected content appears in the index.
5. Search within the knowledge base to see whether the content is findable.
When this page matters most [#when-this-page-matters-most]
This page is especially useful when:
* A newly uploaded file is not appearing in AI-grounded responses yet
* A synced source looks stale
* You need to confirm whether the problem is with the raw file, the sync run, or the indexed document layer
* You want to clean up duplicate or low-value content
Related [#related]
* [Knowledge Base](/knowledge-base)
* [Context Engine Settings](/context-engine-settings)
* [Query Mapping](/query-mapping)
---
# Managed APIs
URL: /managed-apis
Type: howto
Description: Import an OpenAPI spec so Stylo can use your REST API as tools in workflows and AI experiences.
Keywords: managed api, openapi, rest, tools, spec
Managed APIs let you bring your own REST API into Stylo. You create a managed API, import its OpenAPI spec, then choose which operations or tool groups Stylo can use. This is useful when your team needs Stylo to look up data or take actions in a system that does not already have a built-in integration.
{/* TODO(docs): Screenshot of the Managed APIs detail page showing the Configuration card, Operations tab, and Tool Groups tab. Tracked in public/images/README.md. */}
What you can do with Managed APIs [#what-you-can-do-with-managed-apis]
After setup, Stylo can turn your imported API into tools that are available to workflows and AI.
* Import operations from an OpenAPI spec in JSON or YAML
* Choose an authentication type for the API
* Review imported operations one by one
* Enable or disable groups of related operations
* Limit what Stylo can call before the API is used in production
Before you start [#before-you-start]
Managed APIs are gated by plan. In the current product, the Managed APIs area is shown as a Professional feature, and your workspace can only create up to the number of managed API configurations allowed by your plan.
Before you create one, make sure you have:
* A valid base URL for the API
* An OpenAPI specification for the endpoints you want Stylo to use
* A clear list of which read actions and write actions should be exposed
Create a managed API [#create-a-managed-api]
1. Go to **Integrations**.
2. Open the **Managed APIs** tab.
3. Click **Add API**.
4. Enter a **Name**.
5. Enter the API **Base URL**.
6. Select an **Auth Type**:
* `None`
* `Bearer`
* `API Key`
* `Basic`
* `Custom Header`
7. Add an optional **Description**.
8. Click **Create API**.
Stylo then opens the new managed API detail page, where you can import the OpenAPI spec and review what will be available as tools.
Import an OpenAPI spec [#import-an-openapi-spec]
1. Open the managed API you created.
2. Click **Import OpenAPI**.
3. Paste the OpenAPI specification into the dialog.
4. Click **Import**.
If the import succeeds, Stylo shows a result summary with:
* Number of operations imported
* Number of tool groups created
* Number of operation-to-group mappings created
If the spec cannot be parsed, the import fails with a validation error.
{/* TODO(docs): GIF of importing an OpenAPI spec and reviewing the import result summary. Tracked in public/images/README.md. */}
Review imported operations [#review-imported-operations]
The **Operations** tab is the most direct way to control API access.
For each imported operation, Stylo shows:
* The HTTP method
* The imported operation name
* The operation description, when available
* The detected resource, when available
* An enable or disable switch
You can also:
* Filter the list by HTTP method
* Enable or disable a single operation
* Enable or disable all currently filtered operations
This is the safest place to narrow access before you use the managed API in live workflows.
Review tool groups [#review-tool-groups]
The **Tool Groups** tab shows the grouped tools generated from the imported spec. Each group bundles related operations into a smaller set of tools that Stylo can choose from more easily.
For each group, Stylo shows:
* Group name
* Group description, when available
* Intent label
* Sensitivity label
* Number of mapped operations
* An enable or disable switch
Use tool groups when you want broader control over a whole category of actions. Use individual operation toggles when you need tighter control.
Recommended rollout pattern [#recommended-rollout-pattern]
For most teams, the safest rollout is:
1. Import the full OpenAPI spec.
2. Start by enabling only lookup or low-risk operations.
3. Review any write actions carefully before enabling them.
4. Test the managed API in a controlled workflow before wider rollout.
5. Expand access only after the results are predictable.
This matters because managed APIs can expose real external actions, not just read-only lookups.
Limits and safety [#limits-and-safety]
* Managed APIs can be deleted from the list or detail page.
* Deleting a managed API removes its operations and tool groups and cannot be undone.
* Stylo flags some imported operations as write or sensitive actions — review those carefully before you enable them.
* If your workspace reaches its managed API limit, you can't create another until you're on a higher plan.
Maintain a managed API [#maintain-a-managed-api]
You choose an authentication type when you create or edit a managed API. After that, you can:
* Edit its name, base URL, auth type, or description
* Re-import the OpenAPI spec to refresh the available operations
* Revisit operations and tool groups to tighten or widen access
* Delete the managed API when it's no longer needed
{/* TODO(docs): the create/edit forms don't yet expose a step for entering or rotating the API's stored credentials, though the backend supports it. Document the credential setup flow once that surface is confirmed. */}
Related [#related]
* Start with [Integrations](/integrations) for the broader integrations model
* Continue to [Response Workflows](/response-workflows) if you want to use imported tools in automation
---
# MCP Servers
URL: /mcp-servers
Type: howto
Description: Connect external MCP servers so Stylo can discover and use their tools in workflows and AI conversations.
Keywords: mcp, model context protocol, servers, tools
MCP Servers let you connect Stylo to an external Model Context Protocol server and use that server's tools inside Stylo. This is useful when you already have MCP-compatible tools and want Stylo to call them without building a custom native integration first.
{/* TODO(docs): Screenshot of the MCP Servers page showing server status, tool count, and the Add Server button. Tracked in public/images/README.md. */}
What MCP Servers are for [#what-mcp-servers-are-for]
Use an MCP server when you want Stylo to work with tools that live outside Stylo, such as internal support systems, custom data services, or operational actions exposed through an MCP endpoint.
In the current product, MCP servers are described as available for:
* Workflows
* AI conversations
Before you start [#before-you-start]
MCP Servers are gated by plan. In the current product, the MCP Servers area is shown as a Professional feature, and your workspace can only create up to the number of MCP servers allowed by your plan.
Before you add a server, make sure you have:
* The server URL
* Any required request headers
* A clear understanding of which tools the server exposes
* A safe test environment if those tools can make external changes
Add an MCP server [#add-an-mcp-server]
1. Go to **Integrations**.
2. Open the **MCP Servers** tab.
3. Click **Add Server**.
4. Enter a **Name**.
5. Enter the server **URL**.
6. Add an optional **Description**.
7. Add any required **Headers** as key-value pairs.
8. Click **Create Server**.
Stylo then opens the server detail page, where you can test the connection and discover tools.
Test the connection [#test-the-connection]
After creating a server, open its detail page and click **Test Connection**.
Stylo tracks the connection status as:
* **Connected** when the server can be reached successfully
* **Disconnected** before a successful connection has been recorded
* **Error** when the last connection or tool refresh failed
If a connection attempt fails, the detail page shows the latest error message so you can correct the URL, headers, or server availability.
Refresh tools [#refresh-tools]
Stylo does not assume the tool list automatically. Use **Refresh Tools** on the detail page to discover the tools exposed by the server.
After a successful refresh, Stylo stores:
* The number of discovered tools
* The latest refresh time
* The discovered tool definitions
The **Discovered Tools** section then shows each tool's:
* Name
* Description, when provided by the server
* Parameter count
{/* TODO(docs): GIF of testing an MCP server connection and refreshing discovered tools. Tracked in public/images/README.md. */}
How discovered tools are used [#how-discovered-tools-are-used]
Once Stylo has successfully discovered tools from a connected server, those tools can be turned into Stylo tools and workflow blocks.
In practice, this means:
* A healthy MCP server can contribute tools for AI use
* Refreshed tools can appear as dynamic integration blocks in workflows
* Servers in an error state are not eligible for workflow blocks
If you change the tools on the remote MCP server, refresh the server in Stylo so the stored tool list stays current.
Edit an MCP server [#edit-an-mcp-server]
You can edit the same fields that are exposed in the current form:
* Name
* URL
* Description
* Headers
Use this when:
* The server endpoint changes
* Authentication headers rotate
* You want a clearer name or description for the team
Delete an MCP server [#delete-an-mcp-server]
You can delete an MCP server from the list page or the detail page.
Deleting a server:
* Cannot be undone
* Removes it from Stylo's MCP server list
* Stops Stylo from using that server as an MCP source
Limits and safety [#limits-and-safety]
* MCP servers can expose real actions, not just lookups. Test them before using them in production workflows.
* If a server is unreachable or returns errors, Stylo records the failure and marks the connection status as **Error**.
* If your workspace reaches its MCP server limit, Stylo blocks creation of additional servers.
* Headers you enter are kept in Stylo's secret storage, not retained in the form after you save.
{/* TODO(docs): the create/edit forms don't expose the timeout or enabled fields yet, though the detail screen shows a timeout value. Document guidance for those controls once the surface is confirmed. */}
Recommended rollout pattern [#recommended-rollout-pattern]
For most teams, the safest rollout is:
1. Add one MCP server for a narrow use case.
2. Test the connection.
3. Refresh tools and review what is exposed.
4. Verify the tools in a controlled workflow or internal AI use case.
5. Add broader or more sensitive servers only after the first setup is stable.
Related [#related]
* Start with [Integrations](/integrations) for the broader integrations model
* Continue to [Response Workflows](/response-workflows) if you want to use discovered tools in automations
---
# Members and Access
URL: /members-and-access
Type: howto
Description: Invite teammates, manage pending invitations, and use join links safely in Stylo.
Keywords: members, access, invitations, join link, roles
Getting the right people into your Stylo workspace — without handing out more access than you mean to — comes down to three tools. This page covers when to invite someone directly, when to share a join link, and what happens when a person accepts.
The three ways to add people [#the-three-ways-to-add-people]
The **Members** settings page gives you three access tools:
* **Invite Member** for sending a direct invitation to one email address
* **Pending Invitations** for tracking and revoking invitations that have not been accepted yet
* **Join Links** for creating reusable links that let people join with a preset role
{/* TODO(docs): screenshot — Members page (members list, pending invitations, join links). Tracked in public/images/README.md. */}
When to use each access option [#when-to-use-each-access-option]
Choose the access path based on how tightly you need to control who joins.
* Use an **invitation** when you know exactly which person should join
* Use a **join link** when you want to onboard a group with the same role
* Use the **member list** when you need to review who already has access
If you need tighter control, prefer invitations over join links.
Invite one person by email [#invite-one-person-by-email]
Use **Invite Member** when access should go to a specific email address.
When you send an invitation, you choose:
* The teammate's email address
* A role: **Viewer**, **Agent**, or **Admin** (the dialog defaults to **Agent**)
After the invite is sent:
* The invitation appears in **Pending Invitations**
* Stylo sends an invitation email
* The person must accept the invitation before they become a workspace member
If the person is already a member or already has a pending invitation, the invitation request is rejected instead of creating a duplicate.
How invitation acceptance works [#how-invitation-acceptance-works]
Invitations are tied to a specific email address.
When the invited person opens the invitation:
* If they are not signed in, they are prompted to sign up or log in
* If they are signed in with the invited email address, they can accept the invitation
* If they are signed in with a different email address, Stylo blocks acceptance and asks them to sign out and try again with the correct account
This is the safest option when access should go to one known person.
Manage pending invitations [#manage-pending-invitations]
Use **Pending Invitations** to see which invites are still waiting for acceptance.
For each pending invitation, Stylo shows:
* The invited email address
* The role that will be assigned
* When the invitation was sent
* How long until the invitation expires
Invitations expire **7 days** after they're sent. You can revoke a pending invitation at any time; revoking it prevents that invitation from being accepted later.
Use join links carefully [#use-join-links-carefully]
Use **Join Links** when you want a reusable access path instead of sending one invitation at a time.
When you create a join link, you choose:
* A preset role: **Viewer**, **Agent**, or **Admin**
* An optional **Max uses** limit — leave it blank for unlimited uses
Join links are designed for broader sharing than invitations. Anyone with the link can use it while the link is active and within its usage limit.
For that reason:
* Use join links for controlled group onboarding
* Avoid using an admin join link unless you are confident it will stay tightly shared
* Disable a link when you no longer want it used
For each join link, Stylo shows:
* The assigned role
* Whether the link is active
* How many times it has been used
* The max use limit, if one was set
Active links can be copied and disabled from the Members page.
How join link acceptance works [#how-join-link-acceptance-works]
Join links do not use the same email-match check as direct invitations.
When someone opens a join link:
* If they are not signed in, they are prompted to sign up or log in
* If they are signed in, they can join the organization with the role assigned to that link
This makes join links faster for group onboarding, but less restrictive than direct invitations.
Roles [#roles]
Stylo has four roles. The invite and join-link flows can assign **Viewer**, **Agent**, or **Admin**; **Owner** is assigned only through ownership transfer, never through an invite or join link.
| Role | Invite / manage join links | Change roles, remove members | Transfer ownership |
| ---------- | -------------------------- | --------------------------------------------------- | ------------------ |
| **Viewer** | No | No | No |
| **Agent** | No | No | No |
| **Admin** | Yes | Yes — but cannot remove or demote another **Admin** | No |
| **Owner** | Yes | Yes | Yes |
What each role is for:
* **Viewer** — visibility without operational control.
* **Agent** — day-to-day workspace work.
* **Admin** — manage workspace access and settings.
* **Owner** — full control, including ownership transfer.
When an Admin sends an invite or creates a join link, they can only grant **Agent** or **Viewer** — not **Admin** or **Owner**. Owners can grant any assignable role.
Role boundaries that matter on this page [#role-boundaries-that-matter-on-this-page]
The Members page also includes role and removal controls for existing members. A few rules matter when you manage access:
* **Agents** and **Viewers** cannot invite users or manage join links
* **Admins** can invite users, manage join links, change roles, and remove members
* **Admins** cannot remove other admins
* The **Owner** cannot be removed directly
* The **Owner** role cannot be assigned through the invite or join link flow
If ownership needs to change, that is a separate ownership transfer workflow rather than a normal role edit.
Practical examples [#practical-examples]
Use an invitation when:
* You are adding one new support lead as an **Admin**
* You need to make sure access goes only to one exact email address
Use a join link when:
* You are onboarding a training group of new agents with the same role
* You want to cap access with a **Max uses** limit
Use revoke or disable when:
* An invite was sent to the wrong person
* A shared link should no longer be usable
* A temporary onboarding path is complete
Related [#related]
* [Workspace Overview](/workspace-overview)
* [Getting Started](/getting-started)
---
# Query Mapping
URL: /query-mapping
Type: concept
Description: Review AI-generated Q&A candidates from real customer conversations and improve your knowledge base retrieval over time.
Keywords: query mapping, q and a, retrieval, knowledge improvement
Query mapping is how Stylo learns from real customer conversations to improve retrieval accuracy. When customers ask questions and agents send AI-grounded responses, Stylo identifies candidate query-to-article mappings and surfaces them for your review. Confirmed mappings are indexed directly into your knowledge base, making future responses more accurate for similar questions.
How it works [#how-it-works]
Stylo watches for a specific signal: a customer asked a question, the AI retrieved knowledge base articles and generated a draft, an agent accepted that draft (or it was auto-applied), and the ticket was subsequently resolved. When all four conditions are met, Stylo evaluates the interaction as a potential **feedback candidate** — a proposed mapping between the customer's question and the articles that were used to answer it.
Quality filtering [#quality-filtering]
Not every resolved ticket produces a useful candidate. Stylo automatically filters out low-signal interactions before they reach the review queue:
* **Heavy edits** — If an agent rewrote more than 70% of the AI-generated draft, the grounding articles probably weren't useful for that response. These candidates are dropped.
* **Failed grounding check** — Stylo's grounding critic evaluates whether the AI response is actually supported by the retrieved articles. Candidates that fail this check are excluded.
* **Long conversations** — Tickets that took more than 5 replies to resolve suggest the draft wasn't the primary driver of the resolution. These are filtered out.
Candidates that pass filtering are **prioritized** so the highest-confidence items appear first in the queue. Auto-applied drafts (where no agent intervention was needed), low edit distances, and single-reply resolutions all rank higher.
Each knowledge base sync surfaces up to **50 candidates per knowledge base**. This keeps the queue manageable — reviewers see the most promising candidates first, and additional candidates surface in subsequent syncs.
These candidates appear in the Query Mapping review queue, where a reviewer confirms, rejects, or skips each one.
Why human review? [#why-human-review]
Not every accepted draft actually answered the customer's question, and not every retrieved article was actually useful. A draft might have been heavily edited by the agent, a ticket might have taken five more exchanges to resolve, or the AI might have retrieved three articles but only one was relevant. Automated indexing would pollute the knowledge base with false positives. Human review ensures only genuinely useful query-article mappings make it into your retrieval index.
The review queue [#the-review-queue]
Navigate to **Knowledge > Query mapping** in the sidebar. The page shows a split view with a candidate list on the left and a detail pane on the right.
Candidate list [#candidate-list]
The left panel shows all candidates matching your current filters. Each row displays:
* The customer's original question
* A color-coded badge indicating which knowledge base the candidate belongs to
* The ticket number
* How long ago the candidate was created
Use the **Status** filter to switch between Pending, Confirmed, Rejected, Skipped, Edited, and Expired candidates. Use the **KB** filter to narrow the list to a specific knowledge base.
Detail pane [#detail-pane]
Selecting a candidate loads its full detail on the right. You'll see:
* **Knowledge base badge** — color-coded to match the list
* **Ticket reference** — with a link to open the original ticket in Zendesk
* **Resolution context** — when the ticket was resolved and how many replies it took
* **Retrieved articles** — the articles the AI used when generating the draft. Click articles to select or deselect them for confirmation.
* **Draft vs. sent comparison** — a side-by-side view of what the AI generated versus what was actually sent to the customer, with an edit distance indicator showing how much the agent changed the draft
* **Action buttons** — Confirm, Reject, or Skip
Reviewing candidates [#reviewing-candidates]
Confirm [#confirm]
Confirming a candidate indexes the customer's query and your selected articles into the knowledge base. Before confirming:
1. Review the retrieved articles and select the ones that actually answered the question (click to toggle)
2. Optionally edit the question text if the customer's original phrasing was unclear
3. Click **Confirm** (or press **C**)
You must select at least one article. The confirmed mapping is indexed with a high quality score, meaning it will rank above synthetic Q\&A pairs in future retrieval.
Reject [#reject]
Rejecting a candidate records it as evidence of a knowledge gap. This is the right action when the retrieved articles didn't actually answer the question, or the mapping is misleading.
1. Click **Reject** (or press **R**) to expand the reject form
2. Optionally select a preset reason or type your own
3. Click **Confirm reject** to submit
Preset reasons include: Wrong article, Article out of date, Missing article, Question too vague, and Multiple articles partially answer. Selecting a preset pre-fills the reason text, which you can edit further.
Skip [#skip]
Skip a candidate if you're unsure or want to come back to it later. Skipped candidates move out of the pending queue but can be reopened at any time by switching to the Skipped filter and clicking **Reopen**.
Navigating the queue [#navigating-the-queue]
After confirming, rejecting, or skipping, the cursor automatically advances to the next candidate so you can work through the queue efficiently.
Keyboard shortcuts [#keyboard-shortcuts]
The review queue supports keyboard-driven navigation for high-volume review sessions.
| Key | Action |
| ----------------------- | -------------------------------- |
| **J** / **↓** | Next candidate |
| **K** / **↑** | Previous candidate |
| **C** | Confirm (with selected articles) |
| **R** | Reject |
| **S** | Skip |
| **E** | Edit question |
| **1–9** | Toggle article by position |
| **?** | Show keyboard shortcuts |
Press the **?** key or click the keyboard icon in the page header to see the full shortcut reference.
Pending count badge [#pending-count-badge]
The sidebar nav shows a badge next to "Query mapping" with the number of pending candidates. This count updates as you review. When it reaches zero, the badge disappears.
What happens to confirmed candidates [#what-happens-to-confirmed-candidates]
When you confirm a candidate, the query and selected articles are indexed as a retrieval entry in the knowledge base with a quality score of 80. For reference:
* Synthetic Q\&A pairs (generated during KB sync) have a quality score of 50
* Confirmed query mappings score 80
This means confirmed real-customer queries rank higher in retrieval than synthetic ones, which is the desired behavior — real questions from real conversations are the most valuable retrieval signals you have.
What happens to rejected candidates [#what-happens-to-rejected-candidates]
Rejected candidates are recorded as `retrieval_miss` evidence in the knowledge gap pipeline. As rejection evidence accumulates for similar topics, it surfaces as a knowledge gap, signaling that your knowledge base may need a new or updated article in that area.
Tips [#tips]
* **Prioritize pending candidates regularly.** The queue fills during every KB sync. Reviewing frequently keeps the queue manageable and ensures your retrieval index reflects recent customer behavior.
* **Pay attention to the draft-vs-sent comparison.** If an agent heavily edited the draft, the retrieved articles may not have been useful even though the ticket was resolved. Consider rejecting these.
* **Use the KB filter for focused sessions.** If you manage multiple knowledge bases, filter to one at a time to build context around that domain.
* **Deselect irrelevant articles before confirming.** If three articles were retrieved but only one actually answered the question, deselect the other two. Precise mappings produce better retrieval.
* **Don't skip too much.** Skipping is for genuine uncertainty. If you're skipping most candidates, the underlying signal quality may need investigation.
Related [#related]
* [Knowledge Base](/knowledge-base)
* [Knowledge Sync and Documents](/knowledge-sync-and-documents)
---
# Security and Data Handling
URL: /security-and-data-handling
Type: concept
Description: Manage access, credentials, integrations, and uploaded files using the controls available in Stylo today.
Keywords: security, data handling, credentials, access, privacy
Three controls in Stylo decide how exposed your workspace is: who can get in, which external systems Stylo connects to, and what content you upload. This page walks through tightening each one — managing access, reviewing integration connections, and cleaning up uploaded files.
{/* TODO(docs): screenshot — Members, Integrations, and Knowledge Files settings that control access and uploaded content. Tracked in public/images/README.md. */}
Start with access control [#start-with-access-control]
The strongest security step in Stylo is controlling who can join the workspace and what role they receive.
From **Members**, admins can:
* Invite one person by email
* Review and revoke pending invitations
* Create join links with a preset role
* Set an optional max-use limit on a join link
* Disable a join link when it should no longer work
Use direct invitations when access should go to one known person. Use join links only when you need to onboard a group with the same role.
Join links are broader by design. Anyone with an active link can join with the assigned role until the link is disabled or reaches its usage limit.
Choose the least powerful role that will work [#choose-the-least-powerful-role-that-will-work]
Stylo lets you assign these roles from the access workflows:
* **Viewer**
* **Agent**
* **Admin**
Use the lowest role that still supports the person's job. This matters most when you are creating invitations or join links that could be shared more widely than intended.
If you are onboarding a large group, start with **Viewer** or **Agent** unless the group truly needs settings access.
Review pending access regularly [#review-pending-access-regularly]
Pending invitations and active join links are temporary access paths. Review them when:
* A rollout or training session is complete
* Someone no longer needs workspace access
* You sent an invite to the wrong email address
* A shared join link should stop working
Revoking an invitation blocks that invitation from being accepted later. Disabling a join link stops future use of that link.
Understand what Stylo asks for when you connect an integration [#understand-what-stylo-asks-for-when-you-connect-an-integration]
From **Integrations**, Stylo shows providers as not installed, connected, degraded, auth expired, disconnected, or error.
Some integrations use OAuth. Others ask for an API key or a structured JSON secret in a connection dialog.
For API key based connections, the dialog asks for:
* The provider name
* The expected credential label
* One secret value, entered either as a password field or a JSON text field
Use the provider's own least-privilege credential option when you create that secret. Stylo's connection dialog does not decide the permissions of the key. The permissions come from the external system that issued it.
Use integration status as an operational check [#use-integration-status-as-an-operational-check]
The Integrations page is the quickest place to spot connection problems that can affect AI outputs or workflow actions.
Check integration status when:
* A workflow stops pulling data from another system
* An OAuth connection needs attention
* You want to confirm whether a provider is connected before using it in Stylo
Status labels help you decide what to do next:
* **Connected** means the integration is available
* **Degraded** or **Auth Expired** means the connection needs attention
* **Disconnected** means it is not currently connected
* **Error** means the connection failed and should be reviewed
If an integration is no longer needed, remove or replace that access path from its management flow instead of leaving an unused connection in place.
Know which integrations are available on your plan [#know-which-integrations-are-available-on-your-plan]
Some integrations are plan-gated in the current product. If a provider is locked for your workspace plan, Stylo shows the required plan before connection.
This matters for rollout planning. A missing integration may be a plan limitation, not a setup mistake.
Upload only the file types Stylo supports [#upload-only-the-file-types-stylo-supports]
For file-upload knowledge bases, Stylo accepts these file types:
* `.pdf`
* `.docx`
* `.txt`
After upload, each file moves through a visible processing state:
* **Pending**
* **Processing**
* **Completed**
* **Error**
If a file reaches **Error**, Stylo shows the processing error on that file. Use this to decide whether to retry with a different file or remove the failed upload.
{/* TODO(docs): Screenshot of the Files tab showing accepted file types and processing state badges. Tracked in public/images/README.md. */}
Delete outdated files carefully [#delete-outdated-files-carefully]
Uploaded files can be deleted from the file list. The delete dialog states that this action cannot be undone.
Use deletion when:
* A file was uploaded by mistake
* The content is outdated
* The document should no longer be available in that knowledge base
Do not leave stale or duplicate files in a knowledge base if they should no longer inform retrieval.
Practical review checklist [#practical-review-checklist]
Use this sequence when you want to tighten workspace trust controls:
1. Open **Members** and review admins, pending invitations, and active join links.
2. Revoke invitations that should no longer be accepted.
3. Disable join links that were meant for temporary onboarding.
4. Open **Integrations** and review connection status for each provider.
5. Remove or update connections that are no longer valid for your team.
6. Open the **Files** tab in file-upload knowledge bases and remove outdated uploads.
What this page doesn't cover [#what-this-page-doesnt-cover]
This page is about the controls you can see and use in the product. For storage architecture, encryption, retention, and compliance commitments, ask the Stylo team through your security review rather than inferring them from the UI.
Related [#related]
* [Members and Access](/members-and-access)
* [Integrations](/integrations)
* [Knowledge Sync and Documents](/knowledge-sync-and-documents)
---
# Troubleshooting
URL: /troubleshooting
Type: howto
Description: Diagnose common Stylo issues by checking execution history, execution detail, sync status, and integration connection state.
Keywords: troubleshooting, errors, sync stuck, auth failure, not triggering
When something in Stylo isn't behaving as expected, start here. This page helps you tell apart the common culprits — a workflow that failed, an approval that's waiting, knowledge that's out of date, or an integration that stopped returning data — and points you to the right screen for each.
Start with the symptom [#start-with-the-symptom]
Most troubleshooting in Stylo starts from one of these symptoms:
* A workflow did not finish
* A workflow is stuck waiting
* Knowledge content looks stale or incomplete
* An integration stopped returning data
Use the symptom to choose the first screen to inspect.
Common issues and fixes [#common-issues-and-fixes]
Start here for the issues support teams hit most often. Each entry is symptom-first; if none match, use the diagnostic guide further down.
A workflow is not triggering on new tickets [#a-workflow-is-not-triggering-on-new-tickets]
**Likely cause:** the workflow is still a draft, its "when to use" description doesn't match the ticket, a condition is filtering the ticket out, an escalation rule is holding it for review, or a required integration is not connected.
**What to do:**
1. Confirm the workflow is **published** — a draft never runs live. See [Creating a Workflow](/response-workflows/creating-a-workflow).
2. Review the workflow's [conditions](/response-workflows/conditions) — the ticket must match for the workflow to apply.
3. Check the "when to use" description is specific enough to match the ticket's intent, not too narrow.
4. Check your [escalation rules](/response-workflows/escalation-rules) aren't intentionally holding the ticket for human review.
5. Confirm any [integration](/integrations) the workflow depends on shows **Connected**.
Then open **Execution History** for the workflow to see whether it attempted a run at all.
A knowledge base is stuck on "Syncing" [#a-knowledge-base-is-stuck-on-syncing]
**Symptom:** the sync card shows **Syncing** for far longer than a normal sync, sometimes with a document count of 0, and the content never refreshes.
**Likely cause:** a sync run did not finish cleanly, so its status was never advanced to **Idle** or **Error**.
**What to do:**
1. Open the knowledge base and start the sync again.
2. If it completes, the status returns to **Idle** and the document count updates. See [Knowledge Sync and Documents](/knowledge-sync-and-documents).
3. If it stays on **Syncing**, escalate with the knowledge base ID and the time the sync started.
While a knowledge base is stuck on **Syncing**, do not assume its content is
current — workflows may be grounding on stale or incomplete content.
An integration shows "Auth Expired" or stopped returning data [#an-integration-shows-auth-expired-or-stopped-returning-data]
**Symptom:** workflows that rely on an integration stop getting external data, and the integration detail page shows **Auth Expired** or **Error**.
**Likely cause:** the stored credentials expired or were revoked at the provider, or the provider changed the access Stylo was granted.
**What to do:**
1. Open the integration's detail page and **reconnect** it.
2. For OAuth integrations, sign in again at the provider. For API-key integrations, re-enter a valid key. See [Integrations](/integrations).
3. Re-run an affected workflow to confirm data returns.
4. If the integration returns to **Auth Expired** or **Error** after reconnecting, escalate.
If a workflow did not finish [#if-a-workflow-did-not-finish]
Start with **Execution History** for the affected workflow.
Execution History helps you answer these questions quickly:
* Did the workflow run at all
* Did the latest run succeed or fail
* When did it start
* Which trigger started it
* How long did it run
If the workflow has multiple recent runs, compare them before changing anything. A repeated failure pattern is usually easier to diagnose than one isolated run.
If a run failed [#if-a-run-failed]
Open the run in **Execution Detail**.
That view is the best place to inspect:
* The execution status
* The result summary
* The failure message
* The error code
* The event timeline
* Execution timing and metadata
When a run fails, use the error message and event timeline together. The error message tells you what failed. The timeline helps you narrow down which step failed first.
If a run is still in progress [#if-a-run-is-still-in-progress]
Not every unexpected result is a failure. The current execution states mean different things:
* `pending` means the run is queued
* `running` means work is still in progress
* `waiting_for_approval` means the workflow is paused for human review
* `succeeded` means the run completed
* `failed` means the run ended with an error
If the run is `pending` or `running`, do not treat it as broken immediately. Check the start time, duration, and event timeline first.
If a run is waiting for approval [#if-a-run-is-waiting-for-approval]
Use **Approvals** instead of staying in the execution detail page.
Execution detail can show that the status is `waiting_for_approval`, but the approval action itself happens in the **Approvals** queue. This is the expected path for workflows that include a human review step.
Use Approvals when:
* A workflow is paused for review
* A draft or action needs human confirmation
* A backlog run created review items that still need attention
If knowledge content looks stale [#if-knowledge-content-looks-stale]
Open the knowledge base and check **Sync Status** first.
The sync card shows whether the knowledge base is:
* **Idle**
* **Syncing**
* **Error**
If the status is **Syncing**, Stylo also shows document progress and failed document count. If the status is **Error**, Stylo shows the current sync error.
This is the fastest way to separate a content freshness problem from a workflow or retrieval problem.
If uploaded files are not available yet [#if-uploaded-files-are-not-available-yet]
For file-upload knowledge bases, check the file processing state before assuming the content is ready.
Uploaded files can be:
* **Pending**
* **Processing**
* **Completed**
* **Error**
If a file is still pending or processing, wait for it to finish. If it reaches error, review the file-level error and decide whether to retry with a corrected file or remove that upload.
If an integration stopped working [#if-an-integration-stopped-working]
Open the integration’s detail page and review its connection status.
The integration surfaces distinguish between:
* **Connected**
* **Degraded**
* **Auth Expired**
* **Disconnected**
* **Error**
These statuses point to different next steps:
* **Connected** means the issue is likely elsewhere
* **Degraded** means some features may not work correctly
* **Auth Expired** means the connection needs updated credentials
* **Disconnected** means the integration is not active
* **Error** means the integration failed and should be reviewed before reuse
The integration detail page also gives you recovery actions such as reconnecting or disconnecting the integration.
Practical troubleshooting workflow [#practical-troubleshooting-workflow]
Use this sequence for most operational issues:
1. Identify whether the problem is about a workflow run, an approval, knowledge freshness, or an integration.
2. If it is a workflow issue, open **Execution History** and then the affected run in **Execution Detail**.
3. If the run is waiting for review, move to **Approvals**.
4. If the issue looks like missing or stale content, check **Sync Status** in the relevant knowledge base.
5. If the issue looks like missing external data, open the relevant integration and review its status.
When to escalate [#when-to-escalate]
Escalate beyond normal workspace troubleshooting when:
* The same workflow keeps failing after you confirm the configuration is unchanged
* A knowledge base remains in **Error** after you address the visible content issue
* An integration stays in **Error** or **Auth Expired** after reconnecting it
* The product surfaces do not expose enough information to explain the failure safely
When you escalate, include the execution ID, workflow name, sync error text, or integration status so the next reviewer can start from the same evidence.
Related [#related]
* [Analytics and Operations](/analytics-and-operations)
* [Knowledge Sync and Documents](/knowledge-sync-and-documents)
* [Integrations](/integrations)
* [Workflow Testing and Execution History](/response-workflows/testing-and-history)
---
# Voice Intelligence
URL: /voice-intelligence
Type: howto
Description: Manage Zendesk call processing in Stylo by enabling Voice Intelligence and maintaining the managed trigger that sends call tickets into Stylo.
Keywords: voice intelligence, zendesk, calls, voice, trigger
Voice Intelligence lets your team process Zendesk call tickets through Stylo's transcription and summarization pipeline. Use it when your support operation handles calls in Zendesk and you want Stylo to receive those call events reliably. The feature is **off by default** — turn it on and install the managed trigger to start processing calls.
{/* TODO(docs): screenshot — Voice Intelligence page (enable toggle, trigger status badge, trigger actions). Tracked in public/images/README.md. */}
What you can do here [#what-you-can-do-here]
From the Voice Intelligence page you can:
* Turn Voice Intelligence on or off for the workspace
* Check whether the managed Zendesk trigger is installed and healthy
* Repair or remove the managed trigger when Zendesk delivery breaks
* Review the latest trigger check time, install time, and any current error
Before you use it [#before-you-use-it]
Voice Intelligence currently depends on Zendesk.
* Your workspace must have a Zendesk integration connected before you can install the managed trigger
* Only workspace owners and admins can change Voice Intelligence settings
* Agents and viewers can see the page, but they cannot change the settings
If Zendesk is not connected, the page shows a warning and the trigger actions stay unavailable.
Set up Voice Intelligence [#set-up-voice-intelligence]
1. Open **Voice Intelligence** from the main navigation.
2. Turn on **Enable Voice Intelligence**.
3. Select **Install Trigger**.
4. Confirm that the status changes to a healthy state.
When the managed trigger is installed, Zendesk is configured to send voice ticket events to Stylo.
Understand trigger status [#understand-trigger-status]
The status badge shows the current trigger state.
* `not installed`: No managed Zendesk voice trigger is installed yet.
* `healthy`: The managed trigger is installed and appears to be working.
* `broken`: Stylo recorded a trigger problem. Check the current error and repair or recheck the trigger.
* `unknown`: Stylo could not confirm the current trigger state.
The page also shows:
* **Last checked** for the most recent status check
* **Last installed** for the most recent install time
* **Current Error** for the latest recorded trigger error message and code, if one exists
Fix common trigger problems [#fix-common-trigger-problems]
If the trigger is missing or failing, use the actions on the page in this order:
1. Select **Recheck Status** to refresh the current snapshot.
2. If the trigger is still broken, select **Repair Trigger**.
3. If the managed trigger should no longer send voice ticket events to Stylo, select **Remove Trigger**.
Use **Install Trigger** only when no managed trigger is installed yet.
When to escalate [#when-to-escalate]
Voice Intelligence is an admin-managed feature. Escalate to a workspace admin if:
* Zendesk is not connected
* The page shows a persistent broken status after a repair attempt
* The current error keeps returning after a recheck
* Your team needs Voice Intelligence disabled or the trigger removed
What happens when you disable Voice Intelligence [#what-happens-when-you-disable-voice-intelligence]
Turning Voice Intelligence off stops Stylo from processing calls, even if the managed Zendesk trigger is still installed:
* Zendesk keeps sending call webhooks (the trigger remains on Zendesk's side).
* Stylo drops each incoming call event at ingestion — no transcription or summarization runs.
* Existing summaries are preserved.
* The trigger stays installed, so you can re-enable Voice Intelligence later without reinstalling it.
To stop Zendesk from sending the events entirely, use **Remove Trigger**.
Related [#related]
* [Integrations](/integrations)
* [Analytics and Operations](/analytics-and-operations)
---
# Workflow Builder Configuration
URL: /workflow-builder-configuration
Type: howto
Description: Configure workflow blocks in Stylo by selecting a node, setting its fields, inserting variables, and defining structured schema or JSON where needed.
Keywords: workflow builder, blocks, configuration, variables, schema
After you place a block on the workflow canvas, you configure it from the panel on the right side of the editor. Use this panel to choose the block type, connect the right integration, set field values, and pass data from earlier steps into later ones.
{/* TODO(docs): screenshot — Workflow Builder with a selected node and the configuration panel open. Tracked in public/images/README.md. */}
Open the configuration panel [#open-the-configuration-panel]
Select any node on the canvas to open its configuration.
The panel can show:
* The current block name
* The node label
* The block type selector
* Required configuration fields for that block
* Integration selection when the block needs connected credentials
If no block type is set yet, Stylo prompts you to choose one before the node can be fully configured.
Set the block type and label [#set-the-block-type-and-label]
Each node has two different identifiers in practice:
* **Block type** defines what the node does
* **Label** is the name you see on the canvas
Change the block type when you want the node to perform a different action. Change the label when you want a clearer name for the step in your workflow.
For trigger nodes, the configuration panel includes a trigger type picker so you can switch between supported trigger blocks directly.
Connect the right integration [#connect-the-right-integration]
Some blocks depend on a connected integration before they can run.
When a block requires an integration, the configuration panel shows an integration picker for that provider. This lets you choose which connected account the block should use.
If the required integration is not connected, the block configuration may remain incomplete until that connection exists.
Fill in block fields [#fill-in-block-fields]
Stylo renders block fields based on the block’s configuration schema.
Depending on the block, fields may appear as:
* Short text inputs
* Long text areas
* Dropdowns
* Toggles
* Sliders and number inputs
* Template-aware fields
* Structured JSON builders
* Structured schema builders
Required fields are marked in the panel, so you can see which settings must be completed before the block is ready.
Use template variables in fields [#use-template-variables-in-fields]
Some fields support template-style references to data from earlier steps.
When a field supports variable insertion, Stylo can help you insert:
* Outputs from upstream nodes
* Nested output paths from prior steps
* Built-in date and time values
The variable picker is scoped to upstream nodes, which helps prevent you from referencing a step that does not feed into the current node.
{/* TODO(docs): GIF — inserting an upstream variable into a template-enabled field. Tracked in public/images/README.md. */}
Pin output shapes from a test run [#pin-output-shapes-from-a-test-run]
Dynamic blocks — webhooks, AI outputs, API calls — don't declare their full output structure upfront. The variable picker learns those fields from test runs, but a run can fall out of recent history, and a brand-new workflow has no runs at all. Pinning solves that.
After a successful test run, Stylo automatically records each node's output structure (the field names and their types — not the actual values) on the workflow. Those pinned fields stay available in the variable picker from then on, even if the run itself is no longer in the recent history list.
You can also pin or unpin a node's shape manually:
* In the execution terminal, select a step whose output you want to keep available.
* In the output panel header, click **Pin shape** to freeze it, or **Unpin** to remove it.
* A small pin indicator appears on the node in the canvas when a shape is pinned.
Pinning captures the structure only — no sample values are stored on the workflow. When a field's path comes from a pinned shape, the variable picker labels it **Pinned from prior run** so you can tell it apart from fields declared by the block itself.
Use workflow variables [#use-workflow-variables]
Workflow-level variables can also be referenced in node configuration.
These are useful when:
* The same value should be reused across several blocks
* You want one place to update a shared constant
* A workflow needs structured default data that multiple steps depend on
For example, you might use workflow variables for routing values, repeated messages, or default JSON payload fragments.
Use the schema builder [#use-the-schema-builder]
Some blocks need a structured schema instead of a single value.
The schema builder lets you define fields with supported types such as:
* `string`
* `number`
* `boolean`
* `array`
* `object`
* `enum`
You can also:
* Mark fields as optional
* Define nested fields for objects
* Define item types for arrays
* Upload a JSON file to replace the current schema
This is useful when a block needs a predictable output structure or a structured contract for downstream steps.
Use the JSON builder [#use-the-json-builder]
Some blocks expect raw JSON configuration.
The JSON builder supports two editing styles:
* **Builder mode** for editing fields visually
* **Raw mode** for editing the JSON directly
Use the builder when you want a safer visual editor. Use raw mode when you already have the JSON structure you want and prefer to paste or edit it directly.
Use large text editors for prompts and templates [#use-large-text-editors-for-prompts-and-templates]
Longer text fields can be expanded into a larger editing surface.
This is especially useful for:
* AI prompts
* Instructions
* Templated messages
* Large structured text values
If a field supports templating, the larger editor keeps that variable-insertion behavior available while giving you more room to work.
Structured outputs and downstream references [#structured-outputs-and-downstream-references]
Configuration choices affect what later nodes can reference.
For example:
* Declared block outputs become available to later steps
* Schema-builder fields can create nested output paths that later template fields can insert
* Cleaner node labels make output references easier to recognize in the variable picker
This means configuration is not just about making one node valid. It also shapes how easy the rest of the workflow is to build.
Recommended configuration workflow [#recommended-configuration-workflow]
Use this order when configuring a new node:
1. Select the node and confirm the block type.
2. Rename the node label so the step is easy to recognize later.
3. Choose the correct integration if the block needs one.
4. Fill in required fields first.
5. Add template variables or workflow variables where values should come from other steps.
6. Use schema or JSON builders only when the block expects structured data.
7. Test or review the workflow after configuration changes.
Related [#related]
* [Workflow Builder Overview](/workflow-builder-overview) for the broader automation-builder layout and concepts
* [Workflow Testing and Execution History](/response-workflows/testing-and-history) for testing and reviewing workflow behavior
---
# Workflow Builder Overview
URL: /workflow-builder-overview
Type: concept
Description: Learn how Stylo's automation builder is organized, how to start a workflow, and how blocks, containers, variables, and approvals fit together.
Keywords: workflow builder, automation, blocks, containers, approvals
The Workflow Builder is Stylo's general automation surface for multi-step operational flows. Use it when you need more than a single response draft, such as routing work, calling connected systems, pausing for approval, or combining AI with system actions in one automation.
{/* TODO(docs): screenshot — Workflow Builder (canvas, block palette, toolbar). Tracked in public/images/README.md. */}
Where it lives [#where-it-lives]
In the main navigation, the **Workflows** area contains two distinct surfaces:
* **Response Workflows** for response-specific drafting and automation
* **Workflow Builder** for multi-step, block-based automations
The two are separate. Choose the **Workflow Builder** when your process needs a visual flow of connected steps rather than a single response workflow configuration.
Start a workflow [#start-a-workflow]
From the **Workflows** page, you can:
* Create a blank workflow
* Start from a workflow template
* Open an existing workflow and continue editing
Templates are available for common operational patterns, while a blank workflow opens an empty canvas.
What the builder includes [#what-the-builder-includes]
The editor is centered on a visual canvas.
* **Canvas** for placing and connecting workflow steps
* **Block palette** for adding triggers, system blocks, AI blocks, and integration blocks
* **Variables** for reusable values that can be referenced across node configuration
* **Workflow settings** for the workflow name and description
Build on the canvas [#build-on-the-canvas]
Each workflow is made of connected nodes.
* A workflow starts from a trigger node
* Additional blocks are connected on the canvas to define execution flow
* Edges show how the workflow moves from one step to the next
* You can add a block by opening the block palette or by dropping a connection onto empty canvas space
The canvas is designed for visual editing, so layout and flow structure are part of how you review the automation.
{/* TODO(docs): GIF — adding a block from the palette and connecting it on the canvas. Tracked in public/images/README.md. */}
Use blocks and containers [#use-blocks-and-containers]
The block palette groups blocks by category and integration provider.
* **Triggers** start a workflow
* **System** blocks handle platform-level actions
* **AI** blocks add model-powered behavior
* **Integration** blocks are grouped under the connected provider they belong to
The builder also supports container-style structures for more complex logic.
* **Loop** containers group steps that repeat over a set of items
* **Parallel** containers group steps that run in parallel branches
Regular action nodes can be moved into or out of those containers on the canvas.
Use workflow variables [#use-workflow-variables]
Workflow variables are reusable key-value pairs defined at the workflow level.
* Variables can be created with `string`, `number`, `boolean`, or `json` types
* Each variable has a default value
* Variable names must be unique inside the workflow
* You can reference a variable in node configuration fields using the workflow variable placeholder format shown in the Variables dialog
Variables are useful when the same value needs to be reused across multiple steps.
Human review and approvals [#human-review-and-approvals]
Some automations need a person to review or approve an action before the workflow continues.
The workflow builder supports approval-based pauses through approval-capable blocks. When a workflow pauses for human review, Stylo routes the review to **Approvals** before the automation continues.
This is especially important for higher-risk actions such as sensitive API operations or workflows that should not run without a human checkpoint.
Backlog runs for automations [#backlog-runs-for-automations]
The broader workflow builder also supports backlog runs, but only when the workflow includes an approval block.
That requirement exists so backlog execution stays reviewable instead of running unattended across older tickets.
Workflow status [#workflow-status]
Each workflow on the overview list shows one of three primary statuses:
* **Published** — the workflow has an active published version. Triggers will start new runs against that version.
* **Draft** — the workflow has never been published. It's being built and will not run.
* **Paused** — the workflow was previously published but has been paused from the editor. It will not run until you publish again.
Use the **Published**, **Draft**, and **Paused** tabs at the top of the list to filter the view.
Unpublished changes [#unpublished-changes]
If you edit a published workflow, the running version keeps firing on triggers while your edits live in the draft. In that state the list shows an **Edited** indicator next to the **Published** badge so you can tell at a glance that the draft has moved ahead of the live version. Clicking **Publish new version** in the editor promotes the draft and clears the indicator.
When to use this builder instead of Response Workflows [#when-to-use-this-builder-instead-of-response-workflows]
Choose the workflow builder when you need:
* Multi-step automation across several systems
* Visual branching or grouped execution
* Workflow-level variables reused across multiple nodes
* Approval checkpoints inside the automation itself
Choose [Response Workflows](/response-workflows) when your goal is primarily to generate or automate support responses.
Related [#related]
* [Backlog Runs](/response-workflows/backlog-runs) for the response workflow backlog review pattern
* [Analytics and Operations](/analytics-and-operations) for operational review once that guide is available
---
# Workspace Overview
URL: /workspace-overview
Type: concept
Description: Learn what each main area of the Stylo workspace is for and where to go for setup, daily operations, and review.
Keywords: workspace, overview, navigation, areas
Stylo is organized so your team can move from setup to daily work without hunting for the right screen. The main sidebar separates day-to-day work, review queues, and organization setup so agents and admins can get to the right area quickly.
Main navigation areas [#main-navigation-areas]
The main sidebar has three navigation sections:
* The main workspace section for **Dashboard**, **Workflows**, **Tone & Instructions**, **Context Engine**, **Voice Intelligence**, and **Sentiment**
* **Observe** for **Analytics**, **Logs**, and **Approvals**
* **Org Settings** for **Integrations** and **Settings**
{/* TODO(docs): Screenshot of the Stylo sidebar showing the main navigation groups and the most important destinations. Tracked in public/images/README.md. */}
Some items in the sidebar expand into sub-pages. This helps you move from a broad area like **Tone & Instructions** or **Context Engine** into a more specific setup page without leaving the same part of the workspace.
Start with Dashboard [#start-with-dashboard]
**Dashboard** is the main landing page in the sidebar, and the page itself is titled **Home**. It gives you a quick view of what needs attention right now:
* Pending approvals
* Failed executions
* Knowledge bases with sync errors
* Your onboarding checklist
This is the best place to start when you want to see what is blocking setup or what needs review today.
Build and manage workflows [#build-and-manage-workflows]
Use **Workflows** when you want Stylo to help with repeatable support tasks.
Inside this area, Stylo separates two workflow types:
* **Response Workflows** for AI-generated customer replies
* **Workflow Builder** for broader, multi-step workflow automation
If your team is still validating response quality, start with response workflows and route drafts through review before expanding automation.
Set the voice and rules for replies [#set-the-voice-and-rules-for-replies]
Use **Tone & Instructions** to control how Stylo writes.
This area includes:
* **Tone** for voice and style
* **Instructions & Policies** for response rules
* **Language Settings** for language behavior
This area matters before you scale usage. If replies sound off-brand or miss a policy requirement, this is one of the first places to review.
Ground responses in your source content [#ground-responses-in-your-source-content]
Use **Context Engine** to manage the information Stylo can pull into AI responses.
This area includes:
* **Knowledge** for your connected knowledge bases
* **Query mapping** for improving how real support requests map to useful context
* **Settings** for context engine behavior
If response quality is weak because Stylo is missing the right article or pulling weak context, start here.
Review what needs human attention [#review-what-needs-human-attention]
Use the **Observe** group to monitor work after workflows run.
* **Logs** shows execution history so you can inspect what ran and where something failed
* **Approvals** is the review queue for drafts that need a person before they go out
This matters most when you are expanding automation. Logs help you investigate failures. Approvals help you keep a human review step where needed.
Manage workspace configuration [#manage-workspace-configuration]
Use **Org Settings** for organization-wide setup:
* **Integrations** for connected systems
* **Settings** for workspace configuration
Inside **Settings**, Stylo uses its own sidebar with:
* **General**
* **Members**
* **Assist Sidebar Layout**
This is where workspace admins typically handle team setup and configuration changes.
Voice Intelligence [#voice-intelligence]
**Voice Intelligence** appears as its own main navigation item in the core workspace. Use it when your team needs voice-specific AI settings instead of standard text-only workflows.
What is not available yet [#what-is-not-available-yet]
Some navigation items are visible but marked as coming soon:
* **Sentiment**
* **Analytics**
If you see these items in the sidebar, treat them as placeholders rather than active workspace areas.
Help and support [#help-and-support]
The workspace footer also includes **Help & Feedback**. From there, customers can open:
* Documentation
* Support
Use this when you need product guidance without leaving the app.
A practical way to move through Stylo [#a-practical-way-to-move-through-stylo]
For most teams, the workspace flow looks like this:
1. Open **Home** to see onboarding steps and anything that needs attention.
2. Configure **Tone & Instructions**, **Context Engine**, and **Integrations**.
3. Build or refine **Response Workflows** for common ticket types.
4. Use **Approvals** and **Logs** to review outputs and fix issues.
5. Return to **Settings** when you need to manage members or workspace behavior.
Related [#related]
* [Getting Started](/getting-started)
* [Assist](/assist)
* [Brand Settings](/brand-settings)
* [Knowledge Base](/knowledge-base)
* [Integrations](/integrations)
* [Response Workflows](/response-workflows)
---
# Auto-Triage & Route
URL: /recipes/auto-triage-and-route
Type: howto
Description: Automatically classify incoming Zendesk tickets by intent and urgency, then route to the right team with correct priority and tags.
Keywords: auto-triage & route, auto-triage-and-route, recipe, workflow template, workflow builder, zendesk
Automatically classify incoming Zendesk tickets by intent and urgency, then route to the right team with correct priority and tags.
**Prerequisites:** Connect **Zendesk** before adding this recipe. See [Integrations](/integrations).
How it works [#how-it-works]
Each box is a block; arrows show the order Stylo runs them, and branch labels show the path taken on each outcome.
Parameters [#parameters]
This recipe has no configurable parameters — connect the required integrations and it runs as shipped.
Blocks used [#blocks-used]
Every block in this recipe, linked to its reference page where one exists:
| Block | Type | What it does |
| -------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------- |
| [Webhook](/reference/blocks/trigger-webhook) | `trigger/webhook` | Trigger workflow via HTTP webhook |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | `zendesk/get-ticket-context` | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Classify](/reference/blocks/ai-classify) | `ai/classify` | Classify content into predefined categories using AI |
| [Condition](/reference/blocks/system-condition) | `system/condition` | Branch the workflow based on a boolean expression |
| [Set Ticket Priority](/reference/blocks/zendesk-set-ticket-priority) | `zendesk/set-ticket-priority` | Set the priority level on a Zendesk ticket (low, normal, high, or urgent). |
| [Add Tags](/reference/blocks/zendesk-add-tags) | `zendesk/add-tags` | Add tags to a ticket for classification and tracking |
| [Assign Ticket](/reference/blocks/zendesk-assign-ticket) | `zendesk/assign-ticket` | Assign a ticket to an agent or group |
| [Router](/reference/blocks/system-router) | `system/router` | Branch into N paths via boolean predicates or AI classification. |
When to use it [#when-to-use-it]
Reach for this when inbound tickets arrive faster than a person can sort them, and you want every new ticket classified by urgency and topic, then routed to the right team — before an agent ever opens it.
Adapt it [#adapt-it]
This recipe is a starting point. To fit it to your workspace:
* Edit the **Classify Ticket** prompt to match your own definition of an urgent ticket.
* Edit the routes in **Route by Topic** (billing / technical / general) to reflect your actual teams, and update each route's description so classification stays accurate.
* Set the `groupId` (or `assigneeId`) on each **Assign** block — they ship blank, so assignment is a no-op until you fill in your Zendesk group IDs.
* Change the tags on the **Tag** blocks if your workspace uses a different tagging scheme.
Related [#related]
* [All recipes](/recipes)
* [Workflow blocks reference](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# CSAT Follow-Up Campaign
URL: /recipes/csat-follow-up
Type: howto
Description: Run daily to find recently solved Zendesk tickets, then send each customer a personalized follow-up email asking about their experience.
Keywords: csat follow-up campaign, csat-follow-up, recipe, workflow template, workflow builder, zendesk, resend
Run daily to find recently solved Zendesk tickets, then send each customer a personalized follow-up email asking about their experience.
**Prerequisites:** Connect **Zendesk**, **Resend** before adding this recipe. See [Integrations](/integrations).
How it works [#how-it-works]
Each box is a block; arrows show the order Stylo runs them, and branch labels show the path taken on each outcome.
Parameters [#parameters]
Set these when you add the recipe to your workspace:
| Parameter | Type | Default |
| -------------- | ------ | ---------------------------------- |
| `from_email` | string | `support@yourcompany.com` |
| `company_name` | string | `Your Company` |
| `survey_url` | string | `https://yourcompany.com/feedback` |
Blocks used [#blocks-used]
Every block in this recipe, linked to its reference page where one exists:
| Block | Type | What it does |
| ------------------------------------------------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| [Schedule](/reference/blocks/trigger-schedule) | `trigger/schedule` | Trigger workflow on a cron schedule |
| [Search Tickets](/reference/blocks/zendesk-search-tickets) | `zendesk/search-tickets` | Search for Zendesk tickets |
| [Condition](/reference/blocks/system-condition) | `system/condition` | Branch the workflow based on a boolean expression |
| [Loop](/reference/blocks/system-loop) | `system/loop` | Iterate over items, a fixed count, or while a condition is true |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | `zendesk/get-ticket-context` | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Generate Text](/reference/blocks/ai-generate-text) | `ai/generate-text` | Generate text using AI models |
| [Send Email](/reference/blocks/resend-send-email) | `resend/send-email` | Send an email via Resend |
When to use it [#when-to-use-it]
Use this to measure satisfaction after a ticket is resolved. It runs on a schedule, finds recently solved tickets, and emails each customer a short, personalized follow-up linking to your survey.
Adapt it [#adapt-it]
This recipe is a starting point. To fit it to your workspace:
* Set the `from_email`, `company_name`, and `survey_url` parameters to your own sender, brand, and feedback link.
* Change the schedule trigger's cadence if daily is too frequent or not frequent enough.
* Edit the **Search Solved Tickets** filters to narrow which resolved tickets receive a follow-up.
Related [#related]
* [All recipes](/recipes)
* [Workflow blocks reference](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Customer 360 Enrichment
URL: /recipes/customer-360-enrichment
Type: howto
Description: When a new ticket arrives, pull the customer's full context from Zendesk and HubSpot, then use AI to generate a comprehensive summary posted as an internal note.
Keywords: customer 360 enrichment, customer-360-enrichment, recipe, workflow template, workflow builder, zendesk, hubspot
When a new ticket arrives, pull the customer's full context from Zendesk and HubSpot, then use AI to generate a comprehensive summary posted as an internal note.
**Prerequisites:** Connect **Zendesk**, **Hubspot** before adding this recipe. See [Integrations](/integrations).
How it works [#how-it-works]
Each box is a block; arrows show the order Stylo runs them, and branch labels show the path taken on each outcome.
Parameters [#parameters]
This recipe has no configurable parameters — connect the required integrations and it runs as shipped.
Blocks used [#blocks-used]
Every block in this recipe, linked to its reference page where one exists:
| Block | Type | What it does |
| ------------------------------------------------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| [Webhook](/reference/blocks/trigger-webhook) | `trigger/webhook` | Trigger workflow via HTTP webhook |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | `zendesk/get-ticket-context` | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Get User](/reference/blocks/zendesk-get-user) | `zendesk/get-user` | Fetch a Zendesk user by ID |
| [Get User Tickets](/reference/blocks/zendesk-get-user-tickets) | `zendesk/get-user-tickets` | Get ticket history for a customer |
| [Get Organization](/reference/blocks/zendesk-get-organization) | `zendesk/get-organization` | Get organization details for B2B context |
| [Search Contacts](/reference/blocks/hubspot-search-contacts) | `hubspot/search-contacts` | Search HubSpot contacts |
| [Generate Text](/reference/blocks/ai-generate-text) | `ai/generate-text` | Generate text using AI models |
| [Add Comment / Reply](/reference/blocks/zendesk-add-comment) | `zendesk/add-comment` | Add a public reply or internal note to a ticket |
| [Add Tags](/reference/blocks/zendesk-add-tags) | `zendesk/add-tags` | Add tags to a ticket for classification and tracking |
When to use it [#when-to-use-it]
Use this to give agents full context the moment a ticket arrives. It pulls the customer's history from Zendesk and HubSpot, then posts an AI-written summary as an internal note so the agent starts informed.
Adapt it [#adapt-it]
This recipe is a starting point. To fit it to your workspace:
* Edit the summary generation prompt to highlight the facts your agents care about most.
* Swap the **HubSpot** lookup for a different CRM block if you don't use HubSpot.
* Change the **Add Comment** block to post the summary publicly instead of as an internal note, if that fits your workflow.
Related [#related]
* [All recipes](/recipes)
* [Workflow blocks reference](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Escalation & SLA Monitor
URL: /recipes/escalation-sla-monitor
Type: howto
Description: Run every 30 minutes to find open tickets approaching or breaching SLA, then escalate with priority bumps, tags, Slack alerts, and internal notes.
Keywords: escalation & sla monitor, escalation-sla-monitor, recipe, workflow template, workflow builder, zendesk, slack
Run every 30 minutes to find open tickets approaching or breaching SLA, then escalate with priority bumps, tags, Slack alerts, and internal notes.
**Prerequisites:** Connect **Zendesk**, **Slack** before adding this recipe. See [Integrations](/integrations).
How it works [#how-it-works]
Each box is a block; arrows show the order Stylo runs them, and branch labels show the path taken on each outcome.
Parameters [#parameters]
Set these when you add the recipe to your workspace:
| Parameter | Type | Default |
| --------------------- | ------ | -------------- |
| `sla_hours` | number | `4` |
| `slack_channel` | string | `#escalations` |
| `escalation_group_id` | string | — |
Blocks used [#blocks-used]
Every block in this recipe, linked to its reference page where one exists:
| Block | Type | What it does |
| -------------------------------------------------------------------- | ----------------------------- | -------------------------------------------------------------------------- |
| [Schedule](/reference/blocks/trigger-schedule) | `trigger/schedule` | Trigger workflow on a cron schedule |
| [Search Tickets](/reference/blocks/zendesk-search-tickets) | `zendesk/search-tickets` | Search for Zendesk tickets |
| [Condition](/reference/blocks/system-condition) | `system/condition` | Branch the workflow based on a boolean expression |
| [Loop](/reference/blocks/system-loop) | `system/loop` | Iterate over items, a fixed count, or while a condition is true |
| [Set Ticket Priority](/reference/blocks/zendesk-set-ticket-priority) | `zendesk/set-ticket-priority` | Set the priority level on a Zendesk ticket (low, normal, high, or urgent). |
| [Add Tags](/reference/blocks/zendesk-add-tags) | `zendesk/add-tags` | Add tags to a ticket for classification and tracking |
| [Assign Ticket](/reference/blocks/zendesk-assign-ticket) | `zendesk/assign-ticket` | Assign a ticket to an agent or group |
| [Send Slack Message](/reference/blocks/slack-send-message) | `slack/send-message` | Send a message to a Slack channel |
| [Add Comment / Reply](/reference/blocks/zendesk-add-comment) | `zendesk/add-comment` | Add a public reply or internal note to a ticket |
When to use it [#when-to-use-it]
Use this to enforce response-time commitments. It runs on a schedule, finds open tickets approaching or past their SLA, and escalates them with a priority bump, tags, a Slack alert, and an internal note.
Adapt it [#adapt-it]
This recipe is a starting point. To fit it to your workspace:
* Set the `sla_hours` parameter to your own SLA window.
* Set the `slack_channel` parameter to the channel that should receive escalation alerts.
* Set the `escalation_group_id` parameter to the Zendesk group that owns at-risk tickets.
* Edit the **Search** filters and the schedule interval to match how often you want SLA checks to run.
Related [#related]
* [All recipes](/recipes)
* [Workflow blocks reference](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Recipes
URL: /recipes
Type: howto
Description: Goal-oriented walkthroughs of Stylo's shipped workflow templates — what each does, the blocks it uses, and how to adapt it.
Keywords: recipes, workflow templates, examples, workflow builder, starter workflows
Each recipe documents a shipped workflow template you can add from the Workflow Builder, then tailor to your workspace. Start from the goal closest to yours.
Automatically classify incoming Zendesk tickets by intent and urgency, then route to the right team with correct priority and tags.
Search your knowledge base for relevant articles, generate a grounded AI draft reply, and surface it in the Zendesk agent sidebar for one-click approval.
Run daily to find recently solved Zendesk tickets, then send each customer a personalized follow-up email asking about their experience.
Run every 30 minutes to find open tickets approaching or breaching SLA, then escalate with priority bumps, tags, Slack alerts, and internal notes.
Analyze ticket sentiment, classify intent with AI, then route to specialized handling: human review for refunds, Linear issues for bugs, and auto-tagging for everything else.
When a new ticket arrives, pull the customer's full context from Zendesk and HubSpot, then use AI to generate a comprehensive summary posted as an internal note.
Related [#related]
* [Workflow Builder overview](/workflow-builder-overview)
* [Workflow blocks reference](/reference/blocks)
* [Build a Response Workflow](/response-workflows/creating-a-workflow)
---
# Sentiment-Driven Routing
URL: /recipes/sentiment-driven-routing
Type: howto
Description: Analyze ticket sentiment, classify intent with AI, then route to specialized handling: human review for refunds, Linear issues for bugs, and auto-tagging for everything else.
Keywords: sentiment-driven routing, sentiment-driven-routing, recipe, workflow template, workflow builder, zendesk, linear
Analyze ticket sentiment, classify intent with AI, then route to specialized handling: human review for refunds, Linear issues for bugs, and auto-tagging for everything else.
**Prerequisites:** Connect **Zendesk**, **Linear** before adding this recipe. See [Integrations](/integrations).
How it works [#how-it-works]
Each box is a block; arrows show the order Stylo runs them, and branch labels show the path taken on each outcome.
Parameters [#parameters]
Set these when you add the recipe to your workspace:
| Parameter | Type | Default |
| ------------------------- | ------ | ------------------- |
| `linear_team_id` | string | — |
| `refund_approval_channel` | string | `#refund-approvals` |
Blocks used [#blocks-used]
Every block in this recipe, linked to its reference page where one exists:
| Block | Type | What it does |
| ------------------------------------------------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| [Webhook](/reference/blocks/trigger-webhook) | `trigger/webhook` | Trigger workflow via HTTP webhook |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | `zendesk/get-ticket-context` | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Classify](/reference/blocks/ai-classify) | `ai/classify` | Classify content into predefined categories using AI |
| [Add Tags](/reference/blocks/zendesk-add-tags) | `zendesk/add-tags` | Add tags to a ticket for classification and tracking |
| [Router](/reference/blocks/system-router) | `system/router` | Branch into N paths via boolean predicates or AI classification. |
| Human Review | `system/human-review` | Pause and wait for human approval before continuing |
| [Add Comment / Reply](/reference/blocks/zendesk-add-comment) | `zendesk/add-comment` | Add a public reply or internal note to a ticket |
| [Create Ticket](/reference/blocks/linear-create-ticket) | `linear/create-ticket` | Create an issue in Linear |
When to use it [#when-to-use-it]
Use this when different emotional tones and intents deserve different handling — for example, routing refund requests to a human for approval, filing bug reports as Linear issues, and auto-tagging everything else.
Adapt it [#adapt-it]
This recipe is a starting point. To fit it to your workspace:
* Set the `linear_team_id` parameter so bug reports file into the right Linear team.
* Set the `refund_approval_channel` parameter to the Slack channel where refund approvals are requested.
* Edit the sentiment categories and the **Route** definitions to match the intents your team handles.
Related [#related]
* [All recipes](/recipes)
* [Workflow blocks reference](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Smart Auto-Reply with Knowledge Base
URL: /recipes/smart-auto-reply
Type: howto
Description: Search your knowledge base for relevant articles, generate a grounded AI draft reply, and surface it in the Zendesk agent sidebar for one-click approval.
Keywords: smart auto-reply with knowledge base, smart-auto-reply, recipe, workflow template, workflow builder, zendesk
Search your knowledge base for relevant articles, generate a grounded AI draft reply, and surface it in the Zendesk agent sidebar for one-click approval.
**Prerequisites:** Connect **Zendesk** before adding this recipe. See [Integrations](/integrations).
How it works [#how-it-works]
Each box is a block; arrows show the order Stylo runs them, and branch labels show the path taken on each outcome.
Parameters [#parameters]
Set these when you add the recipe to your workspace:
| Parameter | Type | Default |
| ------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `min_kb_confidence` | number | `0.4` |
| `brand_voice` | string | `Friendly, professional, and empathetic. Use the customer's first name when available. Keep responses concise but thorough.` |
Blocks used [#blocks-used]
Every block in this recipe, linked to its reference page where one exists:
| Block | Type | What it does |
| ------------------------------------------------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| [Webhook](/reference/blocks/trigger-webhook) | `trigger/webhook` | Trigger workflow via HTTP webhook |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | `zendesk/get-ticket-context` | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Search Knowledge Base](/reference/blocks/context-engine-search-knowledge-base) | `context-engine/search-knowledge-base` | Search synced knowledge base documents using semantic search with automatic reranking |
| [Condition](/reference/blocks/system-condition) | `system/condition` | Branch the workflow based on a boolean expression |
| [Generate Text](/reference/blocks/ai-generate-text) | `ai/generate-text` | Generate text using AI models |
| Human Review | `system/human-review` | Pause and wait for human approval before continuing |
| [Add Comment / Reply](/reference/blocks/zendesk-add-comment) | `zendesk/add-comment` | Add a public reply or internal note to a ticket |
When to use it [#when-to-use-it]
Use this when you want agents to start from a knowledge-grounded draft instead of a blank reply box. It searches your knowledge base, drafts a reply only when a confident match exists, and surfaces it in the Zendesk sidebar for an agent to review.
Adapt it [#adapt-it]
This recipe is a starting point. To fit it to your workspace:
* Tune the `min_kb_confidence` parameter to control how strong a knowledge-base match must be before a draft is generated.
* Edit the `brand_voice` parameter to set the tone and style of the generated draft.
* Adjust the confidence **condition** branch if you want different behavior when no confident match is found.
Related [#related]
* [All recipes](/recipes)
* [Workflow blocks reference](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Actions
URL: /response-workflows/actions
Type: reference
Description: Automatically update tickets after a Response Workflow generates a response — set status, add tags, and more.
Keywords: actions, ticket update, status, tags
Actions are changes that are applied to the ticket after a Response Workflow successfully generates and sends a response. They automate the follow-up steps agents would normally do manually — setting the status to "solved," adding a tag for tracking, or updating a custom field.
Available actions [#available-actions]
| Action | What it does | Example |
| -------------------- | ------------------------------------- | ---------------------------------------------------------- |
| **Set status** | Changes the ticket status | Set to "solved" after a resolution response |
| **Set priority** | Changes the ticket priority | Downgrade to "low" after initial response |
| **Add tags** | Adds one or more tags to the ticket | Add "auto-responded" for tracking |
| **Remove tags** | Removes tags from the ticket | Remove "needs-response" after replying |
| **Set group** | Assigns the ticket to a support group | Route to "billing" group after identifying a billing issue |
| **Set custom field** | Sets a Zendesk custom field value | Set "response\_type" to "automated" |
When actions run [#when-actions-run]
Actions run **after** the response is successfully generated and either:
* **Sent automatically** (internal note or public reply mode) — actions are applied as part of the send step
* **Accepted by an agent** (cache mode) — actions are applied when the agent accepts the draft
Actions do not run if:
* The workflow's escalation rules trigger (no response generated)
* The quality check fails (public mode only)
* The ticket becomes stale (agent or customer replied during the delay)
* The agent dismisses the suggestion (cache mode)
Setting up actions [#setting-up-actions]
1. Open your workflow and go to the **Actions** section
2. Click to add an action
3. Select the action type and configure its value
4. Add multiple actions if needed — they all run together when the response is sent
Actions are executed in order, but they all apply in a single ticket update to avoid triggering multiple Zendesk webhooks.
Common patterns [#common-patterns]
**Auto-close after resolution:**
* Set status to "solved"
* Add tags: \["auto-resolved"]
* Best for: Simple, high-confidence workflows like order status or FAQ responses
**Track automated responses:**
* Add tags: \["stylo-responded"]
* Set custom field "response\_source" to "automated"
* Best for: Monitoring and reporting on AI-handled tickets
**Route after classification:**
* Set group to the appropriate team based on the workflow's purpose
* Remove tags: \["needs-triage"]
* Best for: Workflows that classify tickets and route them
**Escalation cleanup:**
* Add tags: \["escalated"]
* Set priority to "high"
* Best for: Used in combination with escalation rules — when a workflow decides to escalate instead of respond, apply these actions to ensure the ticket gets agent attention
Custom field classification [#custom-field-classification]
A powerful pattern is using actions to classify tickets by setting custom field values. For example:
* A "Sentiment Detection" workflow sets a custom dropdown field to "positive", "neutral", or "negative"
* An "Issue Category" workflow sets a custom field to "billing", "shipping", "product", or "other"
* A "Priority Assessment" workflow sets priority based on order value or customer tier
This enriches your ticket data for reporting and routing without agents needing to manually classify each ticket.
Tips [#tips]
* **Keep actions reversible.** Prefer adding tags over removing them, and setting fields over clearing them. This makes it easier to audit what happened if something goes wrong.
* **Use tags for tracking.** Adding a unique tag (like "stylo-refund-workflow") to every ticket processed by a workflow makes it easy to report on workflow performance in Zendesk.
* **Don't over-automate status changes.** Setting status to "solved" is powerful but risky if the response doesn't fully resolve the issue. Start with just adding tags, and add status changes once you're confident in the workflow's quality.
* **Combine with conditions.** If a workflow's actions include setting status to "solved," add a condition that the ticket must be in "open" status — this prevents the workflow from re-solving tickets that agents have already handled.
Related [#related]
* [Conditions](/response-workflows/conditions)
* [Escalation Rules](/response-workflows/escalation-rules)
* [Creating a Workflow](/response-workflows/creating-a-workflow)
---
# Assist suggestions
URL: /response-workflows/assist-suggestions
Type: concept
Description: How Stylo pre-generates responses and surfaces them as draft suggestions in the Zendesk sidebar.
Keywords: assist suggestions, copilot suggestions, sidebar, drafts
Assist suggestions are draft responses that appear in the Stylo sidebar when an agent opens a ticket. Instead of starting from scratch, agents see ready-to-use responses that have already been generated based on the ticket context, customer data, and your workflow's instructions.
Suggestions can come from two sources:
* **Response Workflows** — AI-powered response templates that are automatically matched to tickets based on their "when to use" description
* **Workflows** — multi-step automations (data lookups, API calls, conditional logic) that produce a draft at the end of their execution
Both types surface in the same place in the sidebar, and agents interact with them the same way.
How suggestions work [#how-suggestions-work]
From Response Workflows [#from-response-workflows]
1. **Customer sends a message** — a new message arrives on a ticket
2. **Stylo runs in the background** — all response workflows set to "cache" mode are evaluated against the ticket
3. **Responses are pre-generated** — workflows that match the ticket generate their responses and store them as drafts
4. **Agent opens the ticket** — the Stylo sidebar shows the best matching suggestions, ranked by confidence
5. **Agent reviews and sends** — the response is pasted into the Zendesk composer for review and sending
Suggestions are generated proactively — by the time the agent opens the ticket, the response is already waiting.
From Workflows [#from-workflows]
1. **A trigger fires** — a webhook, schedule, or manual action starts the workflow
2. **The workflow executes** — steps run in sequence (fetch order data, check eligibility, call an API, generate a response with AI)
3. **The workflow pauses for review** — when the workflow reaches a human review step set to surface a draft, it pauses and shows the draft in the sidebar
4. **Agent reviews and sends** — the agent reviews the draft, optionally edits it, and approves. The workflow then resumes and completes any remaining steps (update ticket status, add tags, log to CRM).
Workflow-sourced drafts carry structured context data from the steps that ran before the review — agents can see what data was gathered and what decisions the workflow made.
What agents see [#what-agents-see]
Each suggestion shows:
* **Source name** — which response workflow or workflow generated this response
* **Confidence** — how confident Stylo is that this suggestion matches the ticket (for response workflow suggestions)
* **Generated response** — the full response text, ready to review
* **Context data** — structured data from the workflow's execution (for workflow-sourced suggestions)
Agents can:
* **Use the suggestion as-is** — paste it into the composer and send
* **Edit before sending** — modify the response in the Zendesk composer
* **Dismiss** — skip the suggestion and write their own response
Setting up suggestions [#setting-up-suggestions]
For Response Workflows [#for-response-workflows]
1. Set the workflow's automation mode to **Cache**
2. Choose a trigger type (typically **Customer reply**)
3. Write a clear "when to use" description so Stylo matches it to the right tickets
4. Publish the workflow
The workflow will now run in the background whenever a matching ticket event occurs, and the generated response will appear as a suggestion in the sidebar.
For Workflows [#for-workflows]
1. Build your workflow with the steps needed to gather data and generate a response
2. Add a **Human Review** step and turn on its draft-to-sidebar option {/* TODO(docs): the Workflow Builder still labels this toggle with the retired agent-assist term; name it here once that label is updated. */}
3. Configure the draft text field to reference the upstream node that contains the response
4. Set the visibility mode to **Cache**
5. Publish the workflow
When the workflow's trigger fires, it will execute up to the human review step, then surface the draft in the sidebar for agent review.
Multiple suggestions [#multiple-suggestions]
If more than one source matches a ticket, agents see multiple suggestions ranked by confidence. For example, an order-related ticket might have a pre-generated response from a "Refund Policy" response workflow and a data-enriched draft from a "Order Investigation" workflow — the agent sees both and picks the most relevant one.
On-demand generation [#on-demand-generation]
Some suggestions appear with a "generate" option instead of a pre-rendered response. This happens when Stylo identified a matching response workflow but didn't pre-generate the response (to save resources). The agent clicks to generate the response on demand, using the current ticket state.
Suggestions on messaging channels [#suggestions-on-messaging-channels]
For messaging channels (WhatsApp, Web Widget, chat), suggestions work the same way from the agent's perspective — they appear in the Stylo sidebar in Zendesk Agent Workspace. The difference is in how the response is delivered once the agent approves it.
Progressive automation [#progressive-automation]
Assist suggestions are the starting point of Stylo's progressive automation model:
1. **Start with suggestions** — agents review every response before sending. This builds confidence in Stylo's quality and surfaces edge cases.
2. **Monitor acceptance rates** — track how often agents use suggestions as-is, edit them, or dismiss them. High acceptance rates indicate the workflow is ready for more automation.
3. **Graduate to automatic sending** — once you're confident in a workflow's quality, switch it from cache mode to internal note or public reply mode. The AI sends responses automatically, and agents only handle escalations.
This progression lets you build trust gradually — every suggestion that an agent reviews is a data point that informs whether full automation is appropriate.
Tips [#tips]
* **Cache mode is risk-free.** Cached suggestions are never sent automatically — an agent always reviews first. This makes it a great starting point for any workflow.
* **Use "when to use" descriptions to reduce noise.** If agents see too many irrelevant suggestions, tighten the response workflow's "when to use" description so it only matches the right tickets.
* **Track usage.** Monitor how often agents use, edit, or dismiss suggestions. High dismissal rates indicate the workflow needs improvement — either the matching is off or the generated responses aren't helpful.
* **Combine sources.** Response workflows are great for straightforward responses. Workflows are better when the response requires multi-step data gathering or conditional logic. Use both together for comprehensive coverage.
Related [#related]
* [Assist](/assist)
* [Background Automation](/response-workflows/background-automation)
* [Response Workflows](/response-workflows)
---
# Background Automation
URL: /response-workflows/background-automation
Type: concept
Description: Set up workflows to automatically generate and send responses without agent involvement.
Keywords: background automation, auto send, cache mode
Background automation lets workflows run on their own — triggered by ticket events, generating responses, and optionally sending them without any agent involvement. This is how you achieve full ticket deflection for scenarios where automated responses are appropriate.
Automation modes [#automation-modes]
Each workflow can be set to one of four automation levels:
| Mode | What happens | Agent involved? |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| **Disabled** | Workflow only runs when an agent manually selects it | Yes |
| **Cache** | Workflow runs in the background and pre-generates a response, but doesn't send it. The response appears as an [Assist suggestion](/response-workflows/assist-suggestions) for agents to review. | Yes (reviews before sending) |
| **Internal note** | Workflow runs and automatically posts the response as an internal note on the ticket. Not visible to the customer. Useful for agent-assist artifacts like QA reports, ticket summaries, or engineering handoff notes. | Optional (can review the note) |
| **Public reply** | Workflow runs, passes a quality check, and sends the response directly to the customer. | No |
These modes represent a progression from fully manual to fully automated. See [Progressive Automation](/response-workflows/progressive-automation) for guidance on moving between modes.
How background execution works [#how-background-execution-works]
When a ticket event occurs (like a customer sending a message), here's what happens:
1\. Trigger [#1-trigger]
A customer message arrives on a ticket. Stylo evaluates all workflows with background automation enabled to determine which ones might apply.
2\. Classification [#2-classification]
Stylo evaluates the ticket against all eligible workflows in a single step, comparing the customer's message and ticket context to each workflow's "when to use" description. Each workflow receives a confidence score.
3\. Execution [#3-execution]
* **Cache mode:** all workflows that pass classification are executed. Their pre-generated responses are stored as [Assist suggestions](/response-workflows/assist-suggestions) for agents to review.
* **Internal/Public mode:** only the highest-confidence workflow runs.
4\. Response delay (optional) [#4-response-delay-optional]
For internal and public modes, you can set a delay (in seconds) between when the response is generated and when it's sent. This gives agents a window to respond first. If an agent replies during the delay, the automated response is discarded.
5\. Revalidation [#5-revalidation]
Before sending (internal and public modes), Stylo re-checks the ticket to make sure nothing has changed:
* Is the ticket still open?
* Has anyone (agent or customer) posted since the triggering message?
If the ticket state has changed, the response is discarded. This prevents stale or duplicated responses.
6\. Quality check (public mode only) [#6-quality-check-public-mode-only]
For public replies, a separate AI evaluation checks the generated response for:
* **Accuracy** — is the information correct?
* **Relevance** — does it address the customer's question?
* **Tone** — is it professional and appropriate?
* **Safety** — does it avoid harmful or misleading content?
* **Completeness** — does it fully address the issue?
If the response doesn't meet quality standards, it's blocked and the ticket is left for an agent.
7\. Send [#7-send]
If all checks pass, the response is posted to the ticket and any configured actions (set status, add tags) are applied.
Trigger types [#trigger-types]
You can choose what type of ticket event triggers the workflow:
| Trigger | When it fires |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Customer reply** | When a customer posts a public message on the ticket |
| **Agent internal note** | When an agent posts an internal note (useful for agent-initiated automation — the agent adds a note like "process refund" and the workflow handles the rest) |
Setting up automation [#setting-up-automation]
1. Open your workflow and go to the automation settings
2. Choose the automation mode (cache, internal, or public)
3. Select the trigger type
4. Optionally set a response delay (recommended for public mode — 30-60 seconds gives agents a chance to respond first)
5. Publish the workflow
Monitoring automated responses [#monitoring-automated-responses]
All automated executions are logged with full details:
* **Status** — succeeded, quality check rejected, stale (ticket changed), escalation triggered
* **Confidence** — how confident the classification was that this workflow matched
* **Response** — the generated text
* **Duration** — how long execution took
Use the draft analytics dashboard to monitor acceptance rates, edit distances, and confidence distributions over time. This data is what informs the decision to graduate a workflow from cache mode to automatic sending.
Best practices [#best-practices]
* **Start with cache mode.** Let agents review AI-generated responses before enabling automatic sending. This builds confidence and reveals edge cases. See [Progressive Automation](/response-workflows/progressive-automation) for the full approach.
* **Use response delays for public mode.** Even 30 seconds gives agents a chance to jump in on tickets they're already handling.
* **Combine with escalation rules.** Automated sending should never handle high-stakes situations — configure [escalation rules](/response-workflows/escalation-rules) to route those to humans.
* **Monitor the quality check rejection rate.** If more than 10-15% of responses are being blocked by the quality check, your strategy instructions or template may need improvement.
* **Review stale rejection rates.** High stale rates may indicate your response delay is too long, or that agents are already handling the tickets your workflows target.
* **Use internal note mode for agent tooling.** Not every automated response is customer-facing. Use internal notes for QA summaries, ticket categorization, engineering handoff briefs, and other artifacts that help agents without being visible to customers.
Related [#related]
* [Progressive Automation](/response-workflows/progressive-automation)
* [Assist suggestions](/response-workflows/assist-suggestions)
* [Escalation Rules](/response-workflows/escalation-rules)
---
# Backlog Runs
URL: /response-workflows/backlog-runs
Type: howto
Description: Run response workflows across an existing Zendesk backlog, preview the matched tickets first, and review the resulting drafts in Approvals.
Keywords: backlog, bulk run, approvals, zendesk
Backlog runs let you apply your enabled response workflows to an existing Zendesk view instead of waiting for new tickets to arrive. Use this when you want to review drafts for older tickets in bulk, validate workflow coverage against real backlog work, or work through a queue with human review before anything is sent.
{/* TODO(docs): Screenshot of the Response Workflows page showing the Run on backlog button and Zendesk view picker dialog. Tracked in public/images/README.md. */}
What a backlog run does [#what-a-backlog-run-does]
When you start a backlog run, Stylo:
* Reads tickets from a selected Zendesk view
* Evaluates each ticket against all enabled response workflows in the workspace
* Chooses the best candidate for each ticket
* Creates drafts in **Approvals** for review
For response workflows, backlog runs do not send customer-facing responses automatically.
Before you start [#before-you-start]
Backlog runs depend on your current setup.
* Zendesk must be connected
* You need access to the backlog-run feature on your plan
* Only enabled response workflows are considered during the run
* The current filter source is a Zendesk view
If your plan does not include background workflow access, Stylo blocks the run.
Preview a backlog run [#preview-a-backlog-run]
Start from the **Response Workflows** page and select **Run on backlog**.
1. Choose a Zendesk view.
2. Select **Preview matches**.
3. Review the matched ticket count before starting the run.
The preview shows:
* How many tickets matched
* Whether the result was truncated
* A small sample of matched ticket IDs
{/* TODO(docs): GIF of previewing a Zendesk view before starting a backlog run. Tracked in public/images/README.md. */}
Understand the ticket cap [#understand-the-ticket-cap]
Backlog runs use a cap when resolving tickets from the selected view.
* The current backlog dialog runs up to 500 tickets from the selected view
* If the selected Zendesk view contains more than 500 tickets, the preview and run are truncated to that capped set
* The preview step tells you when truncation happened before you start the run
Start the run [#start-the-run]
After previewing the matches, select **Start backlog run**.
Stylo creates a backlog run ID and routes you to **Approvals** filtered to that backlog run. From there, your team can review the generated drafts.
Review results in Approvals [#review-results-in-approvals]
Backlog-run drafts are reviewed in the Approvals queue, not in the workflow editor.
In the backlog review flow, you can:
* Filter to backlog items only
* Filter to one specific backlog run
* See live progress for the active run
* Approve or reject the generated drafts
The backlog run header shows:
* How many tickets were queued
* How many drafts have been approved or rejected
* How many are still pending review
* The current approval rate
Watch for the stopping warning [#watch-for-the-stopping-warning]
Stylo shows a caution banner when a backlog batch is being rejected often.
That warning appears when:
* At least 10 items have been reviewed
* The approval rate drops below 60%
If that warning appears, stop reviewing the batch and adjust the workflow before continuing.
Recommended workflow [#recommended-workflow]
Use backlog runs as a controlled rollout step:
1. Make sure the workflows you want to evaluate are enabled.
2. Choose a Zendesk view with representative tickets.
3. Preview the matched count.
4. Start the backlog run.
5. Review the generated drafts in **Approvals**.
6. If approval quality is low, stop and refine the workflow before running another batch.
Boundaries and risk [#boundaries-and-risk]
Backlog runs are safer than auto-send because they create drafts for review, but they still affect how much work your team must process afterward.
* Every matched ticket is evaluated against all enabled response workflows
* The selected view can generate a large review queue quickly
* A weak workflow can create many low-quality drafts if you run it against a broad view
* Execution details for individual workflows still appear in each workflow's execution history
Related [#related]
* [Workflow Testing and Execution History](/response-workflows/testing-and-history) to validate workflows before running them at backlog scale
* [Assist suggestions](/response-workflows/assist-suggestions) to understand how drafts appear for review
* [Progressive Automation](/response-workflows/progressive-automation) to place backlog runs in a safer rollout path
---
# Conditions
URL: /response-workflows/conditions
Type: reference
Description: Filter which tickets a Response Workflow applies to based on ticket fields, tags, and custom data.
Keywords: conditions, filter, ticket fields, tags
Conditions let you control exactly which tickets a Response Workflow runs on. Instead of matching every ticket, you can filter by ticket status, channel, tags, requester info, and custom fields — ensuring the workflow only fires when it's relevant.
How conditions work [#how-conditions-work]
Conditions are evaluated before a workflow executes. If the ticket doesn't match the conditions, the workflow is skipped entirely — no response is generated, no resources are used.
Conditions use three logic groups that are combined with AND:
| Group | Logic | Meaning |
| ----------- | ----- | ------------------------------------------ |
| **All of** | AND | Every condition in this group must be true |
| **Any of** | OR | At least one condition must be true |
| **None of** | NOT | No condition in this group can be true |
All three groups must pass for the workflow to run. If any group fails, the workflow is skipped.
**Example:** A workflow that handles refund requests might use:
* **All of:** Status is "open", Channel is "email"
* **Any of:** Tags contain "refund" OR Subject contains "return"
* **None of:** Tags contain "vip" (VIP customers get routed to a senior agent instead)
Available fields [#available-fields]
Standard ticket fields [#standard-ticket-fields]
| Field | Type | Description |
| ------------ | ---- | ---------------------------------------------------------- |
| **Subject** | Text | The ticket subject line |
| **Status** | Text | Current ticket status (new, open, pending, solved, closed) |
| **Channel** | Text | How the ticket was created (email, web, chat, phone, etc.) |
| **Priority** | Text | Ticket priority level (low, normal, high, urgent) |
| **Tags** | Tags | Tags applied to the ticket |
People fields [#people-fields]
| Field | Type | Description |
| --------------------- | ---- | ---------------------------- |
| **Requester name** | Text | The customer's name |
| **Requester email** | Text | The customer's email address |
| **Assignee name** | Text | The assigned agent's name |
| **Organization name** | Text | The requester's organization |
Custom fields [#custom-fields]
You can also filter on Zendesk custom fields. Select the field from the dropdown and choose the appropriate operator for the field type (text, number, or dropdown).
Operators [#operators]
Text fields [#text-fields]
| Operator | Matches when... |
| ---------------- | ------------------------------------------------ |
| **Equals** | Field value exactly matches the specified value |
| **Not equals** | Field value does not match |
| **Contains** | Field value includes the specified text anywhere |
| **Not contains** | Field value does not include the text |
| **Starts with** | Field value begins with the specified text |
| **Ends with** | Field value ends with the specified text |
Numeric fields (custom fields) [#numeric-fields-custom-fields]
| Operator | Matches when... |
| -------------------------- | ---------------------------------------- |
| **Equals** | Field value exactly matches the number |
| **Not equals** | Field value does not match |
| **Greater than** | Field value is above the threshold |
| **Greater than or equals** | Field value is at or above the threshold |
| **Less than** | Field value is below the threshold |
| **Less than or equals** | Field value is at or below the threshold |
Tag fields [#tag-fields]
| Operator | Matches when... |
| -------------------- | ------------------------------------------------------- |
| **Contains any** | At least one of the specified tags is present |
| **Contains all** | All of the specified tags are present |
| **Not contains any** | None of the specified tags are present |
| **Not contains all** | Not all of the specified tags are present (some may be) |
Presence [#presence]
| Operator | Matches when... |
| ------------------ | ------------------------------------------- |
| **Is present** | The field has any value (not empty or null) |
| **Is not present** | The field is empty or null |
Setting up conditions [#setting-up-conditions]
1. Open your workflow and go to the **Conditions** section
2. Add conditions to the appropriate logic group (all of, any of, none of)
3. For each condition, select the field, operator, and value
4. Conditions are saved automatically as you edit
Leave conditions empty if the workflow should match any ticket — the classification step (based on the "when to use" description) still controls whether the workflow fires.
Conditions vs. "When to use" [#conditions-vs-when-to-use]
These serve different purposes:
| | Conditions | "When to use" |
| ---------------- | ----------------------------------------------------------- | --------------------------------------------- |
| **How it works** | Deterministic field matching | AI classification based on description |
| **When it runs** | Before classification | During classification |
| **Use for** | Hard requirements (must be this status, must have this tag) | Soft matching (ticket topic, customer intent) |
Use conditions for absolute requirements ("only run on open tickets in the email channel") and "when to use" for intent matching ("customer asking about order status").
Common patterns [#common-patterns]
**Channel-specific workflows:**
* All of: Channel equals "chat"
* Ensures the workflow only generates responses appropriate for live chat (shorter, more conversational)
**Priority routing:**
* None of: Priority equals "urgent"
* Skips the workflow for urgent tickets, letting agents handle them directly
**Tag-based activation:**
* Any of: Tags contain any \["billing", "payment", "invoice"]
* Fires for any billing-related ticket regardless of exact wording
**VIP exclusion:**
* None of: Tags contain any \["vip", "enterprise"]
* Routes VIP customers to human agents instead of automated responses
**Custom field filtering:**
* All of: Custom field "order\_value" greater than 500
* Only handles high-value orders with this workflow (useful paired with [escalation rules](/response-workflows/escalation-rules))
Tips [#tips]
* **Start broad, then narrow.** Begin with no conditions and use the "when to use" description for matching. Add conditions once you identify specific cases that need filtering.
* **Combine conditions with escalation rules.** Conditions prevent a workflow from running at all. Escalation rules let the workflow run but prevent it from responding if certain criteria are met. Use conditions for coarse filtering and escalation rules for fine-grained safety checks.
* **Test your conditions.** Use the test panel with different ticket IDs to verify your conditions match the right tickets and exclude the wrong ones.
Related [#related]
* [Actions](/response-workflows/actions)
* [Escalation Rules](/response-workflows/escalation-rules)
* [Creating a Workflow](/response-workflows/creating-a-workflow)
---
# Creating a Workflow
URL: /response-workflows/creating-a-workflow
Type: tutorial
Description: Step-by-step guide to building your first Response Workflow.
Keywords: create workflow, response workflow, setup, first workflow
This guide walks through creating a Response Workflow from scratch. By the end, you'll have a working workflow that generates contextual responses for a specific type of customer interaction.
**Before you start**, you need an admin role. Connecting any integrations and
knowledge bases the workflow will use first (steps 4–5) makes setup smoother,
but you can add them later.
Build your workflow [#build-your-workflow]
Create the workflow [#create-the-workflow]
Navigate to **Response Workflows** in the Stylo dashboard and click **New Workflow**.
Give your workflow a name that describes the situation it handles — for example, "Order Refund Request" or "Shipping Delay Response." The name is visible to agents when they browse available workflows.
Write your response content [#write-your-response-content]
This is where you decide how the AI generates responses. Choose a mode:
Write strategy instructions that tell the AI how to handle this type of interaction. Think of these as the playbook you'd give a new agent on their first day. See [Strategy Instructions](/response-workflows/strategy-instructions) for detailed guidance.
Use the visual template editor to design the exact structure of the response. Add dynamic placeholders to pull in data:
* **Ticket data** — customer name, email, ticket subject, status, priority
* **Order data** — order number, total, fulfillment status, tracking number (requires Shopify or WooCommerce connection)
* **AI blocks** — sections where the AI generates text based on a prompt you provide
Build a template **and** write strategy instructions. The template controls structure; the strategy instructions make the AI blocks smarter. See [Response Modes](/response-workflows/response-modes) for when to use each approach.
Configure "when to use" [#configure-when-to-use]
Write a description of when this workflow should fire. Stylo uses it to automatically match workflows to incoming tickets. Be specific about the scenario:
* **Good:** "Use when a customer is asking about the status of an order they've already placed, including questions about shipping, tracking, or delivery timeline."
* **Too vague:** "Use for order questions."
* **Too narrow:** "Use when a customer says 'where is my order' exactly."
The "when to use" description is evaluated by AI, so write it in natural language. Describe the intent, not the keywords.
Connect your tools [#connect-your-tools]
If your workflow needs external data (like order details from Shopify), select the tools it should use. The workflow automatically fetches the relevant data before generating a response.
Available tools depend on which integrations you've connected in your Stylo settings.
Select knowledge bases [#select-knowledge-bases]
Choose which knowledge bases the AI should search when generating responses. This grounds responses in your actual documentation — return policies, FAQs, product guides.
If you don't select specific knowledge bases, the AI searches all available knowledge bases for your organization.
Set up escalation rules [#set-up-escalation-rules]
Define conditions where the workflow should **not** respond and instead flag the ticket for human review. See [Escalation Rules](/response-workflows/escalation-rules) for details. Common escalation rules:
* Order value above a threshold
* Disputed or fraudulent orders
* Specific product categories that require specialist knowledge
Configure actions [#configure-actions]
Choose what happens after a response is sent:
* **Set ticket status** — automatically change the ticket to "pending," "solved," etc.
* **Add tags** — tag the ticket for reporting and routing (e.g., "auto-responded," "refund-handled")
Test and publish [#test-and-publish]
Once you're satisfied with the workflow configuration:
1. **Test it** — execute the workflow against sample tickets to verify it generates appropriate responses.
2. **Publish** — make the workflow available for use.
Publishing creates an immutable snapshot of the workflow. You can continue editing the draft without affecting the published version. When you're ready to update the live version, publish again.
**Expected result:** the workflow is live and selectable by agents (or runs automatically, depending on how you configure it next).
Next steps [#next-steps]
After creating your workflow, configure how it's used:
Or leave it as manual — agents select and execute it when they need it.
---
# Escalation Rules
URL: /response-workflows/escalation-rules
Type: howto
Description: Define conditions where a workflow should not respond and instead flag the ticket for human review.
Keywords: escalation, human review, do not respond, guardrails
Escalation rules are guardrails that prevent a workflow from responding when a human needs to be involved. They're evaluated before the AI generates a response — if any rule matches, the workflow stops and the ticket is flagged for agent review.
Why escalation rules matter [#why-escalation-rules-matter]
Even the best-configured workflow shouldn't handle every situation. Escalation rules give you confidence that automated responses won't be sent in cases where:
* The financial stakes are too high (large orders, high-value customers)
* The situation requires specialized knowledge (legal, technical, compliance)
* The data indicates something unusual (disputed transactions, fraud signals)
* Company policy requires human review for specific scenarios
How they work [#how-they-work]
Escalation rules are checked against the data fetched by your workflow's connected tools (e.g., Shopify order data). Each rule defines:
* **Field** — what data to check (e.g., order total, fulfillment status)
* **Condition** — how to evaluate it (equals, greater than, contains, etc.)
* **Reason** — why this should escalate (logged for visibility)
Rules are evaluated in order. If any rule matches, the workflow stops immediately — the AI is never called, and the response is never generated.
Available conditions [#available-conditions]
| Condition | What it checks | Example |
| ------------ | ---------------------------------- | ---------------------------------- |
| Equals | Field matches an exact value | Financial status equals "disputed" |
| Not equals | Field does not match a value | Status not equals "delivered" |
| Contains | Field contains a substring | Customer notes contain "VIP" |
| Greater than | Field is above a numeric threshold | Order total greater than 500 |
| Less than | Field is below a numeric threshold | Order total less than 0 (refunded) |
| Is missing | Field is not present in the data | Tracking number is missing |
Common escalation rules [#common-escalation-rules]
By order value [#by-order-value]
Escalate high-value orders to ensure a human reviews the response:
| Field | Condition | Value | Reason |
| ----------- | ------------ | ----- | -------------------------------------- |
| Order total | Greater than | 500 | High-value order requires human review |
By financial status [#by-financial-status]
Prevent automated responses for disputed or potentially fraudulent orders:
| Field | Condition | Value | Reason |
| ---------------- | --------- | -------- | -------------------------------------- |
| Financial status | Equals | disputed | Disputed orders require human review |
| Financial status | Equals | refunded | Already refunded — agent should verify |
By missing data [#by-missing-data]
Escalate when the workflow can't find the data it needs to respond:
| Field | Condition | Value | Reason |
| ------------ | ---------- | ----- | ----------------------------------- |
| Order number | Is missing | — | Cannot find order for this customer |
What happens when a rule triggers [#what-happens-when-a-rule-triggers]
When an escalation rule matches:
1. The workflow execution stops — no response is generated
2. The execution is recorded with status "escalation triggered" and the rule's reason
3. If background automation is enabled, an "escalated" tag is added to the ticket so agents can filter and prioritize
4. The ticket remains in the queue for an agent to handle manually
Escalation is visible in the workflow's execution history, so you can track how often each rule fires and adjust thresholds over time.
Tips [#tips]
* **Start conservative.** It's better to escalate too often at first and reduce thresholds as you build confidence. A missed escalation is worse than an unnecessary one.
* **Combine with "when to use" rules.** Escalation rules check data *after* tool data is fetched. If you want to prevent the workflow from running entirely based on ticket attributes (tags, status, channel), use conditions in the workflow's activation settings instead.
* **Review escalation frequency.** If a rule fires on more than 30-40% of tickets, the workflow's "when to use" description may need tightening — it's matching tickets it shouldn't be handling at all.
Related [#related]
* [Conditions](/response-workflows/conditions)
* [Actions](/response-workflows/actions)
* [Progressive Automation](/response-workflows/progressive-automation)
---
# Response Workflows
URL: /response-workflows
Type: concept
Description: AI-powered response templates that generate contextual replies for your support team.
Keywords: response workflows, reply automation, templates
Response Workflows let you create AI-powered response templates that generate personalized replies based on your customer's ticket, their order data, your knowledge base, and your specific instructions for how to handle each situation.
How it works [#how-it-works]
A Response Workflow brings together everything the AI needs to write a great response:
1. **Your instructions** tell the AI how to handle the situation — what to check, what to say, what tone to use
2. **Customer context** is pulled automatically from the ticket — the customer's name, their messages, the channel they're on
3. **External data** is fetched from your connected tools — order details from Shopify, subscription info from Stripe
4. **Knowledge base articles** are searched to ground the response in your actual policies and documentation
5. **Escalation rules** prevent the AI from responding when a human needs to be involved
The result is a response that reads like it was written by an experienced agent who knows your policies, has the customer's data in front of them, and follows your team's best practices.
Three ways to use them [#three-ways-to-use-them]
Response Workflows work across three execution modes:
* **Manual** — An agent selects a workflow from the Stylo sidebar, reviews the generated response, and sends it
* **Assist suggestions** — Stylo automatically identifies the best workflow for each ticket and pre-generates a response that agents can review and send with one click
* **Background automation** — Stylo automatically generates, quality-checks, and sends responses without agent involvement
You choose the level of automation that's right for each workflow. A simple thank-you response might run fully automated, while a complex refund workflow might generate suggestions for agents to review. Over time, you can [progressively increase automation](/response-workflows/progressive-automation) as you build confidence in the AI's quality.
What's in a workflow [#whats-in-a-workflow]
Every workflow has these components:
| Component | What it does |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Response content** | Either a structured template with placeholders, or strategy instructions that guide the AI (see [Response Modes](/response-workflows/response-modes)) |
| **When to use** | A description of what situations this workflow handles — used by Stylo to match workflows to tickets |
| **Tools** | Which integrations to pull data from (Shopify orders, etc.) |
| **Knowledge bases** | Which knowledge bases to search for grounding context |
| **Escalation rules** | Conditions that should prevent the AI from responding (see [Escalation Rules](/response-workflows/escalation-rules)) |
| **Actions** | What happens after sending — set ticket status, add tags, etc. |
Next steps [#next-steps]
* [Response Modes](/response-workflows/response-modes) — Understand the difference between template, guided, and hybrid modes
* [Creating a Workflow](/response-workflows/creating-a-workflow) — Step-by-step guide to building your first workflow
* [Assist suggestions](/response-workflows/assist-suggestions) — How pre-generated responses appear in the agent sidebar
* [Background Automation](/response-workflows/background-automation) — Set up fully automated responses
* [Progressive Automation](/response-workflows/progressive-automation) — A structured approach to increasing automation over time
---
# Progressive Automation
URL: /response-workflows/progressive-automation
Type: concept
Description: A structured approach to moving from AI-assisted responses to fully automated customer support.
Keywords: progressive automation, rollout, review, trust
Progressive automation is Stylo's approach to building trust in AI-generated responses. Instead of choosing between "fully manual" and "fully automated," you start with human-reviewed suggestions and gradually increase automation as you build confidence in the AI's quality.
The automation ladder [#the-automation-ladder]
| Stage | How it works | Who sends the response? |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| **1. Assist** | Stylo generates a free-form suggestion based on the ticket and your knowledge base. The agent reviews, edits, and sends. | Agent |
| **2. Assist suggestions** | Response workflows pre-generate structured responses based on your specific instructions. Agents review and send with one click. | Agent |
| **3. Conditional automation** | Workflows that consistently produce high-quality responses are switched to auto-send for straightforward cases. Complex cases still go to agents. | AI (simple) / Agent (complex) |
| **4. Full automation** | Proven workflows handle end-to-end resolution. Agents focus on escalations and edge cases. | AI |
Each stage builds on the last. The data from stage 2 (acceptance rates, edit distances) is what gives you confidence to move to stage 3.
How to progress [#how-to-progress]
Stage 1 to 2: Add structure [#stage-1-to-2-add-structure]
When you notice agents repeatedly handling the same type of ticket:
1. Create a response workflow with clear strategy instructions
2. Set it to **cache** mode so it pre-generates suggestions
3. Write a specific "when to use" description
The workflow now handles the research and drafting — agents just review and send.
Stage 2 to 3: Build trust with data [#stage-2-to-3-build-trust-with-data]
Monitor your workflow's performance:
* **Acceptance rate** — how often agents use the suggestion vs. dismiss it
* **Edit distance** — how much agents modify the suggestion before sending
* **Confidence scores** — how well the workflow matches the right tickets
When you see consistently high acceptance rates (>80%) with minimal edits over a sustained period, the workflow is a candidate for automatic sending.
Stage 3 to 4: Expand coverage [#stage-3-to-4-expand-coverage]
Once a workflow is reliably auto-sending:
1. Review the escalation rules — make sure edge cases are properly routed to agents
2. Monitor the quality check rejection rate
3. Consider creating new workflows for related ticket types
What to measure [#what-to-measure]
| Metric | What it tells you | Target for graduation |
| --------------------------- | -------------------------------------------------- | ------------------------------ |
| **Acceptance rate** | How often agents use the suggestion | Above 80% over 2+ weeks |
| **Edit distance** | How much agents change the text | Under 15% average modification |
| **Confidence distribution** | Whether the workflow matches the right tickets | Above 0.8 average confidence |
| **Quality check pass rate** | Whether generated responses meet quality standards | Above 90% |
| **Escalation rate** | Whether edge cases are properly caught | Stable, not increasing |
Internal notes as a stepping stone [#internal-notes-as-a-stepping-stone]
The **internal note** automation mode is a useful intermediate step. Instead of sending directly to the customer, the AI posts the response as an internal note. This lets you:
* See exactly what the AI would have sent in a real ticket context
* Monitor quality at volume without customer risk
* Build confidence before switching to public replies
This is especially useful for workflows that handle sensitive topics (refunds, cancellations, complaints) where you want extra verification before enabling customer-facing automation.
Tips [#tips]
* **Don't rush to automate.** The value of suggestions is that they make agents faster without any risk. There's no deadline to move to full automation.
* **Automate the boring stuff first.** Simple, high-volume, low-risk tickets (order status, shipping updates, thank-you responses) are the best candidates for early automation.
* **Keep escalation rules tight.** Every workflow that auto-sends should have escalation rules that catch edge cases. It's better to over-escalate than to send an inappropriate response.
* **Review regularly.** Even after automation, periodically review a sample of auto-sent responses to make sure quality hasn't drifted.
Related [#related]
* [Background Automation](/response-workflows/background-automation)
* [Escalation Rules](/response-workflows/escalation-rules)
* [Workflow Testing and Execution History](/response-workflows/testing-and-history)
---
# Response Modes
URL: /response-workflows/response-modes
Type: concept
Description: Choose how much creative control you give the AI — from structured templates to fully guided responses.
Keywords: response modes, template, guided, hybrid
Every Response Workflow uses one of three response modes. You don't choose the mode explicitly — it's determined by the type of content you create. If you write a template, it's template mode. If you write strategy instructions, it's guided mode. If you write both, it's hybrid mode.
Template mode [#template-mode]
**Best for:** Standardized responses where the exact wording matters — legal replies, compliance acknowledgments, shipping confirmations with specific formatting.
In template mode, you design the exact structure of the response using a visual editor. You control the greeting, the paragraphs, the sign-off — everything. The AI only fills in specific gaps that you mark with placeholders.
**How it works:**
* You build a response template with a mix of static text and dynamic placeholders
* Placeholders pull in ticket data (customer name, ticket subject), external data (order number, tracking info), or AI-generated text (a paragraph explaining your refund policy for this specific situation)
* The structure of the response is always the same — only the placeholder values change per ticket
**Example template:**
> Hi \{\{customer first name}},
>
> Thanks for reaching out about your order \{\{order number}}.
>
> \{\{AI: Explain the current order status and next steps based on the fulfillment data}}
>
> Let me know if you have any other questions.
>
> Best,
> \{\{agent name}}
Guided mode [#guided-mode]
**Best for:** Adaptive responses where the AI needs to reason about the situation — refund requests that depend on order age, troubleshooting that varies by product, any scenario where a single template can't cover all the variations.
In guided mode, you write strategy instructions that tell the AI *how to think about* the response — what data to check, what decisions to make, what tone to use. The AI generates the entire response from scratch, guided by your instructions.
**How it works:**
* You write strategy instructions — a set of guidelines the AI follows when crafting the response
* The AI receives your instructions along with the full ticket context, any external data (orders, subscriptions), and relevant knowledge base articles
* The AI generates a complete response that follows your strategy while adapting to the specific situation
* The response format adjusts automatically based on the channel — longer and more formal for email, brief and conversational for chat, very concise for social messaging
**Example strategy instructions:**
> 1. Look up the customer's most recent order using their email
> 2. Check the fulfillment status and financial status
> 3. If the order was delivered less than 30 days ago, explain the refund process and let them know we'll initiate it
> 4. If the order was delivered more than 30 days ago, explain the policy but offer store credit as an alternative
> 5. If the order shows as disputed, do not respond — this will be escalated to a human agent
> 6. Always include the order number and current status in your response
> 7. Use a warm, empathetic tone
The same workflow handles multiple scenarios because the AI adapts based on what it finds. You don't need separate templates for "refund within policy" and "refund outside policy" — one set of instructions covers both.
Hybrid mode [#hybrid-mode]
**Best for:** Structured responses where you want consistent formatting but with AI-powered sections that follow a strategy — like an order status email where the greeting and sign-off are fixed, but the middle section adapts based on order data.
Hybrid mode combines both approaches. You build a template that controls the overall structure, and the AI sections within that template use your strategy instructions as additional context for how to generate their content.
**How it works:**
* You create a template (like template mode) AND write strategy instructions (like guided mode)
* The template controls the overall structure — greeting, sections, sign-off
* AI placeholder blocks within the template receive your strategy instructions as context, making them smarter about how to fill in their sections
* You get the structural consistency of a template with the adaptive intelligence of guided mode
Choosing the right mode [#choosing-the-right-mode]
| Scenario | Recommended mode |
| -------------------------------------------------------------------- | ---------------- |
| Exact wording required (legal, compliance) | Template |
| Simple fill-in-the-blank responses | Template |
| Complex situations with multiple possible outcomes | Guided |
| Responses that need to reason about data before deciding what to say | Guided |
| Structured format with smart AI sections | Hybrid |
| Gradually migrating from templates to AI | Hybrid |
You can change modes at any time by adding or removing content. Add strategy instructions to a template and it becomes hybrid. Remove the template from a hybrid workflow and it becomes guided.
Related [#related]
* [Creating a Workflow](/response-workflows/creating-a-workflow)
* [Strategy Instructions](/response-workflows/strategy-instructions)
---
# Strategy Instructions
URL: /response-workflows/strategy-instructions
Type: howto
Description: How to write effective strategy instructions that guide the AI to generate great responses.
Keywords: strategy instructions, prompt, guidance, authoring
Strategy instructions are the core of guided mode workflows. They tell the AI *how to think about* a customer interaction — what data to check, what decisions to make, and how to craft the response. The better your instructions, the better the AI's output.
What the AI receives [#what-the-ai-receives]
When a workflow executes in guided mode, the AI receives:
1. **Your strategy instructions** — the guidelines you write
2. **Ticket context** — the customer's name, email, the full conversation history, ticket subject, channel, status, and tags
3. **External data** — order details, subscription info, or other data from your connected tools
4. **Knowledge base articles** — relevant articles from your selected knowledge bases
5. **Brand settings** — your company's voice and tone guidelines, response style, and any banned phrases
You only write the strategy instructions. Everything else is assembled and provided to the AI automatically.
Writing effective instructions [#writing-effective-instructions]
Be specific about what to check [#be-specific-about-what-to-check]
Tell the AI exactly what data to look at and how to interpret it.
**Good:**
> Check the order's fulfillment status. If it shows "shipped" with a tracking number, provide the tracking information. If it shows "unfulfilled," acknowledge the delay and provide an estimated timeline.
**Too vague:**
> Check the order and respond appropriately.
Include decision logic [#include-decision-logic]
The power of guided mode is handling multiple scenarios with one workflow. Lay out the decision tree.
**Good:**
> 1. If the order was delivered less than 30 days ago, explain the refund process
> 2. If the order was delivered more than 30 days ago, explain the policy but offer store credit
> 3. If the order hasn't shipped yet, offer to cancel instead
**Too simple:**
> Help the customer with their refund.
Specify what to include in the response [#specify-what-to-include-in-the-response]
Tell the AI what information the customer needs to see.
**Good:**
> Always include:
>
> * The order number
> * The current fulfillment status
> * The next step the customer should expect
> * A timeline if applicable
Set the tone [#set-the-tone]
While your brand settings provide global voice and tone guidelines, you can add situation-specific tone guidance.
**Good:**
> This is a frustrating situation for the customer. Lead with empathy — acknowledge the inconvenience before providing the solution. Avoid corporate language like "we apologize for any inconvenience."
Specify what NOT to do [#specify-what-not-to-do]
Guardrails are as important as instructions.
**Good:**
> Do not:
>
> * Promise a specific refund amount (this depends on the payment method)
> * Provide legal advice about chargebacks
> * Mention internal processes or tooling
> * Make up tracking numbers or delivery dates
Channel-aware responses [#channel-aware-responses]
The AI automatically adapts the response format based on the channel:
| Channel | Response style |
| ---------------- | -------------------------------------------------------------------------------- |
| Email | Complete, well-structured reply with greeting, clear paragraphs, and sign-off |
| Chat / Messaging | Concise and conversational — 1-4 short sentences, no formal greeting or sign-off |
| Social media | Very brief and natural — 1-2 short sentences matching the casual platform tone |
You don't need to include channel-specific formatting instructions — this happens automatically. Your strategy instructions should focus on *what* to say, not *how to format it*.
Example: Order status workflow [#example-order-status-workflow]
Here's a complete set of strategy instructions for handling order status inquiries:
> **Strategy Instructions:**
>
> 1. Look up the customer's most recent order using their email address
> 2. Check the fulfillment status:
> * **Unfulfilled:** Acknowledge the order is being prepared. If it's been more than 3 business days since the order was placed, apologize for the delay and provide an estimated shipping date if available.
> * **Shipped / In transit:** Provide the tracking number and carrier. If a delivery estimate is available, include it.
> * **Delivered:** Confirm delivery and ask if there's an issue with the order.
> * **Cancelled / Refunded:** Explain the current status and offer to help with a new order if they'd like.
> 3. Always include the order number in your response
> 4. If the customer mentions a specific item, reference it by name
> 5. Keep the tone helpful and reassuring — the customer just wants to know what's happening with their order
Tips [#tips]
* **Start simple, then iterate.** Write basic instructions, test against a few tickets, and refine based on the output. You don't need to cover every edge case on day one.
* **Use numbered steps for sequential logic.** The AI follows numbered instructions more reliably than paragraph-form guidelines.
* **Test with real tickets.** The best way to improve your instructions is to run them against actual tickets and see where the AI goes wrong.
* **Combine with escalation rules.** Don't try to handle everything in instructions — use [escalation rules](/response-workflows/escalation-rules) to route complex cases to humans.
Related [#related]
* [Response Modes](/response-workflows/response-modes)
* [Creating a Workflow](/response-workflows/creating-a-workflow)
---
# Workflow Testing and Execution History
URL: /response-workflows/testing-and-history
Type: howto
Description: Test a response workflow against a real Zendesk ticket, review saved executions, and debug failures or escalations.
Keywords: testing, execution history, debug, zendesk ticket
Use the test panel to check a response workflow against a real Zendesk ticket before you publish changes widely. Then use execution history to review saved runs, inspect failures, and see the exact input, output, and metadata recorded for that workflow.
{/* TODO(docs): Screenshot of the response workflow editor showing the Test Panel and the Executions button. Tracked in public/images/README.md. */}
When to use each tool [#when-to-use-each-tool]
Use the two surfaces for different jobs:
* **Test Panel** for rapid validation while you are editing a workflow
* **Execution History** for reviewing saved workflow runs after the workflow has been used
The test panel is temporary. Execution history is recorded.
Run a test from the editor [#run-a-test-from-the-editor]
Open the workflow editor and use the **Test Panel** at the bottom of the page.
1. Enter a Zendesk ticket ID.
2. Select **Run Test**.
3. Review the returned result before you save or publish.
The test uses the current editor state, including unsaved changes. That means you can test strategy instructions, template edits, tools, escalation rules, and knowledge base selections before you publish a new version.
What the test panel shows [#what-the-test-panel-shows]
After a test run, Stylo can show:
* A generated response when no escalation rule blocks the run
* An escalation result with the matched rule reason
* Tool output for any tool calls used during the test
* Response mode as `template`, `guided`, or `hybrid`
* Model and token usage details when available
* Run time in milliseconds
* The count of unresolved placeholders
{/* TODO(docs): GIF of running a response workflow test and reviewing the result panels. Tracked in public/images/README.md. */}
What the test panel does not do [#what-the-test-panel-does-not-do]
The test panel is designed for editing, not production tracking.
* It does not save an execution record to history
* It does not require you to save the draft first
* It does not publish a new workflow version
* It depends on Zendesk being connected and on a real ticket being available
If Zendesk is not connected, the test request fails. If the ticket ID is invalid or the ticket cannot be loaded, the test also fails.
Use execution history [#use-execution-history]
Select **Executions** from the workflow editor header to open the saved run history for that workflow.
Execution history helps you answer questions like:
* Did this workflow succeed, fail, or remain pending?
* What trigger started the run?
* What input and output were recorded?
* Was there an error message?
* How long did the run take?
The history page lists the most recent executions first.
What each execution record includes [#what-each-execution-record-includes]
Each execution row shows a compact summary first, then expands to reveal the recorded payloads.
* Status such as `pending`, `running`, `succeeded`, or `failed`
* The created time
* The trigger that started the run
* The user ID for the person who started it, when present
* Duration when timing metadata is available
* Error text for failed runs
* Recorded `input`, `output`, and `metadata` JSON when you expand the row
Limits and boundaries [#limits-and-boundaries]
Keep these operational limits in mind:
* Execution history is permission-gated. Users without execution history access cannot view it.
* The response workflow history view shows the most recent 50 executions for that workflow.
* The current response workflow history page is a list view with expandable JSON. It does not provide a separate execution detail page like the broader workflow builder.
Recommended review workflow [#recommended-review-workflow]
Use this sequence when you change a workflow:
1. Run the test panel against one or more representative Zendesk tickets.
2. Fix any escalations, placeholder gaps, or tool output problems.
3. Save and publish the workflow when the result is acceptable.
4. Monitor **Executions** after real usage begins.
5. Open failed or unexpected runs and inspect the stored input, output, and metadata.
Related [#related]
* [Creating a Workflow](/response-workflows/creating-a-workflow) to build the workflow before testing
* [Workflow Editor](/response-workflows/workflow-editor) to understand where editing controls live
* [Escalation Rules](/response-workflows/escalation-rules) to tighten workflow guardrails
* [Background Automation](/response-workflows/background-automation) to understand the higher-risk execution path
---
# Workflow Editor
URL: /response-workflows/workflow-editor
Type: reference
Description: A guided tour of the workflow editor — every setting, what it does, and how to use it.
Keywords: workflow editor, settings, configuration, tour
The workflow editor is where you build and configure Response Workflows. This page walks through every section of the editor, explains what each setting does, and provides guidance on how to configure it.
Opening the editor [#opening-the-editor]
From the Stylo dashboard, navigate to **Response Workflows** and either:
* Click **New Workflow** to create a new one
* Click an existing workflow to edit it
The editor opens with the workflow name at the top and two buttons in the header: **Save Draft** and **Publish**.
Editor layout [#editor-layout]
The editor is organized into five sections:
1. **Essentials** — name, description, enabled toggle, tags
2. **Response Content** — where you write strategy instructions and/or build a template
3. **Activation & Context** — when to use, trigger type, conditions, tools, knowledge bases
4. **Guardrails** — escalation rules and post-response actions
5. **Automation** — background processing mode and response delay
Below the main editor is the **Test Panel**, where you can run your workflow against real tickets without leaving the page.
Each section is a collapsible card. You can work through them in any order.
***
Essentials [#essentials]
Basic information about the workflow.
| Field | Description |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name** | A short name that describes the situation this workflow handles (e.g., "Order Refund Request"). Visible to agents when browsing workflows and in Assist suggestions. |
| **Description** | Optional longer description. Not shown to customers — this is for your team's reference. |
| **Enabled** | Toggle the workflow on or off. Disabled workflows won't appear in Assist suggestions or run in the background, but can still be executed manually. |
| **Tags** | Tags for organizing and filtering workflows in the list view. These are workflow tags, not ticket tags. |
***
Response Content [#response-content]
This is the core of the workflow — where you define what the AI generates. This section has two tabs: **Strategy Instructions** and **Template**.
Strategy Instructions tab [#strategy-instructions-tab]
A text editor where you write guidelines for how the AI should handle this type of interaction. The AI uses these instructions along with the ticket context, tool data, and knowledge base articles to generate a complete response.
Think of strategy instructions as the playbook you'd give a new agent:
* What data to check
* What decisions to make based on that data
* What to include in the response
* What tone to use
* What to avoid
See [Strategy Instructions](/response-workflows/strategy-instructions) for detailed guidance on writing effective instructions.
Template tab [#template-tab]
A rich text editor where you design the exact structure of the response. You can add:
* **Static text** — paragraphs, headings, formatting that appear the same in every response
* **Ticket placeholders** — dynamic values like customer name, ticket subject, pulled from the ticket
* **Tool placeholders** — values from connected tools like Shopify order number, tracking info
* **AI blocks** — sections where the AI generates text based on a prompt you provide
Use the `{{` shortcut to open the placeholder menu, which shows all available placeholders grouped by source.
Using one or both tabs [#using-one-or-both-tabs]
You can use either tab on its own, or both together:
| You fill in... | What happens |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Strategy Instructions only** | The AI generates the entire response from your instructions — no fixed structure, the AI adapts to each situation |
| **Template only** | The AI fills in the placeholders within your structured template — the overall shape of the response is always the same |
| **Both** | Your template controls the structure, and the AI blocks within it use your strategy instructions as additional context to generate smarter content |
Most teams start with strategy instructions (it's faster to write and more flexible), then add a template later if they need more control over formatting. See [Response Modes](/response-workflows/response-modes) for a deeper comparison.
***
Activation & Context [#activation--context]
This section controls when the workflow runs and what information it has access to.
When to Use [#when-to-use]
A natural language description of the situations this workflow handles. This text is evaluated by AI when:
* Ranking Assist suggestions for agents
* Deciding which workflow to execute in background automation
* Classifying incoming tickets
Write it as if you're explaining to a colleague when to use this workflow:
> "Use when a customer is asking about the status of an order they've already placed, including questions about shipping, tracking, or delivery timeline. Don't use for pre-purchase questions about shipping policies."
Be specific about what the workflow handles AND what it doesn't handle.
Trigger Type [#trigger-type]
For background automation, this controls which ticket events trigger the workflow:
| Option | Fires when |
| ----------------------- | ----------------------------------------------------------------------- |
| **Customer reply** | A customer posts a public message on the ticket |
| **Agent internal note** | An agent posts an internal note (useful for agent-initiated automation) |
This setting only matters for workflows that run automatically in the background. A workflow an agent runs manually doesn't use a trigger.
Conditions [#conditions]
Optional rules that the ticket must match for this workflow to run. Unlike the "When to Use" description (which is evaluated by AI), conditions are evaluated deterministically — they either match or they don't.
Available condition types:
* **All of** — every condition must match
* **Any of** — at least one condition must match
* **None of** — no condition can match
Each condition checks a ticket field (subject, status, priority, tags, custom fields) against a value using operators like equals, contains, starts with, etc.
**Example:** A "Refund Request" workflow might have:
* All of: status equals "open"
* Any of: tags contain "refund" OR tags contain "return"
* None of: tags contain "escalated"
Tools [#tools]
Select which integrations the workflow should pull data from before generating a response. The available tools depend on which integrations you've connected in your Stylo settings.
When a tool is enabled, the workflow automatically fetches the relevant data (e.g., order details from Shopify) and makes it available to both the AI and your escalation rules.
Knowledge Bases [#knowledge-bases]
Select which knowledge bases the AI should search when generating responses. The AI will find relevant articles and use them to ground its response in your actual documentation.
* **Select specific knowledge bases** to scope the search to relevant content (e.g., only search the returns policy KB for a refund workflow)
* **Leave empty** to search all available knowledge bases for your organization
***
Guardrails [#guardrails]
Escalation Rules [#escalation-rules]
Define conditions where the workflow should **not** generate a response and instead leave the ticket for a human agent.
Each rule checks a field from your connected tool data against a condition. The field picker shows all available fields based on which tools you've enabled — for example, if you've connected Shopify, you'll see fields like order total, fulfillment status, and financial status.
| Setting | What it means |
| ------------- | ----------------------------------------------------------------------------------------------- |
| **Field** | Pick from the available fields for your connected tools (e.g., order total, fulfillment status) |
| **Condition** | How to evaluate it (equals, greater than, is missing, etc.) |
| **Value** | The value to compare against |
| **Reason** | Why this should escalate — logged for your team's visibility |
Rules are evaluated after tool data is fetched but before the AI generates anything. If any rule matches, the workflow stops immediately.
See [Escalation Rules](/response-workflows/escalation-rules) for common patterns and best practices.
Post-Response Actions [#post-response-actions]
What happens after a response is sent. These apply to all execution modes (manual, cache, background).
| Action | Description |
| -------------------- | ------------------------------------------------------ |
| **Set status** | Change the ticket status (open, pending, hold, solved) |
| **Add tags** | Add tags to the ticket for routing and reporting |
| **Remove tags** | Remove tags from the ticket |
| **Set priority** | Change the ticket priority |
| **Set custom field** | Set a custom field value on the ticket |
Actions are applied after the response is posted. If the workflow escalates (an escalation rule matches), no actions are applied.
***
Automation [#automation]
Controls how the workflow runs in the background. See [Background Automation](/response-workflows/background-automation) for the full guide.
Background Processing Mode [#background-processing-mode]
| Mode | Behavior |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| **Disabled** | Manual only — agents must select and execute the workflow |
| **Cache** | Runs in background, pre-generates a response for agent review in the sidebar (an Assist suggestion) |
| **Internal note** | Runs and auto-posts as an internal note (not visible to customer) |
| **Public reply** | Runs, quality-checks, and sends directly to the customer |
Response Delay [#response-delay]
For internal and public modes, how many seconds to wait after generating the response before sending it. This gives agents a window to respond first — if they do, the automated response is discarded.
Recommended settings:
* **Public reply:** 30-60 seconds minimum
* **Internal note:** 0 seconds (internal notes don't compete with agent responses)
***
Saving and publishing [#saving-and-publishing]
The editor header has two buttons:
* **Save Draft** — saves your changes without making them live. Use this while you're still iterating. Your draft is preserved even if you navigate away.
* **Publish** — saves your changes AND creates an immutable published snapshot. The new version goes live immediately — Assist suggestions and background automation will use it.
**When to use each:**
* Use **Save Draft** while you're building and testing. This lets you iterate without affecting the live version.
* Use **Publish** when you're confident in your changes and ready to go live.
Published versions are immutable snapshots. If you make a mistake, just edit and publish again — the new version replaces the old one. Previous versions are preserved in the execution history for audit purposes.
***
Test Panel [#test-panel]
The test panel sits below the main editor sections. It lets you run your workflow against real tickets without leaving the page — the fastest way to iterate on your instructions or template.
How to test [#how-to-test]
1. Enter a **Zendesk ticket ID** in the test panel
2. Click **Run Test**
3. Stylo fetches the ticket's full context from Zendesk (customer info, conversation history, channel) and runs your workflow against it — using your current unsaved editor state, not the published version
4. The panel shows the result:
**If the workflow generates a response:**
* **Generated Response** — the full text the AI produced, displayed exactly as it would appear to the customer
* **Tool Data** — a collapsible section for each connected tool showing the data that was fetched (e.g., order number, fulfillment status, total price). Expand to see the full data the AI had access to.
* **Metadata** — execution time, which AI model was used, token usage (input/output), and which response mode ran (template, guided, or hybrid)
* **Unresolved Placeholders** — if any template placeholders couldn't be resolved, they're flagged here
**If an escalation rule fires:**
* The panel shows an escalation alert with the rule that triggered and the reason — no response is generated, just as it would work in production
You don't need to save before testing [#you-dont-need-to-save-before-testing]
The test panel runs against whatever is currently in the editor — your unsaved strategy instructions, template changes, escalation rules, and tool selections. This means you can:
1. Change a line in your strategy instructions
2. Hit **Run Test** on the same ticket
3. Instantly see how the output changed
No saving, no publishing, no leaving the page.
Testing tips [#testing-tips]
* **Test with different ticket types.** Run 3-5 tickets that represent different scenarios your workflow should handle. Does the AI adapt correctly?
* **Test edge cases.** Try a ticket where the customer has no order, or where the order is in an unusual state. Does the workflow escalate when it should?
* **Compare before and after.** When you change your instructions, re-run the same ticket ID to see how the output changed. This is the fastest way to refine your strategy instructions.
* **Check the tool data.** If the response is wrong, expand the tool data section to see what the AI was working with. The issue might be missing data, not bad instructions.
Moving to production [#moving-to-production]
Once you're confident in the test results:
1. **Publish** your workflow to make it live
2. Enable **Cache** mode to start generating Assist suggestions — agents review before sending
3. Monitor how agents interact with the suggestions — do they use them as-is, edit them, or dismiss them?
4. When ready, move to **Public reply** mode for full automation
Related [#related]
* [Creating a Workflow](/response-workflows/creating-a-workflow)
* [Conditions](/response-workflows/conditions)
* [Actions](/response-workflows/actions)
---
# Database
URL: /reference/integrations/database
Type: reference
Description: Connect to a PostgreSQL or MySQL database for workflow queries.
Keywords: database, integration, api key, connect
Connect to a PostgreSQL or MySQL database for workflow queries.
Connect [#connect]
Connect Database with an API key in **Settings → Integrations**. Open the Database card, click **Connect**, and provide:
| Field | Required | Notes |
| ------------- | -------- | --------------------- |
| Host | Yes | e.g. `db.example.com` |
| Port | No | e.g. `5432` |
| Database Name | Yes | e.g. `my_database` |
| Username | Yes | e.g. `readonly_user` |
| Password | Yes | — |
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| --------------------------------------------------------- | ----------------------------------------- |
| [Database Query](/reference/blocks/system-database-query) | Execute SQL queries against your database |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Database blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Database-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Databricks
URL: /reference/integrations/databricks
Type: reference
Description: Run SQL statements and inspect SQL warehouses in Databricks.
Keywords: databricks, integration, api key, connect
Run SQL statements and inspect SQL warehouses in Databricks.
Connect [#connect]
Connect Databricks with an API key in **Settings → Integrations**. Open the Databricks card, click **Connect**, and provide:
| Field | Required | Notes |
| ------------- | -------- | ------------------------------------------- |
| Workspace URL | Yes | e.g. `https://dbc-xxx.cloud.databricks.com` |
| Access Token | Yes | e.g. `dapi...` |
| Warehouse ID | No | e.g. `abc123` |
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| --------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| [Execute SQL Statement](/reference/blocks/databricks-execute-sql-statement) | Run a read-only SQL statement against a Databricks SQL warehouse |
| [List SQL Warehouses](/reference/blocks/databricks-list-sql-warehouses) | List available Databricks SQL warehouses |
| [Test Databricks Connection](/reference/blocks/databricks-test-connection) | Verify Databricks connectivity and SQL warehouse visibility |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Databricks blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Databricks-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Firecrawl
URL: /reference/integrations/firecrawl
Type: reference
Description: Web scraping and crawling for knowledge ingestion.
Keywords: firecrawl, integration, api key, connect
Web scraping and crawling for knowledge ingestion.
Connect [#connect]
Connect Firecrawl with an API key in **Settings → Integrations**. Open the Firecrawl card, click **Connect**, and provide:
| Field | Required | Notes |
| ------- | -------- | ------------- |
| API Key | Yes | e.g. `fc-...` |
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ------------------------------------------------ | ----------------------------- |
| [Scrape URL](/reference/blocks/firecrawl-scrape) | Scrape content from a URL |
| [Search Web](/reference/blocks/firecrawl-search) | Search the web with Firecrawl |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Firecrawl blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Firecrawl-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Gmail
URL: /reference/integrations/gmail
Type: reference
Description: Send and receive emails from your support workflows.
Keywords: gmail, integration, oauth, connect
Send and receive emails from your support workflows.
Connect [#connect]
Connect Gmail in **Settings → Integrations**. Open the Gmail card, click **Connect**, and authorize Stylo to access your Gmail account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Gmail scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ------------------------------------------------------ | -------------------------------------------- |
| [Add Label](/reference/blocks/gmail-add-label) | Add label(s) to a Gmail message |
| [Archive Email](/reference/blocks/gmail-archive-email) | Archive a Gmail message (remove INBOX label) |
| [Delete Email](/reference/blocks/gmail-delete-email) | Delete a Gmail message |
| [Draft Email](/reference/blocks/gmail-draft-email) | Create a draft email in Gmail |
| [Mark as Read](/reference/blocks/gmail-mark-read) | Mark a Gmail message as read |
| [Mark as Unread](/reference/blocks/gmail-mark-unread) | Mark a Gmail message as unread |
| [Move Email](/reference/blocks/gmail-move-email) | Move a Gmail message to a label |
| [Read Email](/reference/blocks/gmail-read-email) | Read a Gmail message by ID |
| [Remove Label](/reference/blocks/gmail-remove-label) | Remove label(s) from a Gmail message |
| [Search Email](/reference/blocks/gmail-search-email) | Search Gmail messages with a query |
| [Send Email](/reference/blocks/gmail-send-email) | Send an email via Gmail |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Gmail blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Gmail-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Google
URL: /reference/integrations/google
Type: reference
Description: Access Sheets, Docs, and Drive for data and content.
Keywords: google, integration, oauth, connect
Access Sheets, Docs, and Drive for data and content.
Connect [#connect]
Connect Google in **Settings → Integrations**. Open the Google card, click **Connect**, and authorize Stylo to access your Google account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Google scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Triggers [#triggers]
| Block | What it does |
| -------------------------------------------------------- | ------------------------------------------------------ |
| [Gmail](/reference/blocks/trigger-gmail) | Trigger workflow when new emails are received in Gmail |
| [Google Sheets](/reference/blocks/trigger-google-sheets) | Trigger workflow when Google Sheets data changes |
Actions [#actions]
| Block | What it does |
| ------------------------------------------------------------------------ | --------------------------------------------------------- |
| [Append to Google Doc](/reference/blocks/google-docs-append) | Add content to the end of a Google Doc |
| [Read Google Doc](/reference/blocks/google-docs-read-document) | Read a Google Doc and return plain text |
| [Replace Google Doc Contents](/reference/blocks/google-docs-replace) | Overwrite the entire body of a Google Doc |
| [Google Drive: Read File](/reference/blocks/google-drive-read-file) | Read Google Docs/Sheets or download files and return text |
| [Append Row to Google Sheet](/reference/blocks/google-sheets-append-row) | Add new rows to the end of a sheet |
| [Read from Google Sheet](/reference/blocks/google-sheets-read-rows) | Read rows from a Google Sheet range |
| [Update Row in Google Sheet](/reference/blocks/google-sheets-update-row) | Overwrite cells at a specific range (e.g. Sheet1!A2:E2) |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Google blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Google-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# HubSpot
URL: /reference/integrations/hubspot
Type: reference
Description: Sync contacts, deals, and tickets with your CRM.
Keywords: hubspot, integration, oauth, connect
Sync contacts, deals, and tickets with your CRM.
Connect [#connect]
Connect HubSpot in **Settings → Integrations**. Open the HubSpot card, click **Connect**, and authorize Stylo to access your HubSpot account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact HubSpot scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| -------------------------------------------------------------- | -------------------------------------------------- |
| [Create Company](/reference/blocks/hubspot-create-company) | Create a HubSpot company |
| [Create Contact](/reference/blocks/hubspot-create-contact) | Create a HubSpot contact |
| [Create Ticket](/reference/blocks/hubspot-create-ticket) | Create a ticket in HubSpot |
| [Get Companies](/reference/blocks/hubspot-get-companies) | List HubSpot companies (or fetch one by ID/domain) |
| [Get Contacts](/reference/blocks/hubspot-get-contacts) | List HubSpot contacts (or fetch one by ID/email) |
| [Get Deals](/reference/blocks/hubspot-get-deals) | List deals in HubSpot |
| [Get Ticket](/reference/blocks/hubspot-get-ticket) | Get a ticket by ID in HubSpot |
| [Get Users](/reference/blocks/hubspot-get-users) | List users/owners in HubSpot |
| [Search Companies](/reference/blocks/hubspot-search-companies) | Search HubSpot companies |
| [Search Contacts](/reference/blocks/hubspot-search-contacts) | Search HubSpot contacts |
| [Search Tickets](/reference/blocks/hubspot-search-tickets) | Search tickets in HubSpot |
| [Update Company](/reference/blocks/hubspot-update-company) | Update a HubSpot company |
| [Update Contact](/reference/blocks/hubspot-update-contact) | Update a HubSpot contact |
| [Update Ticket](/reference/blocks/hubspot-update-ticket) | Update a ticket in HubSpot |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, HubSpot blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document HubSpot-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Integrations
URL: /reference/integrations
Type: reference
Description: Reference for each integration that exposes workflow blocks: how to connect it and which triggers and actions it provides.
Keywords: integrations, connect, providers, actions, triggers
Each integration below exposes workflow blocks you can use in the Workflow Builder. Pages are generated from the integration registry, so the connection method and supported blocks stay in sync with the product.
For the full list of connectable systems — including those used only for knowledge or context, without workflow blocks — see the [Integrations overview](/integrations).
| Integration | What it does | Blocks |
| ------------------------------------------------ | --------------------------------------------------------------- | ------ |
| [Database](/reference/integrations/database) | Connect to a PostgreSQL or MySQL database for workflow queries. | 1 |
| [Databricks](/reference/integrations/databricks) | Run SQL statements and inspect SQL warehouses in Databricks. | 3 |
| [Firecrawl](/reference/integrations/firecrawl) | Web scraping and crawling for knowledge ingestion. | 2 |
| [Gmail](/reference/integrations/gmail) | Send and receive emails from your support workflows. | 11 |
| [Google](/reference/integrations/google) | Access Sheets, Docs, and Drive for data and content. | 9 |
| [HubSpot](/reference/integrations/hubspot) | Sync contacts, deals, and tickets with your CRM. | 14 |
| [Intercom](/reference/integrations/intercom) | Connect conversations and customer data from Intercom. | 11 |
| [Linear](/reference/integrations/linear) | Create and sync issues with your engineering team. | 3 |
| [Microsoft](/reference/integrations/microsoft) | Connect Outlook, Teams, and Microsoft 365 services. | 1 |
| [Resend](/reference/integrations/resend) | Send transactional emails from your workflows. | 1 |
| [ServiceNow](/reference/integrations/servicenow) | Integrate with ServiceNow incidents and requests. | 1 |
| [Shopify](/reference/integrations/shopify) | Access orders, customers, and store data. | 1 |
| [Slack](/reference/integrations/slack) | Send notifications and updates to Slack channels. | 1 |
| [Zendesk](/reference/integrations/zendesk) | Manage tickets, users, and support workflows. | 33 |
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
---
# Intercom
URL: /reference/integrations/intercom
Type: reference
Description: Connect conversations and customer data from Intercom.
Keywords: intercom, integration, oauth, connect
Connect conversations and customer data from Intercom.
Connect [#connect]
Connect Intercom in **Settings → Integrations**. Open the Intercom card, click **Connect**, and authorize Stylo to access your Intercom account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Intercom scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| [Create Contact](/reference/blocks/intercom-create-contact) | Create a contact in Intercom |
| [Create Ticket](/reference/blocks/intercom-create-ticket) | Create a ticket in Intercom |
| [Delete Contact](/reference/blocks/intercom-delete-contact) | Delete a contact in Intercom |
| [Get Contact](/reference/blocks/intercom-get-contact) | Get a contact by Intercom ID |
| [Get Conversation](/reference/blocks/intercom-get-conversation) | Get a conversation by ID |
| [Get Ticket](/reference/blocks/intercom-get-ticket) | Get a ticket by ID in Intercom |
| [List Admins](/reference/blocks/intercom-list-admins) | List the admins (teammates) in your Intercom workspace and return them for downstream use. |
| [List Contacts](/reference/blocks/intercom-list-contacts) | List contacts in Intercom |
| [Reply to Conversation](/reference/blocks/intercom-reply-conversation) | Reply to an Intercom conversation |
| [Search Contacts](/reference/blocks/intercom-search-contacts) | Search contacts in Intercom |
| [Update Contact](/reference/blocks/intercom-update-contact) | Update a contact in Intercom |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Intercom blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Intercom-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Linear
URL: /reference/integrations/linear
Type: reference
Description: Create and sync issues with your engineering team.
Keywords: linear, integration, api key, connect
Create and sync issues with your engineering team.
Connect [#connect]
Connect Linear with an API key in **Settings → Integrations**. Open the Linear card, click **Connect**, and provide:
| Field | Required | Notes |
| ------- | -------- | ------------------ |
| API Key | Yes | e.g. `lin_api_...` |
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ------------------------------------------------------- | ------------------------------------------------- |
| [Create Ticket](/reference/blocks/linear-create-ticket) | Create an issue in Linear |
| [Find Issues](/reference/blocks/linear-find-issues) | Search for issues in Linear with optional filters |
| [Update Issue](/reference/blocks/linear-update-issue) | Update an issue in Linear |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Linear blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Linear-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Microsoft
URL: /reference/integrations/microsoft
Type: reference
Description: Connect Outlook, Teams, and Microsoft 365 services.
Keywords: microsoft, integration, oauth, connect
Connect Outlook, Teams, and Microsoft 365 services.
Connect [#connect]
Connect Microsoft in **Settings → Integrations**. Open the Microsoft card, click **Connect**, and authorize Stylo to access your Microsoft account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Microsoft scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Triggers [#triggers]
| Block | What it does |
| -------------------------------------------- | -------------------------------------------------------- |
| [Outlook](/reference/blocks/trigger-outlook) | Trigger workflow when new emails are received in Outlook |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Microsoft blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Microsoft-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Resend
URL: /reference/integrations/resend
Type: reference
Description: Send transactional emails from your workflows.
Keywords: resend, integration, api key, connect
Send transactional emails from your workflows.
Connect [#connect]
Connect Resend with an API key in **Settings → Integrations**. Open the Resend card, click **Connect**, and provide:
| Field | Required | Notes |
| ------- | -------- | ------------- |
| API Key | Yes | e.g. `re_...` |
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ------------------------------------------------- | ------------------------ |
| [Send Email](/reference/blocks/resend-send-email) | Send an email via Resend |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Resend blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Resend-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# ServiceNow
URL: /reference/integrations/servicenow
Type: reference
Description: Integrate with ServiceNow incidents and requests.
Keywords: servicenow, integration, oauth, connect
Integrate with ServiceNow incidents and requests.
Connect [#connect]
Connect ServiceNow in **Settings → Integrations**. Open the ServiceNow card, click **Connect**, and authorize Stylo to access your ServiceNow account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact ServiceNow scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ------------------------------------------------- | --------------------------------------------------- |
| [ServiceNow](/reference/blocks/servicenow-record) | Create, read, update, and delete ServiceNow records |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, ServiceNow blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document ServiceNow-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Shopify
URL: /reference/integrations/shopify
Type: reference
Description: Access orders, customers, and store data.
Keywords: shopify, integration, oauth, connect
Access orders, customers, and store data.
Connect [#connect]
Connect Shopify in **Settings → Integrations**. Open the Shopify card, click **Connect**, and authorize Stylo to access your Shopify account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Shopify scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ------------------------------------------- | ----------------------------------------------------------------------- |
| [Shopify](/reference/blocks/shopify-manage) | Manage products, orders, customers, and inventory in your Shopify store |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Shopify blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Shopify-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Slack
URL: /reference/integrations/slack
Type: reference
Description: Send notifications and updates to Slack channels.
Keywords: slack, integration, oauth, connect
Send notifications and updates to Slack channels.
Connect [#connect]
Connect Slack in **Settings → Integrations**. Open the Slack card, click **Connect**, and authorize Stylo to access your Slack account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Slack scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| ---------------------------------------------------------- | --------------------------------- |
| [Send Slack Message](/reference/blocks/slack-send-message) | Send a message to a Slack channel |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Slack blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Slack-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Zendesk
URL: /reference/integrations/zendesk
Type: reference
Description: Manage tickets, users, and support workflows.
Keywords: zendesk, integration, oauth, connect
Manage tickets, users, and support workflows.
Connect [#connect]
Connect Zendesk in **Settings → Integrations**. Open the Zendesk card, click **Connect**, and authorize Stylo to access your Zendesk account in the window that opens. The connection shows as **Connected** when authorization succeeds.
{/* TODO(docs): document the exact Zendesk scopes/permissions Stylo requests — not encoded in the provider definition. */}
Supported actions and triggers [#supported-actions-and-triggers]
Actions [#actions]
| Block | What it does |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Add Comment / Reply](/reference/blocks/zendesk-add-comment) | Add a public reply or internal note to a ticket |
| [Add Tags](/reference/blocks/zendesk-add-tags) | Add tags to a ticket for classification and tracking |
| [Apply Macro](/reference/blocks/zendesk-apply-macro) | Apply a predefined macro to a ticket |
| [Assign Ticket](/reference/blocks/zendesk-assign-ticket) | Assign a ticket to an agent or group |
| [Close Ticket](/reference/blocks/zendesk-close-ticket) | Mark a ticket as solved with optional closing message |
| [Create Custom Object Record](/reference/blocks/zendesk-create-custom-object-record) | Create a new custom object record |
| [Create Ticket](/reference/blocks/zendesk-create-ticket) | Create a new Zendesk ticket |
| [Create User](/reference/blocks/zendesk-create-user) | Create a new Zendesk user |
| [Delete Custom Object Record](/reference/blocks/zendesk-delete-custom-object-record) | Delete a custom object record by ID |
| [Get Conversation](/reference/blocks/zendesk-get-conversation) | Fetch a Sunshine Conversations conversation, including current switchboard control. |
| [Get Custom Object Record](/reference/blocks/zendesk-get-custom-object-record) | Fetch a Zendesk custom object record by ID |
| [Get Organization](/reference/blocks/zendesk-get-organization) | Get organization details for B2B context |
| [Get Ticket](/reference/blocks/zendesk-get-ticket) | Fetch a Zendesk ticket by ID and return its full data object for downstream use. |
| [Get Ticket Comments](/reference/blocks/zendesk-get-ticket-comments) | Get conversation history for a ticket |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Get User](/reference/blocks/zendesk-get-user) | Fetch a Zendesk user by ID |
| [Get User Tickets](/reference/blocks/zendesk-get-user-tickets) | Get ticket history for a customer |
| [List Agents](/reference/blocks/zendesk-list-agents) | Get available agents for ticket assignment |
| [List Custom Objects](/reference/blocks/zendesk-list-custom-objects) | List all custom object definitions in the Zendesk account |
| [List Groups](/reference/blocks/zendesk-list-groups) | Get all available groups for routing tickets |
| [List Macros](/reference/blocks/zendesk-list-macros) | Get available macros for ticket automation |
| [Pass Conversation Control](/reference/blocks/zendesk-pass-conversation-control) | Pass switchboard control to another integration (e.g. escalate to a human agent). |
| [Post Conversation Message](/reference/blocks/zendesk-post-conversation-message) | Send a business-authored message on a Sunshine Conversations conversation (messaging channels). |
| [Release Conversation Control](/reference/blocks/zendesk-release-conversation-control) | Release switchboard control back to the default integration (per marketplace bot SHOULD). |
| [Remove Tags](/reference/blocks/zendesk-remove-tags) | Remove tags from a ticket |
| [Search Custom Object Records](/reference/blocks/zendesk-search-custom-object-records) | Search custom object records by query string |
| [Search Tickets](/reference/blocks/zendesk-search-tickets) | Search for Zendesk tickets |
| [Set Lookup Field](/reference/blocks/zendesk-set-lookup-field) | Set a lookup relationship field on a ticket to a custom object record by ID, name, or external ID |
| [Set Ticket Priority](/reference/blocks/zendesk-set-ticket-priority) | Set the priority level on a Zendesk ticket (low, normal, high, or urgent). |
| [Set Ticket Type](/reference/blocks/zendesk-set-ticket-type) | Set ticket type (problem, incident, question, task) |
| [Update Custom Object Record](/reference/blocks/zendesk-update-custom-object-record) | Update an existing custom object record |
| [Update Ticket](/reference/blocks/zendesk-update-ticket) | Update ticket with comment, status, tags, priority in one API call. Comment text supports markdown — see the Comment field description for the rendering contract. |
| [Upsert Custom Object Record](/reference/blocks/zendesk-upsert-custom-object-record) | Create or update a custom object record by external ID or name |
Limits and failure modes [#limits-and-failure-modes]
* The connection can expire or be revoked. When it does, Zendesk blocks fail with an authorization error until you reconnect in **Settings → Integrations**.
* A disconnected or unconfigured integration makes its blocks unavailable in the Workflow Builder.
{/* TODO(docs): document Zendesk-specific rate limits and permission errors — not encoded in @stylo/core. */}
Related [#related]
* [Integrations overview](/integrations)
* [All workflow blocks](/reference/blocks)
* [Troubleshooting](/troubleshooting)
---
# Classify
URL: /reference/blocks/ai-classify
Type: reference
Description: Classify content into predefined categories using AI
Keywords: classify, ai/classify, ai, block, workflow builder
`ai/classify` — Classify content into predefined categories using AI.
Where it appears [#where-it-appears]
The **Classify** block lives in the **AI** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------------- | -------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `prompt` | text (multi-line, supports references) | Yes | — | Text the model should classify. Include the content to evaluate (e.g. ticket subject, customer message) using \ references. |
| `categories` | categories | Yes | — | Define the possible classification outcomes. Each category has an ID used in downstream references and a label shown in the UI. |
| `defaultCategory` | text | No | — | Category ID to select when the model cannot confidently match any defined category. Leave empty to return no category on low-confidence inputs. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------------- | ------- | -------------------------------- |
| `success` | boolean | Whether classification succeeded |
| `category` | string | Selected category ID |
| `categoryLabel` | string | Selected category label |
| `reasoning` | string | AI reasoning for the selection |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "ai/classify",
"config": {
"prompt": "",
"categories": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`prompt`, `categories`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Generate Text
URL: /reference/blocks/ai-generate-text
Type: reference
Description: Generate text using AI models
Keywords: generate text, ai/generate-text, ai, block, workflow builder
`ai/generate-text` — Generate text using AI models.
Where it appears [#where-it-appears]
The **Generate Text** block lives in the **AI** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------------- | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `format` | select | No | `text` | Use 'Structured JSON' when you need fields the model must populate. For pick-from-list cases, use the Classify block instead. Options: `text`, `object`. |
| `system` | text (multi-line, supports references) | No | — | Who the model is and what rules always apply. Cached across runs by the model provider. The per-run task and data belong in 'Prompt'. |
| `prompt` | text (multi-line, supports references) | Yes | — | The task and data for this execution. Per-run context belongs here (not in the system prompt). Use \ to inject upstream values. |
| `outputPreset` | select | No | `none` | Apply a canonical output contract for a downstream channel. Injects a system prompt prefix and cleans the model output (e.g. strips stray code fences). Options: `none`, `zendesk-comment`. |
| `files` | text (multi-line, supports references) | No | — | Files for AI to analyze. Images for vision, audio for transcription, PDFs for documents, text files extracted into prompt. |
| `schema` | JSON schema | No | — | Define the fields the model should populate. Add properties manually, paste an example, or import a JSON file. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ------------------------------------- |
| `success` | boolean | Whether generation succeeded |
| `text` | string | Generated text (for text format) |
| `object` | json | Generated object (for object format) |
| `enum` | string | Selected enum value (for enum format) |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "ai/generate-text",
"config": {
"format": "text",
"prompt": "",
"outputPreset": "none"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`prompt`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Transcribe Audio
URL: /reference/blocks/ai-transcribe-audio
Type: reference
Description: Convert audio files to text using speech-to-text AI
Keywords: transcribe audio, ai/transcribe-audio, ai, block, workflow builder
`ai/transcribe-audio` — Convert audio files to text using speech-to-text AI.
Where it appears [#where-it-appears]
The **Transcribe Audio** block lives in the **AI** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------ |
| `audioFile` | text (multi-line, supports references) | Yes | — | Audio file to transcribe. Supports MP3, WAV, M4A, FLAC, OGG, WebM (max 25 MB). |
| `language` | text | No | — | ISO-639-1 language code (e.g., en, es, fr). Leave empty for auto-detection. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ------------------------------------------ |
| `success` | boolean | Whether transcription succeeded |
| `text` | string | Transcribed text |
| `language` | string | Detected language code |
| `duration` | number | Audio duration in seconds |
| `segments` | json | Array of segments with text and timestamps |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "ai/transcribe-audio",
"config": {
"audioFile": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`audioFile`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Validate Response Links
URL: /reference/blocks/automation-validate-response-links
Type: reference
Description: Check that all URLs in a response are from allowed KB sources
Keywords: validate response links, automation/validate-response-links, system, automation, block, workflow builder
`automation/validate-response-links` — Check that all URLs in a response are from allowed KB sources.
Where it appears [#where-it-appears]
The **Validate Response Links** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------- | -------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `response` | text (multi-line, supports references) | Yes | — | The response text whose URLs should be validated against the allowed sources. Use literal text or \ to reference a generated reply. |
| `allowedUrls` | code | Yes | — | JSON array of allowed base URLs/sources; any link in the response not matching one of these is flagged as invalid. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------- | ------- | --------------------------- |
| `success` | boolean | Success status |
| `isValid` | boolean | Whether all links are valid |
| `invalidUrls` | array | Invalid URLs found |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "automation/validate-response-links",
"config": {
"response": "",
"allowedUrls": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`response`, `allowedUrls`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Write Audit Log
URL: /reference/blocks/automation-write-audit-log
Type: reference
Description: Persist an audit record for automated ticket actions
Keywords: write audit log, automation/write-audit-log, system, automation, block, workflow builder
`automation/write-audit-log` — Persist an audit record for automated ticket actions.
Where it appears [#where-it-appears]
The **Write Audit Log** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------------- | -------------------------------------- | -------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `actionType` | select | Yes | `auto_response` | Category of automated action being recorded in the audit log (e.g. an auto-response was sent, a tag was added, the ticket was updated, or it was escalated). Options: `auto_response`, `tag_added`, `ticket_updated`, `escalated`. |
| `ticketId` | text (supports references) | Yes | — | ID of the ticket the audited action applies to. Use a literal ID or \ to reference an ID from a previous step. |
| `ticketSubject` | text (supports references) | No | — | Optional ticket subject stored with the audit record for context. Accepts literal text or \. |
| `responseText` | text (multi-line, supports references) | No | — | Optional response text to record with the audit entry (e.g. the message that was sent). Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------ | ------- | ----------------------- |
| `success` | boolean | Success status |
| `auditLogId` | string | Audit log ID |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "automation/write-audit-log",
"config": {
"actionType": "auto_response",
"ticketId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`actionType`, `ticketId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Search Knowledge Base
URL: /reference/blocks/context-engine-search-knowledge-base
Type: reference
Description: Search synced knowledge base documents using semantic search with automatic reranking
Keywords: search knowledge base, context-engine/search-knowledge-base, integrations, context_engine, block, workflow builder
`context-engine/search-knowledge-base` — Search synced knowledge base documents using semantic search with automatic reranking.
Where it appears [#where-it-appears]
The **Search Knowledge Base** block lives in the **Integrations** group of the Workflow Builder. Connect the Context Engine integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------ |
| `knowledgeBaseId` | select | Yes | — | The synced knowledge base to search. Choose from the knowledge bases configured for your organization. |
| `searchQuery` | text (supports references) | Yes | — | The text to search for. |
| `topK` | number | No | `5` | Maximum number of documents to return |
| `minScore` | number | No | `15` | Only return results above this relevance threshold. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------ | ------ | --------------------------------- |
| `results` | array | Array of matching documents |
| `count` | number | Number of results returned |
| `confidence` | json | Search confidence level and score |
| `meta` | json | Search metadata |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "context-engine/search-knowledge-base",
"config": {
"knowledgeBaseId": "...",
"searchQuery": "",
"topK": 5,
"minScore": 15
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Context Engine integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`knowledgeBaseId`, `searchQuery`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Execute SQL Statement
URL: /reference/blocks/databricks-execute-sql-statement
Type: reference
Description: Run a read-only SQL statement against a Databricks SQL warehouse
Keywords: execute sql statement, databricks/execute-sql-statement, integrations, databricks, block, workflow builder
`databricks/execute-sql-statement` — Run a read-only SQL statement against a Databricks SQL warehouse.
Where it appears [#where-it-appears]
The **Execute SQL Statement** block lives in the **Integrations** group of the Workflow Builder. Connect the Databricks integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------------------- | -------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| `statement` | code | Yes | — | Read-only SQL only. SELECT, WITH, SHOW, DESCRIBE, DESC, and EXPLAIN are allowed; write operations are blocked. |
| `warehouseId` | text (supports references) | No | — | Override the warehouse configured in the integration credentials. |
| `catalog` | text (supports references) | No | — | Optional Databricks catalog for statement execution. |
| `schema` | text (supports references) | No | — | Optional Databricks schema for statement execution. |
| `parameters` | code | No | — | Optional statement parameters as an array of \{name, value, type}. |
| `rowLimit` | text (supports references) | No | — | Optional maximum number of rows returned. |
| `byteLimit` | text (supports references) | No | — | Optional maximum result size in bytes. |
| `waitTimeoutSeconds` | text (supports references) | No | — | Optional server-side wait timeout before the client begins polling. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------- | ------- | ----------------------------------- |
| `success` | boolean | Whether the query succeeded |
| `statementId` | string | Databricks statement ID |
| `status` | json | Statement execution status |
| `result` | json | Databricks statement result payload |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "databricks/execute-sql-statement",
"config": {
"statement": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Databricks integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`statement`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# List SQL Warehouses
URL: /reference/blocks/databricks-list-sql-warehouses
Type: reference
Description: List available Databricks SQL warehouses
Keywords: list sql warehouses, databricks/list-sql-warehouses, integrations, databricks, block, workflow builder
`databricks/list-sql-warehouses` — List available Databricks SQL warehouses.
Where it appears [#where-it-appears]
The **List SQL Warehouses** block lives in the **Integrations** group of the Workflow Builder. Connect the Databricks integration before adding it.
Fields [#fields]
This block has no configurable fields.
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------ | ------- | ----------------------------------- |
| `success` | boolean | Whether the request succeeded |
| `warehouses` | array | Available Databricks SQL warehouses |
| `error` | string | Error message if failed |
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Databricks integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Test Databricks Connection
URL: /reference/blocks/databricks-test-connection
Type: reference
Description: Verify Databricks connectivity and SQL warehouse visibility
Keywords: test databricks connection, databricks/test-connection, integrations, databricks, block, workflow builder
`databricks/test-connection` — Verify Databricks connectivity and SQL warehouse visibility.
Where it appears [#where-it-appears]
The **Test Databricks Connection** block lives in the **Integrations** group of the Workflow Builder. Connect the Databricks integration before adding it.
Fields [#fields]
This block has no configurable fields.
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------------- | ------- | -------------------------------- |
| `success` | boolean | Whether the connection succeeded |
| `warehouseCount` | number | Number of visible SQL warehouses |
| `warehouses` | array | Visible SQL warehouses |
| `error` | string | Error message if failed |
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Databricks integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Scrape URL
URL: /reference/blocks/firecrawl-scrape
Type: reference
Description: Scrape content from a URL
Keywords: scrape url, firecrawl/scrape, integrations, firecrawl, block, workflow builder
`firecrawl/scrape` — Scrape content from a URL.
Where it appears [#where-it-appears]
The **Scrape URL** block lives in the **Integrations** group of the Workflow Builder. Connect the Firecrawl integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `url` | text (supports references) | Yes | — | The web page URL to scrape. Use a literal URL or \ to reference a URL from a previous step. |
| `includeScreenshot` | toggle | No | `false` | When on, also capture a screenshot of the page alongside the scraped content. Defaults to off. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | -------------------------- |
| `success` | boolean | Whether scraping succeeded |
| `content` | string | Scraped content |
| `markdown` | string | Content as markdown |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "firecrawl/scrape",
"config": {
"url": "",
"includeScreenshot": false
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Firecrawl integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`url`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Search Web
URL: /reference/blocks/firecrawl-search
Type: reference
Description: Search the web with Firecrawl
Keywords: search web, firecrawl/search, integrations, firecrawl, block, workflow builder
`firecrawl/search` — Search the web with Firecrawl.
Where it appears [#where-it-appears]
The **Search Web** block lives in the **Integrations** group of the Workflow Builder. Connect the Firecrawl integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------- | -------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `searchQuery` | text (supports references) | Yes | — | Text query to search the web for via Firecrawl. Use literal text or \ to reference a value from a previous step. |
| `limit` | number | No | `10` | Maximum number of search results to return. Defaults to 10. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ------------------------ |
| `success` | boolean | Whether search succeeded |
| `results` | array | Array of search results |
| `count` | number | Number of results |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "firecrawl/search",
"config": {
"searchQuery": "",
"limit": 10
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Firecrawl integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`searchQuery`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Add Label
URL: /reference/blocks/gmail-add-label
Type: reference
Description: Add label(s) to a Gmail message
Keywords: add label, gmail/add-label, integrations, gmail, block, workflow builder
`gmail/add-label` — Add label(s) to a Gmail message.
Where it appears [#where-it-appears]
The **Add Label** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
| `labelIds` | text (supports references) | Yes | — | Comma-separated Gmail label IDs to apply to or remove from the message (e.g. `Label_123,IMPORTANT`). Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `modified` | boolean | Message was modified |
| `message` | json | Updated message |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/add-label",
"config": {
"messageId": "",
"labelIds": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`messageId`, `labelIds`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Archive Email
URL: /reference/blocks/gmail-archive-email
Type: reference
Description: Archive a Gmail message (remove INBOX label)
Keywords: archive email, gmail/archive-email, integrations, gmail, block, workflow builder
`gmail/archive-email` — Archive a Gmail message (remove INBOX label).
Where it appears [#where-it-appears]
The **Archive Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `modified` | boolean | Message was modified |
| `message` | json | Archived message |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/archive-email",
"config": {
"messageId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`messageId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Delete Email
URL: /reference/blocks/gmail-delete-email
Type: reference
Description: Delete a Gmail message
Keywords: delete email, gmail/delete-email, integrations, gmail, block, workflow builder
`gmail/delete-email` — Delete a Gmail message.
Where it appears [#where-it-appears]
The **Delete Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `deleted` | boolean | Message was deleted |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/delete-email",
"config": {
"messageId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`messageId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Draft Email
URL: /reference/blocks/gmail-draft-email
Type: reference
Description: Create a draft email in Gmail
Keywords: draft email, gmail/draft-email, integrations, gmail, block, workflow builder
`gmail/draft-email` — Create a draft email in Gmail.
Where it appears [#where-it-appears]
The **Draft Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------- | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `to` | text (supports references) | Yes | — | Recipient email address. Use literal text or \ to reference an address from a previous step. |
| `cc` | text (supports references) | No | — | Optional CC recipient address(es). Accepts literal text or \. |
| `bcc` | text (supports references) | No | — | Optional BCC recipient address(es), hidden from other recipients. Accepts literal text or \. |
| `subject` | text (supports references) | Yes | — | Subject line of the email. Use literal text or \ to reference a value from a previous step. |
| `body` | text (multi-line, supports references) | Yes | — | Body content of the email, interpreted according to the Content Type field. Use literal text or \ to reference upstream content. |
| `contentType` | select | No | `text` | How the body is sent: Plain Text or HTML. Choose HTML to send formatted markup. Options: `text`, `html`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `draftId` | string | Draft ID |
| `messageId` | string | Message ID |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/draft-email",
"config": {
"to": "",
"subject": "",
"body": "",
"contentType": "text"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`to`, `subject`, `body`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Mark as Read
URL: /reference/blocks/gmail-mark-read
Type: reference
Description: Mark a Gmail message as read
Keywords: mark as read, gmail/mark-read, integrations, gmail, block, workflow builder
`gmail/mark-read` — Mark a Gmail message as read.
Where it appears [#where-it-appears]
The **Mark as Read** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `modified` | boolean | Message was modified |
| `message` | json | Updated message |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/mark-read",
"config": {
"messageId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`messageId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Mark as Unread
URL: /reference/blocks/gmail-mark-unread
Type: reference
Description: Mark a Gmail message as unread
Keywords: mark as unread, gmail/mark-unread, integrations, gmail, block, workflow builder
`gmail/mark-unread` — Mark a Gmail message as unread.
Where it appears [#where-it-appears]
The **Mark as Unread** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `modified` | boolean | Message was modified |
| `message` | json | Updated message |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/mark-unread",
"config": {
"messageId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`messageId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Move Email
URL: /reference/blocks/gmail-move-email
Type: reference
Description: Move a Gmail message to a label
Keywords: move email, gmail/move-email, integrations, gmail, block, workflow builder
`gmail/move-email` — Move a Gmail message to a label.
Where it appears [#where-it-appears]
The **Move Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
| `addLabelIds` | text (supports references) | No | — | Comma-separated Gmail label IDs to add to the message (e.g. `Label_123,IMPORTANT`). Accepts literal text or \. |
| `removeLabelIds` | text (supports references) | No | — | Comma-separated Gmail label IDs to remove from the message (e.g. `INBOX` to move it out of the inbox). Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `modified` | boolean | Message was modified |
| `message` | json | Updated message |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/move-email",
"config": {
"messageId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`messageId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Read Email
URL: /reference/blocks/gmail-read-email
Type: reference
Description: Read a Gmail message by ID
Keywords: read email, gmail/read-email, integrations, gmail, block, workflow builder
`gmail/read-email` — Read a Gmail message by ID.
Where it appears [#where-it-appears]
The **Read Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `message` | json | Email message object |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/read-email",
"config": {
"messageId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`messageId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Remove Label
URL: /reference/blocks/gmail-remove-label
Type: reference
Description: Remove label(s) from a Gmail message
Keywords: remove label, gmail/remove-label, integrations, gmail, block, workflow builder
`gmail/remove-label` — Remove label(s) from a Gmail message.
Where it appears [#where-it-appears]
The **Remove Label** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `messageId` | text (supports references) | Yes | — | Gmail message ID to act on. Use a literal ID or \ to reference an ID from a previous step (e.g. a search result). |
| `labelIds` | text (supports references) | Yes | — | Comma-separated Gmail label IDs to apply to or remove from the message (e.g. `Label_123,IMPORTANT`). Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `modified` | boolean | Message was modified |
| `message` | json | Updated message |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/remove-label",
"config": {
"messageId": "",
"labelIds": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`messageId`, `labelIds`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Search Email
URL: /reference/blocks/gmail-search-email
Type: reference
Description: Search Gmail messages with a query
Keywords: search email, gmail/search-email, integrations, gmail, block, workflow builder
`gmail/search-email` — Search Gmail messages with a query.
Where it appears [#where-it-appears]
The **Search Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `query` | text (supports references) | Yes | — | Gmail search query using Gmail's search operators (e.g. `in:inbox from:support@example.com`). Use literal text or \. |
| `maxResults` | number | No | `25` | Maximum number of matching messages to return. Defaults to 25. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| -------------------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `messages` | array | Array of message IDs |
| `resultSizeEstimate` | number | Estimated result count |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/search-email",
"config": {
"query": "",
"maxResults": 25
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`query`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Send Email
URL: /reference/blocks/gmail-send-email
Type: reference
Description: Send an email via Gmail
Keywords: send email, gmail/send-email, integrations, gmail, block, workflow builder
`gmail/send-email` — Send an email via Gmail.
Where it appears [#where-it-appears]
The **Send Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Gmail integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------- | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `to` | text (supports references) | Yes | — | Recipient email address. Use literal text or \ to reference an address from a previous step. |
| `cc` | text (supports references) | No | — | Optional CC recipient address(es). Accepts literal text or \. |
| `bcc` | text (supports references) | No | — | Optional BCC recipient address(es), hidden from other recipients. Accepts literal text or \. |
| `subject` | text (supports references) | Yes | — | Subject line of the email. Use literal text or \ to reference a value from a previous step. |
| `body` | text (multi-line, supports references) | Yes | — | Body content of the email, interpreted according to the Content Type field. Use literal text or \ to reference upstream content. |
| `contentType` | select | No | `text` | How the body is sent: Plain Text or HTML. Choose HTML to send formatted markup. Options: `text`, `html`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `messageId` | string | Sent message ID |
| `threadId` | string | Thread ID |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "gmail/send-email",
"config": {
"to": "",
"subject": "",
"body": "",
"contentType": "text"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Gmail integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`to`, `subject`, `body`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Append to Google Doc
URL: /reference/blocks/google-docs-append
Type: reference
Description: Add content to the end of a Google Doc
Keywords: append to google doc, google/docs-append, integrations, google, block, workflow builder
`google/docs-append` — Add content to the end of a Google Doc.
Where it appears [#where-it-appears]
The **Append to Google Doc** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `documentId` | text (supports references) | Yes | — | ID of the Google Doc to operate on. Use a literal ID or \ to reference an ID from a previous step. |
| `content` | text (multi-line, supports references) | Yes | — | Text to add to the end of the Google Doc. Use literal text or \ to reference upstream content. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Whether write succeeded |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/docs-append",
"config": {
"documentId": "",
"content": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`documentId`, `content`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Read Google Doc
URL: /reference/blocks/google-docs-read-document
Type: reference
Description: Read a Google Doc and return plain text
Keywords: read google doc, google/docs-read-document, integrations, google, block, workflow builder
`google/docs-read-document` — Read a Google Doc and return plain text.
Where it appears [#where-it-appears]
The **Read Google Doc** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `documentId` | text (supports references) | Yes | — | ID of the Google Doc to operate on. Use a literal ID or \ to reference an ID from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Whether read succeeded |
| `text` | string | Document text content |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/docs-read-document",
"config": {
"documentId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`documentId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Replace Google Doc Contents
URL: /reference/blocks/google-docs-replace
Type: reference
Description: Overwrite the entire body of a Google Doc
Keywords: replace google doc contents, google/docs-replace, integrations, google, block, workflow builder
`google/docs-replace` — Overwrite the entire body of a Google Doc.
Where it appears [#where-it-appears]
The **Replace Google Doc Contents** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | -------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `documentId` | text (supports references) | Yes | — | ID of the Google Doc to operate on. Use a literal ID or \ to reference an ID from a previous step. |
| `content` | text (multi-line, supports references) | Yes | — | This deletes the existing document body and writes this content in its place. Use Append to Google Doc if you just want to add content. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Whether write succeeded |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/docs-replace",
"config": {
"documentId": "",
"content": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`documentId`, `content`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Google Drive: Read File
URL: /reference/blocks/google-drive-read-file
Type: reference
Description: Read Google Docs/Sheets or download files and return text
Keywords: google drive: read file, google/drive-read-file, integrations, google, block, workflow builder
`google/drive-read-file` — Read Google Docs/Sheets or download files and return text.
Where it appears [#where-it-appears]
The **Google Drive: Read File** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------- | -------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `fileId` | text (supports references) | Yes | — | Google Drive file ID to read. Google Docs/Sheets are exported as text; other file types are downloaded. Use a literal ID or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Whether read succeeded |
| `text` | string | File text content |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/drive-read-file",
"config": {
"fileId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`fileId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Append Row to Google Sheet
URL: /reference/blocks/google-sheets-append-row
Type: reference
Description: Add new rows to the end of a sheet
Keywords: append row to google sheet, google/sheets-append-row, integrations, google, block, workflow builder
`google/sheets-append-row` — Add new rows to the end of a sheet.
Where it appears [#where-it-appears]
The **Append Row to Google Sheet** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------------- | -------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| `spreadsheetId` | text (supports references) | Yes | — | The target Google Sheet, given as a spreadsheet ID or its full URL. Use literal text or \. |
| `sheetName` | text (supports references) | Yes | — | Name of the tab within the spreadsheet to append rows to (e.g. `Sheet1`). Use literal text or \. |
| `rowData` | code | Yes | — | JSON array of rows with scalar placeholders in quoted cells, or a single upstream placeholder that resolves to rows. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------- | ------- | ----------------------- |
| `success` | boolean | Whether write succeeded |
| `updatedRows` | number | Number of rows appended |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/sheets-append-row",
"config": {
"spreadsheetId": "",
"sheetName": "",
"rowData": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`spreadsheetId`, `sheetName`, `rowData`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Read from Google Sheet
URL: /reference/blocks/google-sheets-read-rows
Type: reference
Description: Read rows from a Google Sheet range
Keywords: read from google sheet, google/sheets-read-rows, integrations, google, block, workflow builder
`google/sheets-read-rows` — Read rows from a Google Sheet range.
Where it appears [#where-it-appears]
The **Read from Google Sheet** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `spreadsheetId` | text (supports references) | Yes | — | The target Google Sheet, given as a spreadsheet ID or its full URL. Use literal text or \. |
| `sheetName` | text (supports references) | No | — | Optional name of the tab within the spreadsheet to target. Use literal text or \. |
| `range` | text (supports references) | No | — | Optional A1-notation range to read (e.g. `A1:D10`). Leave empty to read all rows in the sheet. Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Whether read succeeded |
| `rows` | array | Array of row arrays |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/sheets-read-rows",
"config": {
"spreadsheetId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`spreadsheetId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Update Row in Google Sheet
URL: /reference/blocks/google-sheets-update-row
Type: reference
Description: Overwrite cells at a specific range (e.g. Sheet1!A2:E2)
Keywords: update row in google sheet, google/sheets-update-row, integrations, google, block, workflow builder
`google/sheets-update-row` — Overwrite cells at a specific range (e.g. Sheet1!A2:E2).
Where it appears [#where-it-appears]
The **Update Row in Google Sheet** block lives in the **Integrations** group of the Workflow Builder. Connect the Google integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `spreadsheetId` | text (supports references) | Yes | — | The target Google Sheet, given as a spreadsheet ID or its full URL. Use literal text or \. |
| `range` | text (supports references) | Yes | — | A1 notation pointing to the exact cells to overwrite. Required — without a row number this would overwrite row 1. |
| `rowData` | code | Yes | — | JSON array of rows. The first row is written to the start of the range; additional rows continue downward. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------- | ------- | ----------------------- |
| `success` | boolean | Whether write succeeded |
| `updatedRows` | number | Number of rows updated |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "google/sheets-update-row",
"config": {
"spreadsheetId": "",
"range": "",
"rowData": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`spreadsheetId`, `range`, `rowData`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Create Company
URL: /reference/blocks/hubspot-create-company
Type: reference
Description: Create a HubSpot company
Keywords: create company, hubspot/create-company, integrations, hubspot, block, workflow builder
`hubspot/create-company` — Create a HubSpot company.
Where it appears [#where-it-appears]
The **Create Company** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `propertiesJson` | code | Yes | — | JSON object of HubSpot company properties to set on the new company (e.g. `name`, `domain`). Property keys must match your HubSpot schema. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `company` | json | Created company |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/create-company",
"config": {
"propertiesJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`propertiesJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Create Contact
URL: /reference/blocks/hubspot-create-contact
Type: reference
Description: Create a HubSpot contact
Keywords: create contact, hubspot/create-contact, integrations, hubspot, block, workflow builder
`hubspot/create-contact` — Create a HubSpot contact.
Where it appears [#where-it-appears]
The **Create Contact** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | ---- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `propertiesJson` | code | Yes | — | JSON object of HubSpot contact properties to set on the new contact (e.g. `email`, `firstname`). Property keys must match your HubSpot schema. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `contact` | json | Created contact |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/create-contact",
"config": {
"propertiesJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`propertiesJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Create Ticket
URL: /reference/blocks/hubspot-create-ticket
Type: reference
Description: Create a ticket in HubSpot
Keywords: create ticket, hubspot/create-ticket, integrations, hubspot, block, workflow builder
`hubspot/create-ticket` — Create a ticket in HubSpot.
Where it appears [#where-it-appears]
The **Create Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | ---- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `propertiesJson` | code | Yes | — | JSON object of HubSpot ticket properties to set on the new ticket (e.g. `subject`, `content`). Property keys must match your HubSpot schema. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `ticket` | json | Created ticket |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/create-ticket",
"config": {
"propertiesJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`propertiesJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Companies
URL: /reference/blocks/hubspot-get-companies
Type: reference
Description: List HubSpot companies (or fetch one by ID/domain)
Keywords: get companies, hubspot/get-companies, integrations, hubspot, block, workflow builder
`hubspot/get-companies` — List HubSpot companies (or fetch one by ID/domain).
Where it appears [#where-it-appears]
The **Get Companies** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `companyIdOrDomain` | text (supports references) | No | — | Optional HubSpot company ID or domain to fetch a single company. Leave empty to list companies. Accepts literal text or \. |
| `limit` | number | No | `100` | Maximum number of records to return when listing. Defaults to 100. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `result` | json | Companies data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/get-companies",
"config": {
"limit": 100
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Contacts
URL: /reference/blocks/hubspot-get-contacts
Type: reference
Description: List HubSpot contacts (or fetch one by ID/email)
Keywords: get contacts, hubspot/get-contacts, integrations, hubspot, block, workflow builder
`hubspot/get-contacts` — List HubSpot contacts (or fetch one by ID/email).
Where it appears [#where-it-appears]
The **Get Contacts** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------ | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `contactIdOrEmail` | text (supports references) | No | — | Optional HubSpot contact ID or email address to fetch a single contact. Leave empty to list contacts. Accepts literal text or \. |
| `limit` | number | No | `100` | Maximum number of records to return when listing. Defaults to 100. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `result` | json | Contacts data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/get-contacts",
"config": {
"limit": 100
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Deals
URL: /reference/blocks/hubspot-get-deals
Type: reference
Description: List deals in HubSpot
Keywords: get deals, hubspot/get-deals, integrations, hubspot, block, workflow builder
`hubspot/get-deals` — List deals in HubSpot.
Where it appears [#where-it-appears]
The **Get Deals** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------- | ------ | -------- | ------- | ------------------------------------------------------------------ |
| `limit` | number | No | `100` | Maximum number of records to return when listing. Defaults to 100. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `result` | json | Deals data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/get-deals",
"config": {
"limit": 100
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Ticket
URL: /reference/blocks/hubspot-get-ticket
Type: reference
Description: Get a ticket by ID in HubSpot
Keywords: get ticket, hubspot/get-ticket, integrations, hubspot, block, workflow builder
`hubspot/get-ticket` — Get a ticket by ID in HubSpot.
Where it appears [#where-it-appears]
The **Get Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------- | -------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `ticketId` | text (supports references) | Yes | — | HubSpot ticket ID to fetch. Use a literal ID or \ to reference an ID from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `ticket` | json | Ticket data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/get-ticket",
"config": {
"ticketId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`ticketId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Users
URL: /reference/blocks/hubspot-get-users
Type: reference
Description: List users/owners in HubSpot
Keywords: get users, hubspot/get-users, integrations, hubspot, block, workflow builder
`hubspot/get-users` — List users/owners in HubSpot.
Where it appears [#where-it-appears]
The **Get Users** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
This block has no configurable fields.
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `owners` | json | List of HubSpot owners |
| `error` | string | Error message if failed |
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Search Companies
URL: /reference/blocks/hubspot-search-companies
Type: reference
Description: Search HubSpot companies
Keywords: search companies, hubspot/search-companies, integrations, hubspot, block, workflow builder
`hubspot/search-companies` — Search HubSpot companies.
Where it appears [#where-it-appears]
The **Search Companies** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | ---- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `searchJson` | code | Yes | — | HubSpot CRM Search API request body as JSON, using `filterGroups` with `propertyName`, `operator`, and `value` to filter companies. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `results` | json | Search results |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/search-companies",
"config": {
"searchJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`searchJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Search Contacts
URL: /reference/blocks/hubspot-search-contacts
Type: reference
Description: Search HubSpot contacts
Keywords: search contacts, hubspot/search-contacts, integrations, hubspot, block, workflow builder
`hubspot/search-contacts` — Search HubSpot contacts.
Where it appears [#where-it-appears]
The **Search Contacts** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | ---- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `searchJson` | code | Yes | — | HubSpot CRM Search API request body as JSON, using `filterGroups` with `propertyName`, `operator`, and `value` to filter contacts. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `results` | json | Search results |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/search-contacts",
"config": {
"searchJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`searchJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Search Tickets
URL: /reference/blocks/hubspot-search-tickets
Type: reference
Description: Search tickets in HubSpot
Keywords: search tickets, hubspot/search-tickets, integrations, hubspot, block, workflow builder
`hubspot/search-tickets` — Search tickets in HubSpot.
Where it appears [#where-it-appears]
The **Search Tickets** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | ---- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `searchJson` | code | Yes | — | HubSpot CRM Search API request body as JSON, using `filterGroups` with `propertyName`, `operator`, and `value` to filter tickets. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `results` | json | Search results |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/search-tickets",
"config": {
"searchJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`searchJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Update Company
URL: /reference/blocks/hubspot-update-company
Type: reference
Description: Update a HubSpot company
Keywords: update company, hubspot/update-company, integrations, hubspot, block, workflow builder
`hubspot/update-company` — Update a HubSpot company.
Where it appears [#where-it-appears]
The **Update Company** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------ |
| `companyId` | text (supports references) | Yes | — | HubSpot company ID to update. Use a literal ID or \ to reference an ID from a previous step. |
| `propertiesJson` | code | Yes | — | JSON object of HubSpot company properties to update. Only the keys you include are changed. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `company` | json | Updated company |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/update-company",
"config": {
"companyId": "",
"propertiesJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`companyId`, `propertiesJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Update Contact
URL: /reference/blocks/hubspot-update-contact
Type: reference
Description: Update a HubSpot contact
Keywords: update contact, hubspot/update-contact, integrations, hubspot, block, workflow builder
`hubspot/update-contact` — Update a HubSpot contact.
Where it appears [#where-it-appears]
The **Update Contact** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------ |
| `contactId` | text (supports references) | Yes | — | HubSpot contact ID to update. Use a literal ID or \ to reference an ID from a previous step. |
| `propertiesJson` | code | Yes | — | JSON object of HubSpot contact properties to update. Only the keys you include are changed. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `contact` | json | Updated contact |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/update-contact",
"config": {
"contactId": "",
"propertiesJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`contactId`, `propertiesJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Update Ticket
URL: /reference/blocks/hubspot-update-ticket
Type: reference
Description: Update a ticket in HubSpot
Keywords: update ticket, hubspot/update-ticket, integrations, hubspot, block, workflow builder
`hubspot/update-ticket` — Update a ticket in HubSpot.
Where it appears [#where-it-appears]
The **Update Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Hubspot integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| `ticketId` | text (supports references) | Yes | — | HubSpot ticket ID to update. Use a literal ID or \ to reference an ID from a previous step. |
| `propertiesJson` | code | Yes | — | JSON object of HubSpot ticket properties to update (e.g. `hs_pipeline_stage`). Only the keys you include are changed. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `ticket` | json | Updated ticket |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "hubspot/update-ticket",
"config": {
"ticketId": "",
"propertiesJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Hubspot integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`ticketId`, `propertiesJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Workflow blocks
URL: /reference/blocks
Type: reference
Description: Reference for every block you can add in the Workflow Builder, generated from the block registry.
Keywords: blocks, workflow builder, reference, actions, triggers
Every block you can add in the Workflow Builder, with its configurable fields, outputs, and limits. Pages are generated from the block registry, so they stay in sync with the product.
{/* TODO(docs): assist-mode trigger/output and the human-review draft block are omitted pending a UI label rename (DOCS-003). */}
Triggers [#triggers]
| Block | What it does |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| [Conversation Message](/reference/blocks/trigger-conversation-message) | Trigger workflow when a customer sends a new message on a Zendesk messaging channel (Sunshine Conversations). |
| [Gmail](/reference/blocks/trigger-gmail) | Trigger workflow when new emails are received in Gmail |
| [Google Sheets](/reference/blocks/trigger-google-sheets) | Trigger workflow when Google Sheets data changes |
| [Outlook](/reference/blocks/trigger-outlook) | Trigger workflow when new emails are received in Outlook |
| [RSS Feed](/reference/blocks/trigger-rss) | Trigger workflow when new items are published to an RSS feed |
| [Schedule](/reference/blocks/trigger-schedule) | Trigger workflow on a cron schedule |
| [Webhook](/reference/blocks/trigger-webhook) | Trigger workflow via HTTP webhook |
Logic & control [#logic--control]
| Block | What it does |
| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| [Validate Response Links](/reference/blocks/automation-validate-response-links) | Check that all URLs in a response are from allowed KB sources |
| [Write Audit Log](/reference/blocks/automation-write-audit-log) | Persist an audit record for automated ticket actions |
| [Condition](/reference/blocks/system-condition) | Branch the workflow based on a boolean expression |
| [Database Query](/reference/blocks/system-database-query) | Execute SQL queries against your database |
| [Delay](/reference/blocks/system-delay) | Pause the workflow for up to 30 seconds before continuing the next step. |
| [Function](/reference/blocks/system-function) | Run custom JavaScript code within your workflow |
| [Guardrails](/reference/blocks/system-guardrails) | Validate outputs, detect hallucinations/PII |
| [HTTP Request](/reference/blocks/system-http-request) | Make HTTP requests to any API endpoint |
| [Loop](/reference/blocks/system-loop) | Iterate over items, a fixed count, or while a condition is true |
| [Merge](/reference/blocks/system-merge) | Reconnect branches after a Condition or Router. Runs when at least one predecessor executed; passes through the active branch's output. |
| [Parallel](/reference/blocks/system-parallel) | Execute a branch once per item and then continue after join |
| [HTTP Response](/reference/blocks/system-response) | Sends a structured HTTP reply (body, status, headers) back to the caller. Use as the final step of an API-triggered workflow. |
| [Router](/reference/blocks/system-router) | Branch into N paths via boolean predicates or AI classification. |
| [Transform](/reference/blocks/system-transform) | Transform and reshape data between steps |
AI [#ai]
| Block | What it does |
| --------------------------------------------------------- | ---------------------------------------------------- |
| [Classify](/reference/blocks/ai-classify) | Classify content into predefined categories using AI |
| [Generate Text](/reference/blocks/ai-generate-text) | Generate text using AI models |
| [Transcribe Audio](/reference/blocks/ai-transcribe-audio) | Convert audio files to text using speech-to-text AI |
Integrations [#integrations]
| Block | What it does |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Search Knowledge Base](/reference/blocks/context-engine-search-knowledge-base) | Search synced knowledge base documents using semantic search with automatic reranking |
| [Execute SQL Statement](/reference/blocks/databricks-execute-sql-statement) | Run a read-only SQL statement against a Databricks SQL warehouse |
| [List SQL Warehouses](/reference/blocks/databricks-list-sql-warehouses) | List available Databricks SQL warehouses |
| [Test Databricks Connection](/reference/blocks/databricks-test-connection) | Verify Databricks connectivity and SQL warehouse visibility |
| [Scrape URL](/reference/blocks/firecrawl-scrape) | Scrape content from a URL |
| [Search Web](/reference/blocks/firecrawl-search) | Search the web with Firecrawl |
| [Add Label](/reference/blocks/gmail-add-label) | Add label(s) to a Gmail message |
| [Archive Email](/reference/blocks/gmail-archive-email) | Archive a Gmail message (remove INBOX label) |
| [Delete Email](/reference/blocks/gmail-delete-email) | Delete a Gmail message |
| [Draft Email](/reference/blocks/gmail-draft-email) | Create a draft email in Gmail |
| [Mark as Read](/reference/blocks/gmail-mark-read) | Mark a Gmail message as read |
| [Mark as Unread](/reference/blocks/gmail-mark-unread) | Mark a Gmail message as unread |
| [Move Email](/reference/blocks/gmail-move-email) | Move a Gmail message to a label |
| [Read Email](/reference/blocks/gmail-read-email) | Read a Gmail message by ID |
| [Remove Label](/reference/blocks/gmail-remove-label) | Remove label(s) from a Gmail message |
| [Search Email](/reference/blocks/gmail-search-email) | Search Gmail messages with a query |
| [Send Email](/reference/blocks/gmail-send-email) | Send an email via Gmail |
| [Append to Google Doc](/reference/blocks/google-docs-append) | Add content to the end of a Google Doc |
| [Read Google Doc](/reference/blocks/google-docs-read-document) | Read a Google Doc and return plain text |
| [Replace Google Doc Contents](/reference/blocks/google-docs-replace) | Overwrite the entire body of a Google Doc |
| [Google Drive: Read File](/reference/blocks/google-drive-read-file) | Read Google Docs/Sheets or download files and return text |
| [Append Row to Google Sheet](/reference/blocks/google-sheets-append-row) | Add new rows to the end of a sheet |
| [Read from Google Sheet](/reference/blocks/google-sheets-read-rows) | Read rows from a Google Sheet range |
| [Update Row in Google Sheet](/reference/blocks/google-sheets-update-row) | Overwrite cells at a specific range (e.g. Sheet1!A2:E2) |
| [Create Company](/reference/blocks/hubspot-create-company) | Create a HubSpot company |
| [Create Contact](/reference/blocks/hubspot-create-contact) | Create a HubSpot contact |
| [Create Ticket](/reference/blocks/hubspot-create-ticket) | Create a ticket in HubSpot |
| [Get Companies](/reference/blocks/hubspot-get-companies) | List HubSpot companies (or fetch one by ID/domain) |
| [Get Contacts](/reference/blocks/hubspot-get-contacts) | List HubSpot contacts (or fetch one by ID/email) |
| [Get Deals](/reference/blocks/hubspot-get-deals) | List deals in HubSpot |
| [Get Ticket](/reference/blocks/hubspot-get-ticket) | Get a ticket by ID in HubSpot |
| [Get Users](/reference/blocks/hubspot-get-users) | List users/owners in HubSpot |
| [Search Companies](/reference/blocks/hubspot-search-companies) | Search HubSpot companies |
| [Search Contacts](/reference/blocks/hubspot-search-contacts) | Search HubSpot contacts |
| [Search Tickets](/reference/blocks/hubspot-search-tickets) | Search tickets in HubSpot |
| [Update Company](/reference/blocks/hubspot-update-company) | Update a HubSpot company |
| [Update Contact](/reference/blocks/hubspot-update-contact) | Update a HubSpot contact |
| [Update Ticket](/reference/blocks/hubspot-update-ticket) | Update a ticket in HubSpot |
| [Create Contact](/reference/blocks/intercom-create-contact) | Create a contact in Intercom |
| [Create Ticket](/reference/blocks/intercom-create-ticket) | Create a ticket in Intercom |
| [Delete Contact](/reference/blocks/intercom-delete-contact) | Delete a contact in Intercom |
| [Get Contact](/reference/blocks/intercom-get-contact) | Get a contact by Intercom ID |
| [Get Conversation](/reference/blocks/intercom-get-conversation) | Get a conversation by ID |
| [Get Ticket](/reference/blocks/intercom-get-ticket) | Get a ticket by ID in Intercom |
| [List Admins](/reference/blocks/intercom-list-admins) | List the admins (teammates) in your Intercom workspace and return them for downstream use. |
| [List Contacts](/reference/blocks/intercom-list-contacts) | List contacts in Intercom |
| [Reply to Conversation](/reference/blocks/intercom-reply-conversation) | Reply to an Intercom conversation |
| [Search Contacts](/reference/blocks/intercom-search-contacts) | Search contacts in Intercom |
| [Update Contact](/reference/blocks/intercom-update-contact) | Update a contact in Intercom |
| [Create Ticket](/reference/blocks/linear-create-ticket) | Create an issue in Linear |
| [Find Issues](/reference/blocks/linear-find-issues) | Search for issues in Linear with optional filters |
| [Update Issue](/reference/blocks/linear-update-issue) | Update an issue in Linear |
| [Send Email](/reference/blocks/resend-send-email) | Send an email via Resend |
| [ServiceNow](/reference/blocks/servicenow-record) | Create, read, update, and delete ServiceNow records |
| [Shopify](/reference/blocks/shopify-manage) | Manage products, orders, customers, and inventory in your Shopify store |
| [Send Slack Message](/reference/blocks/slack-send-message) | Send a message to a Slack channel |
| [Add Comment / Reply](/reference/blocks/zendesk-add-comment) | Add a public reply or internal note to a ticket |
| [Add Tags](/reference/blocks/zendesk-add-tags) | Add tags to a ticket for classification and tracking |
| [Apply Macro](/reference/blocks/zendesk-apply-macro) | Apply a predefined macro to a ticket |
| [Assign Ticket](/reference/blocks/zendesk-assign-ticket) | Assign a ticket to an agent or group |
| [Close Ticket](/reference/blocks/zendesk-close-ticket) | Mark a ticket as solved with optional closing message |
| [Create Custom Object Record](/reference/blocks/zendesk-create-custom-object-record) | Create a new custom object record |
| [Create Ticket](/reference/blocks/zendesk-create-ticket) | Create a new Zendesk ticket |
| [Create User](/reference/blocks/zendesk-create-user) | Create a new Zendesk user |
| [Delete Custom Object Record](/reference/blocks/zendesk-delete-custom-object-record) | Delete a custom object record by ID |
| [Get Conversation](/reference/blocks/zendesk-get-conversation) | Fetch a Sunshine Conversations conversation, including current switchboard control. |
| [Get Custom Object Record](/reference/blocks/zendesk-get-custom-object-record) | Fetch a Zendesk custom object record by ID |
| [Get Organization](/reference/blocks/zendesk-get-organization) | Get organization details for B2B context |
| [Get Ticket](/reference/blocks/zendesk-get-ticket) | Fetch a Zendesk ticket by ID and return its full data object for downstream use. |
| [Get Ticket Comments](/reference/blocks/zendesk-get-ticket-comments) | Get conversation history for a ticket |
| [Get Ticket Context](/reference/blocks/zendesk-get-ticket-context) | Get complete ticket context (ticket, conversation, customer, assignee, organization) optimized for AI |
| [Get User](/reference/blocks/zendesk-get-user) | Fetch a Zendesk user by ID |
| [Get User Tickets](/reference/blocks/zendesk-get-user-tickets) | Get ticket history for a customer |
| [List Agents](/reference/blocks/zendesk-list-agents) | Get available agents for ticket assignment |
| [List Custom Objects](/reference/blocks/zendesk-list-custom-objects) | List all custom object definitions in the Zendesk account |
| [List Groups](/reference/blocks/zendesk-list-groups) | Get all available groups for routing tickets |
| [List Macros](/reference/blocks/zendesk-list-macros) | Get available macros for ticket automation |
| [Pass Conversation Control](/reference/blocks/zendesk-pass-conversation-control) | Pass switchboard control to another integration (e.g. escalate to a human agent). |
| [Post Conversation Message](/reference/blocks/zendesk-post-conversation-message) | Send a business-authored message on a Sunshine Conversations conversation (messaging channels). |
| [Release Conversation Control](/reference/blocks/zendesk-release-conversation-control) | Release switchboard control back to the default integration (per marketplace bot SHOULD). |
| [Remove Tags](/reference/blocks/zendesk-remove-tags) | Remove tags from a ticket |
| [Search Custom Object Records](/reference/blocks/zendesk-search-custom-object-records) | Search custom object records by query string |
| [Search Tickets](/reference/blocks/zendesk-search-tickets) | Search for Zendesk tickets |
| [Set Lookup Field](/reference/blocks/zendesk-set-lookup-field) | Set a lookup relationship field on a ticket to a custom object record by ID, name, or external ID |
| [Set Ticket Priority](/reference/blocks/zendesk-set-ticket-priority) | Set the priority level on a Zendesk ticket (low, normal, high, or urgent). |
| [Set Ticket Type](/reference/blocks/zendesk-set-ticket-type) | Set ticket type (problem, incident, question, task) |
| [Update Custom Object Record](/reference/blocks/zendesk-update-custom-object-record) | Update an existing custom object record |
| [Update Ticket](/reference/blocks/zendesk-update-ticket) | Update ticket with comment, status, tags, priority in one API call. Comment text supports markdown — see the Comment field description for the rendering contract. |
| [Upsert Custom Object Record](/reference/blocks/zendesk-upsert-custom-object-record) | Create or update a custom object record by external ID or name |
Related [#related]
* [Workflow Builder overview](/workflow-builder-overview)
* [Workflow Builder configuration](/workflow-builder-configuration)
---
# Create Contact
URL: /reference/blocks/intercom-create-contact
Type: reference
Description: Create a contact in Intercom
Keywords: create contact, intercom/create-contact, integrations, intercom, block, workflow builder
`intercom/create-contact` — Create a contact in Intercom.
Where it appears [#where-it-appears]
The **Create Contact** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `role` | select | No | `user` | Intercom contact role: User (an identified, signed-up person) or Lead (an unidentified prospect). Defaults to User. Options: `user`, `lead`. |
| `email` | text (supports references) | No | — | Email address for the Intercom contact. Accepts literal text or \ to reference a value from a previous step. |
| `name` | text (supports references) | No | — | Display name for the Intercom contact. Accepts literal text or \. |
| `phone` | text (supports references) | No | — | Optional phone number for the contact, in E.164 format. Accepts literal text or \. |
| `customAttributesJson` | code | No | — | Optional JSON object of custom data attributes to set on the contact (e.g. `{"plan":"pro"}`). Keys must match custom attributes defined in your Intercom workspace. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `contact` | json | Created contact |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/create-contact",
"config": {
"role": "user"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Create Ticket
URL: /reference/blocks/intercom-create-ticket
Type: reference
Description: Create a ticket in Intercom
Keywords: create ticket, intercom/create-ticket, integrations, intercom, block, workflow builder
`intercom/create-ticket` — Create a ticket in Intercom.
Where it appears [#where-it-appears]
The **Create Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | ---- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `ticketJson` | code | Yes | — | Intercom Create Ticket API request body as JSON, including `ticket_type_id`, the associated `contacts`, and ticket attributes such as `title`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `ticket` | json | Created ticket |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/create-ticket",
"config": {
"ticketJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`ticketJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Delete Contact
URL: /reference/blocks/intercom-delete-contact
Type: reference
Description: Delete a contact in Intercom
Keywords: delete contact, intercom/delete-contact, integrations, intercom, block, workflow builder
`intercom/delete-contact` — Delete a contact in Intercom.
Where it appears [#where-it-appears]
The **Delete Contact** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| `contactId` | text (supports references) | Yes | — | Intercom contact ID to act on. Use a literal ID or \ to reference an ID from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `deleted` | boolean | Contact was deleted |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/delete-contact",
"config": {
"contactId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`contactId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Contact
URL: /reference/blocks/intercom-get-contact
Type: reference
Description: Get a contact by Intercom ID
Keywords: get contact, intercom/get-contact, integrations, intercom, block, workflow builder
`intercom/get-contact` — Get a contact by Intercom ID.
Where it appears [#where-it-appears]
The **Get Contact** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| `contactId` | text (supports references) | Yes | — | Intercom contact ID to act on. Use a literal ID or \ to reference an ID from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `contact` | json | Contact data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/get-contact",
"config": {
"contactId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`contactId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Conversation
URL: /reference/blocks/intercom-get-conversation
Type: reference
Description: Get a conversation by ID
Keywords: get conversation, intercom/get-conversation, integrations, intercom, block, workflow builder
`intercom/get-conversation` — Get a conversation by ID.
Where it appears [#where-it-appears]
The **Get Conversation** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `conversationId` | text (supports references) | Yes | — | Intercom conversation ID to act on. Use a literal ID or \ to reference an ID from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| -------------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `conversation` | json | Conversation data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/get-conversation",
"config": {
"conversationId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`conversationId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Get Ticket
URL: /reference/blocks/intercom-get-ticket
Type: reference
Description: Get a ticket by ID in Intercom
Keywords: get ticket, intercom/get-ticket, integrations, intercom, block, workflow builder
`intercom/get-ticket` — Get a ticket by ID in Intercom.
Where it appears [#where-it-appears]
The **Get Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `ticketId` | text (supports references) | Yes | — | Intercom ticket ID to fetch. Use a literal ID or \ to reference an ID from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `ticket` | json | Ticket data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/get-ticket",
"config": {
"ticketId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`ticketId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# List Admins
URL: /reference/blocks/intercom-list-admins
Type: reference
Description: List the admins (teammates) in your Intercom workspace and return them for downstream use.
Keywords: list admins, intercom/list-admins, integrations, intercom, block, workflow builder
`intercom/list-admins` — List the admins (teammates) in your Intercom workspace and return them for downstream use.
Where it appears [#where-it-appears]
The **List Admins** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
This block has no configurable fields.
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `admins` | json | List of admins |
| `error` | string | Error message if failed |
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# List Contacts
URL: /reference/blocks/intercom-list-contacts
Type: reference
Description: List contacts in Intercom
Keywords: list contacts, intercom/list-contacts, integrations, intercom, block, workflow builder
`intercom/list-contacts` — List contacts in Intercom.
Where it appears [#where-it-appears]
The **List Contacts** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------- | ------ | -------- | ------- | -------------------------------------------------------------------- |
| `perPage` | number | No | `50` | Number of contacts to return per page from Intercom. Defaults to 50. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `contacts` | json | List of contacts |
| `pages` | json | Pagination info |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/list-contacts",
"config": {
"perPage": 50
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Reply to Conversation
URL: /reference/blocks/intercom-reply-conversation
Type: reference
Description: Reply to an Intercom conversation
Keywords: reply to conversation, intercom/reply-conversation, integrations, intercom, block, workflow builder
`intercom/reply-conversation` — Reply to an Intercom conversation.
Where it appears [#where-it-appears]
The **Reply to Conversation** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `conversationId` | text (supports references) | Yes | — | Intercom conversation ID to act on. Use a literal ID or \ to reference an ID from a previous step. |
| `message` | text (multi-line, supports references) | Yes | — | Reply text to post to the Intercom conversation. Use literal text or \ to reference upstream content such as a generated reply. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| -------------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `conversation` | json | Updated conversation |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/reply-conversation",
"config": {
"conversationId": "",
"message": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`conversationId`, `message`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Search Contacts
URL: /reference/blocks/intercom-search-contacts
Type: reference
Description: Search contacts in Intercom
Keywords: search contacts, intercom/search-contacts, integrations, intercom, block, workflow builder
`intercom/search-contacts` — Search contacts in Intercom.
Where it appears [#where-it-appears]
The **Search Contacts** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | ---- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `queryJson` | code | Yes | — | Intercom Search Contacts API request body as JSON, using a `query` object with `field`, `operator`, and `value` (and optional nested AND/OR groups). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `results` | json | Search results |
| `pages` | json | Pagination info |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/search-contacts",
"config": {
"queryJson": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`queryJson`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Update Contact
URL: /reference/blocks/intercom-update-contact
Type: reference
Description: Update a contact in Intercom
Keywords: update contact, intercom/update-contact, integrations, intercom, block, workflow builder
`intercom/update-contact` — Update a contact in Intercom.
Where it appears [#where-it-appears]
The **Update Contact** block lives in the **Integrations** group of the Workflow Builder. Connect the Intercom integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `contactId` | text (supports references) | Yes | — | Intercom contact ID to act on. Use a literal ID or \ to reference an ID from a previous step. |
| `email` | text (supports references) | No | — | Email address for the Intercom contact. Accepts literal text or \ to reference a value from a previous step. |
| `name` | text (supports references) | No | — | Display name for the Intercom contact. Accepts literal text or \. |
| `customAttributesJson` | code | No | — | Optional JSON object of custom data attributes to set on the contact (e.g. `{"plan":"pro"}`). Keys must match custom attributes defined in your Intercom workspace. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Operation succeeded |
| `contact` | json | Updated contact |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "intercom/update-contact",
"config": {
"contactId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Intercom integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`contactId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Create Ticket
URL: /reference/blocks/linear-create-ticket
Type: reference
Description: Create an issue in Linear
Keywords: create ticket, linear/create-ticket, integrations, linear, block, workflow builder
`linear/create-ticket` — Create an issue in Linear.
Where it appears [#where-it-appears]
The **Create Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Linear integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------- | -------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ticketTitle` | text (supports references) | Yes | — | Title of the Linear issue to create. Use literal text or \ to reference a value from a previous step. |
| `ticketDescription` | text (multi-line, supports references) | No | — | Optional description body for the Linear issue (supports Markdown). Use literal text or \. |
| `ticketPriority` | select | No | `2` | Linear priority for the issue, using Linear's scale (0 = No Priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low). Options: `0`, `1`, `2`, `3`, `4`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | --------------------------------------- |
| `success` | boolean | Whether ticket was created successfully |
| `issueId` | string | Created issue ID |
| `issueUrl` | string | URL to the created issue |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "linear/create-ticket",
"config": {
"ticketTitle": "",
"ticketPriority": "2"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Linear integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`ticketTitle`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Find Issues
URL: /reference/blocks/linear-find-issues
Type: reference
Description: Search for issues in Linear with optional filters
Keywords: find issues, linear/find-issues, integrations, linear, block, workflow builder
`linear/find-issues` — Search for issues in Linear with optional filters.
Where it appears [#where-it-appears]
The **Find Issues** block lives in the **Integrations** group of the Workflow Builder. Connect the Linear integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------ | -------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `linearAssigneeId` | text (supports references) | No | — | Optional Linear user ID to filter issues by assignee. Accepts a literal ID or \. |
| `linearTeamId` | text (supports references) | No | — | Optional Linear team ID to limit the search to a single team. Accepts a literal ID or \. |
| `linearStatus` | select | No | `any` | Optional workflow-state category to filter issues by. Select Any to include all statuses. Options: `any`, `backlog`, `todo`, `in_progress`, `done`, `canceled`, `duplicate`. |
| `linearLabel` | text (supports references) | No | — | Optional Linear label name to filter issues by. Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ------------------------ |
| `success` | boolean | Whether search succeeded |
| `issues` | array | Array of matching issues |
| `count` | number | Number of issues found |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "linear/find-issues",
"config": {
"linearStatus": "any"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Linear integration. Calls fail if that integration is disconnected or its authorization has expired.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Update Issue
URL: /reference/blocks/linear-update-issue
Type: reference
Description: Update an issue in Linear
Keywords: update issue, linear/update-issue, integrations, linear, block, workflow builder
`linear/update-issue` — Update an issue in Linear.
Where it appears [#where-it-appears]
The **Update Issue** block lives in the **Integrations** group of the Workflow Builder. Connect the Linear integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------- | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `issueId` | text (supports references) | Yes | — | ID of the Linear issue to update. Use a literal ID or \ to reference an ID from a previous step. |
| `ticketTitle` | text (supports references) | No | — | Optional new title for the issue. Leave blank to keep the current title. Accepts literal text or \. |
| `ticketDescription` | text (multi-line, supports references) | No | — | Optional new description body for the issue (supports Markdown). Leave blank to keep the current description. Accepts literal text or \. |
| `linearStatus` | select | No | — | Optional new workflow-state category for the issue. Leave unset to keep the current status. Options: `backlog`, `todo`, `in_progress`, `done`, `canceled`, `duplicate`. |
| `ticketPriority` | select | No | — | Optional new priority using Linear's scale (0 = No Priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low). Leave unset to keep the current priority. Options: `0`, `1`, `2`, `3`, `4`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | -------------------------------------- |
| `success` | boolean | Whether issue was updated successfully |
| `issueId` | string | Updated issue ID |
| `issueUrl` | string | URL to the updated issue |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "linear/update-issue",
"config": {
"issueId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Linear integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`issueId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Send Email
URL: /reference/blocks/resend-send-email
Type: reference
Description: Send an email via Resend
Keywords: send email, resend/send-email, integrations, resend, block, workflow builder
`resend/send-email` — Send an email via Resend.
Where it appears [#where-it-appears]
The **Send Email** block lives in the **Integrations** group of the Workflow Builder. Connect the Resend integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------------- | -------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `emailTo` | text (supports references) | Yes | — | Recipient email address for the message sent via Resend. Use literal text or \ to reference an address from a previous step. |
| `emailReplyTo` | text (supports references) | No | — | Optional Reply-To address; replies from the recipient go here instead of the sender. Accepts literal text or \. |
| `emailSubject` | text (supports references) | Yes | — | Subject line of the email. Use literal text or \ to reference a value from a previous step. |
| `emailBody` | text (multi-line, supports references) | Yes | — | Body content of the email. Use literal text or \ to reference upstream content such as a generated reply. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------------------- |
| `success` | boolean | Whether email was sent successfully |
| `id` | string | Message ID from Resend |
| `error` | string | Error message if sending failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "resend/send-email",
"config": {
"emailTo": "",
"emailSubject": "",
"emailBody": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Resend integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`emailTo`, `emailSubject`, `emailBody`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# ServiceNow
URL: /reference/blocks/servicenow-record
Type: reference
Description: Create, read, update, and delete ServiceNow records
Keywords: servicenow, servicenow/record, integrations, block, workflow builder
`servicenow/record` — Create, read, update, and delete ServiceNow records.
Where it appears [#where-it-appears]
The **ServiceNow** block lives in the **Integrations** group of the Workflow Builder. Connect the Servicenow integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `operation` | select | Yes | — | Which CRUD action to perform against the ServiceNow table. The remaining fields shown depend on this choice. Options: `servicenow_create_record`, `servicenow_read_record`, `servicenow_update_record`, `servicenow_delete_record`. |
| `tableName` | text (supports references) | Yes | — | ServiceNow table to operate on, given by its API name (e.g. `incident`, `change_request`, `sys_user`). Accepts literal text or \. |
| `createFields` | code | No | — | JSON object of field names to values for the new record, matching the columns of the chosen table (e.g. `short_description`, `priority`). |
| `readSysId` | text (supports references) | No | — | Optional sys\_id of a single record to read. Leave empty to read multiple records matched by the Query. Accepts literal text or \. |
| `query` | text (supports references) | No | — | Optional ServiceNow encoded query to filter records (e.g. `active=true^priority=1`). Accepts literal text or \. |
| `updateSysId` | text (supports references) | Yes | — | sys\_id of the record to update. Use a literal sys\_id or \ from a previous step. |
| `updateFields` | code | No | — | JSON object of field names to new values to apply to the record. Only the keys you include are changed. |
| `deleteSysId` | text (supports references) | Yes | — | sys\_id of the record to delete. Use a literal sys\_id or \ from a previous step. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------- | --------------------------- |
| `success` | boolean | Operation success status |
| `record` | json | Single ServiceNow record |
| `records` | json | Array of ServiceNow records |
| `metadata` | json | Operation metadata |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "servicenow/record",
"config": {
"operation": "servicenow_create_record",
"tableName": "",
"updateSysId": "",
"deleteSysId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Servicenow integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`operation`, `tableName`, `updateSysId`, `deleteSysId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Shopify
URL: /reference/blocks/shopify-manage
Type: reference
Description: Manage products, orders, customers, and inventory in your Shopify store
Keywords: shopify, shopify/manage, integrations, block, workflow builder
`shopify/manage` — Manage products, orders, customers, and inventory in your Shopify store.
Where it appears [#where-it-appears]
The **Shopify** block lives in the **Integrations** group of the Workflow Builder. Connect the Shopify integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `operation` | select | Yes | — | Which Shopify action to perform across products, orders, customers, inventory, locations, fulfillments, and collections. The other fields apply based on this choice. Options: `shopify_create_product`, `shopify_get_product`, `shopify_list_products`, `shopify_update_product`, `shopify_delete_product`, `shopify_get_order`, `shopify_list_orders`, `shopify_update_order`, `shopify_cancel_order`, `shopify_create_customer`, `shopify_get_customer`, `shopify_list_customers`, `shopify_update_customer`, `shopify_delete_customer`, `shopify_list_inventory_items`, `shopify_get_inventory_level`, `shopify_adjust_inventory`, `shopify_list_locations`, `shopify_create_fulfillment`, `shopify_list_collections`, `shopify_get_collection`. |
| `resourceId` | text (supports references) | No | — | The ID of the resource to operate on (when applicable) |
| `propertiesJson` | code | No | — | Properties for create/update operations |
| `searchQuery` | text (supports references) | No | — | Search query for list operations |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ------------------------ |
| `success` | boolean | Operation success status |
| `result` | json | Operation result data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "shopify/manage",
"config": {
"operation": "shopify_create_product"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Shopify integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`operation`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Send Slack Message
URL: /reference/blocks/slack-send-message
Type: reference
Description: Send a message to a Slack channel
Keywords: send slack message, slack/send-message, integrations, slack, block, workflow builder
`slack/send-message` — Send a message to a Slack channel.
Where it appears [#where-it-appears]
The **Send Slack Message** block lives in the **Integrations** group of the Workflow Builder. Connect the Slack integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------------- | -------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `slackChannel` | text (supports references) | Yes | — | Target Slack channel, given as a `#channel-name` or a channel ID (e.g. `C01234567`). Use literal text or \. |
| `slackMessage` | text (multi-line, supports references) | Yes | — | Text of the Slack message to post. Supports Slack mrkdwn formatting. Use literal text or \ to reference upstream content. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ------------------------------------- |
| `success` | boolean | Whether message was sent successfully |
| `ts` | string | Timestamp of the message |
| `channel` | string | Channel where message was sent |
| `error` | string | Error message if sending failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "slack/send-message",
"config": {
"slackChannel": "",
"slackMessage": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Slack integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`slackChannel`, `slackMessage`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Condition
URL: /reference/blocks/system-condition
Type: reference
Description: Branch the workflow based on a boolean expression
Keywords: condition, system/condition, system, block, workflow builder
`system/condition` — Branch the workflow based on a boolean expression.
Where it appears [#where-it-appears]
The **Condition** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | ---------- | -------- | ------- | ----------------------------------------------------------- |
| `condition` | conditions | Yes | — | Boolean expression evaluated against upstream node outputs. |
Operators: ===, !==, >, \<, >=, \<=, !, &&, ||
Methods: .includes(), .startsWith(), .endsWith(), .toLowerCase()
Helpers: containsAny, containsAll, isOneOf, isNoneOf, matches, isPresent, isEmpty |
\| `trueLabel` | text | No | `True` | Display name for the branch taken when the condition evaluates to true. Shown on the canvas edge and in logs. |
\| `falseLabel` | text | No | `False` | Display name for the branch taken when the condition evaluates to false. Shown on the canvas edge and in logs. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------ | ------- | ---------------- |
| `condition` | boolean | Condition result |
| `route` | string | Selected route |
| `routeLabel` | string | Route label |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/condition",
"config": {
"condition": "",
"trueLabel": "True",
"falseLabel": "False"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`condition`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Database Query
URL: /reference/blocks/system-database-query
Type: reference
Description: Execute SQL queries against your database
Keywords: database query, system/database-query, system, database, block, workflow builder
`system/database-query` — Execute SQL queries against your database.
Where it appears [#where-it-appears]
The **Database Query** block lives in the **Logic & control** group of the Workflow Builder. Connect the Database integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------- | ----------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dbQuery` | code | Yes | — | SQL run against the connected database. Use positional placeholders like $1 for parameterized values rather than interpolating untrusted input directly. Returned rows are exposed on the `rows` output. |
| `dbSchema` | JSON schema | No | — | Optional declaration of the shape of each returned row, so downstream steps can reference typed fields (under the `rows` prefix). Leave empty to return rows untyped. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------- |
| `success` | boolean | Whether query succeeded |
| `rows` | array | Query result rows |
| `count` | number | Row count |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/database-query",
"config": {
"dbQuery": "..."
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Database integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`dbQuery`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Delay
URL: /reference/blocks/system-delay
Type: reference
Description: Pause the workflow for up to 30 seconds before continuing the next step.
Keywords: delay, system/delay, system, block, workflow builder
`system/delay` — Pause the workflow for up to 30 seconds before continuing the next step.
Where it appears [#where-it-appears]
The **Delay** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------- |
| `delayMs` | text (supports references) | Yes | `5000` | Delay in milliseconds. Maximum 30000 (30 seconds). Accepts a number or a \ reference. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ---------------------------------------------------- |
| `success` | boolean | Whether the delay completed |
| `delayMs` | number | Effective delay in milliseconds (clamped to 0–30000) |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/delay",
"config": {
"delayMs": "5000"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`delayMs`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Function
URL: /reference/blocks/system-function
Type: reference
Description: Run custom JavaScript code within your workflow
Keywords: function, system/function, system, block, workflow builder
`system/function` — Run custom JavaScript code within your workflow.
Where it appears [#where-it-appears]
The **Function** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------- | -------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inputData` | text (multi-line, supports references) | No | — | Data to expose to your code as `input.inputData`. If you reference a single upstream object/array, it's passed through as-is; otherwise the JSON is parsed. |
| `code` | code | Yes | — | JavaScript executed at this step. Read the Input Data field via `input.inputData` and `return` a value, which becomes the block's `result` output for downstream steps. |
| `timeout` | text | No | `5000` | Maximum execution time. Values above 10000ms are clamped. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | -------------------------------------------------- |
| `result` | json | Return value from the executed JavaScript function |
| `stdout` | string | Console log output from function execution |
| `success` | boolean | Whether function executed successfully |
| `error` | string | Error message if execution failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/function",
"config": {
"code": "...",
"timeout": "5000"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`code`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Guardrails
URL: /reference/blocks/system-guardrails
Type: reference
Description: Validate outputs, detect hallucinations/PII
Keywords: guardrails, system/guardrails, system, block, workflow builder
`system/guardrails` — Validate outputs, detect hallucinations/PII.
Where it appears [#where-it-appears]
The **Guardrails** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------- | ---- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payload` | code | No | — | JSON payload the guardrails run against to detect hallucinations and PII. Use \ to pass in upstream content (e.g. a generated draft). Leave empty to check the default upstream output. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------------- | ------- | ------------------------- |
| `success` | boolean | Whether guardrails passed |
| `policy` | json | Policy applied |
| `redactedPayload` | json | Redacted payload |
| `warnings` | array | Warnings array |
| `error` | string | Error if failed |
Limits and failure modes [#limits-and-failure-modes]
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# HTTP Request
URL: /reference/blocks/system-http-request
Type: reference
Description: Make HTTP requests to any API endpoint
Keywords: http request, system/http-request, system, block, workflow builder
`system/http-request` — Make HTTP requests to any API endpoint.
Where it appears [#where-it-appears]
The **HTTP Request** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------- | -------------------------- | -------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `httpMethod` | select | Yes | `GET` | The HTTP verb used for the request. For GET and DELETE the request body is typically omitted; POST/PUT/PATCH send the configured body. Options: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`. |
| `endpoint` | text (supports references) | Yes | — | Full URL. Any params already in the query string are preserved; the Query Params field below is merged on top. |
| `queryParams` | code | No | `{}` | JSON object of query parameters to append to the URL — e.g. \{"page": 1, "limit": 50}. Values can reference upstream outputs via \. |
| `httpHeaders` | code | No | `{}` | JSON object of request headers — e.g. \{"Authorization": "Bearer ..."}. Values can reference upstream outputs via \. |
| `httpBody` | code | No | `{}` | JSON request body sent with POST, PUT, and PATCH requests. Values can reference upstream outputs via \. |
| `timeout` | text | No | `30000` | Request timeout in milliseconds. Default 30000 (30s). Maximum 60000 (60s). |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ------------------------- |
| `success` | boolean | Whether request succeeded |
| `status` | number | HTTP status code |
| `data` | any | Response data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/http-request",
"config": {
"httpMethod": "GET",
"endpoint": "",
"queryParams": "{}",
"httpHeaders": "{}",
"httpBody": "{}",
"timeout": "30000"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`httpMethod`, `endpoint`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Loop
URL: /reference/blocks/system-loop
Type: reference
Description: Iterate over items, a fixed count, or while a condition is true
Keywords: loop, system/loop, system, block, workflow builder
`system/loop` — Iterate over items, a fixed count, or while a condition is true.
Where it appears [#where-it-appears]
The **Loop** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------------- | -------------------------------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loopType` | select | No | `forEach` | How the loop decides when to stop. For Each iterates over an array, Repeat N Times runs a fixed count, While checks a condition before each iteration, and Do-While runs once before checking. The other fields shown depend on this choice. Options: `forEach`, `forLoop`, `while`, `doWhile`. |
| `items` | text (multi-line, supports references) | Yes | — | The array to iterate over, one iteration per element. Accepts a literal JSON array or a \ reference to an upstream array output. |
| `iterations` | text (supports references) | No | — | Number of iterations to run. Accepts a fixed number or \ reference. |
| `condition` | conditions | Yes | — | Boolean expression evaluated each iteration. Loop continues while truthy. Operators: ===, !==, >, \<, >=, \<=, !, &&, \|\| |
| `maxIterations` | text | No | `100` | Hard cap to prevent infinite loops. Loop exits once this count is reached even if the condition is still true. |
| `errorPolicy` | select | No | `stop` | What happens when an iteration throws an error. Stop halts the whole workflow; Continue lets execution proceed down the loop's exit path. Options: `stop`, `continue`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------ | ------ | ------------------------------ |
| `items` | array | Items iterated over |
| `iterations` | number | Number of iterations executed |
| `results` | array | Array of all iteration results |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/loop",
"config": {
"loopType": "forEach",
"items": "",
"condition": "",
"maxIterations": "100",
"errorPolicy": "stop"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`items`, `condition`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Merge
URL: /reference/blocks/system-merge
Type: reference
Description: Reconnect branches after a Condition or Router. Runs when at least one predecessor executed; passes through the active branch's output.
Keywords: merge, system/merge, system, block, workflow builder
`system/merge` — Reconnect branches after a Condition or Router. Runs when at least one predecessor executed; passes through the active branch's output.
Where it appears [#where-it-appears]
The **Merge** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
This block has no configurable fields.
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success` | boolean | True when at least one predecessor executed successfully. False is never observed in practice — the block is skipped if all predecessors were skipped. |
| `source` | string | Node id of the predecessor whose output is exposed via `data`. When multiple predecessors executed, the topologically-first one wins. |
| `data` | json | Pass-through of the selected predecessor's `data` field, or its full output object if the predecessor did not declare a `data` output. |
| `executedSources` | array | Node ids of all predecessors that executed, in topological order. Useful for observability and for downstream function blocks that need to know which branches fired. |
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Parallel
URL: /reference/blocks/system-parallel
Type: reference
Description: Execute a branch once per item and then continue after join
Keywords: parallel, system/parallel, system, block, workflow builder
`system/parallel` — Execute a branch once per item and then continue after join.
Where it appears [#where-it-appears]
The **Parallel** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------- | -------------------------------------- | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `items` | text (multi-line, supports references) | Yes | — | The array fanned out across branches — one branch runs per element. Accepts a literal JSON array or a \ reference to an upstream array output. |
| `maxBranches` | text (supports references) | No | — | Hard cap on total branches. Items beyond this index are skipped — useful as a safety net when the input array could be unexpectedly large. Default: 100. |
| `concurrency` | text (supports references) | No | — | How many branches run at the same time. Subsequent branches start as in-flight branches finish, until all branches complete. Lower this to throttle downstream APIs. Default: 5. |
| `joinPolicy` | select | No | `allSuccess` | How the join after the branches behaves. All Success only continues past the join if every branch succeeded; Always continues regardless of branch failures. Options: `allSuccess`, `always`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ---------- | ------ | --------------------------- |
| `items` | array | Items iterated over |
| `branches` | number | Number of branches executed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/parallel",
"config": {
"items": "",
"joinPolicy": "allSuccess"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`items`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# HTTP Response
URL: /reference/blocks/system-response
Type: reference
Description: Sends a structured HTTP reply (body, status, headers) back to the caller. Use as the final step of an API-triggered workflow.
Keywords: http response, system/response, system, block, workflow builder
`system/response` — Sends a structured HTTP reply (body, status, headers) back to the caller. Use as the final step of an API-triggered workflow.
Where it appears [#where-it-appears]
The **HTTP Response** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------- | ---- | -------- | ------- | ----------------------------------------------------------------------------------- |
| `data` | code | Yes | — | JSON response body. Use \ to inject values from previous nodes. |
| `status` | text | No | `200` | HTTP status code (default: 200) |
| `headers` | code | No | — | Additional HTTP headers to include in the response |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ----------------------------------------------- |
| `data` | json | Response body |
| `status` | number | HTTP status code |
| `headers` | json | Response headers |
| `success` | boolean | Whether the response was formatted successfully |
| `error` | string | Error message if formatting failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/response",
"config": {
"data": "...",
"status": "200"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`data`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Router
URL: /reference/blocks/system-router
Type: reference
Description: Branch into N paths via boolean predicates or AI classification.
Keywords: router, system/router, system, block, workflow builder
`system/router` — Branch into N paths via boolean predicates or AI classification.
Where it appears [#where-it-appears]
The **Router** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------- | -------------------------------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `routerMode` | select | Yes | `predicate` | Predicate: each route has its own boolean expression; first match wins. AI: an LLM picks the route by description. Options: `predicate`, `ai`. |
| `prompt` | text (multi-line, supports references) | Yes | — | The text the LLM reads to decide which route to take. Use \ to pass in the content to classify (e.g. ticket subject, customer message). |
| `routes` | routes | Yes | — | Each route has its own outgoing branch. The Default branch fires when no route matches. |
| `defaultRouteLabel` | text | No | `Default` | Display name for the fallback branch that fires when no route condition matches. Shown on the canvas edge. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------ | ------- | ------------------------------------------------------------------------------------------------ |
| `matched` | boolean | true when one of the named routes fired; false when execution fell through to the Default branch |
| `route` | string | Selected route id (or "default" if none matched) |
| `routeLabel` | string | Selected route label |
| `reasoning` | string | AI reasoning (AI mode only) |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/router",
"config": {
"routerMode": "predicate",
"prompt": "",
"routes": "...",
"defaultRouteLabel": "Default"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`routerMode`, `prompt`, `routes`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Transform
URL: /reference/blocks/system-transform
Type: reference
Description: Transform and reshape data between steps
Keywords: transform, system/transform, system, block, workflow builder
`system/transform` — Transform and reshape data between steps.
Where it appears [#where-it-appears]
The **Transform** block lives in the **Logic & control** group of the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------------- | -------------------------------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inputData` | text (multi-line, supports references) | Yes | — | The data to reshape. Accepts a literal JSON value or a \ reference to an upstream output, which the selected transform is then applied to. |
| `transformType` | select | Yes | `extract` | The kind of reshape to apply to the input. Extract pulls a single field by path, Filter keeps only listed fields, Map renames fields, and Template formats the data as text. The configuration field shown below depends on this choice. Options: `extract`, `filter`, `map`, `template`. |
| `extractPath` | text | No | — | Dot/bracket path to the single value to pull out of the input — e.g. ticket.subject or items\[0].name. |
| `includeFields` | text (multi-line) | No | — | JSON array of top-level field names to keep from the input; all other fields are dropped from the output. |
| `fieldMappings` | text (multi-line) | No | — | JSON object mapping new output field names to source field names from the input — e.g. \{"ticketSubject": "subject"} reads input.subject and writes it as ticketSubject. |
| `outputTemplate` | text (multi-line, supports references) | No | — | Text template rendered with values from the input, where \{\{fieldName}} placeholders are replaced by the matching field. The rendered string becomes the transform's output. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | --------------------------- |
| `success` | boolean | Whether transform succeeded |
| `data` | any | Transformed data |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "system/transform",
"config": {
"inputData": "",
"transformType": "extract"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`inputData`, `transformType`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Conversation Message
URL: /reference/blocks/trigger-conversation-message
Type: reference
Description: Trigger workflow when a customer sends a new message on a Zendesk messaging channel (Sunshine Conversations).
Keywords: conversation message, trigger/conversation-message, triggers, trigger, block, workflow builder
`trigger/conversation-message` — Trigger workflow when a customer sends a new message on a Zendesk messaging channel (Sunshine Conversations).
Where it appears [#where-it-appears]
The **Conversation Message** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------------ | ------------ | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `channels` | multi-select | No | — | Limit to specific messaging channels. Leave all unchecked to fire on any channel. Options: `whatsapp`, `messenger`, `instagram`, `web`, `ios`, `android`, `twitter`, `line`, `viber`, `telegram`, `wechat`, `kakao`, `sms`, `googlebusinessmessages`, `applebusinesschat`. |
| `brandIds` | list | No | — | Limit to conversations on specific Zendesk brands. Leave empty to fire on any brand. |
| `firstMessageOnly` | toggle | No | `false` | Fire only on the first inbound message on a conversation (e.g. for auto-greet workflows). |
| `testInput` | code | No | — | Sample message-event JSON to use when running this workflow in test mode instead of waiting for a real inbound conversation message. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ------------------ | ------- | -------------------------------------------------- |
| `triggered` | boolean | Whether the trigger fired |
| `timestamp` | number | Trigger timestamp (epoch ms) |
| `conversationId` | string | Sunshine Conversations conversation ID |
| `ticketId` | string | Zendesk ticket ID resolved from the conversation |
| `messageId` | string | SC message ID |
| `messageText` | string | Message text body |
| `messageTimestamp` | string | ISO 8601 timestamp of the message |
| `authorUserId` | string | SC user ID of the message author |
| `channel` | string | SC channel type (e.g. whatsapp, web, messenger) |
| `brandId` | string | Zendesk brand ID, if available |
| `subdomain` | string | Zendesk subdomain |
| `webhookEventId` | string | Deduplication ID for the originating webhook event |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "trigger/conversation-message",
"config": {
"firstMessageOnly": false
}
}
```
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Gmail
URL: /reference/blocks/trigger-gmail
Type: reference
Description: Trigger workflow when new emails are received in Gmail
Keywords: gmail, trigger/gmail, triggers, google, block, workflow builder
`trigger/gmail` — Trigger workflow when new emails are received in Gmail.
Where it appears [#where-it-appears]
The **Gmail** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------------- | ------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `pollingInterval` | select | Yes | `5min` | How often Stylo checks the Gmail inbox for new messages. Options: `1min`, `5min`, `15min`, `30min`, `1hour`. |
| `searchQuery` | text | No | — | Gmail search syntax to filter which incoming emails trigger the workflow. Leave empty to fire on any new email. |
| `markAsRead` | toggle | No | `false` | When enabled, matched emails are marked as read in Gmail after triggering the workflow. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | --------------------------------------------------------------------- |
| `triggered` | boolean | Whether trigger fired |
| `timestamp` | string | Trigger timestamp |
| `email` | json | Email data (object — fields: `subject`, `from`, `to`, `body`, `date`) |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "trigger/gmail",
"config": {
"pollingInterval": "5min",
"markAsRead": false
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`pollingInterval`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Google Sheets
URL: /reference/blocks/trigger-google-sheets
Type: reference
Description: Trigger workflow when Google Sheets data changes
Keywords: google sheets, trigger/google-sheets, triggers, google, block, workflow builder
`trigger/google-sheets` — Trigger workflow when Google Sheets data changes.
Where it appears [#where-it-appears]
The **Google Sheets** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------------- | ------ | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
| `spreadsheetId` | text | Yes | — | The Google Sheets spreadsheet to watch, given as its ID or full URL. Changes to this spreadsheet trigger the workflow. |
| `sheetName` | text | No | — | Name of the specific tab within the spreadsheet to watch. Leave empty to watch the default sheet. |
| `pollingInterval` | select | Yes | `5min` | How often Stylo checks the spreadsheet for new or changed rows. Options: `1min`, `5min`, `15min`, `30min`, `1hour`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | ----------------------- |
| `triggered` | boolean | Whether trigger fired |
| `timestamp` | number | Trigger timestamp |
| `row` | json | New or changed row data |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "trigger/google-sheets",
"config": {
"spreadsheetId": "",
"pollingInterval": "5min"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Google integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`spreadsheetId`, `pollingInterval`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Outlook
URL: /reference/blocks/trigger-outlook
Type: reference
Description: Trigger workflow when new emails are received in Outlook
Keywords: outlook, trigger/outlook, triggers, microsoft, block, workflow builder
`trigger/outlook` — Trigger workflow when new emails are received in Outlook.
Where it appears [#where-it-appears]
The **Outlook** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------------- | ------ | -------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `pollingInterval` | select | Yes | `5min` | How often Stylo checks the Outlook mailbox for new messages. Options: `1min`, `5min`, `15min`, `30min`, `1hour`. |
| `searchQuery` | text | No | — | Search terms to filter which incoming emails trigger the workflow. Leave empty to fire on any new email. |
| `markAsRead` | toggle | No | `false` | When enabled, matched emails are marked as read in Outlook after triggering the workflow. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | --------------------------------------------------------------------- |
| `triggered` | boolean | Whether trigger fired |
| `timestamp` | string | Trigger timestamp |
| `email` | json | Email data (object — fields: `subject`, `from`, `to`, `body`, `date`) |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "trigger/outlook",
"config": {
"pollingInterval": "5min",
"markAsRead": false
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Microsoft integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required field (`pollingInterval`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# RSS Feed
URL: /reference/blocks/trigger-rss
Type: reference
Description: Trigger workflow when new items are published to an RSS feed
Keywords: rss feed, trigger/rss, triggers, trigger, block, workflow builder
`trigger/rss` — Trigger workflow when new items are published to an RSS feed.
Where it appears [#where-it-appears]
The **RSS Feed** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ----------------- | ------ | -------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| `feedUrl` | text | Yes | — | URL of the RSS or Atom feed to monitor. The workflow fires when new items are published to this feed. |
| `pollingInterval` | select | Yes | `5min` | How often Stylo checks the feed for newly published items. Options: `1min`, `5min`, `15min`, `30min`, `1hour`. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | --------------------------------------------------------------------------------- |
| `triggered` | boolean | Whether trigger fired |
| `timestamp` | string | Trigger timestamp |
| `item` | json | RSS item data (object — fields: `title`, `link`, `pubDate`, `content`, `creator`) |
| `feed` | json | RSS feed metadata |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "trigger/rss",
"config": {
"feedUrl": "",
"pollingInterval": "5min"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required fields (`feedUrl`, `pollingInterval`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Schedule
URL: /reference/blocks/trigger-schedule
Type: reference
Description: Trigger workflow on a cron schedule
Keywords: schedule, trigger/schedule, triggers, trigger, block, workflow builder
`trigger/schedule` — Trigger workflow on a cron schedule.
Where it appears [#where-it-appears]
The **Schedule** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| -------------- | ---- | -------- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `scheduleCron` | text | Yes | — | Standard cron expression that defines when the workflow runs. For example, `0 9 * * *` fires every day at 9 AM. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | --------------------- |
| `triggered` | boolean | Whether trigger fired |
| `timestamp` | number | Trigger timestamp |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "trigger/schedule",
"config": {
"scheduleCron": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Required field (`scheduleCron`) must be set, or the block fails validation before it runs.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Webhook
URL: /reference/blocks/trigger-webhook
Type: reference
Description: Trigger workflow via HTTP webhook
Keywords: webhook, trigger/webhook, triggers, trigger, block, workflow builder
`trigger/webhook` — Trigger workflow via HTTP webhook.
Where it appears [#where-it-appears]
The **Webhook** block is a trigger — it starts a workflow. Add it from the **Triggers** group in the Workflow Builder.
Fields [#fields]
| Field | Type | Required | Default | Description |
| --------------- | ----------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webhookUrl` | text | No | — | The unique URL that triggers this workflow when called with an HTTP POST. Copy and paste it into the external service that should fire the workflow. |
| `webhookSchema` | JSON schema | No | — | Declare the expected shape of the incoming request body. Defined fields become typed outputs available for downstream references. |
| `testInput` | code | No | — | Sample JSON payload to use when running this workflow in test mode instead of waiting for a real webhook call. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| ----------- | ------- | --------------------- |
| `triggered` | boolean | Whether trigger fired |
| `timestamp` | number | Trigger timestamp |
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
---
# Add Comment / Reply
URL: /reference/blocks/zendesk-add-comment
Type: reference
Description: Add a public reply or internal note to a ticket
Keywords: add comment / reply, zendesk/add-comment, integrations, zendesk, block, workflow builder
`zendesk/add-comment` — Add a public reply or internal note to a ticket.
Where it appears [#where-it-appears]
The **Add Comment / Reply** block lives in the **Integrations** group of the Workflow Builder. Connect the Zendesk integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------- | -------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ticketId` | text (supports references) | Yes | — | Numeric Zendesk ticket ID to comment on. Use a literal number or \ to reference an ID from upstream. |
| `comment` | text (multi-line, supports references) | Yes | — | Markdown is rendered to Zendesk HTML: **bold**, lists (`- `), blockquotes (`> `), links (`[label](url)`). Single newlines preserved as line breaks. Avoid `#` headers — use **bold** instead. |
| `public` | select | No | `true` | Whether the comment is sent as a public reply visible to the customer or as an internal note visible to agents only. Options: `true`, `false`. |
| `authorId` | select | No | — | Pick a Zendesk agent/admin, choose Current User (assist workflows only), or reference an upstream variable. Leave blank to inherit the brand or organization default. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success` | boolean | Success status |
| `ticket` | json | Updated ticket (object — fields: `id`, `subject`, `description`, `status`, `priority`, `type`, `tags`, `requester_id`, `assignee_id`, `group_id`, `custom_fields`, `created_at`, `updated_at`) |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "zendesk/add-comment",
"config": {
"ticketId": "",
"comment": "",
"public": "true"
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Zendesk integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`ticketId`, `comment`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Add Tags
URL: /reference/blocks/zendesk-add-tags
Type: reference
Description: Add tags to a ticket for classification and tracking
Keywords: add tags, zendesk/add-tags, integrations, zendesk, block, workflow builder
`zendesk/add-tags` — Add tags to a ticket for classification and tracking.
Where it appears [#where-it-appears]
The **Add Tags** block lives in the **Integrations** group of the Workflow Builder. Connect the Zendesk integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `ticketId` | text (supports references) | Yes | — | Numeric Zendesk ticket ID to add tags to. Use a literal number or \ to reference an ID from a previous step. |
| `tags` | text (supports references) | Yes | — | Comma-separated tags to add to the ticket. Added to existing tags without removing them. Accepts literal text or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success` | boolean | Success status |
| `ticket` | json | Updated ticket (object — fields: `id`, `subject`, `description`, `status`, `priority`, `type`, `tags`, `requester_id`, `assignee_id`, `group_id`, `custom_fields`, `created_at`, `updated_at`) |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "zendesk/add-tags",
"config": {
"ticketId": "",
"tags": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Zendesk integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`ticketId`, `tags`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Apply Macro
URL: /reference/blocks/zendesk-apply-macro
Type: reference
Description: Apply a predefined macro to a ticket
Keywords: apply macro, zendesk/apply-macro, integrations, zendesk, block, workflow builder
`zendesk/apply-macro` — Apply a predefined macro to a ticket.
Where it appears [#where-it-appears]
The **Apply Macro** block lives in the **Integrations** group of the Workflow Builder. Connect the Zendesk integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ---------- | -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `ticketId` | text (supports references) | Yes | — | Numeric Zendesk ticket ID to apply the macro to. Use a literal number or \ to reference an ID from a previous step. |
| `macroId` | text (supports references) | Yes | — | Numeric Zendesk macro ID whose actions should be applied to the ticket. Use a literal ID or \. |
Inputs and outputs [#inputs-and-outputs]
Inputs are the configurable fields above. The block produces these outputs:
**Outputs**
Reference an output downstream with ``.
| Name | Type | Description |
| --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success` | boolean | Success status |
| `ticket` | json | Updated ticket (object — fields: `id`, `subject`, `description`, `status`, `priority`, `type`, `tags`, `requester_id`, `assignee_id`, `group_id`, `custom_fields`, `created_at`, `updated_at`) |
| `error` | string | Error message if failed |
Example [#example]
A minimal configuration for this block:
```json
{
"type": "zendesk/apply-macro",
"config": {
"ticketId": "",
"macroId": ""
}
}
```
Limits and failure modes [#limits-and-failure-modes]
* Requires a connected Zendesk integration. Calls fail if that integration is disconnected or its authorization has expired.
* Required fields (`ticketId`, `macroId`) must be set, or the block fails validation before it runs.
* On failure the `error` output is populated; downstream blocks that reference other outputs may not receive values.
Related [#related]
* [All workflow blocks](/reference/blocks)
* [Workflow Builder overview](/workflow-builder-overview)
* [Integrations](/integrations)
---
# Assign Ticket
URL: /reference/blocks/zendesk-assign-ticket
Type: reference
Description: Assign a ticket to an agent or group
Keywords: assign ticket, zendesk/assign-ticket, integrations, zendesk, block, workflow builder
`zendesk/assign-ticket` — Assign a ticket to an agent or group.
Where it appears [#where-it-appears]
The **Assign Ticket** block lives in the **Integrations** group of the Workflow Builder. Connect the Zendesk integration before adding it.
Fields [#fields]
| Field | Type | Required | Default | Description |
| ------------ | -------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `ticketId` | text (supports references) | Yes | — | Numeric Zendesk ticket ID to assign. Use a literal number or \ to reference an ID from a previous step. |
| `assigneeId` | text (supports references) | No | — | Numeric Zendesk user ID of the agent to assign the ticket to. Use a literal ID or \ from a previous step. |
| `groupId` | text (supports references) | No | — | Numeric Zendesk group ID to route the ticket to. Use a literal ID or \