Table of Contents
Mastodon Plugin
Author: Fraenkiman
What this plugin does
The Mastodon plugin connects one FlatPress installation with one Mastodon account.
It can synchronize content in both directions:
- FlatPress entry → Mastodon status
- FlatPress comment → Mastodon reply
- FlatPress reply to a comment → Mastodon reply to that reply
- Mastodon top-level status → FlatPress entry
- Mastodon reply inside a known imported thread → FlatPress comment
The plugin can also synchronize:
- images from FlatPress entries to Mastodon
- image attachments from Mastodon to FlatPress
- audio and video from FlatPress entries to Mastodon when the FlatPress AudioVideo plugin is active
- Mastodon audio and video attachments to FlatPress AudioVideo player tags
- FlatPress entry tags and Mastodon hashtags when the FlatPress Tag plugin is active
Important concept
Mastodon does not have a separate “comment” object like a blog.
In Mastodon, comments are simply replies inside a thread.
The plugin therefore uses this mapping:
- Entry → Mastodon status without
in_reply_to_id - Comment on an entry → Mastodon reply to the entry status
- Comment on a comment → Mastodon reply to the parent reply
That means a synchronized discussion can continue on both sides as one thread.
Requirements
You need:
- FlatPress 1.5.1 Stringendo or newer
- PHP 7.2 to 8.5
- the plugin files from this package
The plugin uses:
- cURL when available
allow_url_fopenas a fallback if cURL is not available- JSON
- DOMDocument / libxml for the best HTML-to-BBCode conversion
- OpenSSL to protect stored secrets when available
Mastodon compatibility range:
- Technical: >= 4.0.0 as of November 2022
- Recommended: >= 4.4.0 as of July 2025
Recommended FlatPress plugins
For the best result with synchronized Mastodon content, also enable these FlatPress plugins:
- BBCode renders imported formatting, links, images and galleries properly.
- PhotoSwipe improves image and gallery display.
- AudioVideo renders imported and synchronized audio/video attachments as HTML5 media players.
- Tag enables tag / hashtag synchronization.
- Emoticons renders imported emoji shortcodes more nicely.
What the plugin currently does and does not do
Visibility
- Exported FlatPress entries are posted to Mastodon as public statuses.
- Exported FlatPress comments are posted to Mastodon as public replies.
- Mastodon statuses or replies with visibility private or direct are not imported into FlatPress.
Text and formatting
- FlatPress content is converted to Mastodon-friendly plain text during export.
- Mastodon HTML is converted to FlatPress-friendly BBCode during import.
- If you enable Update existing local content from Mastodon, already imported local entries and comments may be refreshed from Mastodon later. In that mode the plugin keeps local texts within a practical size limit.
Images and media
- FlatPress entries can export local images referenced by
[img]and[gallery]. - FlatPress entries can export local audio referenced by
[audioplayer]and local video referenced by[videoplayer]when the AudioVideo plugin is active. - FlatPress comments do not export images, audio or video.
- Mastodon image attachments can be imported into FlatPress.
- Mastodon audio attachments can be imported into FlatPress as
[audioplayer]tags. - Mastodon video and GIFV attachments can be imported into FlatPress as
[videoplayer]tags; available preview images are stored as video posters. - If the Mastodon server has media limits, extra media attachments are skipped instead of breaking the whole synchronization.
- When the plugin already knows a media description, it sends that description during the initial Mastodon media upload.
- If only the media description changes later, the plugin can update the description on supported Mastodon servers without re-uploading the file.
- Audio, video and GIFV uploads may be processed asynchronously by Mastodon. The plugin waits for the uploaded media to become ready and uses longer bounded polling windows for audio/video than for images.
- Remote audio/video imports try alternate direct media URLs when the first download URL is temporarily unavailable.
Tags
- Tag synchronization works only when the FlatPress Tag plugin is active.
- FlatPress entry tags are exported as Mastodon hashtags.
- Mastodon hashtags are imported as FlatPress entry tags.
- Comments do not carry tags.
How scheduling works
- The default daily synchronization time is 03:00.
- You can change the time in the plugin settings.
- Automatic synchronization runs only on a normal website request after the due time.
- It does not run during CLI execution.
- It is skipped for HTTP POST requests.
- If nobody visits the site after the scheduled time, the automatic synchronization waits until the next normal page request.
There is also a Run synchronization now button in the plugin settings for a manual run.
Deletion synchronization runs later
The plugin separates normal synchronization from deletion synchronization.
That means:
- content synchronization runs first
- deletion synchronization is marked as pending
- the delete check runs in a later follow-up request
This keeps the main synchronization request shorter and more stable.
The option Enable deletion synchronization controls whether that follow-up delete pass is used at all.
Admin page overview
In Plugins → Mastodon you will see these areas:
1. Basic settings
Tip of the day:
Between 3:00 a.m. and 6:00 a.m., there is little internet traffic and the Mastodon server is fast to access.
Here you set:
- Username
- Mastodon URL
- Daily sync time
- Synchronization start date
The Synchronization start date is useful when you do not want to import or export much older content.
I recommend setting the start date once and then not changing it. You can change the start date in the following scenarios:
| Action | Recommendation |
| Historical initial import / backfill | Extend backward in 7–14-day blocks |
| Many gallery/video posts in the history | Rather by number of media items, not by days: max. approx. 20–24 media items per run |
Automatic window for scheduled runs (specific guidelines).
| Usage scenario | Recommendation |
| Normal blog, few media files, few comments | 14 days |
| Very quiet blog, hardly any media, few old changes | 30 days maximum |
| Media-heavy: galleries, audio, video | 7 days |
| Many comments or many old edits | 7–14 days |
Tip: If you see error messages indicating that limits have been reached, select a shorter time frame, such as 7 days.
2. More options
These switches are especially important:
- Update existing local content from Mastodon
Allows already imported FlatPress entries and comments to be refreshed from Mastodon later.
- Import comments as entries as well
Allows certain synchronized Mastodon replies to also appear as FlatPress entries. Leave this disabled if you want to avoid duplicate content and keep thread replies mainly in the comment area.
- Enable deletion synchronization
Enables the separate follow-up delete pass. Deletion synchronization ensures that posts/ statuses, comments/ replies deleted on one side are also deleted on the other.
3. OAuth helper
This section is used only to connect FlatPress to your Mastodon account.
The usual order is:
- save the basic settings
- click Register Mastodon app
- open the shown authorization URL
- allow the app on Mastodon
- copy the shown code back into FlatPress
- click Exchange code for token
Without a valid access token, synchronization cannot work.
4. Mastodon instance information
This section lets you manually fetch information about your Mastodon server, for example:
- exact Mastodon version
- API compatibility version
- server limits relevant to synchronization
This is mainly a diagnostic aid. It is not required before every synchronization.
5. Status and counters
The lower part of the page shows:
- the last synchronization time
- the last deletion synchronization time
- the last error
- counters for imported, updated, exported and deleted entries and comments
Installation and first setup
Step 1: Install the plugin
Copy these directories to your FlatPress root directory:
fp-plugins/fp-includes/
Then activate the plugin in the FlatPress admin area.
Step 2: Enter the Mastodon server URL
Use only the base URL of your Mastodon server, for example:
Do not enter a profile or status URL such as:
Step 3: Save the basic settings
Save at least:
- Username
- Mastodon URL
- Daily sync time
You can also set a Synchronization start date now.
Step 4: Register the Mastodon app
Click Register Mastodon app.
The plugin then stores the technical app information it needs for OAuth.
Step 5: Authorize the app
Open the shown authorization URL in your browser, approve the app and copy the displayed authorization code.
Step 6: Exchange the code for a token
Paste the code into the plugin page and click Exchange code for token.
After that, FlatPress has the access token it needs for synchronization.
Step 7: Optional: fetch Mastodon instance information
You can click Fetch Mastodon instance information to store a snapshot of your server information in the admin area.
This is helpful when you want to check:
- the exact Mastodon version
- media and text limits
- whether the server reports useful compatibility information
Step 8: Run the first synchronization
Click Run synchronization now.
After the run, also check:
- Last sync
- Last error
- the counters in the admin area
For technical details you can additionally inspect:
fp-content/plugin_mastodon/sync.log
How synchronization works in practice
FlatPress -> Mastodon
Entry export
A FlatPress entry becomes one Mastodon top-level status.
The exported text is built from:
- the entry subject
- the entry content converted into Mastodon-friendly text
- a public entry link when the blog URL is publicly usable
Local media in the entry can be attached to the Mastodon status:
[img]and[gallery]become Mastodon image uploads[audioplayer]becomes a Mastodon audio upload[videoplayer]becomes a Mastodon video upload- a local
posterattribute on[videoplayer]is sent as the Mastodon media thumbnail when usable
Mastodon instances can take longer to process audio and video than images. The plugin therefore polls the Mastodon media endpoint until the uploaded attachment reports its final media URL or a bounded timeout is reached.
Comment export
A FlatPress comment becomes one Mastodon reply to the synchronized entry.
If the comment is itself a reply to another FlatPress comment, it becomes a Mastodon reply to that parent reply.
This keeps reply chains intact on Mastodon.
What happens on imported Mastodon threads
If a Mastodon top-level status was already imported as a FlatPress entry, and you then write a new FlatPress comment under that entry, the plugin exports that new FlatPress comment as a Mastodon reply in the existing Mastodon thread.
The same applies to replies to local FlatPress comments inside that thread.
Mastodon -> FlatPress
Top-level status import
A Mastodon top-level status from the connected account can become a FlatPress entry.
Media attachments are imported with FlatPress-native markup:
- one image becomes an
[img]tag - multiple images become a
[gallery]tag - audio becomes an
[audioplayer]tag - video and GIFV become a
[videoplayer]tag
If a video preview image is available, it is stored and referenced as the video poster.
Reply import inside known threads
Replies that belong to a known imported Mastodon thread are imported as FlatPress comments under the matching FlatPress entry.
If a reply belongs under a previously synchronized FlatPress comment, it is imported as a reply to that local comment.
This also applies when another Mastodon member replies inside that known thread.
About “Import comments as entries as well”
Tip of the day:
Mastodon limits posts to a maximum of 500 characters. If your FlatPress posts and comments are longer than 500 characters and you want to keep them that way, disable the "Update existing local content from Mastodon" option.
When this option is disabled, thread replies should stay in the comment area instead of also appearing as separate FlatPress entries.
When the option is enabled, the plugin may additionally import certain synchronized replies as entries as well.
If you mainly want a blog-like discussion structure, leaving the option disabled is usually the safer choice.
Where plugin data is stored
The plugin stores its working data in:
fp-content/plugin_mastodon/sync.logfp-content/plugin_mastodon/sync.guard.jsonfp-content/plugin_mastodon/state.jsonfp-content/plugin_mastodon/scheduler-state.jsonfp-content/plugin_mastodon/rate-limit-windows.json
Imported Mastodon images are stored under:
fp-content/images/mastodon/
Imported Mastodon audio and video files are stored under:
fp-content/attachs/mastodon/
Imported video poster images are stored under:
fp-content/images/mastodon/
OAuth and plugin settings are stored in the FlatPress configuration.
Troubleshooting
“No access token saved”
The OAuth setup is not finished yet.
Do this:
- save the Mastodon URL
- click Register Mastodon app
- open the authorization URL
- approve the app on Mastodon
- paste the shown code back into FlatPress
- click Exchange code for token
“The synchronization finished successfully” but nothing new appears
Check these points:
- Is the content older than the configured Synchronization start date?
- Is the Mastodon post private or direct?
- Is the local FlatPress entry still a draft?
- Is the content already synchronized and therefore only counted as an update or not changed at all?
- Is the automatic run simply not due yet?
Also check:
- the counters in the plugin page
fp-content/plugin_mastodon/sync.log
Comments are not where I expected them
Remember these rules:
- top-level Mastodon posts become FlatPress entries
- replies inside a known imported thread become FlatPress comments
- if Import comments as entries as well is disabled, replies should normally stay in the comment area only
Media is missing on Mastodon
Notice:
Mastodon allows either multiple images or one audio/video attachment per post.
Check these points:
- Is the media in a FlatPress entry and not only in comments?
- Are images referenced with
[img]or[gallery]? - Are audio files referenced with
[audioplayer]? - Are video files referenced with
[videoplayer]? - Are the local files stored below
fp-content/attachs/orfp-content/images/? - Does the Mastodon server allow the number, MIME type and size of the uploaded media?
- For large audio or video files, check
fp-content/plugin_mastodon/sync.logfor media processing messages.
Imported Mastodon media is missing in FlatPress
Check these points:
- Are the attachments public and downloadable by the web server?
- Can FlatPress write to
fp-content/images/mastodon/? - Can FlatPress write to
fp-content/attachs/mastodon/? - Can the web server download files from the Mastodon media host?
- Is the FlatPress AudioVideo plugin active when you want imported audio/video to render as players?
Audio or video upload reports ''media_processing_timeout''
Mastodon may accept an audio or video upload first and then process it asynchronously.
The plugin waits longer for audio/video than for images, but processing can still fail when:
- the file is larger than the Mastodon instance allows
- the Mastodon server rejects the MIME type
- the server-side transcoder is overloaded
- the web host stops long-running PHP requests too early
Check:
- the Mastodon instance media limits in the plugin admin page
fp-content/plugin_mastodon/sync.log- the real file type and file size of the referenced media
Security notes
- The plugin stores connection secrets in FlatPress configuration.
- When OpenSSL is available, those secrets are protected more strongly.
- Protect your FlatPress admin access and your backups carefully.
Practical recommendation
The safest order is:
- install and activate the plugin
- save Mastodon URL and sync time
- register the Mastodon app
- authorize the app on Mastodon
- exchange the authorization code for a token
- run a manual sync
License
The plugin's code is licensed under the FlatPress Project License.
FAQ
- Q: Why do Mastodon texts not look exactly like the original FlatPress formatting?
- A: The plugin converts FlatPress formatting into Mastodon-friendly text. Mastodon itself stores and renders statuses differently from a blog system, so the result is intentionally adapted instead of copied 1:1.
- Q: Can videos and audio be synchronized?
- A: Yes. FlatPress entries can export local
[audioplayer]and[videoplayer]media to Mastodon, and Mastodon audio/video attachments can be imported into FlatPress when the AudioVideo plugin is available. FlatPress comments do not synchronize media attachments.
- Q: Why can the deletion counters change later than the synchronization counters?
- A: Because the deletion pass runs in a later follow-up request, not in the main synchronization request.
Download
FlatPress-Extras github repo of Mastodon Plugin
Changelog
2026-05-15: Version 2.4.4
- Compliant with PHPStan Level 5
2026-05-10: Version 2.4.3
- New policy for mixed image/audio/video sets in posts:
- Images present: → Export only images, up to the Mastodon media limit.
- No images, but audio present: → Export exactly one audio file.
- No images, no audio, but video present: → Export exactly one video. → Export the poster image only as a
/api/v2/mediathumbnail, not as a separatemedia_id.
2026-05-09: Version 2.4.2
- Instructions and documentation have been updated to reflect the latest plugin version.
- A fallback has been added to the deletion sync for Maston servers older than 4.4.0.
2026-05-07: Version 2.4.1
- The
statfile is no longer loaded with every request. Instead, we only loadscheduler-state, which requires less response time when there is a lot of content. - The
statfile is now only loaded when a full admin synchronization and deletion run is initiated, or ifscheduler-stateis missing or has been corrupted. - The FlatPress core has received new hooks.
entry_savedentry_deletedcomment_savedcomment_deleted
- Therefore, the two existing core files,
core.entry.phpandcore.comment.php, must be replaced with the files from the package.
2026-05-06: Version 2.4.0
- There are now dynamic time windows for text-heavy, mixed, and media-heavy blogs.
- The scheduled remote existence check for the delete sync has been tied to the automatic window.
- Progress cursors for entry and comment mappings, so that large datasets are distributed across multiple runs.
- Pending child rechecks are not blocked by the automatic window.
- Added limits for paging, deletion, and media uploads based on the Mastodon REST API documentation.
- APCu- and file-based cooldown guard for scheduled content and deletion synchronizations, ensuring that synchronization does not occur again with every web request under unfavorable conditions.
- Rate-limit guard with request budget, media upload budget, and delete budget per run.
- Manual synchronization in the admin area has been expanded:
- Normal synchronization → Run now as a scheduled run, with an automatic window
- Full synchronization from start date → Ignores the automatic window, uses the manual start date
- Resume full deletion synchronization → Intentionally performs a full synchronization starting from the manual start date, including cursors and budgets
2026-05-02: Version 2.2.1
- When the AudioVideo plugin is active, audio and video content can also be synchronized in both directions.
- Starting with version 1.1.0 of the Audio and Video Player plugin, you can specify a description between the start and end tags.
- The description is used as alt-text on Mastodon.
- Deletion synchronization for nested replies has been optimized so that deep reply chains converge more quickly.
- Check direct children specifically, but after a child is confirmed deleted, immediately transfer its direct children to a small FIFO queue in the same run
- Downstream deletion synchronization restores the referenced reply and its children to their original status
- The formatted date and time + timeoffset is now displayed in the admin area
- Emoticons are displayed correctly in exported posts and comments on Mastodon.
- When importing statuses or replies, FlatPress now takes the time offset relative to UTC into account.
- This ensures that comments in FlatPress are displayed chronologically from top to bottom.
- If a reply to another reply is created on Mastodon, the imported comment in FlatPress is optionally quoted to enhance the user experience.





