Skip to content

Slack 1-Click Interactive Approvals

New

Last updated 11 October 2026

Autonomous AI agents and automated workflows can draft emails without unilateral send authority. When an email triggers an approval policy, SadaSend posts a rich Block Kit card into your Slack channel with one-click decision buttons.

Public Beta: SadaSend REST APIs, Port 587 ESMTP submission relay, hosted MCP tools for AI agents, and official zero-dependency TypeScript and Python SDKs are live. Every account receives 6,000 monthly transactional emails with strict server-enforced guardrails.

How Slack interactive approvals work

SadaSend introduces interactive human-in-the-loop email governance directly inside your engineering and operations channels in Slack. When an AI agent, background worker, or API key with approval policies queues an email, it enters pending_approval status rather than dispatching directly.

Instead of requiring human operators to log into the web dashboard, SadaSend formats and delivers an interactive Block Kit notification card into your designated Slack channel. The card includes recipient details, subject line, security hold reason, agent key label, and a safe blockquote preview of the draft content.

Operators can click Approve & Send ✅ or Reject ❌ directly in Slack. SadaSend receives the signed interaction payload, verifies its HMAC-SHA256 signature, validates a strict 5-minute replay window, atomically updates the message status, releases it into the MTA outbox queue, and replaces the Slack card in-place with an authoritative audit confirmation.

  • Zero-friction review: Human sign-off happens in your team channel in one second without opening a browser or logging into a dashboard.
  • In-place replacement: Once decided, action buttons vanish and are replaced with a persistent confirmation card noting who approved or rejected the message and the exact timestamp.
  • Tamper-evident audit trail: The decision event is permanently recorded in the tamper-evident message event log, including the reviewer’s Slack user ID and username.
  • Double-decision locking: Distributed transactional idempotency ensures that concurrent clicks by multiple team members cannot cause double dispatch.

Quickstart: 3-Minute Slack app setup

Setting up SadaSend Approvals in Slack takes three minutes using Slack’s App Manifest feature. Follow these five quick steps:

1. Create the app: Visit api.slack.com/apps → Click Create New App → Select From an app manifest → Select your target workspace.

2. Paste the manifest: Choose the JSON tab, paste the official manifest provided in the section below, and click Create.

3. Install to workspace: In the left sidebar, click Install App → Click Install to Workspace → Select your target notification channel (e.g., #email-approvals) → Click Allow.

4. Copy credentials: Copy the generated Incoming Webhook URL (under *Incoming Webhooks*) and the Signing Secret (under *Basic Information → App Credentials*).

5. Enable interactivity: In the left sidebar, click Interactivity & Shortcuts → Toggle Interactivity to On → In Request URL, enter https://api.sadasend.com/webhooks/slack/actions → Click Save Changes.

Official Slack app manifest (JSON)

You can copy and paste this complete manifest into the Slack App Manifest editor. It automatically configures the required bot scopes (incoming-webhook, chat:write), app display info, and interactivity endpoints:

JSON
{
  "display_information": {
    "name": "SadaSend Approvals",
    "description": "1-Click Interactive Human Approvals for Autonomous Email Sends",
    "background_color": "#09090b"
  },
  "features": {
    "bot_user": {
      "display_name": "SadaSend Approvals",
      "always_online": true
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "incoming-webhook",
        "chat:write"
      ]
    }
  },
  "settings": {
    "interactivity": {
      "is_enabled": true,
      "request_url": "https://api.sadasend.com/webhooks/slack/actions"
    },
    "org_deploy_enabled": false,
    "socket_mode_enabled": false,
    "token_rotation_enabled": false
  }
}

Connecting Slack in the SadaSend dashboard

Once your Slack app is created, connect it to your SadaSend organization:

1. In your SadaSend dashboard, navigate to Settings → Slack Approvals (/app/settings#slack-integration).

2. Enter your Incoming Webhook URL (https://hooks.slack.com/services/...).

3. Enter your Slack Signing Secret from *Basic Information → App Credentials*.

4. Enter your target Channel Name (e.g., #email-approvals).

5. Click Test Connection to dispatch a live verification card into your Slack channel.

6. Click Save Slack Settings to persist the encrypted configuration.

Triggering approval mode in code

You can hold emails for Slack approval using any of SadaSend’s four ingress channels: REST API, TypeScript SDK, Python SDK, or Model Context Protocol (MCP).

To require human approval on an email send, provide mode: "approval" or set approval mode on the API key used by your agent:

TYPESCRIPT
// TypeScript SDK — Hold email for Slack 1-click human review
import { SadaSend } from 'sadasend';

const sadasend = new SadaSend({ apiKey: process.env.SADASEND_API_KEY });

const result = await sadasend.emails.send({
  from: 'Deal Agent <deals@yourdomain.com>',
  to: 'client@example.com',
  subject: 'Q4 Contract Amendment & Volume Discount',
  html: '<p>Attached please find the revised agreement...</p>',
  mode: 'approval', // Held for human review
  agent_name: 'AutonomousDealNegotiator',
  hold_reason: 'High-value outbound communication requires human review',
});

if (result.status === 'pending_approval') {
  console.log('Held for Slack review:', result.id);
  console.log('Approval card dispatched to your configured Slack channel.');
}
Field / HeaderTypeDescription
modestring (optional)Set to "approval" to hold the email for human sign-off rather than sending immediately.
agent_namestring (optional)Human-readable label for the AI agent or automated script drafting the email.
hold_reasonstring (optional)Contextual explanation displayed in the Slack card explaining why review was requested.
Idempotency-Keyheader (recommended)UUID preventing duplicate holds if an agent or background worker retries.

Python SDK example

Holding messages from Python autonomous workflows or LangChain / CrewAI agents:

PYTHON
# Python SDK — Hold email for Slack interactive review
from sadasend import SadaSend

client = SadaSend(api_key="sada_live_sk_...")

res = client.emails.send(
    from_="billing@yourdomain.com",
    to="vendor@example.com",
    subject="Wire Transfer Payment Confirmation",
    text="Please confirm receipt of wire transfer #WT-94810.",
    mode="approval",
    agent_name="ProcurementAgent",
    hold_reason="Wire transfers above threshold require operator sign-off",
)

if res.status == "pending_approval":
    print(f"Held for Slack approval with ID: {res.id}")

Security, cryptographic verification & replay defense

SadaSend enforces strict zero-trust cryptographic guardrails on every incoming Slack action callback to prevent forgery and unauthorized email releases:

• HMAC-SHA256 Signature Verification: Every request to POST /webhooks/slack/actions must carry a valid X-Slack-Signature header calculated with your account’s Slack signing secret (v0=hash(signing_secret, "v0:timestamp:body")). Invalid signatures are rejected with HTTP 401 signature_mismatch.

• 5-Minute Replay Attack Defense: SadaSend inspects X-Slack-Request-Timestamp and verifies that |now - timestamp| <= 300 seconds. Replayed or delayed requests are rejected immediately.

• In-Place Atomic Transition: When an operator clicks Approve & Send ✅, the database executes an atomic state transition from pending_approval to queued, pushes the job to the transactional MTA outbox queue, and locks the row. Attempting to approve or reject a message that has already been decided returns an ephemeral notice to Slack and prevents duplicate processing.

• Tamper-Evident Audit Logging: Every decision logs an immutable queued or cancelled event in message_event, permanently recording the operator’s Slack username, user ID, channel ID, and timestamp.

Troubleshooting & common questions

Why does clicking the button in Slack show an exclamation mark (!)?

Ensure that your Slack App has Interactivity enabled under *Interactivity & Shortcuts* and that the Request URL is set exactly to https://api.sadasend.com/webhooks/slack/actions. If the URL is misconfigured or inaccessible, Slack cannot deliver the click event.

Can I approve emails from the SadaSend web app instead of Slack?

Yes. All emails held in pending_approval are visible under Approvals (/app/approvals). You can review the full HTML email, headers, and security rules, and click Approve or Reject directly from the web dashboard.

What happens if an approval card is ignored?

Held emails remain safely paused in pending_approval status until an authorized operator approves or rejects them, or until their expiration window is reached. They will never send autonomously without human action.