funkwhale/docs/specs/nodeinfo21/index.md

6.3 KiB

NodeInfo 2.1

{bdg-secondary}In progress

The issue

Servers need to communicate their capabilities in a network of communicating nodes to negotiate a common protocol.

Proposed solution

Use NodeInfo, a well-defined standard for exactly this purpose that's widely used within the Fediverse.

Feature behavior

The NodeInfo endpoint is used to communicate the features and capabilities of a server. It presents details about:

  • Implemented protocols
  • Enabled features
  • Usage statistics
  • Content metadata

:::{seealso} Read the NodeInfo specification for more information. :::

The NodeInfo endpoint must contain all mandatory elements listed in the specification. In addition to this, Funkwhale's implementation should list additional details about the instance in the metadata object.

actorId (URL)
The URL of the pod service actor
private (Boolean)
Whether the pod is private
shortDescription (String)
A short description of the pod
longDescription (String)
A longer description of the pod
contactEmail (Email address)
The email address of the pod administrator
nodeName(String)
The name of the pod
banner (URL)
The URL of the banner image
defaultUploadQuota (Number)
The default upload quota (in megabytes) allowed for new users
supportedUploadExtensions (Array<String>)
A list of file extensions enabled for upload
allowlist.enabled (Boolean)
Whether the pod admin has enabled allow-listing
allowlist.domains (Array<String>)
A list of allowed domains
funkwhaleSupportMessageEnabled (Boolean)
Whether the admin has enabled the Funkwhale project support message
instanceSupportMessage (String)
The support message associated with the instance
content.local (Object)
An object containing a summary of local content
content.local.artists (Number)
The number of artists associated with local uploads on the pod
content.local.releases (Number)
The number of albums or series associated with local uploads on the pod
content.local.recordings (Number)
The number of tracks or episodes associated with local uploads on the pod
content.local.hoursOfContent (Number)
The total number of hours of content associated with local uploads on the pod
content.topMusicCategories (Array<{ name: String, count: Number}>)
The top three music genres and the number of uploads tagged with them
content.topPodcastCategories (Array<{ name: String, count: Number}>)
The top three podcast categories and the number of uploads tagged with them
languages (Array<String>)
The languages spoken by the pod administrators
location (String)
The country the pod is located in
codeOfConduct (String <Url>)
If the server admin has populated the Rules setting on their pod, this value is populated with the URL to the pod's about page: <server_domain>/about/pod#rules.
federation.followsInstances (Number)
The number of Funkwhale pods that the target pod follows
federation.followingInstances (Number)
The number of Funkwhale pods that publicly follow the target pod
usage.listenings (Number)
The total number of listenings on the pod
usage.downloads (Number)
The total number of downloads (streams) the pod has served
usage.favorites.tracks (Number)
The total number of track favorites recorded on the pod.
features (Array<String>)
A list of enabled features

Backend

A new NodeInfo endpoint will be created that sits alongside the existing v1 endpoint for backwards-compatibility.

/api/v2/instance/nodeinfo/2.1

This endpoint supports only GET requests and responds with the information outlined in the NodeInfo specification.

Example response:

{
  "version": "2.1",
  "software": {
    "name": "Funkwhale",
    "version": "1.4.0",
    "repository": "https://dev.funkwhale.audio/funkwhale/funkwhale",
    "homepage": "https://funkwhale.audio"
  },
  "protocols": ["activitypub"],
  "services": {
    "inbound": ["atom1.0"],
    "outbound": ["atom1.0"]
  },
  "openRegistrations": true,
  "usage": {
    "users": {
      "total": 0,
      "activeHalfYear": 0,
      "activeMonth": 0
    },
    "localPosts": 0,
    "localComments": 0
  },
  "metadata": {
    "actorId": "string",
    "private": true,
    "shortDescription": "string",
    "longDescription": "string",
    "contactEmail": "user@example.com",
    "nodeName": "string",
    "banner": "string",
    "defaultUploadQuota": 0,
    "supportedUploadExtensions": ["string"],
    "allowList": {
      "enabled": true,
      "domains": ["string"]
    },
    "funkwhaleSupportMessageEnabled": true,
    "instanceSupportMessage": "string",
    "languages": ["string"],
    "location": "string",
    "codeOfConduct": "string",
    "content": {
      "local": {
        "artists": 1000,
        "releases": 10000,
        "recordings": 150000,
        "hoursOfContent": 7500
      },
      "topMusicCategories": [
        {
          "name": "rock",
          "count": 1256
        },
        {
          "name": "jazz",
          "count": 604
        },
        {
          "name": "classical",
          "count": 308
        }
      ],
      "topPodcastCategories": [
        {
          "name": "comedy",
          "count": 12
        },
        {
          "name": "politics",
          "count": 4
        },
        {
          "name": "nature",
          "count": 1
        }
      ],
      "federation": {
        "followedInstances": 0,
        "followingInstances": 0
      }
    },
    "usage": {
      "listenings": 0,
      "downloads": 0,
      "favorites": {
        "tracks": 0
      }
    },
    "features": [
      "channels",
      "podcasts",
      "collections",
      "audiobooks",
      "federation",
      "anonymousCanListen"
    ]
  }
}

Availability

  • Admin panel
  • App frontend
  • CLI
  • API

Responsible parties

Since the actual endpoint is already standardized, Backend developers need only to agree on an implementation. The Frontend group needs to check to see if changing the location of /.well-known/nodeinfo has an impact on the web app.

The NodeInfo endpoint MUST be accompanied by a {download}full OpenAPI schema file <schema.yml> for ease of reference and implementation.

Open questions

  • Does changing /.well-known/nodeinfo have any implications on the Frontend?