Resources Core API Statically documented

FediSuite API

This page documents the complete static non-admin API of the FediSuite application. It covers public endpoints, login and connection flows, accounts, posts, analytics, user preferences, and mobile bundles, including request examples, JSON responses, and practical `curl` sequences.

Coverage

All statically visible core endpoints except `/api/admin/...`.

Auth

JWT via `Authorization: Bearer <JWT>`, obtained from `POST /api/auth/login`.

Important boundary

Plugins can mount additional routes at runtime, so they cannot be fully enumerated from the core repo alone.

Important: This reference is complete for the core API, but not automatically the full runtime API of every possible instance. Installed plugins can provide additional endpoints and need to document those separately.

FediSuite API reference

This file documents the complete static, non-admin API of FediSuite-Docker-Image.

Not included:

  • all /api/admin/... endpoints
  • the catch-all GET *, which only delivers the web app

Important:

  • this file describes all non-admin endpoints statically visible in the core repo
  • In addition, active plugins can register their own HTTP routes
  • these dynamic plugin routes are not completely statically enumerable from this repo because they are mounted from plugin code at runtime

Basic rules

Base URL

All paths are relative to a FediSuite instance, for example:

  • https://fedisuite.example.com
  • https://fedisuite.example.com
  • https://example.org

Authentication

Use authenticated requests:

http
Authorization: Bearer <JWT>

The JWT is obtained via POST /api/auth/login.

Language

Many error texts are localized using Accept-Language.

Example:

http
Accept-Language: de

Time format

Timestamps are typically delivered as ISO-8601 strings, usually in UTC.

Standard error format

Most often:

json
{
  "error": "Fehlermeldung"
}

Typical status codes:

  • 400 invalid request
  • 401 missing or invalid token
  • 403 access denied
  • 404 resource not found
  • 429 rate limit
  • 500 internal error

Scope rule

Almost all user endpoints are bound to req.user.id. A user only sees his or her own accounts, posts, dashboards and preferences.

Overview of all documented endpoints

Public

  • GET /api/health
  • GET /api/public/config
  • GET /api/public/notice
  • GET /api/mobile/public/info

Auth

  • POST /api/auth/register
  • POST /api/mobile/auth/register
  • POST /api/auth/resend-verification
  • POST /api/mobile/auth/resend-verification
  • POST /api/auth/verify
  • POST /api/auth/login
  • GET /api/auth/providers/:providerId/start
  • GET /api/auth/providers/:providerId/callback
  • POST /api/auth/forgot-password
  • POST /api/auth/reset-password
  • POST /api/auth/fediverse/connect
  • GET /api/auth/fediverse/callback
  • GET /api/auth/misskey/callback
  • POST /api/auth/peertube/connect

Plugin and provider discovery

  • GET /api/plugins/discovery
  • GET /api/plugins/:pluginId/web/manifest
  • GET /api/plugins/:pluginId/web/assets/*
  • GET /api/providers/discovery
  • POST /api/providers/:providerId/connect
  • GET /api/providers/:providerId/callback
  • POST /api/providers/:providerId/callback
  • POST /api/providers/:providerId/disconnect
  • GET /api/plugin-settings/:pluginId
  • PUT /api/plugin-settings/:pluginId

Accounts and Notifications

  • GET /api/accounts
  • GET /api/accounts/:id/notifications
  • POST /api/accounts/:id/notifications/:notificationId/read
  • POST /api/accounts/:id/notifications/:notificationId/favourite
  • POST /api/accounts/:id/notifications/:notificationId/reply
  • DELETE /api/accounts/:id

Posts and queue

  • GET /api/posts
  • POST /api/posts
  • POST /api/posts/publish-now
  • POST /api/posts/:id/repost
  • PUT /api/posts/:id
  • DELETE /api/posts/:id

Account analytics and refresh

  • POST /api/refresh-stats
  • GET /api/accounts/:id/import-status
  • GET /api/accounts/:id/top-posts
  • GET /api/accounts/:id/daily-stats
  • GET /api/accounts/:id/stats-history
  • GET /api/accounts/:id/engagement-rate
  • GET /api/accounts/:id/weekly-growth
  • GET /api/accounts/:id/engagement-breakdown
  • GET /api/accounts/:id/best-times
  • GET /api/accounts/:id/follower-events
  • GET /api/accounts/:id/media-performance
  • GET /api/accounts/:id/weekday-engagement
  • GET /api/accounts/:id/visibility-breakdown
  • GET /api/accounts/:id/hashtag-overview
  • GET /api/accounts/:id/top-hashtags
  • GET /api/accounts/:id/hashtag-combinations
  • GET /api/accounts/:id/insights

User self-service

  • GET /api/user/dashboard-layout
  • PUT /api/user/dashboard-layout
  • GET /api/user/profile
  • PUT /api/user/language
  • PUT /api/user/theme
  • PUT /api/user/email
  • PUT /api/user/password
  • PUT /api/user/timezone
  • PUT /api/user/default-account
  • DELETE /api/user/account

Mobile Bundles

  • GET /api/mobile/bootstrap
  • GET /api/mobile/accounts/:id/dashboard
  • PUT /api/mobile/preferences

1. Public API

1.1 GET /api/health

Purpose:

  • Check availability
  • Check database connection
  • most important instance compatibility check for the Android app

Auth:

  • none

Answer if successful:

json
{
  "status": "ok",
  "db": "connected",
  "timestamp": "2026-05-06T12:34:56.000Z"
}

Answer to DB problem:

json
{
  "status": "error",
  "db": "disconnected",
  "error": "connect ECONNREFUSED ..."
}

curl:

bash
curl -sS "https://fedisuite.example.com/api/health"

1.2 GET /api/public/config

Purpose:

  • public instance configuration

Auth:

  • none

Answer:

json
{
  "enableUserRegistration": true,
  "appName": "FediSuite",
  "publicSiteUrl": "https://fedisuite.example.com",
  "authProviders": []
}

curl:

bash
curl -sS "https://fedisuite.example.com/api/public/config"

1.3 GET /api/public/notice

Purpose:

  • global public notice text

Auth:

  • none

Answer:

json
{
  "enabled": true,
  "markdown": "Wartung heute ab 22:00 Uhr."
}

curl:

bash
curl -sS "https://fedisuite.example.com/api/public/notice"

1.4 GET /api/mobile/public/info

Purpose:

  • mobile public bundle for login/instance selection
  • combines Config, Notice and Auth capabilities

Auth:

  • none

Answer, shortened:

json
{
  "enableUserRegistration": true,
  "appName": "FediSuite",
  "publicSiteUrl": "https://fedisuite.example.com",
  "authProviders": [],
  "notice": {
    "enabled": false,
    "markdown": ""
  },
  "connectorProviders": [],
  "auth": {
    "supportsLogin": true,
    "supportsRegistration": true,
    "supportsEmailVerification": true,
    "supportsResendVerification": true,
    "loginIdentifierMode": "email",
    "pluginProviders": [],
    "pluginAuthProviders": []
  }
}

curl:

bash
curl -sS "https://fedisuite.example.com/api/mobile/public/info"

2. Auth API

2.1 POST /api/auth/register

Alias:

  • POST /api/mobile/auth/register Purpose:
  • create new user

Request body:

json
{
  "email": "user@example.com",
  "password": "geheimes-passwort",
  "language": "de",
  "timezone": "Europe/Berlin"
}

Validation:

  • email is normalized
  • password must be at least 8 characters long
  • Registration can be disabled globally
  • Admin email is immediately created as verified
  • all other users receive a verification link

Answer:

json
{
  "success": true,
  "requiresVerification": true,
  "message": "Bitte bestaetige zuerst deine E-Mail-Adresse.",
  "user": {
    "email": "user@example.com",
    "language": "de",
    "timezone": "Europe/Berlin"
  }
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "geheimes-passwort",
    "language": "de",
    "timezone": "Europe/Berlin"
  }'

Mobile alias:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/mobile/auth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "geheimes-passwort"
  }'

2.2 POST /api/auth/resend-verification

Alias:

  • POST /api/mobile/auth/resend-verification Purpose:
  • Resend verification email

Request body:

json
{
  "email": "user@example.com"
}

or:

json
{
  "identifier": "user@example.com"
}

Special features:

  • if the user does not exist, a neutral success response will still be received
  • if it is already verified, success also comes with alreadyVerified

Answer:

json
{
  "success": true,
  "requiresVerification": true,
  "message": "Bitte bestaetige zuerst deine E-Mail-Adresse."
}

or:

json
{
  "success": true,
  "requiresVerification": false,
  "alreadyVerified": true,
  "message": "Dein Konto wurde bestaetigt."
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/resend-verification" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'

2.3 POST /api/auth/verify

Purpose:

  • Complete email verification

Request body:

json
{
  "token": "hex-token-aus-mail"
}

Answer:

json
{
  "success": true,
  "message": "Dein Konto wurde bestaetigt."
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/verify" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "hex-token-aus-mail"
  }'

2.4 POST /api/auth/login

Purpose:

  • Login with email and password
  • supplies JWT

Request body:

json
{
  "identifier": "user@example.com",
  "password": "mein-passwort"
}

Important:

  • On the server side, the user email is currently being checked
  • unverified users get 403

Answer:

json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....",
  "user": {
    "id": 42,
    "email": "user@example.com"
  },
  "isAdmin": false,
  "auth": {
    "type": "Bearer"
  }
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "user@example.com",
    "password": "mein-passwort"
  }'

2.5 GET /api/auth/providers/:providerId/start

Purpose:

  • Launch of a plugin-based auth provider

Answer:

  • usually redirect or JSON with additional start data
  • exact semantics depends on the respective plugin

Error:

  • 404 if the provider does not exist Example:
bash
curl -i "https://fedisuite.example.com/api/auth/providers/google/start"

2.6 GET /api/auth/providers/:providerId/callback

Purpose:

  • Callback for plugin-based login providers

Behavior:

  • creates or finds a user
  • creates a JWT
  • typically redirects with auth_token and is_admin

Important:

  • typical browser flow, not a classic API JSON endpoint

Example:

bash
curl -i "https://fedisuite.example.com/api/auth/providers/google/callback?code=abc&state=xyz"

2.7 POST /api/auth/forgot-password

Purpose:

  • Request password reset

Request body:

json
{
  "email": "user@example.com"
}

Answer:

json
{
  "message": "Wenn ein Konto existiert, wurde eine Mail verschickt."
}

Special feature:

  • intentionally does not provide a distinction between existing and non-existent email

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/forgot-password" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'

2.8 POST /api/auth/reset-password

Purpose:

  • Set password with valid reset token

Request body:

json
{
  "token": "reset-token",
  "password": "neues-passwort"
}

Answer:

json
{
  "message": "Das Passwort wurde erfolgreich geaendert."
}

Rules:

  • new password at least 8 characters
  • Token must be valid and not expired

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/reset-password" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "reset-token",
    "password": "neues-passwort"
  }'

2.9 POST /api/auth/fediverse/connect

Purpose:

  • Start OAuth or MiAuth connection establishment for Fediverse accounts

Auth:

  • Bearer token required

Request body:

json
{
  "instanceUrl": "https://mastodon.example"
}

Possible answers:

Normal OAuth instance:

json
{
  "redirectUrl": "https://mastodon.example/oauth/authorize?..."
}

Misskey family:

json
{
  "redirectUrl": "https://misskey.example/miauth/..."
}

PeerTube:

json
{
  "requiresCredentials": true,
  "instanceType": "peertube",
  "instanceUrl": "https://video.example"
}

Important:

  • the server first detects the instance type
  • if an instance is unknown or not supported, 400 will appear

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/fediverse/connect" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceUrl": "https://mastodon.example"
  }'

2.10 GET /api/auth/fediverse/callback

Purpose:

  • OAuth callback for Mastodon compatible, Loops and Vernissage instances

Query parameters:- code

  • state Behavior:
  • exchanges the OAuth code for access tokens
  • reads account profile
  • creates an accounts record
  • sets default_account_id if none already exists
  • starts historical import in the background
  • redirects at the end to /?tab=accounts

Example:

bash
curl -i "https://fedisuite.example.com/api/auth/fediverse/callback?code=abc&state=xyz"

2.11 GET /api/auth/misskey/callback

Purpose:

  • MiAuth callback for Misskey family

Query parameters:- session Behavior:

  • validates the session with the remote instance
  • creates the connected account locally
  • starts historical import
  • redirects to /?tab=accounts

Example:

bash
curl -i "https://fedisuite.example.com/api/auth/misskey/callback?session=session-id"

2.12 POST /api/auth/peertube/connect

Purpose:

  • Connect PeerTube account via username/password

Auth:

  • Bearer token required

Request body:

json
{
  "instanceUrl": "https://video.example",
  "username": "alice",
  "password": "secret"
}

Answer:

json
{
  "success": true
}

Special features:

  • no browser redirect
  • the server first obtains local OAuth client credentials of the PeerTube instance
  • then an account is created and an import is started

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/auth/peertube/connect" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceUrl": "https://video.example",
    "username": "alice",
    "password": "secret"
  }'

3. Plugin and Provider API

3.1 GET /api/plugins/discovery

Purpose:

  • provides discovery payload of all loaded plugins

Auth:

  • Bearer token required

Answer:

  • pluginRegistry discovery payload
  • Structure depends on loaded plugins

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/plugins/discovery" \
  -H "Authorization: Bearer $TOKEN"

3.2 GET /api/plugins/:pluginId/web/manifest

Purpose:

  • returns the public web manifest of an active plugin

Auth:

  • Bearer token required

Error:

  • 404 if the plugin is not active/booted or does not expose a web manifest curl:
bash
curl -sS \
  "https://fedisuite.example.com/api/plugins/fedisuite-plugin-bluesky/web/manifest" \
  -H "Authorization: Bearer $TOKEN"

3.3 GET /api/plugins/:pluginId/web/assets/*

Purpose:

  • delivers web assets of a plugin

Auth:

  • no explicit auth middleware

Behavior:

  • content type is set appropriately
  • Cache-Control: no-store curl:
bash
curl -i "https://fedisuite.example.com/api/plugins/fedisuite-plugin-bluesky/web/assets/main.js"

3.4 GET /api/providers/discovery

Purpose:

  • delivers all connector providers registered by plugins

Auth:

  • Bearer token required

Answer:

json
{
  "providers": []
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/providers/discovery" \
  -H "Authorization: Bearer $TOKEN"

3.5 POST /api/providers/:providerId/connect

Purpose:

  • starts the connection process for a plugin provider

Auth:

  • Bearer token required

Answer:

  • plugin specific
  • often redirect URL or start payload

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/providers/demo-provider/connect" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

3.6 GET /api/providers/:providerId/callback

3.7 POST /api/providers/:providerId/callback

Purpose:

  • Callback for plugin providers

Behavior:

  • executes the provider callback
  • if result.account and result.user_id are supplied, the account will be persisted
  • optionally a historical import is started
  • optional Redirect, otherwise JSON

Typical success answer:

json
{
  "success": true,
  "account_id": 123,
  "provider_id": "demo-provider"
}

curl:

bash
curl -i "https://fedisuite.example.com/api/providers/demo-provider/callback?code=abc&state=xyz"

or authenticated:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/providers/demo-provider/callback" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

3.8 POST /api/providers/:providerId/disconnect

Purpose:

  • plugin-specific disconnect cleanup

Auth:

  • Bearer token required

Answer:

  • plugin specific

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/providers/demo-provider/disconnect" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

3.9 GET /api/plugin-settings/:pluginId

Purpose:

  • read plugin-specific settings

Auth:

  • Bearer token required

Query parameters:

  • scope=user|account|global default user
  • for scope=account additionally account_id

Important:

  • scope=global is not allowed for regular users
  • Permissions are checked against plugin permissions

Answer:

json
{
  "plugin_id": "demo-plugin",
  "settings_schema": {},
  "settings_values": {},
  "settings_updated_at": "2026-05-06T12:00:00.000Z",
  "scope": "user",
  "scope_ref_id": "42"
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/plugin-settings/demo-plugin?scope=user" \
  -H "Authorization: Bearer $TOKEN"

Account specific:

bash
curl -sS \
  "https://fedisuite.example.com/api/plugin-settings/demo-plugin?scope=account&account_id=123" \
  -H "Authorization: Bearer $TOKEN"

3.10 PUT /api/plugin-settings/:pluginId

Purpose:

  • Write plugin-specific settings

Auth:

  • Bearer token required

Request body:

json
{
  "scope": "user",
  "settings": {
    "enabled": true
  }
}

For scope=account:

json
{
  "scope": "account",
  "account_id": 123,
  "settings": {
    "enabled": true
  }
}

Answer:

json
{
  "plugin_id": "demo-plugin",
  "settings_schema": {},
  "settings_values": {
    "enabled": true
  },
  "settings_updated_at": "2026-05-06T12:00:00.000Z",
  "scope": "user",
  "scope_ref_id": "42"
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/plugin-settings/demo-plugin" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "user",
    "settings": {
      "enabled": true
    }
  }'

4. Accounts and Notifications

4.1 GET /api/accounts

Purpose:

  • all connected accounts of the user

Auth:

  • Bearer token required

Answer, shortened:

json
[
  {
    "id": 123,
    "instance_url": "https://mastodon.example",
    "username": "alice",
    "display_name": "Alice Example",
    "avatar_url": "https://mastodon.example/media/avatar.jpg",
    "stats_followers": 1200,
    "stats_following": 300,
    "stats_statuses": 800,
    "max_characters": 500,
    "characters_reserved_per_url": 23,
    "max_media_attachments": 4,
    "instance_type": "mastodon",
    "composer_text_format": "plain",
    "import_status": "done",
    "auth_error_code": null,
    "auth_error_message": null,
    "auth_error_at": null,
    "created_at": "2026-04-20T10:00:00.000Z",
    "is_default": true,
    "indexed_posts_count": 780,
    "effective_statuses_count": 800
  }
]

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts" \
  -H "Authorization: Bearer $TOKEN"

4.2 GET /api/accounts/:id/notifications

Purpose:

  • Retrieve notifications directly from the connected target platform

Auth:

  • Bearer token required

Query parameters:- limit Default 30, Maximum 80

  • cursor Pagination-Cursor Supported platform families:
  • Mastodon compatible
  • Misskey family
  • Vernissage

Answer, generic:

json
{
  "items": [],
  "next_cursor": null,
  "support": {
    "supported": true,
    "can_reply": true,
    "can_favourite": true,
    "can_mark_read": true,
    "reason": null
  }
}

Special feature:

  • for account reauth errors, 401 can come with code: "account_reauth_required"

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/notifications?limit=30" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept-Language: de"

4.3 POST /api/accounts/:id/notifications/:notificationId/read

Purpose:

  • Mark notification as read

Auth:

  • Bearer token required

Supports: -Mastodon

  • Vernissage

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/accounts/123/notifications/999/read" \
  -H "Authorization: Bearer $TOKEN"

4.4 POST /api/accounts/:id/notifications/:notificationId/favourite

Purpose:

  • react to/favorite the post associated with the notification

Auth:

  • Bearer token required

Request body:

json
{
  "statusId": "114460000000000001"
}

Families supported:

  • Mastodon: Favorite
  • Misskey: Reaction
  • Vernissage: Favorite

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/accounts/123/notifications/999/favourite" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "statusId": "114460000000000001"
  }'

4.5 POST /api/accounts/:id/notifications/:notificationId/reply

Purpose:

  • Send a reply to a notification-related post

Auth:

  • Bearer token required

Request body:

json
{
  "statusId": "114460000000000001",
  "content": "Danke!",
  "visibility": "public"
}

Validation:

  • content must not be empty
  • Misskey does not allow direct/specified here

Answer:

json
{
  "success": true,
  "id": "114460000000000002"
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/accounts/123/notifications/999/reply" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "statusId": "114460000000000001",
    "content": "Danke!",
    "visibility": "public"
  }'

4.6 DELETE /api/accounts/:id

Purpose:

  • remove connected account

Side effects:

  • deletes local posts from this account
  • cleans up media and thumbnails
  • sets default_account_id to NULL if necessary
  • executes plugin disconnect hooks

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X DELETE "https://fedisuite.example.com/api/accounts/123" \
  -H "Authorization: Bearer $TOKEN"

5. Posts and queue

5.1 GET /api/posts

Purpose:

  • Read the user's queue and post history

Auth:

  • Bearer token required

Query parameters:- page Default 1

  • pageSize Default 20, Maximum 100
  • search Answer:
json
{
  "items": [],
  "pagination": {
    "page": 1,
    "page_size": 20,
    "total_items": 0,
    "total_pages": 1,
    "has_previous_page": false,
    "has_next_page": false
  },
  "summary": {
    "scheduled": 0,
    "failed": 0,
    "published": 0,
    "draft": 0,
    "total": 0
  },
  "filters": {
    "search": ""
  }
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/posts?page=1&pageSize=20&search=" \
  -H "Authorization: Bearer $TOKEN"

5.2 POST /api/posts

Purpose:

  • Schedule mail locally
  • optional thread splitting and media upload

Auth:

  • Bearer token required

Content type:- multipart/form-data Form fields:

  • accountId
  • content
  • scheduledAt
  • spoilerText
  • visibility
  • title
  • language
  • autoSplitThread
  • multiple times media
  • optional altText_0, altText_1, ...

Rules:

  • PeerTube needs title
  • Language is validated
  • the server can create multiple thread segments

Answer:

  • single post record or
  • Thread payload with thread_group_id, thread_total, items

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/posts" \
  -H "Authorization: Bearer $TOKEN" \
  -F "accountId=123" \
  -F "content=Geplanter Post" \
  -F "scheduledAt=2026-05-07T08:00:00.000Z" \
  -F "visibility=public" \
  -F "language=de"

5.3 POST /api/posts/publish-now

Purpose:

  • Create a post immediately locally and publish it directly

Auth:

  • Bearer token required

Content type:- multipart/form-data Form fields:

  • same as POST /api/posts, only for immediate publication

Answer:

  • single published post record or
  • Thread payload with published segments

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/posts/publish-now" \
  -H "Authorization: Bearer $TOKEN" \
  -F "accountId=123" \
  -F "content=Direkt raus" \
  -F "visibility=public"

5.4 POST /api/posts/:id/repost

Purpose:

  • resend existing mail

Behavior:

  • tries to copy local media
  • if necessary, reload remote media
  • creates new local data set
  • publishes immediately

Answer:

json
{
  "success": true,
  "postId": 1009,
  "fediverseId": "114460000000000099"
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/posts/991/repost" \
  -H "Authorization: Bearer $TOKEN"

5.5 PUT /api/posts/:id

Purpose:

  • update local post

Request body:

json
{
  "content": "Aktualisiert",
  "title": null,
  "scheduledAt": "2026-05-08T10:00:00.000Z",
  "spoilerText": "CW",
  "visibility": "private",
  "language": "de"
}

Rules:

  • editable for scheduled, draft, failed, published
  • empty content only allowed if media is present
  • certain fields are included in thread segments that have not yet been published

Answer:

  • raw updated post record

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/posts/991" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Aktualisiert",
    "visibility": "private",
    "language": "de"
  }'

5.6 DELETE /api/posts/:id

Purpose:

  • delete local post or parts of a thread

Behavior:

  • without published thread parts, a complete thread can be deleted
  • with published parts only matching remaining segments
  • Media and thumbnails are cleaned up

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X DELETE "https://fedisuite.example.com/api/posts/991" \
  -H "Authorization: Bearer $TOKEN"

6. Refresh and individual analytics

6.1 POST /api/refresh-stats

Purpose:

  • Refresh all user accounts immediately

Behavior:

  • calls platform-specific profile/stats endpoints per account
  • updates followers, following, status counts, profile metadata and platform limits
  • writes stats_history if necessary
  • Accounts with reauth errors will be skipped

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X POST "https://fedisuite.example.com/api/refresh-stats" \
  -H "Authorization: Bearer $TOKEN"

6.2 GET /api/accounts/:id/import-status

Purpose:

  • read current import status and last import job

Answer:

json
{
  "import_status": "done",
  "job": {
    "status": "completed",
    "total_posts_fetched": 500,
    "total_pages_fetched": 12,
    "started_at": "2026-05-05T10:00:00.000Z",
    "completed_at": "2026-05-05T10:04:00.000Z",
    "error_message": null,
    "next_retry_at": null,
    "retry_count": 0
  }
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/import-status" \
  -H "Authorization: Bearer $TOKEN"

6.3 GET /api/accounts/:id/top-posts

Query:- days

  • limit Maximum 50
  • sort=favourites_count|reblogs_count|replies_count|total_engagement Answer:
  • Array of post_stats entries including total_engagement

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/top-posts?days=30&limit=10&sort=total_engagement" \
  -H "Authorization: Bearer $TOKEN"

6.4 GET /api/accounts/:id/daily-stats

Query:- days Answer:

json
[
  {
    "date": "2026-05-01",
    "posts_count": 3,
    "total_favourites": 20,
    "total_reblogs": 5,
    "total_replies": 2
  }
]

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/daily-stats?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.5 GET /api/accounts/:id/stats-history

Query:- days Answer:

json
[
  {
    "followers": 1200,
    "following": 300,
    "statuses": 800,
    "recorded_at": "2026-05-06T09:00:00.000Z"
  }
]

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/stats-history?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.6 GET /api/accounts/:id/engagement-rate

Answer:

  • Array with date, posts_count, engagement_rate

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/engagement-rate?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.7 GET /api/accounts/:id/weekly-growth

Answer:

  • Array with week, follower_change, followers_end

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/weekly-growth?days=90" \
  -H "Authorization: Bearer $TOKEN"

6.8 GET /api/accounts/:id/engagement-breakdown

Answer:

json
{
  "favourites": 320,
  "boosts": 74,
  "replies": 41
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/engagement-breakdown?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.9 GET /api/accounts/:id/best-times

Answer:

  • Array with day_of_week, hour, avg_engagement, post_count

Note:

  • this single endpoint uses UTC based created_at derivation
  • The mobile bundle, however, calculates the time windows in the user time zone

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/best-times?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.10 GET /api/accounts/:id/follower-events

Answer:

  • Array with date, followers_end, net_change

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/follower-events?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.11 GET /api/accounts/:id/media-performance

Answer:

  • Array with type media|text and average values

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/media-performance?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.12 GET /api/accounts/:id/weekday-engagement

Answer:

  • Array with day_of_week, average and post counts

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/weekday-engagement?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.13 GET /api/accounts/:id/visibility-breakdown

Answer:

  • Array with visibility and post_count

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/visibility-breakdown?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.14 GET /api/accounts/:id/hashtag-overview

Answer:

json
{
  "posts_total": 18,
  "posts_with_hashtags": 9,
  "posts_without_hashtags": 9,
  "hashtag_uses": 22,
  "unique_hashtags": 8,
  "avg_hashtags_per_post": 1.22,
  "avg_hashtags_per_tagged_post": 2.44
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/hashtag-overview?days=30" \
  -H "Authorization: Bearer $TOKEN"

6.15 GET /api/accounts/:id/top-hashtags

Query:- days

  • limit Maximum 30
  • sort=total_engagement|avg_engagement|posts_count Answer:
  • Array with tag, posts_count, total_*, avg_engagement, boost_rate, reply_rate

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/top-hashtags?days=30&limit=12&sort=avg_engagement" \
  -H "Authorization: Bearer $TOKEN"

6.16 GET /api/accounts/:id/hashtag-combinations

Query:- days

  • limit Maximum 25 Answer:
  • Array with tag_a, tag_b, posts_count, total_engagement, avg_engagement

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/hashtag-combinations?days=30&limit=10" \
  -H "Authorization: Bearer $TOKEN"

6.17 GET /api/accounts/:id/insights

Purpose:

  • Read server-side generated growth/analysis tips

Query:- days Answer:

json
{
  "tips": [],
  "meta": {}
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/accounts/123/insights?days=30" \
  -H "Authorization: Bearer $TOKEN"

7. User self-service

7.1 GET /api/user/dashboard-layout

Purpose:

  • read saved dashboard layout

Answer:

  • Array or null

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/user/dashboard-layout" \
  -H "Authorization: Bearer $TOKEN"

7.2 PUT /api/user/dashboard-layout

Request body:

  • an array as a complete layout

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/dashboard-layout" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '["summary","top_posts","best_times"]'

7.3 GET /api/user/profile

Answer:

json
{
  "id": 42,
  "email": "user@example.com",
  "timezone": "Europe/Berlin",
  "default_account_id": 123,
  "language": "de",
  "theme": "dark"
}

curl:

bash
curl -sS \
  "https://fedisuite.example.com/api/user/profile" \
  -H "Authorization: Bearer $TOKEN"

7.4 PUT /api/user/language

Request body:

json
{
  "language": "de"
}

Answer:

json
{
  "success": true,
  "language": "de"
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/language" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "de"
  }'

7.5 PUT /api/user/theme

Request body:

json
{
  "theme": "dark"
}

Answer:

json
{
  "success": true,
  "theme": "dark"
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/theme" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "theme": "dark"
  }'

7.6 PUT /api/user/email

Request body:

json
{
  "newEmail": "neu@example.com",
  "currentPassword": "mein-passwort"
}

Answer:

json
{
  "success": true
}

Rules:

  • Current password is mandatory
  • new email must not already be occupied by another user

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/email" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "newEmail": "neu@example.com",
    "currentPassword": "mein-passwort"
  }'

7.7 PUT /api/user/password

Request body:

json
{
  "currentPassword": "altes-passwort",
  "newPassword": "neues-passwort"
}

Answer:

json
{
  "success": true
}

Rules:

  • both fields are mandatory
  • new password at least 8 characters

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/password" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "altes-passwort",
    "newPassword": "neues-passwort"
  }'

7.8 PUT /api/user/timezone

Request body:

json
{
  "timezone": "Europe/Berlin"
}

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/timezone" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "timezone": "Europe/Berlin"
  }'

7.9 PUT /api/user/default-account

Request body:

json
{
  "accountId": 123
}

or to reset:

json
{
  "accountId": null
}

Answer:

json
{
  "success": true,
  "default_account_id": 123
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/user/default-account" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": 123
  }'

7.10 DELETE /api/user/account

Purpose:

  • Delete entire user including accounts and posts

Request body:

json
{
  "password": "mein-passwort"
}

Behavior:

  • Password check
  • Media cleanup
  • Plugin cleanup for all accounts
  • Deletion of posts, accounts and users

Answer:

json
{
  "success": true
}

curl:

bash
curl -sS \
  -X DELETE "https://fedisuite.example.com/api/user/account" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "password": "mein-passwort"
  }'

8. Mobile Bundle API

8.1 GET /api/mobile/bootstrap

Purpose:

  • central mobile initial payload

Auth:

  • Bearer token required

Contains:- server_time

  • public_config
  • notice
  • user
  • summary
  • accounts
  • mobile_capabilities Important Capabilities:- dashboard_periods: aktuell [7, 30, 90, 365, 730, 0]
  • top_post_sort_options
  • top_hashtag_sort_options
  • supports_preferences_batch_update: true curl:
bash
curl -sS \
  "https://fedisuite.example.com/api/mobile/bootstrap" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept-Language: de"

8.2 GET /api/mobile/accounts/:id/dashboard

Purpose:

  • complete mobile dashboard bundle for one account

Auth:

  • Bearer token required

Query parameters:- days

  • topPostsLimit
  • topPostsSort
  • topHashtagsLimit
  • topHashtagsSort
  • hashtagCombinationsLimit Defaults:- days=30
  • topPostsLimit=5
  • topHashtagsLimit=12
  • hashtagCombinationsLimit=10
  • topPostsSort=total_engagement
  • topHashtagsSort=total_engagement Allowed sorts:
  • Top posts: favourites_count, reblogs_count, replies_count, total_engagement
  • Top hashtags: total_engagement, avg_engagement, posts_count

Bundle content:

  • period
  • account
  • summary
  • charts
  • top_posts
  • insights Special features:
  • best_times and weekday_engagement are calculated in the user time zone inside the bundle
  • effective_statuses_count is based on GREATEST(stats_statuses, indexed_posts_count) curl:
bash
curl -sS \
  "https://fedisuite.example.com/api/mobile/accounts/123/dashboard?days=30&topPostsSort=total_engagement&topHashtagsSort=avg_engagement" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept-Language: de"

8.3 PUT /api/mobile/preferences

Purpose:

  • Update multiple user preferences in one request

Auth:

  • Bearer token required

Possible fields:

  • language
  • theme
  • timezone
  • defaultAccountId Answer:
json
{
  "success": true,
  "profile": {
    "id": 42,
    "email": "user@example.com",
    "timezone": "Europe/Berlin",
    "default_account_id": 123,
    "language": "de",
    "theme": "dark"
  }
}

curl:

bash
curl -sS \
  -X PUT "https://fedisuite.example.com/api/mobile/preferences" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "de",
    "theme": "dark",
    "timezone": "Europe/Berlin",
    "defaultAccountId": 123
  }'

9. Dynamic plugin routes

In addition to the static endpoints documented above, FediSuite mounts additional plugin routes via mountPluginHttpRoutes(...).

Important:

  • these routes are not hard-coded in the core repo
  • they depend on installed and activated plugins
  • they can be authenticated, unauthenticated, user-scoped, or admin-scoped
  • their documentation belongs in the specific plugin

Practical consequence:

  • API.md is complete for the core API
  • for a fully complete runtime API of a specific instance, all installed plugins must be considered as well

10. Practical complete workflow

Set base:

bash
BASE_URL="https://fedisuite.example.com"

Check health:

bash
curl -sS "$BASE_URL/api/health"

Login:

bash
LOGIN_RESPONSE=$(curl -sS \
  -X POST "$BASE_URL/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "user@example.com",
    "password": "mein-passwort"
  }')

Extract tokens:

bash
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.token')

Load Bootstrap:

bash
curl -sS "$BASE_URL/api/mobile/bootstrap" \
  -H "Authorization: Bearer $TOKEN"

Load accounts:

bash
curl -sS "$BASE_URL/api/accounts" \
  -H "Authorization: Bearer $TOKEN"

Load dashboard:

bash
curl -sS "$BASE_URL/api/mobile/accounts/123/dashboard?days=30" \
  -H "Authorization: Bearer $TOKEN"

Load queue:

bash
curl -sS "$BASE_URL/api/posts" \
  -H "Authorization: Bearer $TOKEN"

Create scheduled post:

bash
curl -sS \
  -X POST "$BASE_URL/api/posts" \
  -H "Authorization: Bearer $TOKEN" \
  -F "accountId=123" \
  -F "content=Testpost" \
  -F "visibility=public" \
  -F "scheduledAt=2026-05-07T08:00:00.000Z"