---
title: "Insulin Slack Bot: Tools, Approvals and Jobs"
url: https://www.insulin.dev/blog/insulin-slack-bot-tools-approvals-jobs/
canonical: https://www.insulin.dev/blog/insulin-slack-bot-tools-approvals-jobs/
type: Blog
description: "How Insulin's Slack bot picks tools, when a Slack send waits for approval, and how to build job notifications that post to Slack safely. For GTM engineers."
---

# Insulin Slack Bot: Tools, Approvals and Jobs

> Canonical HTML version: https://www.insulin.dev/blog/insulin-slack-bot-tools-approvals-jobs/

1.  [Home](/)
2.  [Blog](/blog/)
3.  Insulin in Slack: Tools, Approvals and Job Notifications

# Insulin in Slack: Tools, Approvals and Job Notifications

How the Insulin Slack bot decides who is asking, which tools it may call, when an action waits for an approval card, and how a job reports back to Slack. A build guide for GTM engineers.

![Stacy Wu](/authors/stacy-wu.jpg)

Stacy Wu

Oct 13, 2026

 ![Insulin in Slack: Tools, Approvals and Job Notifications](/images/blog/insulin-slack-bot-tools-approvals-jobs/hero.png)

Explore AI Summary

 [![](/logos/company/openai.svg)](https://chat.openai.com/?q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Finsulin-slack-bot-tools-approvals-jobs%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Agents%2C%20Jobs%2C%20Trust. "Summarize with ChatGPT")[![](/logos/company/anthropic.svg) ](https://claude.ai/new?q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Finsulin-slack-bot-tools-approvals-jobs%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Agents%2C%20Jobs%2C%20Trust. "Summarize with Claude")[![](/logos/company/gemini.svg)](https://www.google.com/search?udm=50&aep=11&q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Finsulin-slack-bot-tools-approvals-jobs%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Agents%2C%20Jobs%2C%20Trust. "Summarize with Gemini")[](https://www.perplexity.ai/search/new?q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Finsulin-slack-bot-tools-approvals-jobs%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Agents%2C%20Jobs%2C%20Trust. "Summarize with Perplexity")

Table of Contents

-   [How does the bot decide who is asking?](#how-does-the-bot-decide-who-is-asking)
-   [Which tools can the bot call?](#which-tools-can-the-bot-call)
-   [What can the bot do with Slack itself?](#what-can-the-bot-do-with-slack-itself)
-   [When does an action wait for an approval card?](#when-does-an-action-wait-for-an-approval-card)
-   [How do you create a job from Slack?](#how-do-you-create-a-job-from-slack)
-   [How do job notifications reach Slack?](#how-do-job-notifications-reach-slack)
-   [How do you test and debug a Slack-posting job?](#how-do-you-test-and-debug-a-slack-posting-job)
-   [Frequently asked questions](#frequently-asked-questions)
-   [Quick troubleshooting](#quick-troubleshooting)

_The Insulin Slack bot is the same Insulin agent you use in the web workspace, reached from a Slack DM or an @mention. What it can do in a given message is decided by three things: whose connections it runs on, which surface the message came from, and whether the action is a Slack send. This guide walks through each layer, then shows how to build job notifications that post to Slack without surprising anyone._

* * *

GTM engineers tend to meet the Slack bot twice. First, someone on the sales team asks why the bot answered their colleague but not them. Then someone asks for “a Slack alert when an offer is accepted, but with the context the built-in alert doesn’t have.” Both questions have the same root: the bot is not a Slack integration with its own settings. It is the Insulin agent, and Slack is just one more place it can be addressed.

That means there is nothing to configure per channel. Everything is set in the Fours console, and Slack inherits it.

## How does the bot decide who is asking?

**By the email on the sender’s Slack profile.** Insulin matches it to a Fours user and checks that the user belongs to the Fours organization the Slack workspace is connected to. If any step fails, the bot says which one rather than guessing.

The checks run in order:

1.  The workspace is still connected to a Fours organization.
2.  The Slack profile has an email the app is allowed to read.
3.  A Fours account uses that email.
4.  That account is a member of the connected organization.

Identity is per person, all the way down. Two people @mentioning the bot in the same thread each run on their own connections and their own Fours role, so they can get different answers to the same question. When a rep says “it works for Dana but not me”, compare what each of them has connected before assuming the data is missing.

## Which tools can the bot call?

**Only the tools behind your own user-level connections, filtered by the access level you chose and by the surface the message came from.** Three layers apply, in this order.

### Layer 1: your connections, never the organization’s

The Slack bot is the built-in Insulin agent, and that agent is user-level by design. It uses the integrations you connected under your own account (Gmail, Google Calendar, Gong, Salesforce, your Slack user connection) and **never** the organization-level ones, even for an org admin. When the bot says it lacks an integration, it is describing your connections, and the fix is to connect that tool to your own account.

Fours data itself (offers, entitlements, buyers, revenue, co-sell records) comes through the **Fours MCP server**, which each person connects under **Settings ▸ Integrations ▸ Custom MCP Servers**. Without it, the bot can talk but has no Fours records to read, and it says so rather than claiming the data does not exist.

### Layer 2: the Fours MCP access level

When you connect the Fours MCP server, you choose how far it reaches. **Read** is the default.

Access level

Tools offered

**Read** (default)

Look up and report. Nothing can change.

**Read & write**

Also create and update records, such as an offer or a referral.

**Read, write & delete**

Also delete them.

The level caps which tools are offered to the model. Your Fours permissions are then checked again on every call, so nothing done through Slack can exceed what you could do in the console. This is the setting that bounds record changes, which matters for the approval section below. For where read-only lives in other systems, see [where read-only access for AI agents is set](/blog/read-only-access-for-ai-agents/).

### Layer 3: the surface

The same person gets a different agent depending on where they asked. Anyone in a channel can write the messages the bot reads there, so **a channel turn is treated as untrusted**: the bot still looks things up and answers, but anything it can’t recognize as a read waits for the asker’s approval first.

Slack DM

@mention in a channel

Read through your connections

Yes

Yes; a lookup whose tool isn’t recognized as a read asks first

Create or update Fours records

Yes, if the access level allows, with no card

After approval, if the access level allows

Post a Slack message

After approval

After approval

Memory, goals, creating jobs, agents or channels

Yes

After approval

Hand part of the work to a helper agent

Yes

After approval

Who sees the answer

You

Everyone in the channel

Conversation scope

The DM, or each DM thread separately

The thread under the mention

The last two rows are the ones to put in your team’s onboarding note. An answer in a channel can draw on anything your connections can read, including your private Slack messages, Teams chats and email, and everyone in that channel, including a Slack Connect partner, sees it.

## What can the bot do with Slack itself?

**With your user-level Slack connection, the agent gets six Slack capabilities. Sending always waits for approval where a card can be shown; the rest are reads.**

Capability

Notes

Send a message

To a channel, a private channel or a person, by name or ID. **Waits for approval** on interactive surfaces.

Find channels

By partial name, so “post in the deals channel” resolves.

Look up one channel

Turns an opaque ID into a name and says whether the account is a member.

Find a person

By email or partial name. Returns every match and asks which one you meant.

Read a conversation

Up to 200 recent messages from one channel, DM or thread.

Search messages

Slack search modifiers such as `in:#channel` and `from:@person`. Needs a user-level connection.

Whose agent is running decides whose Slack identity is used. The built-in assistant and agents you own use **your** user-level connection: messages post as you, and reads and searches see only what you can see. Org-level agents use the org installation, post as the bot, and cannot search.

## When does an action wait for an approval card?

**In a DM, one action is gated: posting a Slack message. In a channel mention, everything the bot can’t recognize as a read is gated.** Before a send, the agent stops and posts a **Tool approval required** card naming the destination and showing a preview of the text, with **Allow** and **Deny**. In a channel, the card before any other action asks _“Run `<tool>` from an untrusted shared-channel request?”_ and names the tool.

The card’s rules, in Slack:

-   **Only the asker can decide.** Anyone can see the card in a channel, but a click from anyone else is refused.
-   **The destination is resolved first.** The agent names the channel behind an ID before asking, and the card flags a destination given only as a raw ID so you can check it.
-   **Three minutes, then nothing.** If nobody answers, the turn ends with “No approval within 3 minutes — nothing was sent,” and a late click is told the approval expired.
-   **The decision is recorded on the card.** It shows _Allowed by_ or _Denied by_ the asker, then the turn carries on.

What is **not** gated is just as important for anyone designing a workflow:

-   **Reads and lookups.** Finding channels or people, reading a conversation and searching don’t prompt. In a channel, a lookup whose tool isn’t recognized as a read can.
-   **Changes to Fours records, in a DM.** Ask the bot in a DM to update an offer and it updates it, the way a teammate would on your instruction. The control for that is the access level in layer 2, not a card. Decide it there.

And the gate only exists where someone can answer it. It is armed in the web workspace’s main thread, in Slack DMs and in Slack mentions. It is **not** armed in an Insulin channel, a sub-thread in the web workspace, a Microsoft Teams DM or **a job run**. On those surfaces a Slack send goes out without waiting. A goal’s background rounds can’t show the card either, so they don’t get the Slack send tool at all: a goal never posts to Slack on its own.

## How do you create a job from Slack?

**Describe it in a DM.** There is no form: tell the agent what should happen and when, and it creates the job, choosing the trigger itself.

> Every time an AWS private offer is accepted, post a two-line summary in #deal-desk with the buyer, the contract value and the account owner from Salesforce.

From a channel mention, creating a job waits on an approval card like any other change, so a DM is the simpler place to set one up. A job you create is private to you, organization admins included, and runs with your access and connections.

The three triggers, and what to know about each:

Trigger

Fires

What to know

**Manual**

When you run it

Not rate limited when run directly.

**Cron**

On a cron expression, such as `0 9 * * 1-5`

No timezone field: it runs on the service’s clock. Check the job’s **Next** timestamp to see when it lands for you.

**Push**

When an event arrives

Fours events use `suger.<entity>.<action>`, such as `suger.OFFER.ACCEPT`. GitHub, Google Calendar and Gmail events need a live OAuth connection and can only be set up by asking the assistant.

A push job can carry a [filtrex](https://github.com/m93a/filtrex) filter evaluated against the payload under `event`. A run that fails the filter is recorded as **Filtered**, not dropped silently:

```
event.action == "entitlement_created" and event.partner == "AWS"
```

With no filter, every event runs the agent. [Which events actually run a job](/blog/which-events-actually-run-a-job/) covers filters in depth, and [scheduled versus event-driven jobs](/blog/scheduled-vs-event-driven-ai-jobs/) covers choosing a trigger.

## How do job notifications reach Slack?

**Three ways: built-in Fours notifications when the event itself is the message, the job result DM when you only need to know a run finished, and a job that posts to Slack when the message needs reasoning or has to reach a channel.** They are different mechanisms with different identities and guardrails.

Built-in Fours notifications

Job result DM

A job that posts to Slack

Set up by

An org admin, as `ACTION.ENTITY` scopes routed to channels (for example `CREATE.OFFER` to `#sales-wins`)

Nobody: automatic once the org has connected Slack

Any user, by asking the agent

Content

A fixed card for the event

The run’s output or error, under a status heading, with a console link

Whatever the agent writes: summaries, joins with CRM or call data

Goes to

The routed channel

A DM to the job’s owner

The channel or person named in the job

Posts as

The bot

The bot

**You**, through your user-level Slack connection

Approval card

Not applicable

Not applicable

**None.** A job run is not an interactive surface

Which jobs

Not job-driven

Single-turn manual and scheduled jobs you own

Any job

### The job result DM

When a run of a job you own finishes, whether you started it or a schedule did, the bot sends you a direct message headed one of three ways:

-   ✅ **Job finished: {job title}**, followed by the job’s output
-   ❌ **Job failed: {job title}**, followed by the error
-   ⚠️ **Job finished — rate-limited, result may be partial: {job title}**

Each heading links to the job in the **Jobs** app with **Open in Fours Insulin console**, where a result too long for Slack can be read in full. Reply in the message’s thread to follow up, and the bot answers with the result in view.

Three limits to design around. Jobs triggered by an incoming event, goal jobs and jobs owned by a channel send no DM. Fours finds you by your Fours account’s email in the connected Slack workspace, so no match means no message. And the DM goes only to the owner: when a team needs to see the result, that is the case for a job that posts to a channel.

### A job that posts to Slack

The **None** cell is the design constraint. A job’s Slack send is unattended: it posts under your name with no card in front of it. So treat the job’s instructions as the review step:

1.  **Name the destination exactly** in the prompt, as a channel name rather than “the team channel”. Ambiguity that a card would have caught has no card here.
2.  **Filter at the trigger, not in the prompt.** A filter expression that returns false costs a **Filtered** row. A prompt that says “only post if…” costs a full agent run, and a model may not follow it.
3.  **Invite the posting account to private channels.** Your user connection can only post where you can. A send to a private channel the account hasn’t joined fails with `not_in_channel`, and the run reports that failure rather than a silent success.
4.  **Mind the clock and the cap.** A cron job runs on the service’s clock, and a busy push source can hit the per-job limit of 60 runs an hour. Excess runs are recorded as **Rate limited**.

## How do you test and debug a Slack-posting job?

**Fire it once with Run now, then read the run’s Steps tab.** Steps is the persisted tool-call transcript: which tools ran, in order, with each call’s arguments and its result or error. For a Slack-posting job, the send call’s arguments show exactly which channel and text it used. For a manual or scheduled job, the result DM is the quicker check: it lands in your Slack DMs when the run finishes, with a link back to it.

Two details about **Run now** on a cron or push job:

-   It replays the job through the same path a real tick or event takes, so it is **filtered and rate limited** like an automatic run. It does bypass the enabled switch, so you can test a disabled job.
-   The in-app button fires with an **empty payload**, so a push job with a filter will usually record **Filtered**. To exercise the filter, ask the assistant to trigger the job with a sample payload, or use the REST trigger endpoint, which accepts one.

A failed run opens on **Steps** automatically. The **Input** tab shows the event payload a push run received, which is where to look when a filter you expected to pass didn’t. [How to see past runs of a scheduled AI job](/blog/ai-job-run-history-and-runs-table/) walks through the runs table.

## Frequently asked questions

### Which actions does the Insulin Slack bot ask approval for?

In a DM, posting a Slack message. In a channel mention, anything it cannot recognize as a read, such as creating or changing a record, a memory or a job. Only the asker can answer the card, within three minutes.

### Does a job that posts to Slack wait for approval?

No. A job run is not an interactive surface, so its Slack send goes out without a card, posted as the job owner through their user-level Slack connection. Name the destination exactly and filter at the trigger.

### How do I find out that a job run finished?

If your organization has connected Slack, the bot sends you a direct message when a run of a single-turn manual or scheduled job you own finishes, with the result or error and a console link. Event-triggered, goal and channel-owned jobs send none.

### Can the bot use organization-level integrations?

No. The Slack bot is the built-in Insulin agent, which is user-level by design. It uses only the integrations each person connected to their own account, even when that person is an org admin.

### What limits what the bot can change in Fours?

The access level on each person’s Fours MCP connection: Read by default, or Read and write, or Read, write and delete. Fours permissions are then checked on every call, and from a channel any change also waits for approval.

### How do I test a push job that posts to Slack?

Ask the assistant to trigger it with a sample payload, or use the REST trigger endpoint, then read the run’s Steps tab. The in-app Run now button sends an empty payload, so a filtered job usually records Filtered.

## Quick troubleshooting

Symptom

Likely cause

The bot doesn’t answer in a channel

Its name was typed as text rather than @mentioned, or it isn’t in the channel. A private channel needs `/invite @Suger`; the app still carries its former name, Suger.

”Couldn’t find an account matching your Slack email”

The Slack profile email differs from the Fours account email.

It says it can’t create or change something

The Fours MCP connection is **Read**, the default. From a channel, the change also needs your approval on the card.

It says it doesn’t have an integration

That tool isn’t connected under **your** account. An org-level connection doesn’t count.

A teammate gets an answer you don’t

Different connections or different Fours roles. Working as designed.

A job’s Slack message never arrived

Check the run’s **Steps**. Common causes: `not_in_channel`, a **Filtered** or **Rate limited** run, or no user-level Slack connection.

No result DM after a job run

The job is event-triggered, a goal job or channel-owned, or your Fours email has no match in the connected Slack workspace.

The full setup, including the console steps for each connection, is in the [Insulin Slack bot documentation](https://doc.fours.com/insulin/slack-bot/).

## Sources

Primary sources for the platform rules cited above. Last verified October 14, 2026. Providers change their products, prices and terms without notice — check the source before relying on a detail.

-   [Fours Insulin docs: Slack Bot](https://doc.fours.com/insulin/slack-bot/) — The bot is the same Insulin agent as the console; identity by Slack profile email matched to a Fours user in the connected organization; per-person connections and no organization-level integrations; a channel answer able to draw on private messages your connections reach; the Fours MCP server's Read (default), Read & write and Read, write & delete access levels capping the tools offered while Fours permissions apply on every call; in a channel, anything not recognized as a read waiting for approval; the approval card before a send, answerable only by the asker, expiring after three minutes; record changes in a DM not gated; creating a job by asking, private to its owner; the direct message with a result when a run of a job you own finishes, its three headings, the console link and following up in the thread, and the jobs that send none
-   [Fours Insulin docs: Agents, Tool Approvals and Slack and Teams](https://doc.fours.com/insulin/agents/) — Posting a Slack message as the gated tool call, plus anything not recognized as a read in a Slack channel, with the Run <tool> from an untrusted shared-channel request? card; the card's Approved, Rejected and Expired states; the gate offered in the web workspace's main thread and in Slack, and not in an Insulin channel, a Teams DM, a sub-thread or a job run; goals never posting to Slack on their own; a channel turn treated as untrusted, with records, memory, goals, jobs, agents, channels and helper agents waiting for approval; DM threads as separate conversations; large tables attached as CSV
-   [Fours docs: Slack integration, Fours AI Tools](https://doc.fours.com/integrations/slack/) — User-level versus org-level Slack connections and their scopes; the six Slack capabilities, reading up to 200 messages at a time and search needing a user-level connection; the assistant and your own agents posting as you, org-level agents posting as the bot and unable to search; sends from a job going out without approval; not\_in\_channel reported as a failure; ACTION.ENTITY notification scopes routed per channel
-   [Fours Insulin docs: Jobs](https://doc.fours.com/insulin/jobs/) — Manual, cron and push triggers; push sources matching suger.<entity>.<action>, such as suger.OFFER.ACCEPT, and GitHub, Google Calendar and Gmail sources created only by asking the assistant; filtrex filters under the event namespace and the Filtered status; cron with no timezone field; 60 runs per hour per job and 300 per organization; Run now replaying through the filter and rate limit, with an empty payload from the button; the Output, Steps and Input tabs; a Slack direct message when a run of a job you own finishes, except event-triggered, goal and channel-owned jobs

## Keep reading

-   [TrustAI Agents in Shared Slack Channels: The RisksOct 23, 2026](/blog/ai-agents-shared-slack-channels/)
-   [TrustBackground AI Agents: Controls Before They RunOct 19, 2026](/blog/background-ai-agents-controls/)
-   [TrustThe AI Agent Sandbox: Test Before ProductionAug 27, 2026](/blog/ai-agent-sandbox-before-production/)
-   [TrustAI Model Governance: Choosing by Workflow RiskAug 27, 2026](/blog/ai-model-governance-by-workflow-risk/)

[Browse every post on the Insulin Blog](/blog/)

### Stay Updated

New posts, product updates and marketplace strategy are shared on LinkedIn as they publish.

[Follow Fours on LinkedIn](https://www.linkedin.com/company/suger-inc)
