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.
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 inboxoutbox: URL of the user’s outboxsharedInbox: 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.
- 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. - 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). - Locate the outbox URL in the response
In the returned JSON, find theoutboxfield. It will look like"outbox": "https://mastodon.social/users/Gargron/outbox". - Fetch the outbox collection
Run:curl -H "Accept: application/activity+json" https://mastodon.social/users/Gargron/outbox
The response is an OrderedCollection with afirstlink to the first page. - Follow the first page link
Use the URL in thefirstfield to get the initial page of activities. Each item in theorderedItemsarray is an ActivityPub activity. - Inspect individual activities
Each activity includes atypefield. Common types areCreate(new post),Announce(boost),Like(favorite), andFollow. Theobjectfield 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", ""))
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.