Mastodon can queue a post through the same statuses API endpoint that publishes immediately. Scheduling is useful for maintenance announcements, release notices, or automation where the publication time matters more than when the script runs.
The scheduling field is scheduled_at on POST /api/v1/statuses. When that field is present, Mastodon returns a ScheduledStatus object instead of a published status, so automation should keep the returned scheduled-status ID until the post is published or cancelled.
A scheduled timestamp must be an RFC3339 datetime at least five minutes in the future. Use a token with write:statuses for the creation request and read:statuses for the verification request, and keep bearer tokens out of saved transcripts, screenshots, and shared ticket text.
Required scopes: write:statuses read:statuses
A token with only write:statuses can create the scheduled post, but it cannot list or read scheduled statuses through GET /api/v1/scheduled_statuses.
$ export MASTODON_URL="https://social.example.com"
$ read -r -s MASTODON_ACCESS_TOKEN
The token can post as the account that granted it. Do not paste a real token into scripts, screenshots, logs, or support tickets.
$ export SCHEDULED_AT="2030-07-01T09:00:00.000Z"
Replace the sample time with the real target time. A value less than five minutes ahead of the server clock is rejected as a validation error.
$ curl --silent --show-error --request POST "$MASTODON_URL/api/v1/statuses" \ --header "Authorization: Bearer $MASTODON_ACCESS_TOKEN" \ --header "Idempotency-Key: status-maintenance-20300701-0900" \ --data-urlencode "status=Scheduled maintenance starts at 09:00 UTC." \ --data-urlencode "visibility=unlisted" \ --data-urlencode "scheduled_at=$SCHEDULED_AT" { "id": "3221", "scheduled_at": "2030-07-01T09:00:00.000Z", "params": { "text": "Scheduled maintenance starts at 09:00 UTC.", "visibility": "unlisted", "scheduled_at": null }, "media_attachments": [] }
Use a unique Idempotency-Key for each intended scheduled post. Reusing one within the one-hour retry window can return the earlier submission instead of creating a separate scheduled post.
$ export SCHEDULED_STATUS_ID="3221"
$ curl --silent --show-error --request GET "$MASTODON_URL/api/v1/scheduled_statuses" \ --header "Authorization: Bearer $MASTODON_ACCESS_TOKEN" [ { "id": "3221", "scheduled_at": "2030-07-01T09:00:00.000Z", "params": { "text": "Scheduled maintenance starts at 09:00 UTC.", "visibility": "unlisted" }, "media_attachments": [] } ]
$ curl --silent --show-error --request DELETE "$MASTODON_URL/api/v1/scheduled_statuses/$SCHEDULED_STATUS_ID" \ --header "Authorization: Bearer $MASTODON_ACCESS_TOKEN" {}
Do not run this against a real announcement that should remain queued for publication.