> **Shapeless documentation index**
> Fetch https://shapelessai.com/llms.txt to discover every page before exploring further.
> Every page also answers Markdown: append `.md` to its path, or send `Accept: text/markdown`.

# Platforms

Every platform the rail publishes to, with the character limit, media rules, first-comment support and per-platform settings we enforce before a post goes out.

*Verified 2026-09-14. Source: https://shapelessai.com/docs/platforms*

These are the rules our publishing engine enforces *before* a post is accepted onto the queue, so
a post that breaks one is a `422` at creation rather than a failure hours later.

Read them live from `GET /api/platforms` - no auth, no key:

```bash
curl -s https://shapelessai.com/api/platforms
```

```jsonc
{
  "platforms": [
    {
      "id": "linkedin",
      "label": "LinkedIn",
      "oauth": true,          // connectable through the platform's own sign-in today
      "live": true,           // publishing works end to end; false = built, waiting on the platform
      "waitingOn": null,      // why it is not live, when it is not
      "text": { "maxChars": 3000 },
      "media": {
        "maxChars": 3000, "maxImages": 20, "minImages": 0,
        "allowsPdf": true, "maxVideos": 1, "requiresVideo": false, "imagesOrVideoOnly": true
      },
      "titleRequired": false, // true = documentTitle is required (YouTube)
      "firstComment": { "supported": true, "maxChars": 1250 },
      "settingsSchema": { "type": "object", "properties": {}, "additionalProperties": false },
      "connectPath": "/studio/accounts"
    }
  ]
}
```

`settingsSchema` is plain JSON Schema, which is what every MCP host and OpenAPI reader already
speaks - so an agent can fill `settings` from it instead of hard-coding field names.

The table below is generated from the same engine table that route reads, at build time, so the
two cannot drift.

| Platform | `id` | Text | Images | Video | PDF | First comment | Images + video |
| --- | --- | --- | --- | --- | --- | --- | --- |
| LinkedIn | `linkedin` | 3,000 characters | 20 | 1 | yes | 1,250 chars | no |
| LinkedIn Page | `linkedin_page` | 3,000 characters | 20 | 1 | yes | 1,250 chars | no |
| X | `x` | 280 weighted chars | 4 | 1 | no | 280 chars | no |
| Instagram | `instagram` | 2,200 characters | 10 (at least 1) | 1 | no | no | no |
| TikTok | `tiktok` | 2,200 characters | none | 1, required | no | no | n/a |
| YouTube | `youtube` | 5,000 characters | none | 1, required | no | no | n/a |
| Facebook Page | `facebook_page` | 63,206 characters | 10 | 1 | no | no | no |
| Threads | `threads` | 500 characters | 1 | 1 | no | no | no |
| Bluesky | `bluesky` | 300 graphemes | 4 | not yet | no | 300 chars | n/a |
| Reddit (waiting on Reddit's app approval) | `reddit` | 40,000 characters | 1 | 1 | no | no | no |

*Reddit: Built - waiting on Reddit's app approval before we switch it on.*

**Counting.** X counts weighted characters (a URL always costs 23, most emoji cost 2) using the
official twitter-text rules. Bluesky counts grapheme clusters. Everything else counts Unicode code
points. The free [character counters](https://shapelessai.com/tools) run exactly these rules in
the browser.

**Images or video.** Most platforms take images *or* a video in one post, never both. Sending both
is a `422` before the row exists.

**What we deliver vs what the platform allows.** A few numbers above are ours, not the network's,
because our adapter delivers less than the platform would take: Threads publishes one image where
Threads itself allows a 20-item carousel, Reddit one image where a gallery allows 20, and Bluesky
video needs a service-auth flow we have not built. The per-platform pages under
[/specs](https://shapelessai.com/specs) carry each number's source and the date we last checked
it.

**Reddit** is waiting on Reddit's app approval. The publisher is built and the rules above are
enforced, but posting to Reddit is not open yet.

**Mastodon** is not offered.

## Settings, per platform

`settings` on `POST /api/posts` is passed through to the adapter, and `settingsSchema` is its JSON
Schema. Today: TikTok requires an explicit `privacyLevel` (and takes seven more toggles), YouTube
takes `privacyStatus`, Reddit takes one `subreddit` plus an optional `title` and `url`, and
nothing else takes settings. The shapes are on [Posts](/docs/posts#per-platform-settings).

YouTube is the one platform with `titleRequired: true`: its video title rides `documentTitle` on
the post, not `settings`.

## Connecting an account

Platform OAuth is a browser redirect carrying a platform grant, so it is deliberately the one
thing an API key cannot do. Send the human to
[shapelessai.com/studio/accounts](https://shapelessai.com/studio/accounts) - `connectPath` in the
payload above - and read the result back with `GET /api/connections`.
