FlowplaneDocs

#Approvals in Slack

Let your reviewers approve or reject an AI action without leaving Slack. When a decision is routed to the Slack surface, Flowplane posts an interactive message with the full context and Approve / Reject buttons — one click decides it and resumes your workflow. No dashboard login, no context-switch.

Slack is a surface (how the binding verdict is recorded), independent of the route (how the approver is reached). See Core concepts.

#What your reviewers see

The approval message carries the same context blocks your reviewers see everywhere else — the prompt, the tool call, the diff, the cost — rendered natively in Slack, with two buttons:

  • Approve / Reject — a single click records the verdict.
  • After a decision, the buttons are replaced with the outcome ("✅ Approved — the workflow has resumed"), so the same message can't be actioned twice.

With a multi-approver quorum, each person's click counts as one vote; the message updates as the decision resolves.

#Refine a draft in the thread

When a decision carries an editable draft (a Conversational Approval), the Slack message shows the draft and invites the reviewer to reply in the thread to refine it. Each reply is applied by your model and the revised draft is posted straight back into the thread — reply again to keep iterating, then Approve to resume your workflow with the final version.

This needs the workspace's Slack app to have Event Subscriptions enabled — subscribe the bot to the message.channels event (or message.groups for private channels) with the request URL pointed at /v1/surfaces/slack/events. Thread replies are plain messages, delivered over Slack's Events API — a separate channel from the button clicks that decide plain approvals, so both must be configured for the full experience.

#Routing a decision to Slack

Set the decision's surface to slack — either on the call, or (recommended) as the default on a named approval policy so it's declarative:

json
{  "name": "payouts-over-5k",  "defaults": { "surface": "slack", "approvers": ["finance@acme.com"] }}

Any decision the policy gates is now presented in Slack. The context.blocks you pass to awaitApproval are what the reviewer sees in the message.

#Requirements

  • The workspace's Ratifia Slack app is connected. Slack approvals are available once your workspace's Slack app is installed and its credentials are configured; until then the surface is inactive and decisions fall back to the dashboard Inbox.
  • The approver is reachable in Slack. An approver with a verified slack method is DM'd directly; otherwise the message goes to your team's configured approvals channel. An approver can only bind a verdict on a surface they're verified for — a policy that routes to slack for an approver who isn't Slack-verified is rejected when you save it.

#Security

Every button click is verified before it can move a decision:

  • Each interaction is signed by Slack and checked against your app's signing secret — a forged or replayed callback is rejected, never recorded.
  • A decided approval is final: re-clicking a stale button does nothing, and it can't be flipped after it resolves.

The buttons are a bearer affordance in the sense that whoever can see the message can click — so route Slack approvals to the people (DMs) or private channels you intend, the same way you'd scope any approval.