{
  "connector": "slack",
  "label": "Slack",
  "vendor_docs": "https://api.slack.com/methods",
  "summary": "A Slack workspace that answers the Web API, Events API, Socket Mode and interactivity flows `slack_sdk` and Bolt use, plus an MCP server.",
  "surfaces": [
    {
      "kind": "REST",
      "path": "/api/<method>",
      "notes": "the Web API; an unknown method answers 404 `unknown_method`"
    },
    {
      "kind": "Streaming",
      "path": "apps.connections.open",
      "notes": "Socket Mode WebSocket with an `xapp-` app-level token"
    },
    {
      "kind": "Webhooks",
      "path": "Events API",
      "notes": "event callbacks and interactivity payloads delivered to your app"
    },
    {
      "kind": "OAuth",
      "path": "oauth.v2.access",
      "notes": "bot and user tokens, and Sign in with Slack (`openid.connect.*`)"
    },
    {
      "kind": "MCP",
      "path": "/mcp",
      "notes": "Slack MCP tools over the same workspace"
    }
  ],
  "api_versions": [
    "Web API (unversioned methods)"
  ],
  "supported": [
    {
      "item": "Users, conversations, history, replies, members, chat, reactions, pins, bookmarks, usergroups and views"
    },
    {
      "item": "The `files_upload_v2` external upload flow, file info and downloads; `files.upload` answers `method_deprecated`"
    },
    {
      "item": "`search.messages`, `search.files` and `search.all` with the operators `in:`, `from:`, `after:`, `before:`, `on:` and `during:`"
    },
    {
      "item": "Socket Mode with `slack_sdk`'s `SocketModeClient`, the Events API and interactivity"
    },
    {
      "item": "The official Python SDK, documented in its own matrix"
    },
    {
      "item": "SCIM and the Audit Logs API for the one workspace a tenant models"
    }
  ],
  "unsupported": [
    {
      "item": "Enterprise Grid, cross-team installs and `admin.*` methods"
    },
    {
      "item": "Slack Connect with a second real org; shared channels are with synthetic partner orgs"
    },
    {
      "item": "Methods the SDK documents but the replica does not simulate"
    }
  ],
  "differences": [
    {
      "scenario": "Search ranking",
      "difference": "Search is substring matching over the workspace, not Slack's ranked index; `score` and highlighting are approximations.",
      "guidance": "Assert that the expected message is in the results, not on its rank or score."
    },
    {
      "scenario": "Rate limits",
      "difference": "Nothing throttles on its own; a 429 only happens when you inject one.",
      "guidance": "Do not expect organic tier limits. Inject `throttle` or `fail_next` to test retry handling."
    },
    {
      "scenario": "Human activity",
      "difference": "Nobody clicks buttons, votes or replies unless you inject the event or interaction.",
      "guidance": "Drive interactions yourself; do not wait for a user response."
    },
    {
      "scenario": "File contents",
      "difference": "Text, Markdown and CSV bodies are generated from the document's title, folder and owner, not original bytes.",
      "guidance": "Assert on file metadata and format, not on content."
    },
    {
      "scenario": "Canvases, polls, assistant threads, streaming replies, link unfurls",
      "difference": "Canvases are markdown sections; polls are ordinary messages with poll blocks; assistant status and streamed text are stored but not rendered; `chat.unfurl` stores what the app sends and nothing fetches links.",
      "guidance": "Assert on what the API returns, not on client rendering or automatic unfurls."
    },
    {
      "scenario": "Timestamps on writes",
      "difference": "A message you post is stamped from the host clock, which can fall after the seeded history unless the workspace runs on today's date.",
      "guidance": "Do not assert that new messages sort before or among the seeded history."
    },
    {
      "scenario": "Restarts",
      "difference": "Without a state directory the workspace lives in memory and a restart drops writes.",
      "guidance": "Treat each run as starting from the seeded workspace."
    },
    {
      "scenario": "Request size",
      "difference": "A Web API body over 8 MiB is refused with HTTP 413; Slack documents per-argument limits instead.",
      "guidance": "Do not test large-body behaviour against the replica."
    }
  ],
  "faults_supported": [
    {
      "fault": "throttle",
      "behaviour": "429 with `Retry-After` and `{\"ok\": false, \"error\": \"ratelimited\"}`, which `slack_sdk` retries on"
    },
    {
      "fault": "fail_next",
      "behaviour": "The next N calls fail as `throttle` does, then clear"
    },
    {
      "fault": "quota_limit",
      "behaviour": "429 `ratelimited`, the same shape as `throttle`"
    },
    {
      "fault": "error_rate",
      "behaviour": "500 `{\"ok\": false, \"error\": \"internal_error\"}` for the given fraction of calls"
    },
    {
      "fault": "latency_ms",
      "behaviour": "Fixed added latency on every data-plane request"
    }
  ]
}
