A small Python library and CLI for backfilling Slack channel history from an unlisted (non-Marketplace) Slack app under the 1 req/min, 15-msg/req rate limit. Resumable, checkpointed, zero infrastructure. MIT.
Since May 29, 2025, Slack throttles
conversations.history and
conversations.replies to 1 request per
minute, max 15 messages per request for any
commercially-distributed Slack app not listed on the Slack
Marketplace. Existing installs switch over on March 3,
2026. That's 21,600 messages/channel/day
at peak. A busy customer channel with half a million messages
becomes a 23-day backfill. There's no clever way
around the ceiling; Slack means it.
(workspace, route), exactly what Slack asks.Retry-After on every 429 (no fixed 60s sleep).limit=15, halves future windows when pagination gets heavy.slack-shield to-csv when done.| Your situation | Use |
|---|---|
| Need sane 429 retries in a regular Slack app | slack_sdk (official) |
| Personal/local archive with a user token | slackdump |
| Full Slack→Teams/Mattermost migration with files, channel mapping | CloudFuze, Cloudiway, 21b ($5k+) |
| Slack data into a warehouse | Airbyte, Fivetran |
| Compliance archive / eDiscovery | Pagefreezer, Onna, Archive360, ViewExport |
| Enterprise AI search over Slack | Glean ($50/user/mo, 100-seat min) |
| Bot/app token, unlisted Slack app, need to back-fill a customer's history under the 1 rpm limit, with state and resume, zero infra | slack-shield |
v0.1.0. Verified live against a real Slack workspace
on 2026-05-14: auth, the 1 req/min pacing between requests, cursor
pagination across pages, multi-window walk, state checkpoints, and
resume from an interrupted run all behaved as documented. 28
pytest tests cover the components in isolation, including the
429 + Retry-After path and the
adaptive-shrink path.