Posts Photos Archives About

Some notes on posting to Mastodon via their HTTP API using Python. The backend of this site uses similar code to enable automated syndication to my Mastodon account.

Creating an access token

  • Go to your mastodon preferences (it's the gear icon above the search bar in the web interface) and click Development. (Or go to [yourservername]/settings/applications)
  • Click "New Application". Specify application name. Default permissions should be fine. Save.
  • Click your application name in the grid on the Development page. Your access token will be in the top part of the screen.

Posting a status (or as they call it, a "toot")

Just need to send one HTTP request. I recommend using the requests library for Python.

Use the token you got above as the "Bearer" in the authorization header. Post the toot contents as a "status" field to the /api/v1/statuses endpoint of your Mastodon server.

data = { "status": "The content of your toot goes here!"}

url = "%s/api/v1/statuses" % (MASTODON_HOST)
r =, 
        headers={'Authorization': 'Bearer %s' % (MASTODON_TOKEN)})
json_data = r.json() # you can inspect the json response to check for problems

Attaching images to a toot

Fine, I'll use "toot"!

Upload your images via the /api/v1/media endpoint.

The post payload should be a "file" field with (filename, fileobject, mimetype). Pass the file data via the files parameter of

For alt-text, pass a description field via the data parameter.

Get the id field from the json response, you'll need them when posting the toot.

You can upload up to 4 images for a single toot. You can pass the id fields as an array via the media_ids[] parameter when posting the toot.

import requests
from pathlib import Path

# upload test files to /api/v1/media
files_root = Path("d:\\temp\\masto")
media_ids = []
for file in TEST_FILES:
    test_file = files_root / file
    data = {
        'description': 'Test file ' + file
    files = {
        'file': (file,'rb'), 'application/octet-stream')
    url = "%s/api/v1/media" % (MASTODON_HOST)
    r =, 
        headers={'Authorization': 'Bearer %s' % (MASTODON_TOKEN)})
    json_data = r.json()

    media_id = json_data['id']

# after collecting the media ids, include them in the toot payload
data = { 
    "status": "This should be a status with multiple attached images!", 
    "media_ids[]": media_ids

url = "%s/api/v1/statuses" % (MASTODON_HOST)
r =, 
        headers={'Authorization': 'Bearer %s' % (MASTODON_TOKEN)})
json_data = r.json()

That should be it! The API documentation for Mastodon is actually pretty straightforward so it's easy to figure out.

Mon, Nov. 8, 2021, 7:49 p.m. / / blog / #tech-life #software-development #python #mastodon / Syndicated: mastodon twitter / 👍 1 / 💬 1 / 413 words

Last modified at: Nov. 8, 2021, 8:24 p.m. Source file

👍 Flarnie


Al Wirtes said...

This is fantastic! Thank you!

One slight omission: When you're iterating through TEST_FILES, you need to remember to include the data parameter in your post. So you need to add data=data, after files=files,.