A general information about asynchronous I/O in Python can be found in the standard library documentation.


pip install -U atoot

Register an application and get the authentication token

The first thing we will need to do is to register an application, in order to be able to generate access tokens later. The application can be created like so:

instance = "botsin.space"

async with aiohttp.ClientSession() as session:
   client_id, client_secret = await atoot.MastodonAPI.create_app(session,
      instance, client_name="test_bot",

   print(client_id, client_secret)

In the above example, we specify the client name and website, which will be shown on statuses if applicable.

These client_id and client_secret values will be used to generate access tokens, so they should be cached for later use.

Now that we have an application, let’s obtain an access token that will authenticate our requests as that client application.

There are 2 ways to get access token:

  1. Visit the special URL with your browser, which can be generated like so:
login_url = atoot.MastodonAPI.browser_login_url(instance, client_id)

It will display access token after user authentication.

  1. Use username and password to generate access_token without a browser:
instance = "botsin.space"
client_id, client_secret = "...", "..."
username, password = "example@email.com", "Pa$$w0rd"

async with aiohttp.ClientSession() as session:
   access_token = await atoot.MastodonAPI.login(session, instance,
      client_id, client_secret, username=username, password=password)

Once you have the access token, save it in your local cache.

Use the authenticated client

With an access token you may use every other API method, for example:

instance = "botsin.space"

async with atoot.client(instance, access_token=access_token) as c:
    # Retrieve your account information
    print(await c.verify_account_credentials())
    # Create a status
    print(await c.create_status(status="Hello world!"))
    # Get 3 pages of a local timeline
    print(await c.get_n_pages(c.public_timeline(local=True), n=3))