Reelspan posts to your Mastodon account on any server, with an access token you make in the server's settings. Servers that offer Mastodon's API, such as GoToSocial, work the same way.
What you can post
| Post | How it appears |
|---|---|
| Video | A post with the video attached |
| Photos | A post with up to 4 images, each with its alt text. photos[] can mix images and a video |
| Text | A plain post |
Media is uploaded to your server first. Servers process video in the background, so Reelspan waits until it's ready before posting. The result's url is the post on your server and post_id its id.
Connect your account
You need your server's address and an access token. Setup takes about two minutes.
- On your server, open Preferences → Development → New application (on mastodon.social: mastodon.social/settings/applications).
- Name it Reelspan, keep the
readandwritescopes, and save. - Open the application and copy Your access token.
- In the Reelspan dashboard, open Accounts → Connect account, choose the profile and Mastodon, and paste the token with your server (
mastodon.social).
Reelspan checks the token with your server before saving it, encrypted.
With the API
curl -X POST https://api.reelspan.com/v1/accounts/mastodon \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile_username": "my-brand", "server": "mastodon.social", "access_token": "..."}'import { Reelspan } from 'reelspan';
const reelspan = new Reelspan();
await reelspan.accounts.connect('my-brand', 'mastodon', {
server: 'mastodon.social',
access_token: process.env.MASTODON_TOKEN,
});import os
from reelspan import Reelspan
reelspan = Reelspan()
reelspan.accounts.connect("my-brand", "mastodon", server="mastodon.social", access_token=os.environ["MASTODON_TOKEN"]){ "success": true, "platform": "mastodon", "account": "@[email protected]", "reconnected": false }| Field | Required | Also accepted (Upload-Post) |
|---|---|---|
server |
Yes | instance_url |
access_token |
Yes |
server can be mastodon.social or https://mastodon.social; Reelspan always talks to it over https. Connecting again replaces the Mastodon account on that profile. See Connect with credentials.
Example post
Two images behind a content warning, visible to followers only:
curl -X POST https://api.reelspan.com/v1/posts/photos \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-F "user=my-brand" \
-F "platform[]=mastodon" \
-F "title=First look at the new dashboard #design" \
-F "mastodon_visibility=private" \
-F "mastodon_spoiler_text=Product screenshots" \
-F "alt_text[]=The dashboard in light mode" \
-F "alt_text[]=The dashboard in dark mode" \
-F "photos[][email protected]" \
-F "photos[][email protected]"import { Reelspan } from 'reelspan';
import { readFile } from 'node:fs/promises';
const reelspan = new Reelspan();
const post = await reelspan.posts.photos({
user: 'my-brand',
platforms: ['mastodon'],
title: 'First look at the new dashboard #design',
photos: [
{ data: await readFile('photo1.jpg'), name: 'photo1.jpg', type: 'image/jpeg' },
{ data: await readFile('photo2.jpg'), name: 'photo2.jpg', type: 'image/jpeg' },
],
altTexts: ['The dashboard in light mode', 'The dashboard in dark mode'],
extra: { mastodon_visibility: 'private', mastodon_spoiler_text: 'Product screenshots' },
});from reelspan import Reelspan
reelspan = Reelspan()
post = reelspan.posts.photos(
"my-brand", ["mastodon"], ["photo1.jpg", "photo2.jpg"], "First look at the new dashboard #design",
alt_texts=["The dashboard in light mode", "The dashboard in dark mode"],
extra={"mastodon_visibility": "private", "mastodon_spoiler_text": "Product screenshots"},
)Fields
| Field | Meaning |
|---|---|
mastodon_title |
The post's text on Mastodon. Falls back to title. |
title |
The caption every network uses, when mastodon_title isn't sent. |
mastodon_visibility |
Who sees it: public (the default), unlisted, or private (followers only). Sent to your server as given. |
mastodon_spoiler_text |
A content warning shown before the post. |
mastodon_sensitive |
true marks the media as sensitive. Default false. |
mastodon_alt_text |
Alt text for the media: one text for all, or one per image. Falls back to alt_text. Up to 1,500 characters each. |
alt_text |
The alt text for every network that takes it. |
mastodon_first_comment |
Posted as an unlisted reply to the post. Falls back to first_comment. |
In the dashboard composer, the Mastodon tab has Visibility, Content warning and Mark media as sensitive.
Limits and behaviour
- Images: up to 4 per post. With more, the first 4 are sent and the result carries a warning.
- Files: up to 99 MB each; your server may allow less.
- Video processing: Reelspan waits up to about 3 minutes for the server to process a video, then fails with
processing_timeout, which is retried. - Text length: set by your server (500 characters on most). Reelspan sends the text as it is.
- No duplicates: each post is sent with the request's id as Mastodon's idempotency key, so a retry doesn't post twice.
- Analytics: likes, boosts and replies per post, and followers, following and post counts for the account. See Analytics.
- Your server only: calls go only to the server you named, and never to private network addresses.
Common errors
| Code | When | Fix |
|---|---|---|
INVALID_SERVER |
Connecting: the server isn't an address like mastodon.social |
Enter just the server's address. |
INVALID_TOKEN |
Connecting: the server didn't accept the token | Make a token with read and write under Preferences → Development. |
reauth_required |
The server answered 401 or 403: the token was revoked | Make a new token and connect again. |
file_too_large |
A file is over 99 MB | Send a smaller file. |
processing_timeout |
The server took too long to process the video | Reelspan retries; if it keeps failing, try a shorter or smaller video. |
mastodon_error |
The server refused the post, for example text over its limit. Retried automatically on 429 and 5xx | Read error for the server's reason. |
MISSING_FIELD |
Connecting without server or access_token |
Send both. |
Errors when connecting come back as a 400 with the code in error_code. Errors when posting are in that network's result. See Errors.