Pixelfed — Complete Reference
Overview
Pixelfed is a free, open-source, decentralized photo and video sharing platform — the Fediverse's answer to Instagram. Created by Daniel Supernault ("dansup") and launched December 25, 2018, it federates via ActivityPub. As of mid-2025, it has approximately 900,000 registered users across roughly 1,800 servers with 96+ million media items shared. Licensed under AGPL-3.0.
Pixelfed only displays posts with images or video — text-only posts from other Fediverse platforms are hidden. This is a fundamental design decision, not a bug.
1. Technical Stack
| Layer | Technology |
|---|---|
| Backend language | PHP |
| Backend framework | Laravel (currently v12) |
| Database | MySQL 8.0 or PostgreSQL 13 |
| Cache / Queue | Redis |
| Queue management | Laravel Horizon |
| OAuth | Laravel Passport |
| Frontend framework | Vue.js 2.6.14 |
| Frontend state | Vuex |
| CSS | Bootstrap |
| Build | Webpack via Laravel Mix |
| Mobile | React Native (iOS + Android) |
| Storage | Local filesystem or S3/Object Storage |
| License | AGPL-3.0 |
| Runtime | PHP 8.3+ (supports 8.4, 8.5), Node.js for assets |
2. Actor Model
Pixelfed uses Person type actors for user accounts:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{"pixelfed": "http://pixelfed.org/ns#"}
],
"type": "Person",
"id": "https://pixelfed.example/users/alice",
"preferredUsername": "alice",
"name": "Alice",
"summary": "<p>Bio text</p>",
"inbox": "https://pixelfed.example/users/alice/inbox",
"outbox": "https://pixelfed.example/users/alice/outbox",
"following": "https://pixelfed.example/users/alice/following",
"followers": "https://pixelfed.example/users/alice/followers",
"manuallyApprovesFollowers": false,
"indexable": true,
"publicKey": {
"id": "https://pixelfed.example/users/alice#main-key",
"owner": "https://pixelfed.example/users/alice",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
},
"icon": {
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://pixelfed.example/storage/avatars/alice.jpg"
},
"endpoints": {
"sharedInbox": "https://pixelfed.example/f/inbox"
},
"alsoKnownAs": []
}
Key points:
- The shared inbox path is
/f/inbox(not/inboxas with some other implementations) manuallyApprovesFollowerscontrols locked/private account behaviourindexablesignals whether the account should appear in search indexesalsoKnownAsis present but account migration between servers is not currently supported
Instance Actor
Pixelfed uses an instance-wide actor with "type": "Application" to
sign GET requests to remote instances. This is separate from the
Person actors used by regular accounts. The instance actor is used
for authorized fetch (secure mode) — when a remote server requires
signed GET requests, Pixelfed uses this actor's key.
3. Supported Activities
| Activity | Description |
|---|---|
Accept |
Approves follow requests |
Add |
Federates Stories (uses Bearcap URIs for access control) |
Announce |
Reblogs/boosts |
Create |
Creates Note and Question objects |
Delete |
Removes Person, Tombstone, and Story objects |
Flag |
Federated report functionality |
Follow |
Follow request |
Like |
Favorites a post |
Reject |
Denies follow requests |
Undo |
Reverses Announce, Follow, and Like |
Update |
Modifies Note (status) and Person (profile) |
View |
Story view tracking |
Story:Reaction |
Reaction to a Story (Pixelfed-only) |
Story:Reply |
Reply to a Story (Pixelfed-only) |
Story:Reaction and Story:Reply are Pixelfed-specific activity types
that are not understood by other Fediverse software.
4. Object Types and Post Structure
Pixelfed supports three object types: Note, Image, and Document.
Posts are represented as Note objects:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{"pixelfed": "http://pixelfed.org/ns#"}
],
"type": "Note",
"id": "https://pixelfed.example/p/alice/123456",
"attributedTo": "https://pixelfed.example/users/alice",
"content": "<p>Caption text with #hashtag</p>",
"summary": null,
"inReplyTo": null,
"published": "2025-06-15T12:00:00Z",
"url": "https://pixelfed.example/p/alice/123456",
"sensitive": false,
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": ["https://pixelfed.example/users/alice/followers"],
"attachment": [
{
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://pixelfed.example/storage/m/photo.jpg",
"name": "Alt text description",
"blurhash": "LEHV6nWB2yk8pyoJadR*.7kCMdnj"
}
],
"tag": [
{
"type": "Hashtag",
"href": "https://pixelfed.example/discover/tags/hashtag",
"name": "#hashtag"
}
],
"commentsEnabled": true,
"capabilities": {
"announce": "https://www.w3.org/ns/activitystreams#Public",
"like": "https://www.w3.org/ns/activitystreams#Public",
"reply": "https://www.w3.org/ns/activitystreams#Public"
}
}
Key points:
summaryis used for content warnings (null when not set)attachmentcontainsImageobjects with optionalblurhash- Albums can have up to 20 items (some sources say 12 for photos)
- Captions support up to 2,000 characters (configurable)
- Three visibility levels: public, unlisted, followers-only
5. Pixelfed-Specific Extensions
Capabilities
Per-post access control added to Note objects:
"capabilities": {
"announce": "https://www.w3.org/ns/activitystreams#Public",
"like": "https://www.w3.org/ns/activitystreams#Public",
"reply": null
}
Each capability value is either:
"https://www.w3.org/ns/activitystreams#Public"— allowed for everyonenull— disabled
This controls who can boost, like, or reply to a specific post. Other Fediverse software generally ignores this extension — they will still allow their users to interact with the post regardless of these settings.
commentsEnabled
A boolean property on Note objects:
"commentsEnabled": true
When false, replies are disabled on the post. Like capabilities,
this is enforced by Pixelfed but generally ignored by other
implementations.
Stories
Ephemeral 24-hour content, similar to Instagram Stories:
- Federated only between Pixelfed instances — not visible on Mastodon, Pleroma, or other platforms
- Use Bearcap URIs for access control (recipients must present a token to access the content)
- Require
STORIES_ENABLED=truein server configuration - Support activities:
Add,Delete,View,Story:Reaction,Story:Reply - Transform to
StoryReactionandStoryViewinternal models
Location Geo-tagging
Posts can include a Place object for location data:
"location": {
"type": "Place",
"name": "Paris, France",
"longitude": 2.3522,
"latitude": 48.8566,
"country": "France"
}
Blurhash
Pixelfed includes blurhash on image attachments for compact preview
placeholders. This uses the toot:blurhash property from Mastodon's
namespace (http://joinmastodon.org/ns#). The blurhash is a short
string that encodes a blurred preview of the image, useful for showing
a placeholder while the full image loads.
Federated Groups
Pixelfed supports federated Groups via FEP-400e and FEP-1b12 extensions.
Group actors use "type": "Group" with standard inbox/outbox
collections.
6. JSON-LD Context
Pixelfed uses a multi-context approach with four namespaces:
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{"pixelfed": "http://pixelfed.org/ns#"},
{"toot": "http://joinmastodon.org/ns#"}
]
| Namespace | Purpose |
|---|---|
https://www.w3.org/ns/activitystreams |
ActivityStreams 2.0 vocabulary |
https://w3id.org/security/v1 |
W3C Security Vocabulary (publicKey) |
http://pixelfed.org/ns# |
Pixelfed-specific properties (capabilities, commentsEnabled) |
http://joinmastodon.org/ns# |
Mastodon compatibility (blurhash, indexable) |
When processing Pixelfed JSON-LD documents, unknown properties from the
pixelfed: and toot: namespaces should be ignored rather than causing
errors.
7. HTTP Signatures and WebFinger
HTTP Signatures
- Pixelfed signs every POST and GET request
- All incoming POST requests must be signed
- GET requests may require signatures (configurable — this is "authorized fetch" or "secure mode")
- The instance
Applicationactor's key is used for signing GET requests - Individual
Personactor keys are used for signing POST requests (activities from that user)
WebFinger
Pixelfed requires each ActivityPub actor to uniquely map to an acct:
URI resolvable via WebFinger at /.well-known/webfinger. Standard
WebFinger resolution applies.
8. Collections
Three primary user collections using the OrderedCollection pattern:
| Collection | Path | Content |
|---|---|---|
| Following | /users/{username}/following |
Accounts this user follows |
| Followers | /users/{username}/followers |
Accounts following this user |
| Outbox | /users/{username}/outbox |
User's published statuses |
totalItems may return 0 if the collection is hidden per user
privacy preference. This is intentional, not a bug — do not assume an
empty collection means the user has no followers/following.
9. Mastodon API Compatibility
Pixelfed implements a subset of the Mastodon REST API, allowing Mastodon client apps to work with Pixelfed instances.
Working endpoints
- Account endpoints (verify_credentials, update_credentials, relationships, search)
- Status endpoints (create, view, delete, favourite, boost)
- Timeline endpoints (home, public, hashtag)
- Notification endpoints
- OAuth 2.0 authentication (requires
OAUTH_ENABLED=true)
Known compatibility gaps
- OOB OAuth redirect (
urn:ietf:wg:oauth:2.0:oob) is not supported — apps relying on this flow will fail - Authorization code grant type has reported issues
- Some public API endpoints incorrectly require OAuth tokens
- Pixelfed-specific features (Stories, Collections, capabilities) are not accessible via the Mastodon API — only through Pixelfed's own API
10. Federation Interoperability
Cross-platform behaviour
| Feature | Pixelfed to Mastodon | Mastodon to Pixelfed |
|---|---|---|
| Photo posts | Appear as image posts with text | Appear normally if image attached |
| Text-only posts | N/A (Pixelfed requires media) | Not displayed on Pixelfed |
| Album posts (>4 images) | Only first 4 images shown | N/A (Mastodon max 4) |
| Stories | Not visible | N/A |
| Boosts | Appear as boosts | Appear as boosts |
| Likes/Favourites | Federate normally | Federate normally |
| Replies | Federate, but display may be incomplete | Federate normally |
| Content warnings | Show as content warnings | Show as content warnings |
Known federation issues
- Pixelfed does not display older posts created before federation with a particular instance began
- Comment counts may be inaccurate (showing N comments but not all visible) due to incomplete federation of reply threads
- Nested reply threading can be incomplete across platforms
- Profile photo updates sometimes fail to federate properly
- The
capabilitiesextension is not respected by other platforms — a post with"reply": nullcan still receive replies from Mastodon users
11. Configuration Reference
Federation
| Variable | Description |
|---|---|
ACTIVITY_PUB |
Enable/disable federation entirely |
AP_REMOTE_FOLLOW |
Allow/prevent remote following |
Media
| Variable | Default | Description |
|---|---|---|
MAX_PHOTO_SIZE |
15000 (KB) | Per-file size limit (15 MB) |
MAX_ACCOUNT_SIZE |
1000000 (KB) | Per-user total storage (1 GB) |
MAX_ALBUM_LENGTH |
4 | Items per post |
IMAGE_QUALITY |
80 | JPEG quality 1-100 |
PF_OPTIMIZE_IMAGES |
— | Automatic image optimization |
PF_OPTIMIZE_VIDEOS |
— | Automatic video optimization |
PF_ENABLE_CLOUD |
— | S3/Object Storage support |
Accounts
| Variable | Default | Description |
|---|---|---|
MAX_CAPTION_LENGTH |
500 | Caption character limit |
MAX_BIO_LENGTH |
125 | Bio character limit |
MAX_NAME_LENGTH |
30 | Display name limit |
OPEN_REGISTRATION |
true | New account creation |
PF_MAX_USERS |
1000 | User registration cap |
ENFORCE_EMAIL_VERIFICATION |
— | Email confirmation required |
Features
| Variable | Default | Description |
|---|---|---|
STORIES_ENABLED |
false | Stories functionality |
OAUTH_ENABLED |
— | Third-party app authentication |
INSTANCE_DISCOVER_PUBLIC |
— | Public explore feature access |
INSTANCE_PUBLIC_HASHTAGS |
— | Anonymous hashtag feed browsing |
12. Common Implementation Mistakes
- Ignoring the
capabilitiesextension: when federating with Pixelfed, be aware thatcapabilitiesexists — even if you choose not to enforce it, you should not strip it when forwarding posts between instances - Sending text-only posts to Pixelfed: Pixelfed silently drops posts without media attachments — there is no error response, the post simply does not appear
- Assuming Mastodon API parity: Pixelfed's Mastodon API implementation has gaps (no OOB OAuth, some endpoints require tokens when they should not) — test against a real Pixelfed instance
- Not handling
commentsEnabled: false: if your software creates replies, check this field before sending a reply to a Pixelfed post — while Pixelfed cannot prevent your server from delivering the reply, respecting this field is good federation citizenship - Expecting Stories to federate universally: Stories only work between Pixelfed instances — do not implement Story support expecting cross-platform compatibility
- Treating
totalItems: 0as empty: Pixelfed returns0for hidden collections — a followers count of 0 does not mean the account has no followers - Wrong shared inbox path: Pixelfed uses
/f/inboxas the shared inbox, not/inbox— always read theendpoints.sharedInboxvalue from the actor document rather than guessing - Not handling the Application instance actor: Pixelfed uses a
separate
Application-type actor for GET request signing — if your server requires signed fetches, be prepared to resolve and verify keys from actors with"type": "Application", not just"Person"