Mastodon Inbox vs Outbox Endpoints: How to Read ActivityPub Internals
🔍 WiseChecker

Mastodon Inbox vs Outbox Endpoints: How to Read ActivityPub Internals

When you use Mastodon, every action you take—posting, boosting, following—is sent as an ActivityPub message. These messages travel between inbox and outbox endpoints on each server. Understanding how these endpoints work helps you debug federation issues, inspect raw activity flows, and build tools that interact with Mastodon programmatically. This article explains what inbox and outbox endpoints are, how to read their contents, and what common mistakes to avoid when working with ActivityPub internals.

Key Takeaways: Mastodon Inbox vs Outbox Endpoints Explained

  • Outbox endpoint (https://instance.example/users/username/outbox): Lists public activities created by a user, such as posts, boosts, and follows, in reverse chronological order.
  • Inbox endpoint (https://instance.example/users/username/inbox): Receives incoming activities from other servers; its contents are not publicly readable for privacy reasons.
  • SharedInbox endpoint (https://instance.example/inbox): A server-wide inbox that receives activities not directed at a specific user, typically used for broadcast messages like delete and update.

ADVERTISEMENT

ActivityPub Endpoints: What Inbox and Outbox Actually Do

ActivityPub is a decentralized social networking protocol. Every Mastodon actor—a user, a group, or a bot—has two primary endpoints: an inbox and an outbox. These endpoints are URLs exposed in the actor’s JSON-LD profile, which you can retrieve by fetching the actor’s URI with an Accept: application/activity+json header.

The outbox is a collection of activities that the actor has published. For a Mastodon user, this includes Create activities for new posts, Announce activities for boosts, and Follow activities. The outbox is paginated and publicly readable, though private or direct posts are not included.

The inbox is where incoming activities from other actors arrive. When another server sends a Follow activity to a user, that activity goes into the user’s inbox. The inbox is not publicly readable; Mastodon returns a 401 Unauthorized error if you try to fetch it without authentication. This is a deliberate privacy measure.

SharedInbox: The Server-Level Inbox

Mastodon also implements a SharedInbox endpoint. This is a single URL that receives activities for all users on the same domain. For example, when a remote server sends a Delete activity for a post, it often goes to the SharedInbox rather than each user’s personal inbox. The SharedInbox is also not publicly readable.

How Endpoints Are Discovered

Every Mastodon actor’s profile contains a JSON-LD document with the following fields when fetched with the proper Accept header:

  • inbox: URL of the user’s personal inbox
  • outbox: URL of the user’s outbox
  • sharedInbox: URL of the server’s shared inbox

You can discover these endpoints for any public Mastodon profile. For example, fetching https://mastodon.social/users/Gargron with the correct header returns the actor object containing these URLs.

Reading the Outbox Endpoint: Step-by-Step

To read a Mastodon user’s outbox, you send an HTTP GET request to the outbox URL with the appropriate Accept header. The outbox returns an OrderedCollectionPage of activities. Each activity contains an id, type, actor, object, and published timestamp.

  1. Get the actor’s profile URL
    Open the Mastodon user’s profile in a browser. Copy the URL from the address bar. For example, https://mastodon.social/@Gargron.
  2. Fetch the actor JSON with a tool like curl
    Run this command in your terminal:
    curl -H "Accept: application/activity+json" https://mastodon.social/users/Gargron
    Replace the URL with the actual actor URI (the @username path resolves to /users/username).
  3. Locate the outbox URL in the response
    In the returned JSON, find the outbox field. It will look like "outbox": "https://mastodon.social/users/Gargron/outbox".
  4. Fetch the outbox collection
    Run: curl -H "Accept: application/activity+json" https://mastodon.social/users/Gargron/outbox
    The response is an OrderedCollection with a first link to the first page.
  5. Follow the first page link
    Use the URL in the first field to get the initial page of activities. Each item in the orderedItems array is an ActivityPub activity.
  6. Inspect individual activities
    Each activity includes a type field. Common types are Create (new post), Announce (boost), Like (favorite), and Follow. The object field contains the post or target actor.

Reading the Outbox with Python

If you prefer scripting, use Python’s requests library. Here is a minimal example:

import requests

headers = {"Accept": "application/activity+json"}
profile_url = "https://mastodon.social/users/Gargron"
profile = requests.get(profile_url, headers=headers).json()
outbox_url = profile["outbox"]
outbox = requests.get(outbox_url, headers=headers).json()
first_page = requests.get(outbox["first"], headers=headers).json()
for activity in first_page["orderedItems"]:
    print(activity["type"], activity["object"].get("id", ""))

ADVERTISEMENT

Common Misconceptions and Limitations When Reading Endpoints

The Inbox Endpoint Returns 401 Unauthorized

This is expected behavior. Mastodon does not expose inbox contents to unauthenticated requests. Even with authentication, Mastodon’s API does not provide a direct way to read a user’s inbox. The inbox is only used internally by the server to process incoming activities. If you need to see activities sent to a user, use the Mastodon API’s notifications endpoint instead.

Outbox Pagination Is Limited to Recent Activities

Mastodon’s outbox only returns activities from the last 30 days by default. Older activities are not accessible via the ActivityPub outbox. This is a server-side limit. If you need historical data, use the Mastodon API’s statuses endpoint, which can go further back depending on server configuration.

Not All Activities Appear in the Outbox

The outbox only contains activities that are publicly visible. Private mentions, followers-only posts, and direct messages are excluded. Additionally, some server-side activities like automatic account deletion may not appear in the outbox at all.

SharedInbox vs Personal Inbox Confusion

When reading a Mastodon actor’s profile, you will see both inbox and sharedInbox fields. The shared inbox is used for broadcast messages. If you are building a federated application, always send activities to the shared inbox first, because Mastodon’s documentation recommends it for efficiency. The personal inbox is reserved for activities that are explicitly directed at that specific user.

Mastodon Inbox vs Outbox vs SharedInbox: Key Differences

Item Inbox Outbox SharedInbox
Purpose Receives incoming activities for a single user Lists outgoing activities published by a user Receives broadcast activities for all users on the server
Publicly readable No (returns 401) Yes (paginated, last 30 days) No (returns 401)
Authentication needed to read Yes (internal only) No Yes (internal only)
Typical activities received Follow, Like, Announce, Create Create, Announce, Like, Follow Delete, Update, Undo
Scope Per user Per user Per server

Conclusion

Now you can distinguish between a Mastodon user’s inbox, outbox, and shared inbox. The outbox is the only endpoint you can read without authentication, and it shows public activities from the last 30 days. If you need to debug federation issues, start by reading the outbox of the affected user. For incoming activity inspection, use the Mastodon API’s notifications endpoint or enable debug logging on your server. As an advanced tip, set the Accept header to application/activity+json when fetching any actor URI to get the full JSON-LD profile with all endpoint URLs.

ADVERTISEMENT