A tinted, zoomed in screenshot of a JSON object showing server information about a Mastodon instance.

Making fediverse apps for everyone

Fediverse is awesome! And it’s also a huge pain if you want to make a simple app that plays nice with all the different platforms it’s made up of.

Yes, there are standards, like ActivityPub, sure. But there is a lot of technologies being used to build the fediverse software, and they’re not necessarily all compatible, at least not without a bit of effort.

Here’s everything I’ve learned from my experience building my fediverse connections data visualization and other projects.

I will focus on some of the most popular platforms, and I intend to keep this article updated, so if I’m missing anything, please do let me know.

Basic server information

To get a link to an endpoint that shows basic information about the server, including what software it runs, and its version, whether the server is open for public signups, and more, you can send a request to /.well-known/nodeinfo.

Here’s an example from mastodon.social, which runs Mastodon. Many, but not all platforms support the /nodeinfo/2.0 endpoint.

{
  "links": [
    {
      "rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
      "href": "https://mastodon.social/nodeinfo/2.0"
    }
  ]
}

One more example, from stereophonic.space, a Pleroma server.

{
  "links": [
    {
      "href": "https://stereophonic.space/nodeinfo/2.0.json",
      "rel": "http://nodeinfo.diaspora.software/ns/schema/2.0"
    },
    {
      "href": "https://stereophonic.space/nodeinfo/2.1.json",
      "rel": "http://nodeinfo.diaspora.software/ns/schema/2.1"
    }
  ]
}

Here are more examples for some of the popular fediverse platforms.

PlatformExample
Mastodonhttps://mastodon.social/.well-known/nodeinfo
Pleromahttps://blob.cat/.well-known/nodeinfo
Akkomahttps://mycrowd.ca/.well-known/nodeinfo
Friendicahttps://venera.social/.well-known/nodeinfo
Diasporahttps://podington.oksocial.net/.well-known/nodeinfo
Misskeyhttps://misskey.id/.well-known/nodeinfo
Firefishhttps://firefish.social/.well-known/nodeinfo
Peertubehttps://urbanists.video/.well-known/nodeinfo
Pixelfedhttps://pixelfed.de/.well-known/nodeinfo

And here’s a simple example of how you might process this information.

Logging in

Most platforms support OAuth for logging in, with Misskey, and its clone, Firefish (previously called Calckey), being one exception. (Technically, there is a compatibility layer with Mastodon that should provide this functionality, but it doesn’t really work reliably.)

Also, do note that Pixelfed’s OAuth implementation works, but as of the writing of this article, there is a bug preventing you from making API requests once you do successfully log in.

PlatformSupported methods
MastodonOAuth
PleromaOAuth
AkkomaOAuth
FriendicaOAuth and basic HTTP authentication
DiasporaOpenID
MisskeyMiAuth (no OAuth support)
FirefishMiAuth (no OAuth support)
PeertubeA custom implementation of OAuth
PixelfedOAuth

I have a work-in-progress authentication server up on GitHub that should give you a head start implementing your own.

Scopes

Part of the logging-in process is providing permissions your app needs. Here’s how different platforms manage this.

PlatformDocumentation
MastodonOAuth scopes
PleromaAuthentication & Authorization
AkkomaAuthentication & Authorization
Friendican/a
DiasporaAccess scopes
MisskeyThe official documentation links to a non-existent page, but you can see them in the source code.
FirefishSame as Misskey.
Peertuben/a
Pixelfedn/a

Getting account information

Once you obtain a user token, you might want to get basic information about the user logging in, like name, and their profile image.

Here’s an example with node.js for platforms that support Mastodon’s accounts/verify_credentials API endpoint, including Mastodon, Friendica, Pleroma, and Akkoma.

const resp = await fetch(
  `https://${instance}/api/v1/accounts/verify_credentials`,
  {
    headers: new Headers({
      Authorization: `Bearer ${token}`,
    }),
  }
);

const respJSON = await resp.json();

const user = {
  name: respJSON.display_name || respJSON.username,
  username: respJSON.username,
  username_full: `@${respJSON.username}@${instance}`,
  avatar_url: respJSON.avatar_static,
  token,
};

And here’s an example for Misskey, and its clone Firefish (previously Calckey).

const resp = await fetch(`https://${instance}/api/i`, {
  headers: {
    "content-type": "application/json",
  },
  body: JSON.stringify({
    i: token,
  }),
  method: "POST",
});

const respJSON = await resp.json();

const user = {
  name: respJSON.name,
  username: respJSON.username,
  username_full: `@${respJSON.username}@${instance}`,
  avatar_url: respJSON.avatarUrl,
  token,
};

Sharing dialog

Some platforms allow you to link to a page that lets you prefill a message before sharing it. Remember to URI encode any parameters you’re passing to the sharing URL (example with JavaScript).

PlatformExample share URL
Mastodonhttps://mastodon.social/share?text=TEXT
Pleroman/a
Akkoman/a
Friendican/a
Diasporahttps://podington.oksocial.net/bookmarklet?url=URL&title=TITLE&note=NOTE
Misskeyhttps://misskey.id/share?text=TEXT
Firefishhttps://firefish.social/share?text=TEXT
Peertuben/a
Pixelfedn/a

Embedding posts

This section is work in progress. See also my Fediverse Embeds plugin.

I'm looking into embedding fediverse posts and I see that out of the major platforms, only Mastodon and Peertube support embedding via iframes.

Some of the platforms should at least support oEmbed, but I can't seem to get this to work.

Does anyone know more about this?

— Stefan Bohacek (@stefan@stefanbohacek.online) 2023-06-19T13:57:31.945Z

PlatformEmbed supportoEmbed URL
Mastodoniframe, oEmbedhttps://mastodon.social/api/oembed?url=URL
Pleroman/an/a
Akkoman/an/a
Friendican/an/a
Diasporan/an/a
Misskeynon/a
Firefishnon/a
Peertubeiframe, oEmbedhttps://urbanists.video/services/oembed?url=URL
Pixelfediframen/a

Tags

This section is work in progress.

PlatformTagProfile tag
Mastodonhttps://mastodon.social/tags/fediversehttps://mastodon.social/@mastodon/tagged/mastodon
Pleroman/an/a
Akkoman/an/a
Friendican/an/a
Diasporan/an/a
Misskeyn/an/a
Firefishn/an/a
Peertuben/an/a
Pixelfedn/an/a

RSS feeds

This section is work in progress.

PlatformProfileTags
Mastodonhttps://mastodon.social/@mastodon.rsshttps://mastodon.social/@mastodon/tagged/mastodon.rss
Pleromahttps://blob.cat/users/stefanbohacek/feed.rssn/a
Akkomahttps://mycrowd.ca/users/stefanbohacek/feed.rssn/a
Friendican/an/a
Diasporan/an/a
Misskeyn/an/a
Firefishn/an/a
Peertuben/an/a
Pixelfedn/an/a

Mastodon compatibility

While there actually is an ActivityPub client-server standard called ActivityPub Client-to-Server (or AP C2S, thanks to @unexpectedteapot for the heads-up), it is not widely adopted. Instead, some platforms opted for increased compatibility with Mastodon (link to documentation) and support several of the endpoints.

PlatformMastodon compatibility
Pleromadifferences in Mastodon API responses
Akkomadifferences in Mastodon API responses
Friendica– login via OAuth works the same
– Friendica supports many of the same API endpoints
Diasporan/a
Misskeyn/a
FirefishMastodon API layer via plugins, spotty OAuth compatibility
Peertuben/a
Pixelfedn/a

Official documentation

PlatformDocumentation
MastodonGetting started with the API
APIs
PleromaPleroma API
AkkomaAkkoma Documentation
FriendicaFriendica API
Diasporadiaspora* API documentation
MisskeyMisskey API
FirefishFirefish API
PeertubePeerTube documentation
PixelfedPixelfed Documentation
Pixelfed API Reference

More resources

  • Fedidocs: example payloads and notes about different fediverse platforms

Usually I polish my work a bit more before releasing it publicly, but I really wanted to give people interested in making fediverse apps for everyone a bit of a head start.

Here's a very work-in-progress authentication server I use for my fediverse connections data visualization project:

github.com/stefanbohacek/auth-

— Stefan Bohacek (@stefan@stefanbohacek.online) 2023-06-02T14:17:20.706Z

And here's a few things I learned along the way.

stefanbohacek.com/blog/making-

I hope this is all useful, and I'll welcome any help to make these better!

— Stefan Bohacek (@stefan@stefanbohacek.online) 2023-06-02T14:18:13.044Z

More tutorials

A tinted screenshot of two charts, one showing the popularity of various fediverse platforms (with Mastodon far ahead of the rest), and the other chart showing distribution of domain creation dates, mostly clustered around 2023.
A tinted screenshot showing the @mtaupdates Mastodon profile and a few example posts with subway status alerts.
A tinted screenshot showing the finished bot posting a flag and asking about a corresponding capital, followed by a reply from me with a correct answer, and the bot accepting it.

💻 Browse all