documentation/content/en/spec/activitypub.md

19 KiB
Raw Blame History

title description menu
ActivityPub A decentralized social networking protocol based upon the ActivityStreams 2.0 data format and JSON-LD.
docs
weight parent
10 spec

{{< hint style="warning" >}} Sample payloads will be added at a future date. {{< /hint >}}

Status federation

{{< caption-link url="https://github.com/mastodon/mastodon/blob/master/app/lib/activitypub/activity.rb" caption="app/lib/activitypub/activity.rb" >}}

Supported activities for statuses

Create
Transformed into a status and saved into database
Delete
Removes a status from the database
Like
Transformed into a favourite on a status
Announce
Transformed into a boost on a status
Flag
Transformed into a report to the moderation team.
Update
Refresh vote count on polls. As of Mastodon 3.5.0, can be used to edit statuses when the updated timestamp is present.
Undo
Undo a previous Like or Announce.

Payloads

The first-class Object types supported by Mastodon are Note and Question.

  • Notes are transformed into regular statuses.
  • Questions are transformed into a poll status.

Some other Object types are converted as best as possible:

  • Article
  • Page
  • Image
  • Audio
  • Video
  • Event

The transformer uses content if available, or name if not, in order to generate status text. The url will be appended. The summary property will be used as the CW text. The icon will be used as a thumbnail.

Properties used

content
Used as status text
name
Used as status text, if content is not provided on a transformed Object type
summary
Used as CW text
sensitive
Used to determine whether status media or text should be hidden by default
inReplyTo
Used for threading a status as a reply to another status
published
Used as status date
url
Used for status permalinks, and also appended to status text for transformed Objects
attributedTo
Used to determine the profile which authored the status
updated
Used to display the "last edited at" timestamp in the UI to indicate to the user that a status has been edited. Required before an Update activity will be processed. To prevent against race conditions, Mastodon will only process Update payloads with an updated timestamp greater than the currently known last updated time.
to/cc
Used to determine audience and visibility of a status.
  • Public statuses have the as:Public magic collection in to
  • Unlisted statuses have the as:Public magic collection in cc
  • Followers-only statuses have an actor's follower collection in to or cc, but do not include the as:Public magic collection
  • Private statuses have actors in to or cc, at least one of which is not Mentioned in tag
  • Direct statuses have actors in to or cc, all of which are Mentioned in tag
tag
Used to mark up mentions and hashtags.
tag[].type
Either Mention or Hashtag is currently supported
tag[].name
The plain-text Webfinger address of a profile Mention (@user or @user@domain), or the plain-text Hashtag (#tag)
tag[].href
The URL of the actor or tag
attachment
Used to include attached images, videos, or audio.
attachment[].url
Used to fetch the media attachment
attachment[].summary
Used as media description
attachment[].blurhash
Used to generate a blurred preview image corresponding to the colors used within the image. See Blurhash for more details.
replies
A Collection of statuses that are in reply to the current status. Up to 5 replies from the same server will be fetched upon discovery of a remote status, in order to resolve threads more fully. On Mastodon's side, the first page contains self-replies, and additional pages contain replies from other people.

Poll-specific properties

endTime
The timestamp for when voting will close on the poll
closed
The timestamp for when voting closed on the poll. The timestamp will likely match the endTime timestamp. If this property is present, the poll is assumed to be closed.
votersCount
How many people have voted in the poll. Distinct from how many votes have been cast (in the case of multiple-choice polls)
oneOf
Single-choice poll options
anyOf
Multiple-choice poll options
oneOf/anyOf[].name
The poll option's text
oneOf/anyOf[].replies.totalItems
The poll option's vote count

Profile federation

Supported activities for profiles

Follow
Indicate interest in receiving status updates from a profile.
Accept/Reject
Used to approve or deny Follow activities. Unlocked accounts will automatically reply with an Accept, while locked accounts can manually choose whether to approve or deny a follow request.
Add/Remove
Manage pinned posts and featured collections.
Block
Signal to a remote server that they should hide your profile from that user. Not guaranteed.
Flag
Report user
Update
Refresh account details
Move
Migrate followers from one account to another. Requires alsoKnownAs to be set in both directions.
Delete
Remove an account from the database, as well as all of their statuses.
Undo
Undo a previous Follow, Accept Follow, or Block.

Properties used

preferredUsername
Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI.
name
Used as profile display name.
summary
Used as profile bio.
type
Assumed to be Person. If type is Application or Service, it will be interpreted as a bot flag.
url
Used as profile link.
icon
Used as profile avatar.
image
Used as profile header.
manuallyApprovesFollowers
Will be shown as a locked account.
discoverable
Will be shown in the profile directory. See Discoverability flag.
publicKey
Required for signatures. See Public key.
featured
Pinned posts. See Featured collection.
attachment
Used for profile fields. See Profile metadata and Identity proofs.
alsoKnownAs
Required for Move activity.
published
When the profile was created.

HTML sanitization

{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/lib/sanitize_ext/sanitize_config.rb" caption="lib/sanitize_ext/sanitize_config.rb" >}}

Mastodon sanitizes incoming HTML in order to not break assumptions for API client developers. Supported elements include <p>, <span>, <br>, and <a>. Unsupported elements will be converted to <p>.The sanitizer will keep classes if they begin with microformats prefixes or are semantic classes:

  • h-*
  • p-*
  • u-*
  • dt-*
  • e-*
  • mention
  • hashtag
  • ellipsis
  • invisible

JSON-LD Namespacing

{{< caption-link url="https://github.com/mastodon/mastodon/blob/master/app/lib/activitypub/adapter.rb" caption="app/lib/activitypub/adapter.rb" >}}

Mastodon extensions (toot:)

Contains definitions for Mastodon features.

  • toot:Emoji
  • toot:IdentityProof
  • toot:blurhash
  • toot:focalPoint
  • toot:featured
  • toot:featuredTags
  • toot:discoverable
  • toot:suspended
  • toot:votersCount

ActivityStreams extensions (as:)

Contains ActivityStreams extended properties that have been proposed but not officially adopted yet.

  • as:Hashtag
  • as:alsoKnownAs
  • as:manuallyApprovesFollowers
  • as:movedTo
  • as:sensitive

W3ID Security Vocabulary (sec:)

Contains properties used for HTTPS Signatures and Linked Data Signatures. Also used for identity proofs. See [Security]({{< relref "spec/security" >}}) for more information.

  • sec:publicKey
  • sec:publicKeyPem
  • sec:owner
  • sec:signature
  • sec:signatureValue

W3ID Identity

Contains a collection of terms from various namespaces, used for Linked Data Signatures.

  • dc:creator
  • dc:created
  • sec:signature
  • sec:signatureValue

schema.org extensions (schema:)

Contains properties used for profile metadata.

  • schema:PropertyValue
  • schema:value

Extensions

Public key

Public keys are used for HTTPS Signatures and Linked Data Signatures. This is implemented using an extra property publicKey on actor objects. See [Security]({{< relref "spec/security" >}}) for more information. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1"
  ],
  "id": "https://mastodon.social/users/Gargron",
  "type": "Person",
  "publicKey": {
    "id": "https://mastodon.social/users/Gargron#main-key",
    "owner": "https://mastodon.social/users/Gargron",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXc4vkECU2/CeuSo1wtn\nFoim94Ne1jBMYxTZ9wm2YTdJq1oiZKif06I2fOqDzY/4q/S9uccrE9Bkajv1dnkO\nVm31QjWlhVpSKynVxEWjVBO5Ienue8gND0xvHIuXf87o61poqjEoepvsQFElA5ym\novljWGSA/jpj7ozygUZhCXtaS2W5AD5tnBQUpcO0lhItYPYTjnmzcc4y2NbJV8hz\n2s2G8qKv8fyimE23gY1XrPJg+cRF+g4PqFXujjlJ7MihD9oqtLGxbu7o1cifTn3x\nBfIdPythWu5b4cujNsB3m3awJjVmx+MHQ9SugkSIYXV0Ina77cTNS0M2PYiH1PFR\nTwIDAQAB\n-----END PUBLIC KEY-----\n"
  }
}

What is known in Mastodon as “pinned statuses”, or statuses that are always featured at the top of peoples profiles, is implemented using an extra property featured on the actor object that points to a Collection of objects. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "featured": {
        "@id": "toot:featured",
        "@type": "@id"
      }
    }
  ],

  "id": "https://example.com/@alice",
  "type": "Person",
  "featured": "https://example.com/@alice/collections/featured"
}

Featured tags

Mastodon allows users to feature specific hashtags on their profile for easy browsing, as a discoverability mechanism. This is implemented using an extra property featuredTags on the actor object that points to a Collection of Hashtag objects specifically.

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "featuredTags": {
        "@id": "toot:featuredTags",
        "@type": "@id"
      }
    }
  ],

  "id": "https://example.com/@alice",
  "type": "Person",
  "featuredTags": "https://example.com/@alice/collections/tags"
}

Custom emojis

Mastodon supports arbitrary emojis, that is, small images uploaded by admins and invokable via shortcodes. For this, an Emoji type is used. These emojis are listed in the tag property just like Mention and Hashtag objects, since they are entities that affect how the text is rendered. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "Emoji": "toot:Emoji"
    }
  ],

  "id": "https://example.com/@alice/hello-world",
  "type": "Note",
  "content": "Hello world :kappa:",
  "tag": [
    {
      "id": "https://example.com/emoji/123",
      "type": "Emoji",
      "name": ":kappa:",
      "icon": {
        "type": "Image",
        "mediaType": "image/png",
        "url": "https://example.com/files/kappa.png"
      }
    }
  ]
}

Focal points

Mastodon supports setting a focal point on uploaded images, so that wherever that image is displayed, the focal point stays in view. This is implemented using an extra property focalPoint on Image objects. The property is an array of two floating points between -1.0 and 1.0, with 0,0 being the center of the image, the first value being x (-1.0 is the left edge, +1.0 is the right edge) and the second value being y (-1.0 is the bottom edge, +1.0 is the top edge). See [API Guidelines > Focal points]({{< relref "api/guidelines#focal-points" >}}) for more information. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "focalPoint": {
        "@container": "@list",
        "@id": "toot:focalPoint"
      }
    }
  ],

  "id": "https://example.com/@alice/hello-world",
  "type": "Note",
  "content": "A picture attached!",
  "attachment": [
    {
      "type": "Image",
      "mediaType": "image/png",
      "url": "https://example.com/files/cats.png",
      "focalPoint": [
        -0.55,
        0.43
      ]
    }
  ]
}

{{< figure src="assets/focal-points.jpg" caption="A demonstration of various focal points and their coordinates." >}}

The focal point of (-0.55, 0.43) in the example above corresponds to a point 55% to the left of center and 43% above center. This focal point should remain visible within the cropped thumbnail, if any cropping is done.

Blurhash

Mastodon generates colorful preview thumbnails for attachments. This is implemented using an extra property blurhash on Image objects. The property is a string generated by the BlurHash algorithm. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "blurhash": "toot:blurhash"
    }
  ],

  "id": "https://example.com/@alice/hello-world",
  "type": "Note",
  "content": "A picture attached!",
  "attachment": [
    {
      "type": "Image",
      "mediaType": "image/png",
      "url": "https://example.com/files/cats.png",
      "blurhash": "UBL_:rOpGG-oBUNG,qRj2so|=eE1w^n4S5NH"
    }
  ]
}

Profile metadata

Mastodon supports arbitrary profile fields containing name-value pairs. This is implemented using the attachment property on actor objects, with objects in the array having a type of PropertyValue and a value property, both from the schema.org namespace. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "PropertyValue": "schema:PropertyValue",
      "value": "schema:value"
    }
  ],
  "id": "https://mastodon.social/users/Gargron",
  "type": "Person",
  "attachment": [
    {
      "type": "PropertyValue",
      "name": "Patreon",
      "value": "<a href=\"https://www.patreon.com/mastodon\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/mastodon</span><span class=\"invisible\"></span}"
    },
    {
      "type": "PropertyValue",
      "name": "Homepage",
      "value": "<a href=\"https://zeonfederated.com\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">zeonfederated.com</span><span class=\"invisible\"></span}"
    }
  ]
}

Identity proofs

{{< hint style="warning" >}} This property is currently unused/deprecated due to the removal of Keybase support in Mastodon 3.5: https://github.com/mastodon/mastodon/pull/17045 {{}}

Mastodon supports integration with identity providers to prove that a profile is linked to a certain identity. This is implemented using the attachment property on actor objects, with objects in the array having a type of IdentityProof from the Mastodon namespace. The object also includes signatureAlgorithm and signatureValue from the W3ID Security Vocabulary namespace. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1",
    {
      "toot": "http://joinmastodon.org/ns#",
      "IdentityProof": "toot:IdentityProof"
    }
  ],
  "id": "https://mastodon.social/users/Gargron",
  "type": "Person",
  "attachment": [
    {
      "type": "IdentityProof",
      "name": "gargron",
      "signatureAlgorithm": "keybase",
      "signatureValue": "5cfc20c7018f2beefb42a68836da59a792e55daa4d118498c9b1898de7e845690f"
    }
  ]
}

Discoverability flag

Mastodon allows users to opt-in or opt-out of discoverability features like the profile directory. This flag may also be used as an indicator of the user's preferences toward being included in external discovery services, such as search engines or other indexing tools. If you are implementing such a tool, it is recommended that you respect this property if it is present. This is implemented using an extra property discoverable on objects. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "discoverable": "toot:discoverable"
    }
  ],
  "id": "https://mastodon.social/users/Gargron",
  "type": "Person",
  "discoverable": true
}

Suspended flag

Mastodon reports whether a user was locally suspended, for better handling of these accounts. Suspended accounts in Mastodon return empty data. If a remote account is marked as suspended, it cannot be unsuspended locally. Suspended accounts can be targeted by activities such as Update, Undo, Reject, and Delete. This functionality is implemented using an extra property suspended on objects. Example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "toot": "http://joinmastodon.org/ns#",
      "suspended": "toot:suspended"
    }
  ],
  "id": "https://example.com/@eve",
  "type": "Person",
  "suspended": true
}

Other functionality

Secure mode

When a Mastodon server runs in secure mode, all cross-server HTTP requests to it must be signed (in other words, even GET requests to public resources). That way, the Mastodon server can choose to reject requests from servers it has blocked and avoid "leaking" public information. Mastodon itself uses a dedicated system actor to sign such HTTP requests. See [Security]({{< relref "spec/security" >}}) for more details on HTTP signatures.

Secure mode is the foundation upon which "limited federation mode" is built. A Mastodon server in limited federation mode will only federate with servers its admin has explicitly allowed, and reject all other requests.

Follower synchronization mechanism

Mastodon has a concept of "followers-only" posts, but expanding the followers collection is currently handled at the destination rather than at the origin (i.e., not with explicit addressing). Therefore, a mechanism to detect synchronization issues and correct them is needed. This mechanism must work on partial followers collections, rather than the full collection (which may not be public information).

When delivering a message to a remote user, an optional Collection-Synchronization HTTP header is attached, following the same syntax as the Signature header, with the following attributes:

  • collectionId = MUST be the sender's followers collection
  • url = a URL to a partial collection containing the identifiers of the sender's followers residing on the receiver's instance. MUST reside on the same domain as the actor itself, and SHOULD be only accessible with a signed query from the receiver's instance
  • digest = hexadecimal representation of the XORed SHA256 digests of each of the identifiers in the partial collection

Example:

POST https://mastodon.social/users/foo/inbox HTTP/1.1
Collection-Synchronization:
  collectionId="https://social.sitedethib.com/users/Thib/followers",
  url="https://social.sitedethib.com/users/Thib/followers_synchronization",
  digest="b08ab6951c7d6cc2b91e17ebd9557da7fae02489728e9332fcb3a97748244d50"

When a remote user attempts to GET the partial collection url, this request must be signed with HTTP signatures. Example:

GET https://social.sitedethib.com/users/Thib/followers_synchronization HTTP/1.1
Signature: ... # a signature from an account on mastodon.social

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://social.sitedethib.com/users/Thib/followers?domain=mastodon.social",
  "type": "OrderedCollection",
  "orderedItems": [
    "https://mastodon.social/users/Gargron"
  ]
}