# Platforms

2 endpoints.

## List every network's posting rules

```http
GET https://orbitwrite.com/api/v1/platforms
```

What each platform a channel can be connected to accepts: character limits (and the premium ceiling, for X Premium), whether threads are allowed, media limits (count, types, sizes, video length, frame rate, aspect ratio), the `postFormat` values it offers and what each narrows, polls, quotes, reply settings and the JSON Schema of its `platformOptions`. The server enforces every rule here; read it to shape a post before sending. Any credential is served, whatever its scopes.

**Authentication:** bearer token or session cookie.

### Responses

#### 200

One entry per platform, in the app's order

- `platforms` (object[], required)
  - `platform` (string, required) — The platform id, as `list_channels` / `GET /connected-accounts` report it.
  - `name` (string, required)
  - `text` (object, required)
    - `maxChars` (integer, required) — Per post, or per thread item.
    - `unit` (string, required, one of `chars`, `graphemes`) — `graphemes` counts each emoji as one.
    - `premiumMaxChars` (integer | null, required) — The ceiling for a premium account (X Premium), when the platform has one.
    - `premiumLabel` (string | null, required)
    - `withMediaMaxChars` (integer | null, required) — A tighter ceiling when the post carries media (Telegram captions).
    - `commentMaxChars` (integer | null, required) — The ceiling for an auto-comment, when tighter than a post.
  - `threads` (boolean, required) — Whether a post may be a chain of items. Each item has the text limit; there is no cap on the number of items.
  - `media` (object, required)
    - `maxItems` (integer, required) — Attachments per post (per thread item). 0: none.
    - `required` (boolean, required) — A post without media is refused.
    - `mimeTypes` (string[], required)
    - `image` (object | null, required) — Null: no images.
      - `maxBytes` (integer, required)
      - `maxGifBytes` (integer | null, required)
    - `video` (object | null, required) — Null: no video.
      - `maxBytes` (integer, required)
      - `maxDurationSec` (integer | null, required)
      - `minDurationSec` (number | null, required)
      - `minFrameRate` (number | null, required)
      - `exclusive` (boolean, required) — A video takes the whole post: no other media beside it.
    - `externalGifs` (boolean, required) — Accepts a GIF from GIF search.
    - `gifExclusive` (string | null, required, one of `any`, `picked`, `null`) — A GIF takes the whole post. any: every GIF; picked: a GIF from GIF search. Null: GIFs mix with other media.
    - `aspectRatio` (object | null, required) — Width ÷ height. Null: unconstrained.
      - `min` (number | null, required)
      - `max` (number | null, required)
      - `preferred` (number | null, required)
      - `carouselMatchesFirst` (boolean, required) — Every carousel slide, video included, is cropped to the first slide's shape.
    - `document` (object | null, required) — A single document (PDF) in place of media. Null: no documents.
      - `mimeTypes` (string[], required)
      - `maxBytes` (integer | null, required)
      - `maxPages` (integer | null, required)
  - `formats` (object[], required) — The `postFormat` values this platform offers, default first, with what each narrows. Empty: feed posts only.
    - `format` (string, required, one of `post`, `story`, `reel`, `short`)
    - `maxItems` (integer, required)
    - `requiresVideo` (boolean, required)
    - `publishesText` (boolean, required) — False: the text is not published (an Instagram story has no caption).
    - `maxVideoBytes` (integer | null, required)
    - `maxVideoDurationSec` (integer | null, required)
    - `maxAspectRatio` (number | null, required)
  - `polls` (object | null, required) — Null: no polls.
    - `minOptions` (integer, required)
    - `maxOptions` (integer, required)
    - `optionMaxChars` (integer, required)
    - `minDurationMinutes` (integer, required)
    - `maxDurationMinutes` (integer, required)
  - `quotes` (boolean, required) — Accepts a `quoteUrl`.
  - `replies` (boolean, required) — Accepts a `replyToUrl`: publishing as a reply to an existing post.
  - `linkPreviews` (boolean, required)
  - `replySettings` (string[], required) — Values for `replySettings` (who may reply). Empty: not settable.
  - `options` (object | null, required) — Network-specific settings for `platformOptions`. Null: none.
    - `key` (string, required) — The key under `platformOptions`.
    - `schema` (object, required) — JSON Schema of the options object.
  - `aiLabel` (object | null, required) — Where to label a post as AI-generated, so the network shows its own AI label on it. Null: the network's API has no such label. Read the field's description in `options.schema`: YouTube's covers realistic altered or synthetic content only, and X's applies to posts with media.
    - `key` (string, required) — The key under `platformOptions`.
    - `field` (string, required) — The boolean field under that key; set it to `true` to label the post.

#### 401

Not signed in

- `error` (string, required)
- `issues` (any[], optional)

## Get one network's posting rules

```http
GET https://orbitwrite.com/api/v1/platforms/{platform}
```

The rules for one platform, by the id `GET /connected-accounts` reports (`twitter`, `linkedin_page`, `instagram`, …). Same shape as an entry of `GET /platforms`.

**Authentication:** bearer token or session cookie.

### Path parameters

- `platform` (string, required)

### Responses

#### 200

The platform's rules

- `platform` (object, required)
  - `platform` (string, required) — The platform id, as `list_channels` / `GET /connected-accounts` report it.
  - `name` (string, required)
  - `text` (object, required)
    - `maxChars` (integer, required) — Per post, or per thread item.
    - `unit` (string, required, one of `chars`, `graphemes`) — `graphemes` counts each emoji as one.
    - `premiumMaxChars` (integer | null, required) — The ceiling for a premium account (X Premium), when the platform has one.
    - `premiumLabel` (string | null, required)
    - `withMediaMaxChars` (integer | null, required) — A tighter ceiling when the post carries media (Telegram captions).
    - `commentMaxChars` (integer | null, required) — The ceiling for an auto-comment, when tighter than a post.
  - `threads` (boolean, required) — Whether a post may be a chain of items. Each item has the text limit; there is no cap on the number of items.
  - `media` (object, required)
    - `maxItems` (integer, required) — Attachments per post (per thread item). 0: none.
    - `required` (boolean, required) — A post without media is refused.
    - `mimeTypes` (string[], required)
    - `image` (object | null, required) — Null: no images.
      - `maxBytes` (integer, required)
      - `maxGifBytes` (integer | null, required)
    - `video` (object | null, required) — Null: no video.
      - `maxBytes` (integer, required)
      - `maxDurationSec` (integer | null, required)
      - `minDurationSec` (number | null, required)
      - `minFrameRate` (number | null, required)
      - `exclusive` (boolean, required) — A video takes the whole post: no other media beside it.
    - `externalGifs` (boolean, required) — Accepts a GIF from GIF search.
    - `gifExclusive` (string | null, required, one of `any`, `picked`, `null`) — A GIF takes the whole post. any: every GIF; picked: a GIF from GIF search. Null: GIFs mix with other media.
    - `aspectRatio` (object | null, required) — Width ÷ height. Null: unconstrained.
      - `min` (number | null, required)
      - `max` (number | null, required)
      - `preferred` (number | null, required)
      - `carouselMatchesFirst` (boolean, required) — Every carousel slide, video included, is cropped to the first slide's shape.
    - `document` (object | null, required) — A single document (PDF) in place of media. Null: no documents.
      - `mimeTypes` (string[], required)
      - `maxBytes` (integer | null, required)
      - `maxPages` (integer | null, required)
  - `formats` (object[], required) — The `postFormat` values this platform offers, default first, with what each narrows. Empty: feed posts only.
    - `format` (string, required, one of `post`, `story`, `reel`, `short`)
    - `maxItems` (integer, required)
    - `requiresVideo` (boolean, required)
    - `publishesText` (boolean, required) — False: the text is not published (an Instagram story has no caption).
    - `maxVideoBytes` (integer | null, required)
    - `maxVideoDurationSec` (integer | null, required)
    - `maxAspectRatio` (number | null, required)
  - `polls` (object | null, required) — Null: no polls.
    - `minOptions` (integer, required)
    - `maxOptions` (integer, required)
    - `optionMaxChars` (integer, required)
    - `minDurationMinutes` (integer, required)
    - `maxDurationMinutes` (integer, required)
  - `quotes` (boolean, required) — Accepts a `quoteUrl`.
  - `replies` (boolean, required) — Accepts a `replyToUrl`: publishing as a reply to an existing post.
  - `linkPreviews` (boolean, required)
  - `replySettings` (string[], required) — Values for `replySettings` (who may reply). Empty: not settable.
  - `options` (object | null, required) — Network-specific settings for `platformOptions`. Null: none.
    - `key` (string, required) — The key under `platformOptions`.
    - `schema` (object, required) — JSON Schema of the options object.
  - `aiLabel` (object | null, required) — Where to label a post as AI-generated, so the network shows its own AI label on it. Null: the network's API has no such label. Read the field's description in `options.schema`: YouTube's covers realistic altered or synthetic content only, and X's applies to posts with media.
    - `key` (string, required) — The key under `platformOptions`.
    - `field` (string, required) — The boolean field under that key; set it to `true` to label the post.

#### 401

Not signed in

- `error` (string, required)
- `issues` (any[], optional)

#### 404

The resource does not exist

- `error` (string, required)
- `issues` (any[], optional)
