Slack's documentation is reasonably good. What it doesn't tell you is where the edges are — the rate limits that aren't in the docs, the timing issues in socket mode, the production gotcha that costs you an on-call incident. We collected ours. Here they are.
Slack requires your app to acknowledge an interaction (slash command, button click, modal submit) within 3 seconds or it shows the user an error. If your handler needs to do anything slow — like query a database and generate a chart — you have to acknowledge immediately with a 200 and do the work asynchronously, posting the result back via response_url or a chat.postMessage call. We learned this the hard way when our initial query handler occasionally exceeded 3 seconds on cold starts.
Events API (outbound webhooks to your server) is simpler to reason about but requires a public endpoint and means you're responsible for retrying failed deliveries. Socket mode (persistent WebSocket connection from your server to Slack) hides the network complexity but reconnects silently, which can cause duplicate event processing if your handler isn't idempotent. We use socket mode in production with a distributed lock (Redis SETNX) to deduplicate events by event_id.
Slack's rate limiting is applied per API method, not globally per app. chat.postMessage is Tier 3 (1 request/second). conversations.list is Tier 2 (20 requests/minute). users.info is Tier 4 (100 requests/minute). Building a feature that mixes methods doesn't give you a combined rate limit — each method has its own bucket. And the Retry-After header value in a 429 response is the minimum wait; in practice, backing off for 2× the stated value avoids repeat 429s.
Blocks have undocumented character limits that only surface when a user actually triggers the message. A section block text field caps at 3,000 characters; a plain_text element in a button caps at 75. There's no validation at message composition time — you only find out when Slack silently truncates or rejects the block. We wrap all Block Kit payloads with a validation step before sending.
If you realise you need a new scope after your app is live, adding it to your manifest and asking existing users to re-authorise is straightforward. But if you want to remove a scope (because you accidentally requested one you don't use, or a user asks why you need it), you cannot. Existing installations keep the old scopes until the user manually removes and reinstalls the app. Request only what you need from day one.
Orvixo's Slack integration is included on all paid plans. Connect your workspace in under a minute — no public endpoint or infrastructure required. Get started.