Skip to main content

How to build a Fin Procedure that improves over time

A conversation designer's six principles for building Fin Procedures that improve over time covering routing, data fetching, branching, testing, changelogs.

Written by Brian Branca

Building a Fin Procedure that handles a technically complex topic well takes iteration. This article walks through how a real procedure, the Data Connectors Setup and Troubleshooting procedure, was designed from the ground up, refined across successive iterations, and shaped by six principles that consistently made it better. Use it to apply the same thinking to your own procedures.

This article is for teammates building and iterating on Fin Procedures. It assumes you're working in the procedure editor and have published at least one procedure.

The procedure handles the full range of Data Connector questions: initial setup, authentication failures, API call errors, timeouts, response mapping problems, and regressions. It covers a lot of technical ground, and it uses a Data Connector of its own, built specifically to look up live diagnostic data about a customer's connector before Fin asks a single question. That design decision alone changed how the whole procedure works.


What does the Data Connectors procedure handle?

On the surface, "help with Data Connectors" sounds like one topic. In practice it covers a range of distinct situations: a first-time setup, an authentication failure, a broken API call, a timeout, a data mapping problem, a regression (something that used to work and doesn't anymore), an unsupported protocol, and a customer who isn't sure yet what they need. Handling all of these well in a single procedure is only possible if Fin knows, early in the conversation, which situation it's in.

The diagnostic Data Connector

The most significant design decision in the procedure is a dedicated Data Connector that was built specifically to pull live health data about a customer's own connector.

When a customer shares their connector URL, Fin uses the connector ID to make a GET request. It gets back:

  • The connector's current state (draft or live)

  • Its success rate over the last 7 days

  • The total number of calls in that period

  • The most recent HTTP error code

  • Whether authentication is configured

  • How many response fields are mapped, and which ones are included

Fin uses this data to lead its first meaningful reply with something specific, not something generic. That's the difference between a procedure that feels like a support form and one that feels like talking to someone who already looked into your issue before picking up the phone.

How the routing works

The procedure routes in two stages. The first is automatic: Fin reads the diagnostic data and routes before asking the customer anything. The second is intent-based: if the first stage doesn't determine the path, Fin reads what the customer describes and routes to the matching sub-procedure.

The table below shows the 13 distinct situations the Data Connectors Setup and Troubleshooting procedure handles, how Fin detects each one, and which sub-procedure it routes to.

Situation

How Fin detects it

Sub-procedure

General capabilities question

Customer's opening message

Capabilities overview

Connector not found

Diagnostic fields return empty

Asks for the exact name from Settings → Integrations → Data Connectors, then retries

First-time setup

Connector is in draft state, or zero calls in the last 7 days

Setup guide

No authentication configured

Diagnostic data: auth flag is empty or false

Authentication troubleshooting

Authentication failing

Last error code is 401 (authentication failure) or 403 (permission denied)

Authentication troubleshooting

API call errors

Last error code is 404 (not found), 429 (rate limit exceeded), or 5xx (server error)

Call failures (branched further by error code)

Connector is healthy but something is wrong

Diagnostic data shows healthy state

Response mapping investigation

Slow responses or timeouts

Customer describes

Timeout troubleshooting

Data not mapping or writing correctly

Customer describes

Response mapping

Was working before, now broken

Customer describes (regression language)

Regression troubleshooting

Using connectors inside a procedure or workflow

Customer describes

Integration guide (branches by procedure vs. workflow)

Unsupported protocol (SOAP, FTP, gRPC, or WebSockets: protocols that aren't REST over HTTPS)

Customer's opening message

Limitation explained: Data Connectors require REST over HTTPS and JSON. Unsupported protocols can't be connected directly.

Unclear intent

None of the above match

Follow-up questions to clarify, then re-routes

Note: Every sub-procedure ends in one of two ways: resolution (the customer confirms their issue is fixed) or a planned handoff to the Customer Support Tech team. When a handoff happens, the conversation already contains a note with the connector name, URL, and issue category, so the teammate who picks it up doesn't start from scratch.

The six principles below explain how the procedure got there and how to apply the same thinking to your own.

Each principle includes:

  • The principle itself

  • An example of how it was applied

  • What to test for

  • How to use it in your own work

Note: Principles 2–4 apply specifically when your procedure uses Data Connectors. Principles 1, 5, and 6 apply to every procedure regardless of complexity.


Principle 1: Route by intent before you ask anything

Before Fin says a single word to the customer, it should work out what the customer is actually asking about.

Different intents deserve different paths, and a procedure that asks the same opening questions of every customer wastes time for most of them.

Fin also doesn't run procedures as a fixed top-to-bottom script. It uses a non-linear planning approach: it can revisit earlier steps, skip ahead, or change course as the conversation develops. In some cases, it may even switch to a different procedure mid-conversation if another one is a better fit.

That means step order doesn’t always control the order of the conversation. Design procedures around the intent Fin needs to handle, not around a strict step-by-step path.

How to route a procedure by intent

A procedure that handles questions about Data Connectors illustrates this well.

"Data Connector question" actually covers at least five different conversations:

  • General curiosity about what connectors can do

  • Using connectors inside procedures or workflows

  • Unsupported protocols like SOAP or FTP

  • A misbehaving connector that needs diagnosis

  • A vague opening with no clear intent

The opening Instruction step tells Fin to read the customer's first message and determine which situation applies.

Condition steps further down then send the conversation along the matching path.

How to test intent routing

Routing happens at the trigger, so that’s what you need to test — and the right tool is live testing, not simulations. Simulations bypass intent matching entirely; they run a procedure directly without going through the trigger, so they can’t tell you whether Fin selects the right procedure in the first place.

To test routing, set the procedure live with the audience scoped to yourself — for example, a rule where email contains your company domain. Send ten realistic opening messages and check two things: that this procedure starts when it should, and that it doesn't start when it shouldn't. Include ambiguous messages; those are the cases most likely to misroute. When a message routes incorrectly, tighten the trigger description to be more specific about when Fin should and shouldn't use the procedure.

How to apply intent routing to your own procedure

List the distinct types of conversations your procedure will receive. Then ask: are these the same job with slight variations, or genuinely different jobs? If they’re genuinely different, you have two options: split them into separate procedures with distinct triggers, or handle them as branches inside one procedure. Use separate procedures when the jobs are distinct enough that you’d want to see their performance reported separately. Use branches when the jobs are closely related and you want the logic maintained in one place.

Write your trigger so it’s clear about both sides: when Fin should use this procedure, and when it shouldn’t. Vague triggers are the most common source of misrouting. Inside the procedure, never ask customers to categorize their own issue. Fin reads their message and routes from that. The customer’s job is to describe their problem, not label it.

Use the Condition step for major, mutually exclusive paths: situations where what Fin does next is completely different depending on the answer. For minor differences, keep the logic in an Instruction step as natural language. This keeps procedures simpler and easier for Fin to follow.

Tip: Three to six intents is usually enough. If you find yourself adding a tenth, you're probably using routing to solve a problem that belongs in a later Condition step.

How to choose: separate procedures vs. one branching procedure

The following factors help you choose between splitting jobs into separate procedures or handling them as branches inside one procedure:

Factor

What it means

Reporting

Separate procedures report performance per job: resolution rate, escalations, where customers drop off. One branching procedure reports as a single unit, so you lose that breakdown.

Trigger accuracy

More procedures means more chances for Fin to fire the wrong one. Fewer, broader procedures reduce collision risk; many narrow ones increase it unless every trigger is sharply scoped.

Branching doesn't hurt Fin's performance

A heavily branched procedure won't overwhelm Fin at runtime. Fin reads procedures in segments rather than loading everything at once, so step count doesn't degrade execution. The real cost is maintenance and clarity for you, not Fin's runtime.


Principle 2: Fetch data before you ask the customer for it

If your procedure has access to a Data Connector that can answer part of the customer's question, call it before you start interviewing the customer.

Customers experience this as competence. Procedures that interview first feel like forms.

How to fetch data before asking

When a customer's question is about a specific connector, the Data Connectors Setup and Troubleshooting procedure asks once for the connector name. It then calls a dedicated diagnostic Data Connector and gets back the following fields:

  • Status

  • Success rate

  • Total call count

  • Most recent error code

  • Authentication state

  • Other diagnostic fields

Fin's first meaningful reply uses that data. Here's the difference in practice (values below are illustrative):

Before fetching data

After fetching data

"Can you tell me which connector you're working with, whether it's currently live, and what error you're seeing?"

"I checked your Order Lookup connector and I can see it's been having issues. Over the last 7 days it has a 64% success rate across 412 calls. The most recent error was an HTTP 401. Let me help you fix that."

How to test that you're fetching data first

After the Data Connector runs, read Fin's first message out loud. If it asks questions you could have answered from the data you already fetched, you're not using the data aggressively enough.

Push more decisions into Condition steps that read the data instead of pushing them onto the customer.

How to apply data-first fetching to your own procedure

Inventory the Data Connectors available to your procedure. For each one, ask: "Could I call this before the first customer question instead of after?" If the answer is yes, restructure so the data fetch happens first. The customer should feel like Fin already did the homework.


Principle 3: Branch on data, not just on what the customer says

Once you've fetched diagnostic data, branch on the data directly. Don't make the customer describe a state you can already detect.

Screenshot of a Condition step in the procedure editor checking the connector's current status — when status is 'draft', the branch routes the customer to the first-time setup guide.
Screenshot of a Condition step checking the connector's authentication configuration — when authentication is not configured, the branch routes to the authentication setup sub-flow.
Screenshot of a Condition step branching on the most recent HTTP error code — 401 and 403 route to authentication troubleshooting; 404, 429, and 5xx route to call failure handling.

How to branch on fetched data

After the Data Connector runs, its response becomes available as temporary context. Read individual fields using the read attribute action, then use Condition steps that branch directly on those values.

The table below shows how specific Data Connector field values map to Condition step branches and the corresponding action Fin should take:

Data state

Action

Status = "draft"

Walk the customer through publishing

Zero calls in the last 7 days

Help them test the connector

Authentication missing

Begin with auth setup

Most recent error = 401

Route to authentication troubleshooting

Most recent error = 404, 429, or 5xx

Route to request troubleshooting

Connector healthy

Redirect to upstream issues such as field mapping

Each branch produces a different opening message written specifically for that state.

How to test data-driven branches

For each branch, ask: "Would Fin's response in this branch make sense if a real customer in this exact state read it?"

The healthy-connector branch is often the easiest to get wrong because the instinct is to keep diagnosing. Resist that. If the connector looks healthy, say so and move the conversation forward.

Note: The most commonly missed branch is "Everything looks healthy." Don't skip it. Acknowledge that the connector appears healthy and redirect the investigation toward upstream issues.

How to apply data-driven branching to your own procedure

Look at every piece of data you fetch and ask whether it should drive a Condition step.

  • If a field's value changes what Fin should say next, create a branch.

  • If multiple values lead to the same response, combine them.

Keep the logic tight and write each branch as if it were the only response the customer will ever see.


Principle 4: Plan for the lookup that returns nothing

The most common failure mode in a data-driven procedure isn't an error from the Data Connector. It's a successful call that returns no results.

Usually this happens because the customer's input doesn't match anything.

How to handle an empty lookup result

Data Connector URLs must be exact. When customers provide URLs that don't match the connector they intend, whether due to typos, trailing slashes, or other variations, the Data Connector often returns empty fields rather than an error.

Without explicit handling, Fin may continue and generate responses based on data it never actually found.

The fix is a Condition step that checks whether key fields are empty or null. If so, Fin asks the customer to verify the data connector URL in their Data Connectors settings and provide it exactly as it appears. The Data Connector then runs again using the corrected URL.

How to test the empty-result path

Try inputs that almost match but don't:

  • Incorrect URLs (typos, missing protocol, wrong domain)

  • Incomplete URLs (missing path segments)

  • URLs from another workspace or environment

  • Trailing or leading whitespace in the URL

If the procedure doesn't detect and recover from these cases, the fallback path isn't strong enough.

How to apply empty-result handling to your own procedure

Every time you call a Data Connector, add a Condition step immediately afterward for "no results."

In that branch:

  • Be specific: tell the customer exactly where to find the correct URL (Settings → Integrations → Data Connectors, copy the URL from the address bar or connector details)

  • Avoid generic instructions like "try again"

Tip: Don't be afraid to end the conversation if the answer is "this isn't supported." A short, honest answer is better than a long diagnostic conversation that can't help.


Principle 5: Test in layers, from static checks to live conversations

A procedure gets reliable through testing. Intercom gives you three tools that catch progressively different problems. Use them in order, because each one finds issues the one before it can’t.

1. Review: catch build-time problems before running anything

Click Review in the procedure editor (top right, next to Test).

Screenshot of the procedure editor toolbar showing the Review button in the top right, next to the Test button — clicking it runs a static analysis of the procedure's configuration and returns a list of flagged issues.

Review runs a static analysis of your procedure’s configuration and returns a list of flagged issues with specific fixes. It catches build-time problems such as:

  • Missing actions — a step references a handoff or tool that hasn’t been configured

  • Broken or unreachable step references

  • Unhandled else branches: fall-through cases with no defined path

  • Logic issues — reading an attribute before it’s been set, or conditions that are too vague to evaluate reliably

Review doesn’t run a conversation or show how Fin would actually behave at runtime — it only inspects the configuration. Run it first so you fix structural problems before spending time on simulations.

2. Simulations: run the procedure and inspect its decisions

Simulations run the procedure end to end against an opening message, without customer-facing output. The transcript shows more than the final reply: Fin’s thinking at each step, which branch was chosen, attribute updates, and Data Connector calls. You can attach success criteria to assert on the reply, attribute values, connector calls, and outcome, turning a scenario into a repeatable pass/fail check.

Simulations bypass intent matching entirely — they run the procedure directly and don’t test whether your trigger fires correctly. To test intent routing, use live testing scoped to yourself (covered below).

  • Scripted scenarios

    Create one opening message per intent and per data state your procedure handles. This catches obvious routing and branching mistakes.

  • Recreating real conversations

    Take real past conversations and rebuild them as simulations by copying each one’s opening message and context. This surfaces what you didn’t script for, such as:

    • Case-sensitive connector names

    • Ambiguous phrasing

    • Incorrect assumptions about customer intent

3. Live testing, scoped to yourself

Once Review is clean and your simulations pass, test the genuine end-to-end experience. Set the procedure live with the audience limited to yourself — for example, a rule where email contains your company domain. This lets you test the full experience in a real conversation without exposing it to customers. Once you're satisfied, update the audience rule to include all customers. Saving the rule change creates a new draft, so click Set live again for the change to take effect.

Note: Live test conversations with Fin will likely incur a resolution charge, unless the conversation results in an escalation to a teammate.

Live testing catches things simulations can’t — the trigger firing correctly, the real conversation flow, and the feel of each response when it arrives in context.

How to judge whether a procedure is working

Track the percentage of test conversations where Fin's first response would have felt right to the customer. Don't just ask "Did it route correctly?" Ask "Would a thoughtful human find this first response useful?"

Over time, connect this to objective signals already available in Intercom: resolution rate, CSAT, and conversation handle time. If a procedure improvement is working, you should see these move.

How to apply layered testing to your own procedure

Work through the layers in order:

  1. Run Review and clear every flagged issue first.

  2. Build one scripted simulation per intent and per data state your procedure handles — typically five to ten for a procedure of this complexity — and add success criteria so they stay repeatable.

  3. Recreate real past conversations as simulations to find the cases you wouldn’t have thought to script.

  4. Go live scoped to yourself for a true end-to-end check before widening the audience.

Tips:

  • Expect multiple iterations. Plan for at least three rounds: (1) establish the structure, (2) surface edge cases, (3) polish wording and flow. You won't get it right on the first pass.

  • Write each branch as a complete reply. Customers only see one branch, so each one should feel like a thoughtful, standalone answer.


Principle 6: Keep an honest changelog so you can trace and revert changes

Every time you set a procedure live, Intercom asks you to write a ‘What changed?’ note. Treat that field as a real changelog, not a formality. It feels like a chore in the moment, but it’s the record that lets you connect a metric shift to a specific change weeks later instead of guessing.

Screenshot of the 'What changed?' dialog shown when setting a procedure live — a text field prompts the teammate to describe what was modified, forming a version history entry that can be reviewed and edited later.

Why does changelog discipline matter?

A procedure is never done — you’ll keep refining it, and each change is a small bet that the procedure gets better. The version history is the record of those bets. If resolution rate, CSAT, or handle time moves after a change, a clear note tells you what changed and when, so you can trace the shift to a specific edit rather than guessing.

How to write a note worth reading

Write what the change does and why, not just where it lives:

Weak

Strong

"trigger" or "changed conditional"

"Tightened intent classifier: removed the ‘ambiguous’ category and added stricter conditions for the capabilities, integration, and protocol paths; all unclear intent now defaults to URL collection."

The second version is a note you can act on six weeks later. The first one isn’t.

How to revert when a change makes things worse

If a change degrades performance, roll back from Version history:

  1. Open the procedure and click Version history in the top navigation.

  2. Click the … next to the version you want and choose Restore this version.

  3. This creates a new draft from that version and overrides your current draft — make sure you don’t need the current draft before restoring.

  4. The restored version doesn’t go live until you click Set live. Clicking Set live follows the same publish flow as any other change: you'll be prompted to add a 'What changed?' note before the restored version goes live.

You can also edit an existing note (the pencil icon in Version history) to clarify what a past change actually did.

When a metric dips, open Version history first. Line up the date of the dip against your change notes. The cause is usually the change that shipped just before it.


How did this procedure evolve over time?

The first version of the Data Connectors Setup and Troubleshooting procedure interviewed customers before looking anything up. Fin would ask three or four questions before saying anything useful. It was technically functional but felt like a form.

The diagnostic Data Connector came in the next iteration. That single addition changed the character of the whole procedure. Instead of opening with questions, Fin could open with specific observations ("Your connector has a 64% success rate over the last 7 days and the most recent error was a 401") and then move directly to fixing the problem.

After that, the intent routing was separated from the diagnostic flow. Customers asking what Data Connectors can do got a different path from customers with a broken connector. That eliminated a lot of irrelevant diagnostic questions for people who just needed a quick capabilities answer.

Each iteration was driven by a specific failure pattern spotted in real conversations: a customer who landed on the wrong branch, a case the routing hadn't anticipated, a response that was technically correct but unhelpful in context. No iteration came from guessing. Every one came from evidence.


What does a well-built procedure look like in practice?

The clearest signal that a procedure is working is the quality of Fin's first reply. Before this procedure existed, a customer asking about a failing connector would answer several questions before receiving any guidance. With the procedure, Fin's first meaningful reply leads with what it actually found: the connector's state, its success rate over the last week, and its most recent error code. The diagnosis starts with data, not an interview.

Routing depth matters too. 13 distinct paths mean each situation gets guidance that actually fits it. A customer asking about SOAP integration gets a direct, honest answer about what's supported, not a troubleshooting flow that leads nowhere. A customer whose connector is healthy but whose data isn't mapping correctly doesn't get sent through authentication troubleshooting first.

And when a conversation does need a human agent, the handoff note already contains the connector name, the connector URL, and the issue category. The teammate has context before reading a single customer message. That's a small thing from a design perspective (one note step at the end of the procedure), but it changes the handoff from a restart into a continuation.

Tip: The value of a well-built procedure isn't just in the conversations it resolves. It's in the quality of the ones it passes on. A good handoff is part of the design.


Putting it all together: the recommended procedure shape

When these six principles are combined, a procedure like the Data Connectors example tends to follow a predictable structure:

  1. An Instruction step determines the conversation type.

  2. Condition steps route broad categories down different paths.

  3. The data-driven path asks once for a key identifier and then calls a Data Connector.

  4. A "no results" branch handles invalid input gracefully.

  5. Additional Condition steps branch on fetched data and generate state-specific responses.

Principle 6 (keeping an honest changelog) isn't a step in the structure, but it's what makes the whole thing improvable over time. Without a clear record of what changed and when, every iteration is a guess.


Where to start

The best Fin Procedures don't become effective because of a clever first draft. They become effective because every iteration is driven by evidence from real conversations.

Start with your highest-volume procedure. Apply Principle 1 first: map out every intent it might receive and verify the routing is working. Then build from there.

The first version is the starting point. The good version is the one you've refined repeatedly.


💡Tip

Need more help? Get support from our Community Forum
Find answers and get help from Intercom Support and Community Experts


Did this answer your question?