Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Slack By James Joyner IV · · 8 min read Last reviewed Jul 2026

Slack Error Guide: 'restricted_action' — Workspace Policy Blocked the Call

Quick answer

Fix the Slack API restricted_action error: an admin policy blocks posting, inviting, or channel management. Diagnose posting permissions, invite settings, and roles with curl.

  • #slack
  • #api
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this Slack error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

restricted_action means the API call was well-formed and authenticated, but a workspace or channel policy forbids it. This is not a scope problem (missing_scope) and not a membership problem (not_in_channel) — the token, scopes, and channel access can all be correct, yet a workspace admin has restricted who may perform the action. Common triggers: a channel where only admins can post, an invite policy that blocks the app, or an org setting that limits channel management to certain roles.

The response body:

{
    "ok": false,
    "error": "restricted_action"
}

It appears on write-oriented methods — chat.postMessage, conversations.invite, conversations.archive, conversations.setTopic, and similar — where Slack layers admin policy on top of API permissions. The fix lives in workspace settings and channel management, not in your code.

Symptoms

  • Reads succeed (conversations.info, conversations.history) but a specific write returns restricted_action.
  • The same call works in one channel and fails in another (channel-level posting policy).
  • It started failing after an admin tightened workspace settings, with no code change on your side.
  • auth.test succeeds and the app has the needed scopes — only the action is blocked.
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0ANNOUNCE","text":"deploy complete"}'
{
    "ok": false,
    "error": "restricted_action"
}

Common Root Causes

1. The channel restricts who can post

Announcement-style channels are often configured so only owners/admins (or a chosen set) may post. A bot without that privilege gets restricted_action, even though it is a member with chat:write.

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0ANNOUNCE","text":"release notes"}'
{
    "ok": false,
    "error": "restricted_action"
}

Fix: an admin grants the app posting permission in that channel’s settings, or you post to a channel without the restriction.

2. Workspace invite policy blocks the app from inviting

conversations.invite can be blocked if the workspace restricts who may add members to channels, or restricts inviting guests/multi-channel users.

curl -s -X POST "https://slack.com/api/conversations.invite" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0INCIDENT","users":"U0GUEST01"}'
{
    "ok": false,
    "error": "restricted_action"
}

3. Channel management limited to admins

Archiving, renaming, or setting topic/purpose can be restricted to admins or the channel creator. An app performing housekeeping hits restricted_action on those methods.

curl -s -X POST "https://slack.com/api/conversations.archive" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0OLDCHAN"}'
{
    "ok": false,
    "error": "restricted_action"
}

4. Posting as a restricted/guest identity

If the token belongs to a restricted (single/multi-channel guest) user, many actions are policy-blocked regardless of channel membership.

5. An org-level (Enterprise Grid) policy overrides the workspace

On Grid, org admins can set policies that supersede workspace settings — for example, disabling public-channel creation or restricting Slack Connect actions — surfacing as restricted_action.

6. Slack Connect / external-sharing restrictions

Actions touching externally shared (Slack Connect) channels are frequently policy-gated; inviting or posting in ways the connection policy disallows returns restricted_action.

Diagnostic Workflow

Step 1: Confirm auth and scopes are NOT the issue

curl -s "https://slack.com/api/auth.test" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
    "ok": true,
    "team": "ACME Prod",
    "user_id": "U0BOTBOT01"
}

A green auth.test plus the correct scopes proves the credential is fine — the block is policy.

Step 2: Isolate whether it is channel-specific

Try the identical call in a channel you know is unrestricted:

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0SANDBOX","text":"policy probe"}'
{
    "ok": true,
    "channel": "C0SANDBOX",
    "ts": "1720440000.000100"
}

Success in the sandbox but failure in the target channel points squarely at that channel’s posting/management policy.

Step 3: Inspect the target channel’s properties

curl -s "https://slack.com/api/conversations.info?channel=C0ANNOUNCE" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
    "ok": true,
    "channel": {
        "id": "C0ANNOUNCE",
        "name": "announcements",
        "is_general": false,
        "is_member": true
    }
}

is_member: true while the post is blocked confirms the restriction is a posting policy, not membership (not_in_channel).

Step 4: Confirm the identity is not a restricted user

curl -s "https://slack.com/api/auth.test" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN"

Check with a workspace admin whether the app/user is limited (guest/restricted), which policy-blocks a wide range of actions.

Step 5: Verify after the admin adjusts policy

Once an admin permits the app to post/manage in that channel, the same call succeeds:

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0ANNOUNCE","text":"deploy complete"}'
{"ok": true, "channel": "C0ANNOUNCE", "ts": "1720440100.000200"}

Example Root Cause Analysis

A release bot posts changelogs successfully to #eng-releases for months, then starts returning restricted_action only for #announcements. Nothing in the bot changed.

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel":"C0ANNOUNCE","text":"v2.4 released"}'
{"ok": false, "error": "restricted_action"}

The identical call to the sandbox channel succeeds, and conversations.info shows the bot is still a member of #announcements. That rules out auth, scopes, and membership.

Talking to a workspace admin reveals the cause: an admin recently switched #announcements to “only specific people can post” as part of a comms cleanup, and the bot was not on the allowed list.

Fix: the admin adds the bot to the channel’s permitted posters. No code change was needed — the failure was a channel posting policy applied after the integration was built.

Prevention Best Practices

  • Treat restricted_action as a policy signal, not a bug — check channel posting permissions and workspace/org settings before touching code.
  • For bots that post to announcement channels, get the app explicitly allow-listed as a poster and document that dependency.
  • Isolate quickly by retrying the call in a known-unrestricted sandbox channel; success there means the target channel’s policy is the cause.
  • Keep app identities as full (not guest/restricted) users where the workload needs to post/invite/manage broadly.
  • On Enterprise Grid, coordinate with org admins — org policy can override workspace settings and reintroduce restricted_action after a change.
  • Handle it gracefully in code: catch restricted_action, alert an admin channel, and avoid retry storms — retrying will not overcome a policy.

Quick Command Reference

# Prove auth/scopes are fine
curl -s "https://slack.com/api/auth.test" -H "Authorization: Bearer $SLACK_BOT_TOKEN"

# Probe an unrestricted sandbox channel
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d '{"channel":"C0SANDBOX","text":"policy probe"}'

# Inspect the target channel (membership vs policy)
curl -s "https://slack.com/api/conversations.info?channel=C0ANNOUNCE" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN"

# Retry the real post after policy is fixed
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d '{"channel":"C0ANNOUNCE","text":"deploy complete"}'

Conclusion

restricted_action is a policy verdict: the request was valid and authenticated, but a workspace, channel, or org rule forbids the action. The usual root causes:

  1. The channel restricts who may post (announcement channels).
  2. Workspace invite policy blocks adding members/guests.
  3. Channel management (archive/rename/topic) is limited to admins.
  4. The token belongs to a restricted/guest identity.
  5. An Enterprise Grid org policy overrides workspace settings.
  6. Slack Connect external-sharing restrictions gate the action.

Confirm auth and scopes are clean, isolate whether it is channel-specific by probing a sandbox channel, inspect the target with conversations.info, then have an admin adjust the policy. For quickly separating a policy block from a scope or membership error, the incident assistant can classify the failure. See more in Slack guides.

Free download · 368-page PDF

Fixed it? Get 500 Slack & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.