Post

Mastodon API Scheduling: Complete Developer Guide 2026

Master Mastodon API scheduling with this complete developer guide. Learn authentication, endpoints, and code examples for programmatic scheduled posts.

Mastodon API Scheduling: Complete Developer Guide 2026

Building custom scheduling solutions through the Mastodon API scheduling endpoints gives you complete control over automated posting. Whether you’re integrating Mastodon into existing workflows, building a custom scheduling tool, or automating content pipelines, the API provides the foundation for programmatic post scheduling.

This developer guide covers everything needed to implement Mastodon API scheduling: authentication setup, endpoint details, parameter options, and practical code examples in multiple languages.

Why Use the API for Scheduling?

Third-party scheduling tools work well for most users, but the API enables capabilities those tools don’t provide.

Custom integrations become possible. Publish Mastodon posts automatically when you release blog articles, push commits, or trigger any other external event. Connect Mastodon posting to your existing content pipelines rather than managing it separately.

Unique workflows emerge. Build approval processes, batch import from spreadsheets, create custom interfaces optimized for your specific needs, or develop features no existing tool offers.

Privacy considerations matter. Using the API directly means your content and credentials don’t pass through third-party services. For users who value this, direct API interaction provides maximum control.

Cost efficiency improves at scale. Paid scheduling tools charge ongoing fees. Once built, API-based solutions cost only server resources to run.

Authentication Setup

Before making API calls, you need authentication credentials.

Creating an Application

Every Mastodon instance includes a developer interface for creating applications. Navigate to Preferences → Development → Your applications, then create a new application.

When creating your application, you’ll provide:

  • Application name: Something descriptive for your use case
  • Website: Your project’s URL (optional but good practice)
  • Redirect URI: Use urn:ietf:wg:oauth:2.0:oob for development/testing
  • Scopes: The permissions your application needs

For scheduling, you need these scopes:

  • read:statuses - View your scheduled posts
  • write:statuses - Create and manage scheduled posts
  • write:media - Upload media for scheduled posts (if using images/video)

Obtaining Your Access Token

After creating the application, the interface displays your access token. This token authenticates all your API requests. Copy and store it securely—treat it like a password.

The token appears as a long alphanumeric string. You’ll include it in the Authorization header of every API request:

1
Authorization: Bearer your_access_token_here

Never commit tokens to version control or expose them in client-side code. Use environment variables or secure secret management.

The Scheduled Statuses Endpoints

Mastodon’s API includes dedicated endpoints for scheduled post management.

Scheduling a New Post

Creating a scheduled post uses the same endpoint as regular posting, with an additional parameter.

Endpoint: POST /api/v1/statuses

Key Parameters:

Parameter Type Description
status string The text content of your post
scheduled_at string ISO 8601 timestamp for publication
visibility string public, unlisted, private, or direct
media_ids array IDs of uploaded media to attach
spoiler_text string Content warning text
poll object Poll configuration (if including a poll)

The scheduled_at parameter transforms a regular post request into a scheduled one. Without it, the post publishes immediately.

Listing Scheduled Posts

Retrieve all your pending scheduled posts:

Endpoint: GET /api/v1/scheduled_statuses

Parameters:

  • max_id - Return statuses older than this ID
  • since_id - Return statuses newer than this ID
  • min_id - Return statuses immediately newer than this ID
  • limit - Maximum number to return (default 20, max 40)

Viewing a Specific Scheduled Post

Endpoint: GET /api/v1/scheduled_statuses/:id

Returns the full scheduled status object for the specified ID.

Updating a Scheduled Post

Endpoint: PUT /api/v1/scheduled_statuses/:id

You can update the scheduled time of a pending post. Note that content changes may be limited depending on Mastodon version—check current documentation for your instance’s version.

Parameter: scheduled_at - New ISO 8601 timestamp

Canceling a Scheduled Post

Endpoint: DELETE /api/v1/scheduled_statuses/:id

Removes the scheduled post from the queue. The post will not be published.

Code Examples

Here are practical examples implementing Mastodon API scheduling in common languages.

Python Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import requests
from datetime import datetime, timedelta

# Configuration
instance_url = "https://mastodon.social"
access_token = "your_access_token"

headers = {
    "Authorization": f"Bearer {access_token}"
}

# Schedule a post for tomorrow at 2 PM UTC
scheduled_time = datetime.utcnow() + timedelta(days=1)
scheduled_time = scheduled_time.replace(hour=14, minute=0, second=0)

payload = {
    "status": "This is a scheduled post from the API!",
    "scheduled_at": scheduled_time.isoformat() + "Z",
    "visibility": "public"
}

response = requests.post(
    f"{instance_url}/api/v1/statuses",
    headers=headers,
    data=payload
)

if response.status_code == 200:
    scheduled_post = response.json()
    print(f"Scheduled post ID: {scheduled_post['id']}")
    print(f"Will post at: {scheduled_post['scheduled_at']}")
else:
    print(f"Error: {response.status_code}")
    print(response.text)

JavaScript/Node.js Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const axios = require('axios');

const instanceUrl = 'https://mastodon.social';
const accessToken = 'your_access_token';

async function schedulePost(content, scheduledTime) {
  try {
    const response = await axios.post(
      `${instanceUrl}/api/v1/statuses`,
      {
        status: content,
        scheduled_at: scheduledTime.toISOString(),
        visibility: 'public'
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`
        }
      }
    );
    
    console.log('Scheduled post:', response.data);
    return response.data;
  } catch (error) {
    console.error('Scheduling failed:', error.response?.data || error.message);
    throw error;
  }
}

// Schedule for 3 hours from now
const postTime = new Date(Date.now() + 3 * 60 * 60 * 1000);
schedulePost('Hello from the API!', postTime);

cURL Example

1
2
3
4
5
curl -X POST "https://mastodon.social/api/v1/statuses" \
  -H "Authorization: Bearer your_access_token" \
  -d "status=Scheduled via cURL!" \
  -d "scheduled_at=2026-03-15T14:00:00.000Z" \
  -d "visibility=public"

Scheduling with Media

To schedule posts with images or videos, upload media first, then reference it in your scheduled post.

Step 1: Upload Media

Endpoint: POST /api/v2/media

1
2
3
4
5
6
7
8
9
10
11
# Upload an image
with open('image.jpg', 'rb') as f:
    files = {'file': ('image.jpg', f, 'image/jpeg')}
    response = requests.post(
        f"{instance_url}/api/v2/media",
        headers=headers,
        files=files,
        data={'description': 'Alt text for accessibility'}
    )

media_id = response.json()['id']

Step 2: Include Media in Scheduled Post

1
2
3
4
5
6
payload = {
    "status": "Check out this image!",
    "scheduled_at": scheduled_time.isoformat() + "Z",
    "media_ids[]": media_id,  # Note the array syntax
    "visibility": "public"
}

Error Handling

Robust implementations handle common error scenarios.

Rate Limits

Mastodon instances typically allow 300 requests per 5 minutes. When approaching limits, the API returns rate limit headers:

  • X-RateLimit-Limit - Maximum requests allowed
  • X-RateLimit-Remaining - Requests remaining in window
  • X-RateLimit-Reset - When the window resets

Implement backoff logic that respects these limits:

1
2
3
4
5
6
7
8
9
10
11
12
13
import time

def make_request_with_backoff(func, *args, **kwargs):
    while True:
        response = func(*args, **kwargs)
        
        if response.status_code == 429:  # Rate limited
            reset_time = response.headers.get('X-RateLimit-Reset')
            wait_seconds = max(1, int(reset_time) - time.time())
            time.sleep(wait_seconds)
            continue
            
        return response

Validation Errors

The API validates scheduled times. Common rejections:

  • Scheduled time in the past
  • Scheduled time too far in the future (instance-dependent)
  • Invalid timestamp format

Handle 422 responses gracefully with informative error messages.

Building a Scheduling System

For production use, consider these architectural elements:

Job Queue Integration

Rather than scheduling through the API and relying on Mastodon to trigger publication, some systems prefer storing scheduled posts in their own database with a job queue (like Celery, Sidekiq, or Bull) that triggers API calls at the appropriate time.

This approach provides:

  • Better visibility into scheduled content
  • Easier modification and cancellation
  • Integration with approval workflows
  • Independence from Mastodon’s scheduling implementation

Database Storage

Store scheduling metadata:

1
2
3
4
5
6
7
8
9
10
CREATE TABLE scheduled_posts (
  id SERIAL PRIMARY KEY,
  mastodon_scheduled_id VARCHAR(255),
  content TEXT NOT NULL,
  scheduled_at TIMESTAMP NOT NULL,
  visibility VARCHAR(20) DEFAULT 'public',
  media_ids TEXT[], -- Array of media IDs
  status VARCHAR(20) DEFAULT 'pending', -- pending, published, cancelled
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Monitoring

Track scheduled post success:

  • Verification that scheduled posts actually published
  • Alerting when API errors prevent scheduling
  • Dashboards showing scheduling activity

Frequently Asked Questions

How far in advance can I schedule via API?

Most instances allow scheduling weeks or months ahead. Very long-term scheduling (years) may not be supported. The API returns an error if the scheduled time is unacceptable.

Can I modify scheduled post content?

Modifying content depends on Mastodon version. Time modifications are broadly supported. For content changes, you may need to delete and reschedule.

Does the scheduled_at time need to be UTC?

ISO 8601 timestamps should include timezone information or use UTC (indicated by ‘Z’ suffix). UTC is recommended for consistency.

What happens if my instance is down at scheduled time?

Mastodon typically publishes the post when the instance recovers. Brief outages don’t lose scheduled posts.

Can I schedule to multiple accounts?

Yes, but each account needs its own access token. Your application can manage multiple tokens for multiple accounts.

Conclusion

Mastodon API scheduling enables powerful custom solutions beyond what GUI tools provide. With understanding of authentication, endpoints, and proper implementation patterns, you can build scheduling systems tailored precisely to your needs.

Start with basic scheduling, then expand to include media, error handling, and monitoring as your requirements grow. The API is well-documented and stable—a solid foundation for scheduling automation.

For non-developer scheduling options, see our comprehensive guide on how to schedule Mastodon posts.

This post is licensed under CC BY 4.0 by the author.