Back to Blog
slackschedulingapiteamsautomation

How to Schedule Slack Messages: Send Later, chat.scheduleMessage, and the 120-Day Wall

M
Mel Owen
6 min read

Short answer: yes, you can schedule Slack messages, both from the app and from your own code. The part most guides skip is where each method quietly stops working. Thread replies can't be scheduled at all. The API caps out at 120 days. And the rate limit everyone quotes in forum posts is not the one Slack actually enforces.

This is the complete picture for anyone trying to schedule Slack messages in 2026, whether that's a weekly standup reminder, a recurring metrics digest, or an announcement that also needs to go out on your social accounts the same minute.

What you need

  • A Slack workspace where you're a member of the channel you want to post to.
  • For native scheduling: nothing extra. It's built into the composer.
  • For API scheduling: a Slack app with a bot token that has the chat:write scope, installed in your workspace, invited to the target channel.
  • If you're scheduling into a private channel or DM, the bot (or your user token) needs to actually be a member of it. Slack will not let a token post somewhere it hasn't been added.

Native Send later (and its thread-reply gap)

Slack has had native message scheduling for years, and it's the fastest path for a one-off. Type your message, then instead of hitting Enter, click the small arrow next to the send button and choose Schedule for later. Pick a date and time, and Slack queues it. You'll see it sitting in a "Scheduled Messages" view, editable or cancelable right up until it fires.

The gap that trips people up: you cannot schedule a reply inside a thread. The Schedule for later option only appears on top-level channel and DM messages. If your workflow depends on a scheduled thread reply, for example a daily update nested under a pinned kickoff message, native scheduling can't do it. You'd need to post it live or route it through the API with your own timer, since the API has the same restriction baked into how threads work.

Recurring messages via Workflows

Native Send later handles single messages, one at a time. For anything recurring, meaning a message that should fire every Monday at 9am without you re-scheduling it each week, Slack's answer is Workflows (what used to be called Workflow Builder, now folded into Slack Automations). You build a workflow with a scheduled trigger, set the cadence, and attach a "send a message" step. It's a genuinely different system from Send later, built for repetition rather than one-off timing, and it's the honest way to schedule recurring messages in Slack without a script running somewhere.

Want to put this into practice? Start a 14-day TimeToPost trial and start scheduling smarter today.

The API: chat.scheduleMessage, post_at, time_too_far

If you're building this into a tool rather than clicking through the UI, the method is chat.scheduleMessage. You pass a channel, the message text (or blocks), and post_at, a Unix timestamp for when Slack should deliver it.

The limit that catches people: post_at can only be set up to 120 days in the future. Ask for anything beyond that and the API returns a time_too_far error instead of scheduling the message. If you need something further out, a 6-month announcement calendar for example, you're holding the message yourself and calling chat.scheduleMessage closer to the date, or firing chat.postMessage directly when your own timer says it's time.

A couple of practical notes from actually building against this endpoint: scheduled messages show up for cancellation via chat.deleteScheduledMessage, and because thread replies aren't schedulable in the UI, the API mirrors that constraint for thread_ts in most practical setups too, so plan your threading logic accordingly.

Real rate limits (and the fake one everyone quotes)

There's a number that circulates constantly in Slack developer threads: "30 messages per 5 minutes per channel." It shows up in forum answers, in blog posts, in Stack Overflow comments. It is not in Slack's own rate-limit documentation, and treating it as gospel will make you build unnecessarily conservative queues.

What Slack actually publishes is tiered. chat.postMessage and chat.scheduleMessage sit in a tier that's commonly cited as roughly 1 message per second per channel as a sustained-write guideline, with Slack's Tier 3 bucket allowing on the order of 50-plus requests per minute per workspace token before you risk a 429. Treat the specific numbers as Slack's own published tiers rather than the recycled "30 per 5 minutes" folklore, since Slack has adjusted tier thresholds before without much fanfare. If you're firing a burst of scheduled messages at the same moment (say, a digest going to fifty channels at once), stagger them instead of assuming a fixed per-channel ceiling.

On message size: Slack enforces a 40,000-character hard limit per message. Send more than that and the API doesn't reject it outright, it truncates the message server-side and returns a message_truncated warning in the response. Worth checking for in your code if you're ever assembling long digests programmatically, since a silent truncation is easy to miss until someone asks where the rest of the report went.

When a cross-platform scheduler fits

Slack scheduling on its own solves Slack. Most teams who care about this also have an announcement that needs to land somewhere else at the same time: a product update going to a Slack channel and to X and LinkedIn within the same hour, a community digest that's also a Discord post and an Instagram caption.

That's the gap a calendar-first tool like TimeToPost fills. It's not a Slack connector claiming to replace chat.scheduleMessage, it's the layer that sits above individual platforms: one calendar where you draft the announcement once, use a character counter to check it fits your tightest target platform, and schedule the social side of the release to fire at the same moment your Slack message or workflow goes out. If your calendar already lives in TimeToPost for your social accounts, pairing the Slack side of an announcement with the social side on the same visual timeline is a lot less error-prone than tracking both in your head. See our best time to post research for the timing side, and the timezone posting planner if your team and your audience aren't in the same timezone, which is its own scheduling headache on top of everything else here.

Limits and rules, at a glance

  • Native Send later: available on top-level messages, not thread replies.
  • Recurring sends: Slack Automations (Workflows), not Send later.
  • API scheduling: chat.scheduleMessage, max 120 days out via post_at, time_too_far beyond that.
  • Rate limits: tiered by method, commonly cited around 1 msg/sec/channel sustained and 50-plus/min per workspace token before 429s. The "30 per 5 minutes" number is not an official Slack limit.
  • Message length: 40,000-character hard cap, with server-side truncation and a message_truncated warning past that.

FAQ

Can I edit a scheduled Slack message after I set it? Yes, native scheduled messages can be edited or canceled from the Scheduled Messages view any time before they fire. Via the API, use chat.deleteScheduledMessage to cancel, then reschedule with a new post_at.

Is 120 days a hard wall for the API? Yes. post_at beyond 120 days from now returns a time_too_far error. For anything further out, you hold the send date yourself and call the API closer to it.

What's the actual character limit for a Slack message? 40,000 characters. Slack doesn't reject an overlong message outright, it truncates it server-side and flags the response with message_truncated, so check for that if you're sending programmatically.

Can I schedule a Slack DM the same way as a channel message? Yes, Send later and chat.scheduleMessage both work on direct messages the same way they work on channels, with the same thread-reply exception applying to threaded DMs.

Related posts

Put these strategies into action

TimeToPost helps you schedule content, track performance, and grow your audience, all in one place.