# OmniSocials Mastodon API

> Publish posts, images, polls and threads to any Mastodon server, checked against that server’s own limits. Read likes, boosts and poll results. One API key, whichever server the account is on.

This is the machine-readable version of [omnisocials.com/mastodon-api](https://omnisocials.com/mastodon-api), maintained for AI agents. Facts checked against the OmniSocials app and API on October 17, 2026. Platform reference: [docs.omnisocials.com/platforms/mastodon](https://docs.omnisocials.com/platforms/mastodon). API reference: [docs.omnisocials.com/api](https://docs.omnisocials.com/api).

## Basics

- Base URL: `https://api.omnisocials.com/v1`
- Auth: `Authorization: Bearer omsk_live_...`. One key belongs to one workspace. Keys are created in the app under Settings, API.
- Channel id in `accounts`: `mastodon`. The account connects inside the OmniSocials app, not through the API.
- Rate limit: 100 requests per minute per key. A 429 carries `Retry-After`.
- Responses use a `{ "data": ... }` envelope. Create returns `201`.
- Webhooks: `post.scheduled`, `post.published`, `post.failed`, `post.approved`, `post.rejected`, signed with HMAC-SHA256 in `X-OmniSocials-Signature`.

## Skip the setup on every server

Mastodon has no app review, but every server is its own API: an app to register on each one, OAuth per server, its own limits, media that processes before it can post and threads chained reply by reply. OmniSocials does that for any server.

- On your own: Server apps, OAuth, Limits, Counting, Uploads, Processing, Reply chain, Retries, then the first post.
- On OmniSocials: sign in, create an API key, POST. Registered on any server for you.

## Schedule a post

```bash
curl -X POST https://api.omnisocials.com/v1/posts/create \
  -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "New: OmniSocials SDKs in 8 languages",
  "accounts": ["mastodon"],
  "media_urls": [
    {
      "url": "https://cdn.example.com/sdks.png",
      "alt": "Code that creates a post with the Node.js SDK"
    }
  ],
  "schedule_at": "2026-10-22T18:00:00Z"
}'
```

The answer (`201`, shortened):

```json
{
  "data": {
    "id": "1024",
    "status": "scheduled",
    "app_url": "https://app.omnisocials.com/create-post/1024"
  }
}
```

## Every format, one request

Text posts, images, polls and threads share one request shape. Add media URLs with their descriptions, poll options or thread parts, and a time. OmniSocials checks the post against your server’s limits before it goes out.

- **Text and link cards.** Up to your server’s limit, 500 on mastodon.social, with links counted as 23 characters. A post without media gets the link’s card. (`content`)
- **Images, video and polls.** Up to 4 images or one video, each with a description. Or a poll in place of the media, with as many options as your server allows. (`media_urls`, `mastodon.poll`)
- **Threads.** 2 to 25 statuses in one request, each a reply to the one before, with up to 4 media each. (`mastodon.thread_parts`)

### Post

```json
{
  "content": "What's new: https://omnisocials.com/changelog",
  "accounts": ["mastodon"],
  "schedule_at": "2026-10-23T12:00:00Z"
}
```

### Images

```json
{
  "content": "New: OmniSocials SDKs in 8 languages",
  "accounts": ["mastodon"],
  "media_urls": [
    {
      "url": "https://cdn.example.com/sdks.png",
      "alt": "Code that creates a post with the Node.js SDK"
    }
  ],
  "schedule_at": "2026-10-22T18:00:00Z"
}
```

### Poll

```json
{
  "content": "Threads or single posts on Mastodon?",
  "accounts": ["mastodon"],
  "schedule_at": "2026-10-24T11:00:00Z",
  "mastodon": {
    "poll": {
      "options": ["Threads", "Single posts"],
      "expires_in": 259200,
      "multiple": false,
      "hide_totals": true
    }
  }
}
```

### Thread

```json
{
  "content": { "default": "" },
  "accounts": ["mastodon"],
  "schedule_at": "2026-10-25T10:00:00Z",
  "mastodon": {
    "thread_parts": [
      { "text": "A whole thread, in one request." },
      { "text": "The docs: https://docs.omnisocials.com/platforms/mastodon" },
      {
        "text": "Each status keeps its own media.",
        "media_urls": ["https://cdn.example.com/thread.png"]
      }
    ]
  }
}
```

## Any server, with its own limits

Type the server, or paste @you@server, and OmniSocials registers its app there for you. It reads that server’s character limit, link length and poll ranges, and checks every post against them before it goes out.

`POST /v1/posts/create`:

```json
{
  "content": "Threads or single posts on Mastodon?",
  "accounts": ["mastodon"],
  "schedule_at": "2026-10-24T11:00:00Z",
  "mastodon": {
    "poll": {
      "options": ["Threads", "Single posts"],
      "expires_in": 259200,
      "multiple": false,
      "hide_totals": true
    }
  }
}
```

- **Any server.** Type the server, or paste @you@server. OmniSocials registers its app on that server, and you sign in there once.
- **The server’s own limits.** The character limit, how long a link counts and the poll ranges come from the server. Every post is checked against them.
- **Polls.** Options and a duration in the server’s range, 2 to 4 options by default, one answer or several, totals hidden until it ends. The results come back with the analytics. (`mastodon.poll`)

## Connect any server, post from code

Type your server in OmniSocials once and sign in there. Create an API key, and your code posts and reports for that account.

- **Your server, over OAuth.** OmniSocials registers its app on the server you type. Mastodon tokens do not expire, so nothing needs refreshing.
- **A key per workspace.** A key only reaches its own workspace. Each workspace connects one Mastodon account.
- **What the account can post.** The accounts call lists the account with its username and the formats it takes. (`GET /v1/accounts`, `content_types`)

`GET /v1/accounts?platform=mastodon` answers:

```json
{
  "data": [
    {
      "id": "4127_mastodon",
      "platform": "mastodon",
      "username": "omnisocials",
      "display_name": "Omnisocials",
      "content_types": ["post"],
      "status": "active"
    }
  ],
  "workspace_name": "OmniSocials"
}
```

## Read what Mastodon reports

Likes, replies and boosts per status, summed across a thread, quotes on Mastodon 4.5 or later, poll results and the account’s followers per day. The API returns the same numbers the app charts.

- **Per status and per thread.** Likes, replies, boosts, and quotes on Mastodon 4.5 or later. A thread reports the sum of its statuses, and thread_parts says how many. (`/analytics/posts/:id`)
- **Poll results.** Each option’s votes, the number of voters and whether the poll has ended, with the post’s other numbers. (`metrics.poll`)
- **Per account and workspace.** A daily snapshot of the account: followers, following and posts. Plus a workspace overview and best times to post. (`/analytics/accounts`, `/analytics/best-times`)

`GET /v1/analytics/posts/1019` answers:

```json
{
  "data": {
    "post_id": "1019",
    "platforms": {
      "mastodon": {
        "metrics": {
          "likes": 49, "comments": 9,
          "reposts": 21, "quotes": 2
        },
        "thread_parts": 1
      }
    }
  }
}
```

## Mastodon’s rules, in one place

OmniSocials checks every post against them, with your server’s own numbers, before it reaches the server. A status that is too long fails in your request, not at publish time.

| Limit | Value |
| --- | --- |
| Text | Your server’s limit, 500 on mastodon.social |
| Links | Count as 23 characters, or your server’s length |
| Media | Up to 4 images or one video, not both |
| Images | JPEG, PNG, GIF or WebP, up to 16 MB |
| Video | Up to 99 MB |
| Alt text | 1,500 characters per item |
| Polls | Your server’s range, by default 2 to 4 options, 5 minutes to a month |
| Thread | 2 to 25 statuses, 4 media each |
| Visibility | Every status goes out public |
| Rate limit | 100 requests a minute per API key |

## Your first status in three steps

About five minutes from sign-up to a scheduled status on your server. Then hand the key to your coding agent.

1. **Create an API key** (`Settings › API`). Start your trial, open Settings, API and create a key. It is shown once.
2. **Connect your server** (`GET /v1/accounts`). Type your server or paste @you@server in OmniSocials once and sign in there. Then list the account from your code.
3. **Send your first status** (`POST /v1/posts/create`). Post now with create-and-publish, or add schedule_at to plan it. Add mastodon.poll or thread_parts when you need them.

## FAQ

### Do I need to register an app on every Mastodon server?

No. Type your server, or paste @you@server, and OmniSocials registers its app on that server for you. You sign in there once, and your code calls the OmniSocials API with an API key.

### Which servers work?

Any Mastodon server: mastodon.social, fosstodon.org or your team’s own instance. Servers that speak the Mastodon API work too. Each workspace connects one Mastodon account.

### Does OmniSocials know my server’s character limit?

Yes. When you connect, it reads the server’s own limits: the character limit, how many characters a link counts for and the poll ranges. A post over the limit fails in your request with the numbers, not at publish time.

### Can I schedule Mastodon posts?

Yes. Send schedule_at and OmniSocials keeps the queue and publishes on time, with a webhook when the status is live.

### How do polls work?

The post text is the question. Put the options in mastodon.poll, with expires_in in seconds, multiple for several answers and hide_totals to hide the counts until it ends. A poll replaces the media, and on a thread it goes on the first status. The results come back with the post’s analytics.

### How do I post a thread?

Put 2 to 25 statuses in mastodon.thread_parts, each with its text and up to 4 media. OmniSocials posts each one as a reply to the one before, so they read as one thread.

### Can I add alt text?

Yes. Any media entry can be { "url": "...", "alt": "..." }, also per status in a thread. Up to 1,500 characters, sent to the server as the media description.

### Can I set the visibility or add a content warning?

No. Every status OmniSocials publishes is public, without a content warning.

### Which numbers can I read?

Likes, replies and boosts per status, summed across a thread, plus quotes on servers running Mastodon 4.5 or later. Poll results, and the account’s followers per day. Mastodon does not report views, reach or clicks, so the API leaves those out.

### What happens when a Mastodon post fails to publish?

When the error is temporary, OmniSocials retries it up to 3 times, 15 minutes apart. Then post.published or post.failed fires.

A thread that stops partway keeps the statuses that went out, and the post records them. A retry sends the whole thread again, so delete the partial thread on your server first.

### Is the Mastodon API free?

Yes. Every Mastodon server offers its API for free, with its own limits. OmniSocials registers its app on your server, keeps the queue and reads the numbers, and the API is part of the plan, $10 per seat per month billed annually.

### What are the rate limits?

100 requests a minute per API key. Past that the API answers 429 with a Retry-After header that says when to try again.

### How much does OmniSocials cost?

One plan with every feature included: $10 per seat per month billed annually, or $12 billed monthly. Team members and client seats cost the same. Every account starts with a 14-day free trial.

The REST API, the SDKs, the CLI, webhooks and the MCP server are part of that one plan.

## Pricing

From $10 per seat a month, API included. 14-day free trial.

## Related

- [Mastodon scheduler](https://omnisocials.com/mastodon.md)
- [Mastodon MCP server](https://omnisocials.com/mastodon-mcp.md)
- [All channels](https://omnisocials.com/channels.md)

## Links

- Page: https://omnisocials.com/mastodon-api
- Mastodon platform docs: https://docs.omnisocials.com/platforms/mastodon
- API reference: https://docs.omnisocials.com/api
- REST API overview: https://omnisocials.com/api.md
- MCP server: https://omnisocials.com/mcp.md
- Sign up: https://app.omnisocials.com/signup
