Platforms

Bluesky

Post text, images, video, link cards and quote posts to Bluesky, connected with an app password.

Overview

The bluesky platform posts to Bluesky with an app password (no OAuth app needed). You can post:

  • Text posts with automatic link, mention and hashtag detection
  • Up to 4 images, or 1 video
  • A link preview card (automatic for the first link, or a URL you choose)
  • Quote posts (alone or combined with images, video or a link card)
  • Languages, extra hidden tags, content warnings, reply controls and quote controls

Connect the account

Bluesky uses app passwords instead of OAuth.

  1. In the Bluesky app, go to Settings → Privacy and security → App passwords and create one.
  2. Connect it in one of two ways:
curl -X POST https://social-publish-api.onrender.com/v1/accounts/bluesky \
  -H "x-access-key: $RELAYCAST_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "identifier": "yourname.bsky.social", "appPassword": "abcd-efgh-ijkl-mnop" }'

The credentials are checked against Bluesky before they are saved, and stored encrypted. Connecting the same Bluesky account again updates its app password in place, so its account ID doesn't change.

Accounts are signed in through bsky.social. If you revoke the app password in Bluesky, the next publish fails and the account is marked reconnect_required.

Post types & media rules

RuleLimit
Text300 characters (graphemes)
ImagesUp to 4, 2 MB each
Video1, up to 300 MB
Images and videoCan't be combined
Alt textmedia[].altText is sent for images
Link cardOnly when the post has no images or video; the page's thumbnail is used if it is under 1 MB
Extra tagsUp to 8, 64 characters each
LanguagesUp to 3 BCP-47 codes (for example en, pt-BR)

Hashtags, @mentions and links written in the text are detected and linked automatically.

Options

OptionTypeRequiredDefaultDescription
linkCardbooleanNotrueLink preview card. When the post has no images or video, attach a preview card for the first link in the text (or the URL below). Fails quietly to a plain post if the page can't be read.
linkUrlstring (URL)NoCard URL. Defaults to the first link in the post text. Only when linkCard is true.
linkTitlestringNoCard title. Overrides the page's og:title / . Only when <code>linkCard</code> is <code>true</code>.</td></tr><tr><td><code>linkDescription</code></td><td>string</td><td>No</td><td></td><td>Card description. Overrides the page's og:description / meta description. Only when <code>linkCard</code> is <code>true</code>.</td></tr><tr><td><code>tags</code></td><td>string[]</td><td>No</td><td></td><td>Extra tags. Up to 8 hashtags stored on the post but not shown in the text (searchable). Hashtags written in the text are detected automatically.</td></tr><tr><td><code>langs</code></td><td>string[]</td><td>No</td><td></td><td>Languages. Up to 3 BCP-47 language codes for the post text. Used for feeds and translation.</td></tr><tr><td><code>contentWarning</code></td><td><code>none</code> \</td><td><code>sexual</code> \</td><td><code>nudity</code> \</td><td><code>porn</code> \</td></tr><tr><td><code>quoteUrl</code></td><td>string (URL)</td><td>No</td><td></td><td>Quote post. A Bluesky post to quote. Can be combined with images, video or a link card.</td></tr><tr><td><code>replyControl</code></td><td><code>everyone</code> \</td><td><code>nobody</code> \</td><td><code>limited</code></td><td>No</td></tr><tr><td><code>replyAllow</code></td><td>string[]</td><td>No</td><td><code>[]</code></td><td>Allow replies from Only when <code>replyControl</code> is <code>limited</code>.</td></tr><tr><td><code>disableQuotes</code></td><td>boolean</td><td>No</td><td><code>false</code></td><td>Disable quote posts. Prevents other people from quoting this post.</td></tr><tr><td><code>quoteUrl</code> accepts a <code>https://bsky.app/profile/<handle>/post/<id></code> URL or an <code>at://</code> post URI. With <code>replyControl: "limited"</code>, pick at least one group in <code>replyAllow</code>.</td><td></td><td></td><td></td><td></td></tr></tbody></table></div><h2 id="examples"><a href="#examples" class="heading-anchor">Examples</a></h2> <h3 id="post-with-a-link-card-and-reply-limits"><a href="#post-with-a-link-card-and-reply-limits" class="heading-anchor">Post with a link card and reply limits</a></h3> <div class="code-tabs" data-tabs="3"><input type="radio" name="tabs-20" id="tabs-20-0" class="tab-input" checked/><input type="radio" name="tabs-20" id="tabs-20-1" class="tab-input" /><input type="radio" name="tabs-20" id="tabs-20-2" class="tab-input" /><span class="tab-labels"><label for="tabs-20-0" class="tab-label">cURL</label><label for="tabs-20-1" class="tab-label">Node.js</label><label for="tabs-20-2" class="tab-label">Python</label></span><div class="tab-panel"><div class="code-block"><pre class="shiki shiki-themes github-light github-dark-dimmed" style="background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7" tabindex="0"><code><span class="line"><span style="color:#6F42C1;--shiki-dark:#F69D50">curl</span><span style="color:#005CC5;--shiki-dark:#6CB6FF"> -X</span><span style="color:#032F62;--shiki-dark:#96D0FF"> POST</span><span style="color:#032F62;--shiki-dark:#96D0FF"> https://social-publish-api.onrender.com/v1/posts</span><span style="color:#005CC5;--shiki-dark:#F47067"> \</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#6CB6FF"> -H</span><span style="color:#032F62;--shiki-dark:#96D0FF"> "x-access-key: </span><span style="color:#24292E;--shiki-dark:#ADBAC7">$RELAYCAST_API_KEY</span><span style="color:#032F62;--shiki-dark:#96D0FF">"</span><span style="color:#005CC5;--shiki-dark:#F47067"> \</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#6CB6FF"> -H</span><span style="color:#032F62;--shiki-dark:#96D0FF"> "content-type: application/json"</span><span style="color:#005CC5;--shiki-dark:#F47067"> \</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#6CB6FF"> -d</span><span style="color:#032F62;--shiki-dark:#96D0FF"> '{</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "content": "We wrote up how our scheduler works: https://example.com/blog/scheduler #engineering",</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "targets": [{</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "accountId": "7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b",</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "options": {</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "linkCard": true,</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "langs": ["en"],</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "replyControl": "limited",</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "replyAllow": ["followers", "mentioned"],</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "disableQuotes": false</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> }</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> }],</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "publishNow": true</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> }'</span></span></code></pre></div></div><div class="tab-panel"><div class="code-block"><pre class="shiki shiki-themes github-light github-dark-dimmed" style="background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7" tabindex="0"><code><span class="line"><span style="color:#D73A49;--shiki-dark:#F47067">const</span><span style="color:#005CC5;--shiki-dark:#6CB6FF"> res</span><span style="color:#D73A49;--shiki-dark:#F47067"> =</span><span style="color:#D73A49;--shiki-dark:#F47067"> await</span><span style="color:#6F42C1;--shiki-dark:#DCBDFB"> fetch</span><span style="color:#24292E;--shiki-dark:#ADBAC7">(</span><span style="color:#032F62;--shiki-dark:#96D0FF">"https://social-publish-api.onrender.com/v1/posts"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, {</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> method: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"POST"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> headers: {</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "x-access-key"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: process.env.</span><span style="color:#005CC5;--shiki-dark:#6CB6FF">RELAYCAST_API_KEY</span><span style="color:#D73A49;--shiki-dark:#F47067">!</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "content-type"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"application/json"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> },</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> body: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">JSON</span><span style="color:#24292E;--shiki-dark:#ADBAC7">.</span><span style="color:#6F42C1;--shiki-dark:#DCBDFB">stringify</span><span style="color:#24292E;--shiki-dark:#ADBAC7">({</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> content: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"We wrote up how our scheduler works: https://example.com/blog/scheduler #engineering"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> targets: [</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> {</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> accountId: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> options: {</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> linkCard: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">true</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> langs: [</span><span style="color:#032F62;--shiki-dark:#96D0FF">"en"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">],</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> replyControl: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"limited"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> replyAllow: [</span><span style="color:#032F62;--shiki-dark:#96D0FF">"followers"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#032F62;--shiki-dark:#96D0FF">"mentioned"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">],</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> disableQuotes: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">false</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> },</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> },</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> ],</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> publishNow: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">true</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> }),</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7">});</span></span> <span class="line"><span style="color:#D73A49;--shiki-dark:#F47067">const</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> { </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">data</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> } </span><span style="color:#D73A49;--shiki-dark:#F47067">=</span><span style="color:#D73A49;--shiki-dark:#F47067"> await</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> res.</span><span style="color:#6F42C1;--shiki-dark:#DCBDFB">json</span><span style="color:#24292E;--shiki-dark:#ADBAC7">();</span></span></code></pre></div></div><div class="tab-panel"><div class="code-block"><pre class="shiki shiki-themes github-light github-dark-dimmed" style="background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7" tabindex="0"><code><span class="line"><span style="color:#D73A49;--shiki-dark:#F47067">import</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> os, requests</span></span> <span class="line"></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7">res </span><span style="color:#D73A49;--shiki-dark:#F47067">=</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> requests.post(</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "https://social-publish-api.onrender.com/v1/posts"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#E36209;--shiki-dark:#F69D50"> headers</span><span style="color:#D73A49;--shiki-dark:#F47067">=</span><span style="color:#24292E;--shiki-dark:#ADBAC7">{</span><span style="color:#032F62;--shiki-dark:#96D0FF">"x-access-key"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: os.environ[</span><span style="color:#032F62;--shiki-dark:#96D0FF">"RELAYCAST_API_KEY"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">]},</span></span> <span class="line"><span style="color:#E36209;--shiki-dark:#F69D50"> json</span><span style="color:#D73A49;--shiki-dark:#F47067">=</span><span style="color:#24292E;--shiki-dark:#ADBAC7">{</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "content"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"We wrote up how our scheduler works: https://example.com/blog/scheduler #engineering"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "targets"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: [{</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "accountId"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "options"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: {</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "linkCard"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">True</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "langs"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: [</span><span style="color:#032F62;--shiki-dark:#96D0FF">"en"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">],</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "replyControl"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"limited"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "replyAllow"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: [</span><span style="color:#032F62;--shiki-dark:#96D0FF">"followers"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#032F62;--shiki-dark:#96D0FF">"mentioned"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">],</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "disableQuotes"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">False</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> },</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> }],</span></span> <span class="line"><span style="color:#032F62;--shiki-dark:#96D0FF"> "publishNow"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#005CC5;--shiki-dark:#6CB6FF">True</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> },</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7">)</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7">data </span><span style="color:#D73A49;--shiki-dark:#F47067">=</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> res.json()[</span><span style="color:#032F62;--shiki-dark:#96D0FF">"data"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">]</span></span></code></pre></div></div></div><h3 id="images-with-alt-text-and-a-quote"><a href="#images-with-alt-text-and-a-quote" class="heading-anchor">Images with alt text and a quote</a></h3> <div class="code-block"><div class="code-title">Request body</div><pre class="shiki shiki-themes github-light github-dark-dimmed" style="background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7" tabindex="0"><code><span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7">{</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "content"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"Before and after the redesign"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "media"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: [</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> { </span><span style="color:#005CC5;--shiki-dark:#8DDB8C">"url"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"https://cdn.example.com/before.jpg"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#005CC5;--shiki-dark:#8DDB8C">"type"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"image"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#005CC5;--shiki-dark:#8DDB8C">"altText"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"Old settings page"</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> },</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> { </span><span style="color:#005CC5;--shiki-dark:#8DDB8C">"url"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"https://cdn.example.com/after.jpg"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#005CC5;--shiki-dark:#8DDB8C">"type"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"image"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#005CC5;--shiki-dark:#8DDB8C">"altText"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"New settings page"</span><span style="color:#24292E;--shiki-dark:#ADBAC7"> }</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> ],</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "targets"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: [{</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "accountId"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "options"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: {</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "quoteUrl"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"https://bsky.app/profile/example.bsky.social/post/3l7abcxyz2k2a"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">,</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "tags"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: [</span><span style="color:#032F62;--shiki-dark:#96D0FF">"design"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">, </span><span style="color:#032F62;--shiki-dark:#96D0FF">"ux"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">]</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> }</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7"> }],</span></span> <span class="line"><span style="color:#005CC5;--shiki-dark:#8DDB8C"> "scheduledFor"</span><span style="color:#24292E;--shiki-dark:#ADBAC7">: </span><span style="color:#032F62;--shiki-dark:#96D0FF">"2026-11-10T09:00:00Z"</span></span> <span class="line"><span style="color:#24292E;--shiki-dark:#ADBAC7">}</span></span></code></pre></div><h2 id="analytics-comments"><a href="#analytics-comments" class="heading-anchor">Analytics & comments</a></h2> <p>Analytics show likes, replies (comments), reposts + quotes (shares) and bookmarks (saves). Bluesky does not report views, impressions or clicks.</p> <p>Replies and messaging are not supported for Bluesky.</p> <h2 id="limitations-common-errors"><a href="#limitations-common-errors" class="heading-anchor">Limitations & common errors</a></h2> <div class="table-wrap"><table><thead><tr><th>Error</th><th>Cause</th></tr></thead><tbody><tr><td><code>invalid_credentials</code> (connect)</td><td>Bluesky rejected the handle or app password.</td></tr><tr><td><code>Bluesky allows 300 characters (this post has …)</code></td><td>Text is too long.</td></tr><tr><td><code>Bluesky posts can have images or one video, not both</code></td><td>Mixed media.</td></tr><tr><td><code>Bluesky allows up to 4 images</code></td><td>Too many images.</td></tr><tr><td><code>Bluesky allows up to 8 tags</code> / <code>up to 3 languages</code></td><td>Too many <code>tags</code> or <code>langs</code>.</td></tr><tr><td><code>Pick at least one group who can reply …</code></td><td><code>replyControl: "limited"</code> with an empty <code>replyAllow</code>.</td></tr><tr><td>Target fails: image too large</td><td>Bluesky images are limited to 2 MB each.</td></tr><tr><td>Account becomes <code>reconnect_required</code></td><td>The app password was revoked or the account was deactivated.</td></tr></tbody></table></div><p>A link card that can't be built (the page can't be fetched or has no metadata) quietly falls back to a plain post.</p> </div><nav aria-label="Pagination" class="mt-14 grid gap-3 border-t border-line pt-6 sm:grid-cols-2"><a class="card group p-4 transition hover:border-faint" href="/docs/platforms/pinterest"><span class="text-xs text-faint">← Previous</span><span class="mt-1 block font-medium group-hover:text-accent">Pinterest</span></a><a class="card group p-4 text-right transition hover:border-faint" href="/docs/platforms/google-business"><span class="text-xs text-faint">Next →</span><span class="mt-1 block font-medium group-hover:text-accent">Google Business Profile</span></a></nav><p class="mt-8 flex items-center gap-1.5 text-xs text-faint"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20V2H6.5A2.5 2.5 0 0 0 4 4.5v15zM4 19.5A2.5 2.5 0 0 0 6.5 22H20v-5"></path></svg> This page is also available as<!-- --> <a href="/docs/platforms/bluesky.md" class="underline hover:text-ink">Markdown</a>.</p></div></article><aside class="sticky top-[6.6rem] hidden h-[calc(100vh-6.6rem)] w-60 shrink-0 overflow-y-auto py-10 pr-6 xl:block"><nav aria-label="On this page" class="text-[13px]"><p class="mb-3 flex items-center gap-2 font-medium text-ink"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"></path></svg> On this page</p><ul class="space-y-1.5 border-l border-line"><li><a href="#overview" class="-ml-px block border-l py-0.5 transition pl-3 border-accent text-accent">Overview</a></li><li><a href="#connect-the-account" class="-ml-px block border-l py-0.5 transition pl-3 border-transparent text-muted hover:text-ink">Connect the account</a></li><li><a href="#post-types-media-rules" class="-ml-px block border-l py-0.5 transition pl-3 border-transparent text-muted hover:text-ink">Post types & media rules</a></li><li><a href="#options" class="-ml-px block border-l py-0.5 transition pl-3 border-transparent text-muted hover:text-ink">Options</a></li><li><a href="#examples" class="-ml-px block border-l py-0.5 transition pl-3 border-transparent text-muted hover:text-ink">Examples</a></li><li><a href="#post-with-a-link-card-and-reply-limits" class="-ml-px block border-l py-0.5 transition pl-6 border-transparent text-muted hover:text-ink">Post with a link card and reply limits</a></li><li><a href="#images-with-alt-text-and-a-quote" class="-ml-px block border-l py-0.5 transition pl-6 border-transparent text-muted hover:text-ink">Images with alt text and a quote</a></li><li><a href="#analytics-comments" class="-ml-px block border-l py-0.5 transition pl-3 border-transparent text-muted hover:text-ink">Analytics & comments</a></li><li><a href="#limitations-common-errors" class="-ml-px block border-l py-0.5 transition pl-3 border-transparent text-muted hover:text-ink">Limitations & common errors</a></li></ul></nav></aside></div><!--$--><!--/$--></div></div></div><script src="/_next/static/chunks/25kvgcvbp6c14.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n4:I[39756,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"default\"]\n5:I[37457,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"default\"]\n7:I[97367,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"OutletBoundary\"]\n8:\"$Sreact.suspense\"\nb:I[97367,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"ViewportBoundary\"]\nd:I[97367,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"MetadataBoundary\"]\nf:I[68027,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/361p-415-4dxh.css\",\"style\"]\na:X\n0:{\"P\":null,\"c\":[\"\",\"docs\",\"platforms\",\"bluesky\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"docs\",{\"children\":[[\"slug\",\"platforms/bluesky\",\"oc\",[]],{\"children\":[\"__PAGE__\",{},\"$undefined\",\"$undefined\",4096]},\"$undefined\",\"$undefined\",4096]},\"$undefined\",\"$undefined\",4096]},\"$undefined\",\"$undefined\",4112],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/361p-415-4dxh.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/2corl6wyj4669.js\",\"async\":true,\"nonce\":\"$undefined\"}]],\"$L2\"]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/08v9q1-2iyvo-.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/3g-1_mxnc4d1c.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/0jr6nk53yio29.js\",\"async\":true,\"nonce\":\"$undefined\"}]],\"$L3\"]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[\"$L6\",[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/2yjjm-mkyykml.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@9\"}]}]]}],{},null,false,null]},null,false,\"$a\"]},null,false,null]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$Lb\",null,{\"children\":\"$Lc\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Ld\",null,{\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Le\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$f\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/361p-415-4dxh.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":false,\"h\":null,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"jo5bzSjKh6O2_SVXZNdVC\"}\na:C\n2:[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"system\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"min-h-screen bg-canvas text-ink antialiased\",\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]\n10:I[80597,[\"/_next/static/chunks/2corl6wyj4669.js\",\"/_next/static/chunks/08v9q1-2iyvo-.js\",\"/_next/static/chunks/3g-1_mxnc4d1c.js\",\"/_next/static/chunks/0jr6nk53yio29.js\",\"/_next/static/chunks/2yjjm-mkyykml.js\"],\"PageActions\"]\n16:I[31376,[\"/_next/static/chunks/2corl6wyj4669.js\",\"/_next/static/chunks/08v9q1-2iyvo-.js\",\"/_next/static/chunks/3g-1_mxnc4d1c.js\",\"/_next/static/chunks/0jr6nk53yio29.js\"],\"DocsShell\"]\n11:T69c2,\u003ch2 id=\"overview\"\u003e\u003ca href=\"#overview\" class=\"heading-anchor\"\u003eOverview\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003ebluesky\u003c/code\u003e platform posts to Bluesky with an app password (no OAuth app needed). You can post:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eText posts with automatic link, mention and hashtag detection\u003c/li\u003e\n\u003cli\u003eUp to 4 images, \u003cstrong\u003eor\u003c/strong\u003e 1 video\u003c/li\u003e\n\u003cli\u003eA link preview card (automatic for the first link, or a URL you choose)\u003c/li\u003e\n\u003cli\u003eQuote posts (alone or combined with images, video or a link card)\u003c/li\u003e\n\u003cli\u003eLanguages, extra hidden tags, content warnings, reply controls and quote controls\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"connect-the-account\"\u003e\u003ca href=\"#connect-the-account\" class=\"heading-anchor\"\u003eConnect the account\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eBluesky uses \u003cstrong\u003eapp passwords\u003c/strong\u003e instead of OAuth.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eIn the Bluesky app, go to \u003cstrong\u003eSettings → Privacy and security → App passwords\u003c/strong\u003e and create one.\u003c/li\u003e\n\u003cli\u003eConnect it in one of two ways:\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eDashboard:\u003c/strong\u003e open \u003cstrong\u003e\u003ca href=\"https://social-publish-kappa.vercel.app/dashboard/integrations\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eIntegrations\u003c/a\u003e\u003c/strong\u003e, choose \u003cstrong\u003eBluesky\u003c/strong\u003e, and enter your handle and the app password.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eAPI:\u003c/strong\u003e call \u003ca href=\"/docs/api/connect-bluesky\"\u003e\u003ccode\u003ePOST /v1/accounts/bluesky\u003c/code\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block\"\u003e\u003cpre class=\"shiki shiki-themes github-light github-dark-dimmed\" style=\"background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#6F42C1;--shiki-dark:#F69D50\"\u003ecurl\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -X\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e POST\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e https://social-publish-api.onrender.com/v1/accounts/bluesky\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#F47067\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -H\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"x-access-key: \u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e$RELAYCAST_API_KEY\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#F47067\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -H\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"content-type: application/json\"\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#F47067\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -d\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e '{ \"identifier\": \"yourname.bsky.social\", \"appPassword\": \"abcd-efgh-ijkl-mnop\" }'\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eThe credentials are checked against Bluesky before they are saved, and stored encrypted. Connecting the same Bluesky account again updates its app password in place, so its account ID doesn\u0026#39;t change.\u003c/p\u003e\n\u003cdiv class=\"callout callout-note\"\u003e\u003cp\u003eAccounts are signed in through \u003ccode\u003ebsky.social\u003c/code\u003e. If you revoke the app password in Bluesky, the next publish fails and the account is marked \u003ccode\u003ereconnect_required\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\u003ch2 id=\"post-types-media-rules\"\u003e\u003ca href=\"#post-types-media-rules\" class=\"heading-anchor\"\u003ePost types \u0026amp; media rules\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"table-wrap\"\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eRule\u003c/th\u003e\u003cth\u003eLimit\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eText\u003c/td\u003e\u003ctd\u003e300 characters (graphemes)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eImages\u003c/td\u003e\u003ctd\u003eUp to 4, 2 MB each\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eVideo\u003c/td\u003e\u003ctd\u003e1, up to 300 MB\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eImages and video\u003c/td\u003e\u003ctd\u003eCan\u0026#39;t be combined\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eAlt text\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emedia[].altText\u003c/code\u003e is sent for images\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eLink card\u003c/td\u003e\u003ctd\u003eOnly when the post has no images or video; the page\u0026#39;s thumbnail is used if it is under 1 MB\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eExtra tags\u003c/td\u003e\u003ctd\u003eUp to 8, 64 characters each\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eLanguages\u003c/td\u003e\u003ctd\u003eUp to 3 BCP-47 codes (for example \u003ccode\u003een\u003c/code\u003e, \u003ccode\u003ept-BR\u003c/code\u003e)\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/div\u003e\u003cp\u003eHashtags, @mentions and links written in the text are detected and linked automatically.\u003c/p\u003e\n\u003ch2 id=\"options\"\u003e\u003ca href=\"#options\" class=\"heading-anchor\"\u003eOptions\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"table-wrap\"\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eOption\u003c/th\u003e\u003cth\u003eType\u003c/th\u003e\u003cth\u003eRequired\u003c/th\u003e\u003cth\u003eDefault\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003elinkCard\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eboolean\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eLink preview card. When the post has no images or video, attach a preview card for the first link in the text (or the URL below). Fails quietly to a plain post if the page can\u0026#39;t be read.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003elinkUrl\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring (URL)\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003eCard URL. Defaults to the first link in the post text. Only when \u003ccode\u003elinkCard\u003c/code\u003e is \u003ccode\u003etrue\u003c/code\u003e.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003elinkTitle\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003eCard title. Overrides the page\u0026#39;s og:title / \u003ctitle\u003e. Only when \u003ccode\u003elinkCard\u003c/code\u003e is \u003ccode\u003etrue\u003c/code\u003e.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003elinkDescription\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003eCard description. Overrides the page\u0026#39;s og:description / meta description. Only when \u003ccode\u003elinkCard\u003c/code\u003e is \u003ccode\u003etrue\u003c/code\u003e.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003etags\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring[]\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003eExtra tags. Up to 8 hashtags stored on the post but not shown in the text (searchable). Hashtags written in the text are detected automatically.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003elangs\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring[]\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003eLanguages. Up to 3 BCP-47 language codes for the post text. Used for feeds and translation.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003econtentWarning\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enone\u003c/code\u003e \\\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esexual\u003c/code\u003e \\\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enudity\u003c/code\u003e \\\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eporn\u003c/code\u003e \\\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003equoteUrl\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring (URL)\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003eQuote post. A Bluesky post to quote. Can be combined with images, video or a link card.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003ereplyControl\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eeveryone\u003c/code\u003e \\\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enobody\u003c/code\u003e \\\u003c/td\u003e\u003ctd\u003e\u003ccode\u003elimited\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003ereplyAllow\u003c/code\u003e\u003c/td\u003e\u003ctd\u003estring[]\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e[]\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAllow replies from Only when \u003ccode\u003ereplyControl\u003c/code\u003e is \u003ccode\u003elimited\u003c/code\u003e.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003edisableQuotes\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eboolean\u003c/td\u003e\u003ctd\u003eNo\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eDisable quote posts. Prevents other people from quoting this post.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003equoteUrl\u003c/code\u003e accepts a \u003ccode\u003ehttps://bsky.app/profile/\u0026lt;handle\u0026gt;/post/\u0026lt;id\u0026gt;\u003c/code\u003e URL or an \u003ccode\u003eat://\u003c/code\u003e post URI. With \u003ccode\u003ereplyControl: \u0026quot;limited\u0026quot;\u003c/code\u003e, pick at least one group in \u003ccode\u003ereplyAllow\u003c/code\u003e.\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/div\u003e\u003ch2 id=\"examples\"\u003e\u003ca href=\"#examples\" class=\"heading-anchor\"\u003eExamples\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"post-with-a-link-card-and-reply-limits\"\u003e\u003ca href=\"#post-with-a-link-card-and-reply-limits\" class=\"heading-anchor\"\u003ePost with a link card and reply limits\u003c/a\u003e\u003c/h3\u003e\n\u003cdiv class=\"code-tabs\" data-tabs=\"3\"\u003e\u003cinput type=\"radio\" name=\"tabs-20\" id=\"tabs-20-0\" class=\"tab-input\" checked/\u003e\u003cinput type=\"radio\" name=\"tabs-20\" id=\"tabs-20-1\" class=\"tab-input\" /\u003e\u003cinput type=\"radio\" name=\"tabs-20\" id=\"tabs-20-2\" class=\"tab-input\" /\u003e\u003cspan class=\"tab-labels\"\u003e\u003clabel for=\"tabs-20-0\" class=\"tab-label\"\u003ecURL\u003c/label\u003e\u003clabel for=\"tabs-20-1\" class=\"tab-label\"\u003eNode.js\u003c/label\u003e\u003clabel for=\"tabs-20-2\" class=\"tab-label\"\u003ePython\u003c/label\u003e\u003c/span\u003e\u003cdiv class=\"tab-panel\"\u003e\u003cdiv class=\"code-block\"\u003e\u003cpre class=\"shiki shiki-themes github-light github-dark-dimmed\" style=\"background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#6F42C1;--shiki-dark:#F69D50\"\u003ecurl\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -X\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e POST\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e https://social-publish-api.onrender.com/v1/posts\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#F47067\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -H\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"x-access-key: \u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e$RELAYCAST_API_KEY\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#F47067\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -H\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"content-type: application/json\"\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#F47067\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e -d\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e '{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"content\": \"We wrote up how our scheduler works: https://example.com/blog/scheduler #engineering\",\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"targets\": [{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"accountId\": \"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b\",\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"options\": {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"linkCard\": true,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"langs\": [\"en\"],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"replyControl\": \"limited\",\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"replyAllow\": [\"followers\", \"mentioned\"],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"disableQuotes\": false\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e }\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e }],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"publishNow\": true\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e }'\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"tab-panel\"\u003e\u003cdiv class=\"code-block\"\u003e\u003cpre class=\"shiki shiki-themes github-light github-dark-dimmed\" style=\"background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003econst\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003e res\u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e =\u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e await\u003c/span\u003e\u003cspan style=\"color:#6F42C1;--shiki-dark:#DCBDFB\"\u003e fetch\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e(\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"https://social-publish-api.onrender.com/v1/posts\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e method: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"POST\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e headers: {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"x-access-key\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: process.env.\u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003eRELAYCAST_API_KEY\u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e!\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"content-type\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"application/json\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e },\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e body: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003eJSON\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e.\u003c/span\u003e\u003cspan style=\"color:#6F42C1;--shiki-dark:#DCBDFB\"\u003estringify\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e({\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e content: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"We wrote up how our scheduler works: https://example.com/blog/scheduler #engineering\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e targets: [\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e accountId: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e options: {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e linkCard: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003etrue\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e langs: [\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"en\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e replyControl: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"limited\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e replyAllow: [\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"followers\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"mentioned\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e disableQuotes: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003efalse\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e },\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e },\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e ],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e publishNow: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003etrue\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e }),\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e});\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003econst\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e { \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003edata\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e } \u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e await\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e res.\u003c/span\u003e\u003cspan style=\"color:#6F42C1;--shiki-dark:#DCBDFB\"\u003ejson\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e();\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"tab-panel\"\u003e\u003cdiv class=\"code-block\"\u003e\u003cpre class=\"shiki shiki-themes github-light github-dark-dimmed\" style=\"background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003eimport\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e os, requests\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003eres \u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e requests.post(\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"https://social-publish-api.onrender.com/v1/posts\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#E36209;--shiki-dark:#F69D50\"\u003e headers\u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e{\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"x-access-key\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: os.environ[\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"RELAYCAST_API_KEY\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e]},\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#E36209;--shiki-dark:#F69D50\"\u003e json\u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"content\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"We wrote up how our scheduler works: https://example.com/blog/scheduler #engineering\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"targets\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: [{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"accountId\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"options\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"linkCard\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003eTrue\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"langs\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: [\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"en\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"replyControl\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"limited\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"replyAllow\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: [\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"followers\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"mentioned\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"disableQuotes\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003eFalse\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e },\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e }],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e \"publishNow\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#6CB6FF\"\u003eTrue\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e },\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e)\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003edata \u003c/span\u003e\u003cspan style=\"color:#D73A49;--shiki-dark:#F47067\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e res.json()[\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"data\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e]\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\u003ch3 id=\"images-with-alt-text-and-a-quote\"\u003e\u003ca href=\"#images-with-alt-text-and-a-quote\" class=\"heading-anchor\"\u003eImages with alt text and a quote\u003c/a\u003e\u003c/h3\u003e\n\u003cdiv class=\"code-block\"\u003e\u003cdiv class=\"code-title\"\u003eRequest body\u003c/div\u003e\u003cpre class=\"shiki shiki-themes github-light github-dark-dimmed\" style=\"background-color:#fff;--shiki-dark-bg:#22272e;color:#24292e;--shiki-dark:#adbac7\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"content\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"Before and after the redesign\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"media\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: [\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e { \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e\"url\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"https://cdn.example.com/before.jpg\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e\"type\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"image\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e\"altText\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"Old settings page\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e },\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e { \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e\"url\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"https://cdn.example.com/after.jpg\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e\"type\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"image\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e\"altText\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"New settings page\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e }\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e ],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"targets\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: [{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"accountId\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"7c6b5a49-3827-4e1d-8c0b-9a8f7e6d5c4b\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"options\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"quoteUrl\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"https://bsky.app/profile/example.bsky.social/post/3l7abcxyz2k2a\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"tags\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: [\u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"design\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e, \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"ux\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e]\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e }\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e }],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#005CC5;--shiki-dark:#8DDB8C\"\u003e \"scheduledFor\"\u003c/span\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e: \u003c/span\u003e\u003cspan style=\"color:#032F62;--shiki-dark:#96D0FF\"\u003e\"2026-11-10T09:00:00Z\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#24292E;--shiki-dark:#ADBAC7\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"analytics-comments\"\u003e\u003ca href=\"#analytics-comments\" class=\"heading-anchor\"\u003eAnalytics \u0026amp; comments\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eAnalytics show likes, replies (comments), reposts + quotes (shares) and bookmarks (saves). Bluesky does not report views, impressions or clicks.\u003c/p\u003e\n\u003cp\u003eReplies and messaging are not supported for Bluesky.\u003c/p\u003e\n\u003ch2 id=\"limitations-common-errors\"\u003e\u003ca href=\"#limitations-common-errors\" class=\"heading-anchor\"\u003eLimitations \u0026amp; common errors\u003c/a\u003e\u003c/h2\u003e\n\u003cdiv class=\"table-wrap\"\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eError\u003c/th\u003e\u003cth\u003eCause\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003einvalid_credentials\u003c/code\u003e (connect)\u003c/td\u003e\u003ctd\u003eBluesky rejected the handle or app password.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003eBluesky allows 300 characters (this post has …)\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eText is too long.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003eBluesky posts can have images or one video, not both\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMixed media.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003eBluesky allows up to 4 images\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eToo many images.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003eBluesky allows up to 8 tags\u003c/code\u003e / \u003ccode\u003eup to 3 languages\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eToo many \u003ccode\u003etags\u003c/code\u003e or \u003ccode\u003elangs\u003c/code\u003e.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003ePick at least one group who can reply …\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ereplyControl: \u0026quot;limited\u0026quot;\u003c/code\u003e with an empty \u003ccode\u003ereplyAllow\u003c/code\u003e.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eTarget fails: image too large\u003c/td\u003e\u003ctd\u003eBluesky images are limited to 2 MB each.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eAccount becomes \u003ccode\u003ereconnect_required\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eThe app password was revoked or the account was deactivated.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/div\u003e\u003cp\u003eA link card that can\u0026#39;t be built (the page can\u0026#39;t be fetched or has no metadata) quietly falls back to a plain post.\u003c/p\u003e\n6:[\"$\",\"div\",null,{\"className\":\"flex\",\"children\":[[\"$\",\"article\",null,{\"className\":\"min-w-0 flex-1 px-4 py-10 sm:px-8 lg:px-12\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-3xl\",\"children\":[[\"$\",\"p\",null,{\"className\":\"text-sm text-accent\",\"children\":\"Platforms\"}],[\"$\",\"h1\",null,{\"className\":\"mt-2 text-3xl font-bold tracking-tight sm:text-4xl\",\"children\":\"Bluesky\"}],[\"$\",\"p\",null,{\"className\":\"mt-3 text-lg text-muted\",\"children\":\"Post text, images, video, link cards and quote posts to Bluesky, connected with an app password.\"}],[\"$\",\"div\",null,{\"className\":\"mt-5\",\"children\":[\"$\",\"$L10\",null,{\"mdPath\":\"/docs/platforms/bluesky.md\",\"mdUrl\":\"https://social-publish-kappa.vercel.app/docs/platforms/bluesky.md\"}]}],[\"$\",\"div\",null,{\"className\":\"prose-sp mt-8\",\"dangerouslySetInnerHTML\":{\"__html\":\"$11\"}}],\"$L12\",\"$L13\",\"$L14\"]}]}],\"$L15\"]}]\n3:[\"$\",\"$L16\",null,{\"searchIndex\":[{\"href\":\"/docs\",\"title\":\"Getting Started\",\"text\":\"Publish your first post to one or more social networks with a single API request. Relaycast is one REST API and dashboard for publishing to X Twitter , Instagram, Facebook, LinkedIn, TikTok, YouTube, Threads, Pinterest, Bluesky and Google Business Profile. You connect accounts once, then send one request that fans out to every account you choose. Each platform succeeds or fails on its own, and you can read the result per platform. This guide takes about five minutes. You will: 1. Create an access key 2. Connect a social account 3. List your accounts to get an account ID 4. Publish your first p\",\"tab\":\"docs\"},{\"href\":\"/docs#1-create-an-access-key\",\"title\":\"1. Create an access key\",\"section\":\"Getting Started\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs#2-connect-a-social-account\",\"title\":\"2. Connect a social account\",\"section\":\"Getting Started\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs#3-list-your-accounts\",\"title\":\"3. List your accounts\",\"section\":\"Getting Started\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs#4-publish-your-first-post\",\"title\":\"4. Publish your first post\",\"section\":\"Getting Started\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs#5-schedule-a-post\",\"title\":\"5. Schedule a post\",\"section\":\"Getting Started\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs#next-steps\",\"title\":\"Next steps\",\"section\":\"Getting Started\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication\",\"title\":\"Authentication\",\"text\":\"Authenticate API requests with a project access key sent in the x-access-key header. Every request to /v1/ must include an access key. Keys belong to a project: a key can see and publish to every social account connected in that project, and nothing else. Create a key 1. Open Access Keys at https://social publish kappa.vercel.app/dashboard/api keys https://social publish kappa.vercel.app/dashboard/api keys . 2. Click Create key and give it a name up to 60 characters that tells you where it's used. 3. Copy the key. It looks like sp live ... and is shown only once . Relaycast stores only a SHA 2\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#create-a-key\",\"title\":\"Create a key\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#send-the-key\",\"title\":\"Send the key\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#authentication-errors\",\"title\":\"Authentication errors\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#revoke-and-rotate-keys\",\"title\":\"Revoke and rotate keys\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#keep-keys-safe\",\"title\":\"Keep keys safe\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#rate-limits\",\"title\":\"Rate limits\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/authentication#public-endpoints\",\"title\":\"Public endpoints\",\"section\":\"Authentication\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts\",\"title\":\"Core Concepts\",\"text\":\"Projects, social accounts, posts, targets, credits and how a post moves from request to published. A handful of objects make up the whole API. Once you know how they fit together, the rest of the docs are details. Projects A project is the workspace everything else lives in: connected accounts, posts, access keys, credits, notification rules and collaborators. Access keys are scoped to one project, so a key can never read or publish to another project's accounts. You can belong to several projects for example one per client and switch between them from the project menu in the dashboard. See Co\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#projects\",\"title\":\"Projects\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#social-accounts\",\"title\":\"Social accounts\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#posts-and-targets\",\"title\":\"Posts and targets\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#lifecycle\",\"title\":\"Lifecycle\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#post-statuses\",\"title\":\"Post statuses\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#target-statuses\",\"title\":\"Target statuses\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#credits\",\"title\":\"Credits\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#media\",\"title\":\"Media\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#platform-options\",\"title\":\"Platform options\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/core-concepts#idempotency\",\"title\":\"Idempotency\",\"section\":\"Core Concepts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts\",\"title\":\"Social Accounts\",\"text\":\"Connect social accounts, find their IDs, and handle accounts that need reconnecting. A social account is one connected profile, page or channel. Every post targets accounts by their Relaycast id . Supported platforms Platform platform value How to connect X Twitter twitter Dashboard OAuth Instagram instagram Dashboard OAuth Facebook facebook Dashboard OAuth LinkedIn linkedin Dashboard OAuth TikTok tiktok Dashboard OAuth YouTube youtube Dashboard OAuth Threads threads Dashboard OAuth Pinterest pinterest Dashboard OAuth Google Business Profile google business Dashboard OAuth Bluesky bluesky Dash\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#supported-platforms\",\"title\":\"Supported platforms\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#connect-in-the-dashboard\",\"title\":\"Connect in the dashboard\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#let-your-users-connect-with-a-link\",\"title\":\"Let your users connect with a link\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#connect-bluesky-with-the-api\",\"title\":\"Connect Bluesky with the API\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#list-accounts\",\"title\":\"List accounts\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#reconnecting-accounts\",\"title\":\"Reconnecting accounts\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/social-accounts#disconnecting\",\"title\":\"Disconnecting\",\"section\":\"Social Accounts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts\",\"title\":\"Posts\",\"text\":\"Create a post for one or many accounts, customise it per account, and read back per-platform results. A post is one request that publishes to up to 20 accounts at once. You create it with POST /v1/posts and read its results with GET /v1/posts/{id} . Create a post Request body Field Type Required Description content string Yes Shared text, 1–10,000 characters. Each platform also applies its own limit. targets array Yes 1–20 accounts to publish to. targets .accountId UUID Yes An account ID from GET /v1/accounts . targets .content string No Replaces content for this account only 1–10,000 characte\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#create-a-post\",\"title\":\"Create a post\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#request-body\",\"title\":\"Request body\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#validation\",\"title\":\"Validation\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#the-response\",\"title\":\"The response\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#get-results\",\"title\":\"Get results\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#list-posts\",\"title\":\"List posts\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#editing-and-deleting\",\"title\":\"Editing and deleting\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/posts#related\",\"title\":\"Related\",\"section\":\"Posts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling\",\"title\":\"Scheduling\",\"text\":\"Schedule posts for a future time with scheduledFor, and understand time zones and delivery timing. Every post either publishes now or at a time you choose. Scheduling uses the same POST /v1/posts endpoint, with scheduledFor in place of publishNow . Schedule a post The post is created with status: \\\"scheduled\\\" and its targets are queued . At the scheduled time the targets publish and the post moves through publishing to published , partial or failed . Timestamp format scheduledFor must be an ISO 8601 date time with a time zone : either Z for UTC or an offset like +02:00 or 05:00 . Value Accepted\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#schedule-a-post\",\"title\":\"Schedule a post\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#timestamp-format\",\"title\":\"Timestamp format\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#rules\",\"title\":\"Rules\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#timing\",\"title\":\"Timing\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#media-for-scheduled-posts\",\"title\":\"Media for scheduled posts\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#changing-or-cancelling-a-scheduled-post\",\"title\":\"Changing or cancelling a scheduled post\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#get-notified\",\"title\":\"Get notified\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/scheduling#in-the-dashboard\",\"title\":\"In the dashboard\",\"section\":\"Scheduling\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media\",\"title\":\"Media \u0026 Uploads\",\"text\":\"Attach images, videos and PDFs by public URL or from your project's media library. Posts can carry up to 10 media items in the media array. Every target in the post gets the same media. Each item points to a file in one of two ways: A public URL https://... that the platform can download. A media library reference media://\u003cid to a file you've uploaded in the dashboard. Media item fields Field Type Required Description url string Yes http s URL or media://\u003cid , up to 2,048 characters. type string Yes image , video or document . altText string No Up to 1,000 characters. Passed to platforms that \",\"tab\":\"docs\"},{\"href\":\"/docs/media#media-item-fields\",\"title\":\"Media item fields\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media#public-urls\",\"title\":\"Public URLs\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media#media-library\",\"title\":\"Media library\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media#upload\",\"title\":\"Upload\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media#reference-library-files\",\"title\":\"Reference library files\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media#deleting-library-files\",\"title\":\"Deleting library files\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/media#per-platform-rules\",\"title\":\"Per-platform rules\",\"section\":\"Media \u0026 Uploads\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/platform-options\",\"title\":\"Platform Options\",\"text\":\"Set platform-specific fields such as titles, privacy levels and post types with targets[].options. Most of a post is shared across platforms: the text, the media, the publish time. Some settings only make sense on one platform, such as a YouTube video title, a TikTok privacy level or the Pinterest board to pin to. These go in options on each target. How it works Each entry in targets takes an optional options object. The keys depend on the platform of that target's account: Here the YouTube target gets a title, visibility and tags, the TikTok target gets a privacy level, and the LinkedIn targe\",\"tab\":\"docs\"},{\"href\":\"/docs/platform-options#how-it-works\",\"title\":\"How it works\",\"section\":\"Platform Options\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/platform-options#validation\",\"title\":\"Validation\",\"section\":\"Platform Options\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/platform-options#value-types\",\"title\":\"Value types\",\"section\":\"Platform Options\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/platform-options#options-by-platform\",\"title\":\"Options by platform\",\"section\":\"Platform Options\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/platform-options#per-account-content\",\"title\":\"Per-account content\",\"section\":\"Platform Options\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency\",\"title\":\"Idempotency \u0026 Retries\",\"text\":\"Retry post creation safely with Idempotency-Key, and understand how publishing is retried. Networks fail. A request can time out after the server has already created your post, and if you simply retry you might publish twice and pay twice. Relaycast handles this with idempotency keys on the client side and automatic retries on the publishing side. Idempotency keys Send an Idempotency Key header with POST /v1/posts . The first request with a given key creates the post. Any later request with the same key, in the same project, returns that original post instead of creating a new one. How replays\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency#idempotency-keys\",\"title\":\"Idempotency keys\",\"section\":\"Idempotency \u0026 Retries\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency#how-replays-behave\",\"title\":\"How replays behave\",\"section\":\"Idempotency \u0026 Retries\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency#choosing-keys\",\"title\":\"Choosing keys\",\"section\":\"Idempotency \u0026 Retries\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency#what-to-retry\",\"title\":\"What to retry\",\"section\":\"Idempotency \u0026 Retries\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency#publish-retries\",\"title\":\"Publish retries\",\"section\":\"Idempotency \u0026 Retries\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/idempotency#duplicate-protection\",\"title\":\"Duplicate protection\",\"section\":\"Idempotency \u0026 Retries\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live\",\"title\":\"Live Publish\",\"text\":\"Restream one live or recorded source (HLS, MP4, DASH, RTMP, RTSP, SRT or a media library video) to YouTube, Facebook, Twitch and any RTMP destination at the same time. Overview Live Publish takes one source and sends it to up to 10 destinations at once . You can go live now or schedule a stream up to 60 days ahead. You can run it from the dashboard Live https://social publish kappa.vercel.app/dashboard/live or with POST /v1/live . Sources: a public URL HLS .m3u8 , MPEG DASH .mpd , MP4/MOV/WebM/MKV/FLV/TS files, RTMP/RTMPS, RTSP/RTSPS, SRT or a video from your media library /docs/media . Connec\",\"tab\":\"docs\"},{\"href\":\"/docs/live#overview\",\"title\":\"Overview\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#destinations\",\"title\":\"Destinations\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#sources\",\"title\":\"Sources\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#video-and-audio\",\"title\":\"Video and audio\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#lifecycle\",\"title\":\"Lifecycle\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#limits\",\"title\":\"Limits\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#example\",\"title\":\"Example\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/live#self-hosting-notes\",\"title\":\"Self-hosting notes\",\"section\":\"Live Publish\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications\",\"title\":\"Notifications \u0026 Webhooks\",\"text\":\"Get an email or a signed webhook when posts are scheduled, published, partially fail or fail. Notification rules tell you when something happens to a post, so you don't have to poll GET /v1/posts/{id} . Each rule sends either an email or a webhook an HTTPS POST signed with HMAC SHA256 . Events Event Fires when post.scheduled A post is created with scheduledFor . Posts sent with publishNow don't fire this. post.published Every target of a post published. post.partial A post finished with some targets published and some failed. post.failed Every target of a post failed. The last three fire once \",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#events\",\"title\":\"Events\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#create-a-rule\",\"title\":\"Create a rule\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#email\",\"title\":\"Email\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#webhooks\",\"title\":\"Webhooks\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#request\",\"title\":\"Request\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#verify-the-signature\",\"title\":\"Verify the signature\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#respond-and-retries\",\"title\":\"Respond and retries\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/notifications#credit-usage-emails\",\"title\":\"Credit usage emails\",\"section\":\"Notifications \u0026 Webhooks\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground\",\"title\":\"Playground \u0026 Drafts\",\"text\":\"Compose, validate and publish posts in the dashboard while the matching API request builds live. The Playground at https://social publish kappa.vercel.app/dashboard/playground https://social publish kappa.vercel.app/dashboard/playground is a post composer that doubles as an API request builder. Everything you do in it maps one to one to a POST /v1/posts body, so it's the fastest way to learn the API, try platform options, or post by hand. Compose a post 1. Select accounts. Pick one or more connected accounts. You need at least one connected account, see Social Accounts /docs/social accounts . \",\"tab\":\"docs\"},{\"href\":\"/docs/playground#compose-a-post\",\"title\":\"Compose a post\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#live-validation\",\"title\":\"Live validation\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#live-request\",\"title\":\"Live request\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#import-json\",\"title\":\"Import JSON\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#preview\",\"title\":\"Preview\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#drafts\",\"title\":\"Drafts\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#reuse-a-post\",\"title\":\"Reuse a post\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/playground#posts-page\",\"title\":\"Posts page\",\"section\":\"Playground \u0026 Drafts\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/analytics\",\"title\":\"Analytics\",\"text\":\"See posting activity across your project and load engagement numbers for individual posts. The dashboard has two kinds of analytics: a project wide activity overview , and post analytics with engagement numbers fetched from each platform. Both are dashboard features; the public API doesn't expose analytics endpoints. Activity overview Open Posts → Analytics at https://social publish kappa.vercel.app/dashboard/posts/analytics https://social publish kappa.vercel.app/dashboard/posts/analytics and choose a range: Week , Month or 3 Months the last 7, 30 or 90 days . Section What it shows Total post\",\"tab\":\"docs\"},{\"href\":\"/docs/analytics#activity-overview\",\"title\":\"Activity overview\",\"section\":\"Analytics\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/analytics#post-analytics\",\"title\":\"Post analytics\",\"section\":\"Analytics\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/analytics#loading-and-credits\",\"title\":\"Loading and credits\",\"section\":\"Analytics\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/analytics#related\",\"title\":\"Related\",\"section\":\"Analytics\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox\",\"title\":\"Inbox \u0026 Comment Automation\",\"text\":\"Read and reply to Instagram and Facebook messages, and turn Instagram comments into automatic DMs. The Inbox in the dashboard has two parts: Messages , a shared inbox for direct messages, and Comment Automation , which sends a DM to people who comment a trigger word on your Instagram posts. Both are dashboard features with no public API endpoints. Messages Open Inbox → Messages at https://social publish kappa.vercel.app/dashboard/inbox/messages https://social publish kappa.vercel.app/dashboard/inbox/messages . Supported accounts: Platform Messages Instagram Direct messages professional account\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox#messages\",\"title\":\"Messages\",\"section\":\"Inbox \u0026 Comment Automation\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox#comment-automation\",\"title\":\"Comment Automation\",\"section\":\"Inbox \u0026 Comment Automation\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox#create-an-automation\",\"title\":\"Create an automation\",\"section\":\"Inbox \u0026 Comment Automation\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox#match-styles\",\"title\":\"Match styles\",\"section\":\"Inbox \u0026 Comment Automation\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox#how-it-runs\",\"title\":\"How it runs\",\"section\":\"Inbox \u0026 Comment Automation\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/inbox#permissions\",\"title\":\"Permissions\",\"section\":\"Inbox \u0026 Comment Automation\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/oauth-apps\",\"title\":\"OAuth Apps (BYOK)\",\"text\":\"Connect accounts through your own platform developer apps so consent screens show your brand. By default, accounts connect through the Relaycast app on each platform, so the consent screen your users see names Relaycast. With Bring Your Own Key BYOK you add your own platform developer app instead. Accounts connected through it show your name and logo on the consent screen, and every token exchange, token refresh and publish for those accounts uses your app's credentials. Manage apps under Integrations → Apps BYOK at https://social publish kappa.vercel.app/dashboard/integrations?tab=apps https:\",\"tab\":\"docs\"},{\"href\":\"/docs/oauth-apps#supported-platforms\",\"title\":\"Supported platforms\",\"section\":\"OAuth Apps (BYOK)\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/oauth-apps#set-up-an-app\",\"title\":\"Set up an app\",\"section\":\"OAuth Apps (BYOK)\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/oauth-apps#how-accounts-use-your-app\",\"title\":\"How accounts use your app\",\"section\":\"OAuth Apps (BYOK)\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/oauth-apps#secrets\",\"title\":\"Secrets\",\"section\":\"OAuth Apps (BYOK)\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/oauth-apps#deleting-an-app\",\"title\":\"Deleting an app\",\"section\":\"OAuth Apps (BYOK)\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/groups\",\"title\":\"Social Groups\",\"text\":\"Organise connected accounts into groups, for example by client or brand. Social groups let you sort connected accounts into named sets, such as one per client, brand or region. Groups help you find and select the right accounts in the dashboard once a project has many of them. Manage groups under Integrations → Social groups at https://social publish kappa.vercel.app/dashboard/integrations?tab=groups https://social publish kappa.vercel.app/dashboard/integrations?tab=groups . The Default group Every account belongs to exactly one group. Accounts you haven't assigned are in Default , which alway\",\"tab\":\"docs\"},{\"href\":\"/docs/groups#the-default-group\",\"title\":\"The Default group\",\"section\":\"Social Groups\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/groups#create-a-group\",\"title\":\"Create a group\",\"section\":\"Social Groups\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/groups#add-accounts-to-a-group\",\"title\":\"Add accounts to a group\",\"section\":\"Social Groups\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/groups#filter-by-group\",\"title\":\"Filter by group\",\"section\":\"Social Groups\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/groups#groups-in-the-api\",\"title\":\"Groups in the API\",\"section\":\"Social Groups\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/groups#delete-a-group\",\"title\":\"Delete a group\",\"section\":\"Social Groups\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/team\",\"title\":\"Collaborators \u0026 Projects\",\"text\":\"Invite teammates to a project, assign roles, and work across several projects. A project holds everything: connected accounts, posts, drafts, access keys, credits, notification rules and logs. Collaborators are the people who can work in a project. You can belong to several projects and switch between them. Projects Your first project is created when you sign up. Rename it under Settings → General . If you've been invited to other projects, switch between them from the project menu in the dashboard sidebar. Everything you see in the dashboard, including accounts, posts and keys, belongs to the\",\"tab\":\"docs\"},{\"href\":\"/docs/team#projects\",\"title\":\"Projects\",\"section\":\"Collaborators \u0026 Projects\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/team#roles\",\"title\":\"Roles\",\"section\":\"Collaborators \u0026 Projects\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/team#invite-a-collaborator\",\"title\":\"Invite a collaborator\",\"section\":\"Collaborators \u0026 Projects\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/team#manage-members\",\"title\":\"Manage members\",\"section\":\"Collaborators \u0026 Projects\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/team#leave-a-project\",\"title\":\"Leave a project\",\"section\":\"Collaborators \u0026 Projects\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/logs\",\"title\":\"Request Logs\",\"text\":\"Inspect every authenticated API request your project made, with status, timing and errors. The Logs page at https://social publish kappa.vercel.app/dashboard/logs https://social publish kappa.vercel.app/dashboard/logs lists every API request made with your project's access keys. Use it to debug integrations, see which key is calling what, and find the error behind a failed call. What's logged One entry is recorded for each authenticated request to /v1/ : Column Description Time When the request was received. Method and path For example POST /v1/posts . Type The resource group: Posts, Accounts \",\"tab\":\"docs\"},{\"href\":\"/docs/logs#whats-logged\",\"title\":\"What's logged\",\"section\":\"Request Logs\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/logs#what-isnt-logged\",\"title\":\"What isn't logged\",\"section\":\"Request Logs\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/logs#filters\",\"title\":\"Filters\",\"section\":\"Request Logs\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/logs#retention\",\"title\":\"Retention\",\"section\":\"Request Logs\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/logs#debug-with-request-ids\",\"title\":\"Debug with request IDs\",\"section\":\"Request Logs\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/logs#related\",\"title\":\"Related\",\"section\":\"Request Logs\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits\",\"title\":\"Credits \u0026 Usage\",\"text\":\"How publishing and analytics use credits, when credits are refunded, and how to track usage. Relaycast meters usage with credits . Each project has its own credit balance, shown in the dashboard sidebar and on the Usage page. What costs credits Action Cost Publishing a post 1 credit per target per account the post goes to Loading post analytics 1 credit per load , for the whole post Everything else Free A post sent to one LinkedIn profile, one X account and one Instagram account costs 3 credits, whether it publishes now or is scheduled. Free actions include listing accounts, reading posts, val\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#what-costs-credits\",\"title\":\"What costs credits\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#when-credits-are-charged\",\"title\":\"When credits are charged\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#refunds\",\"title\":\"Refunds\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#insufficient-credits\",\"title\":\"Insufficient credits\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#plans\",\"title\":\"Plans\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#usage-page\",\"title\":\"Usage page\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#usage-emails\",\"title\":\"Usage emails\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/credits#related\",\"title\":\"Related\",\"section\":\"Credits \u0026 Usage\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits\",\"title\":\"Rate Limits\",\"text\":\"Per-key request limits, rate limit headers, and the size limits that apply to requests and posts. Relaycast limits how fast each access key can call the API, and how large requests and posts can be. Platforms also enforce their own limits, which are covered in the platform guides /docs/platforms . Request rate limit Each access key can make 120 requests per minute by default. The limit applies per key, so separate keys for example one per service each get their own allowance. The window is fixed to the clock minute: the count resets at the start of each minute rather than sliding. Headers Auth\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#request-rate-limit\",\"title\":\"Request rate limit\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#headers\",\"title\":\"Headers\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#when-you-hit-the-limit\",\"title\":\"When you hit the limit\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#staying-under-the-limit\",\"title\":\"Staying under the limit\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#size-limits\",\"title\":\"Size limits\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#platform-limits\",\"title\":\"Platform limits\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/limits#credits\",\"title\":\"Credits\",\"section\":\"Rate Limits\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors\",\"title\":\"Errors\",\"text\":\"The error response format, every API error code, and the codes recorded on failed targets. Relaycast uses conventional HTTP status codes and returns a JSON error body with a machine readable code . There are two kinds of errors to handle: Request errors are returned immediately by the API, before anything is created. Publish errors happen later, in the background, and are recorded on individual targets of an accepted post. Error format Field Description code Stable identifier. Branch on this. message Human readable explanation. It may change, so don't parse it. details Optional extra data. Its\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#error-format\",\"title\":\"Error format\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#http-status-codes\",\"title\":\"HTTP status codes\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#request-error-codes\",\"title\":\"Request error codes\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#schema-validation-details\",\"title\":\"Schema validation details\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#platform-validation-details\",\"title\":\"Platform validation details\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#publish-errors\",\"title\":\"Publish errors\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/errors#handling-errors\",\"title\":\"Handling errors\",\"section\":\"Errors\",\"text\":\"\",\"tab\":\"docs\"},{\"href\":\"/docs/platforms\",\"title\":\"Platform Guides\",\"text\":\"What Relaycast can post to each social network, how each account connects, and where the per-platform rules live. Relaycast publishes to ten networks through one request shape. You send one POST /v1/posts with shared content and media , list the accounts in targets , and add platform specific settings in targets .options . Each target is validated against its platform's rules before anything is queued, so content a platform would reject comes back as a 400 instead of a failed job. Supported platforms Platform ID Connects with Text only Images Video Multi image / carousel Other formats X Twitte\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#supported-platforms\",\"title\":\"Supported platforms\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#live-streaming\",\"title\":\"Live streaming\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#features-by-platform\",\"title\":\"Features by platform\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#how-posting-works-per-platform\",\"title\":\"How posting works per platform\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#connecting-accounts\",\"title\":\"Connecting accounts\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#finding-account-ids\",\"title\":\"Finding account IDs\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms#platform-options\",\"title\":\"Platform options\",\"section\":\"Platform Guides\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter\",\"title\":\"X (Twitter)\",\"text\":\"Post text, images, GIFs, video, threads, polls and quote posts to X through the X API v2. Overview The twitter platform publishes to an X account with the X API v2. You can post: Text posts 280 weighted characters, or 25,000 with Long post on Premium accounts Up to 4 images, or 1 GIF, or 1 video Threads: extra posts chained as replies to the first one Polls with 2–4 options Quote posts, Community posts, reply restrictions and an AI generated media label Connect the account In the dashboard, open Integrations https://social publish kappa.vercel.app/dashboard/integrations , choose X Twitter and \",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#overview\",\"title\":\"Overview\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#options\",\"title\":\"Options\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#examples\",\"title\":\"Examples\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#thread-with-an-image\",\"title\":\"Thread with an image\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#poll\",\"title\":\"Poll\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#quote-post-in-a-community\",\"title\":\"Quote post in a Community\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitter#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"X (Twitter)\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram\",\"title\":\"Instagram\",\"text\":\"Publish feed posts, carousels, Reels and Stories to Instagram professional accounts. Overview The instagram platform publishes to Instagram professional Business or Creator accounts. Personal accounts cannot publish through the API. You can post: A single image JPEG to the feed A single video, published as a Reel A carousel of 2–10 images and/or videos A Reel with optional cover, thumbnail frame, trial reel mode, and \\\"share to feed\\\" toggle A Story exactly one image or video Up to 3 collaborators on feed posts, carousels and Reels Instagram does not support text only posts: every post needs at \",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#overview\",\"title\":\"Overview\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#instagram-login-setup-self-hosted\",\"title\":\"Instagram Login setup (self-hosted)\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#facebook-login-setup-self-hosted\",\"title\":\"Facebook Login setup (self-hosted)\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#options\",\"title\":\"Options\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#examples\",\"title\":\"Examples\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#reel-with-collaborators-and-a-cover\",\"title\":\"Reel with collaborators and a cover\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#carousel\",\"title\":\"Carousel\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#story\",\"title\":\"Story\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/instagram#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"Instagram\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook\",\"title\":\"Facebook\",\"text\":\"Publish text, link, photo and video posts, Reels and Stories to Facebook Pages. Overview The facebook platform publishes to Facebook Pages not personal profiles . Every Page you grant during login becomes its own account in Relaycast. You can post: Text posts, optionally with a link preview card 1–10 photos 1 video with optional title and custom thumbnail Reels one vertical video Stories one photo or one video Unpublished Page posts for ads, or to publish later in Meta Business Suite Connect the account In Integrations https://social publish kappa.vercel.app/dashboard/integrations , choose Fac\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#overview\",\"title\":\"Overview\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#options\",\"title\":\"Options\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#examples\",\"title\":\"Examples\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#link-post\",\"title\":\"Link post\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#reel-with-title-and-thumbnail\",\"title\":\"Reel with title and thumbnail\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#unpublished-photo-post\",\"title\":\"Unpublished photo post\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/facebook#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"Facebook\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin\",\"title\":\"LinkedIn\",\"text\":\"Publish text, article links, images, video and PDF documents to LinkedIn profiles and Company Pages. Overview The linkedin platform publishes with LinkedIn's versioned REST Posts API, to a personal profile or with extra LinkedIn access to Company Pages you administer. You can post: Text posts Link article posts with your own title and description 1–20 images 1 video A PDF document LinkedIn is the only platform that accepts \\\"type\\\": \\\"document\\\" media Company Page @mentions Connect the account In Integrations https://social publish kappa.vercel.app/dashboard/integrations , choose LinkedIn and appr\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#overview\",\"title\":\"Overview\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#options\",\"title\":\"Options\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#examples\",\"title\":\"Examples\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#pdf-document-post\",\"title\":\"PDF document post\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#article-link-with-a-company-page-mention\",\"title\":\"Article link with a Company Page mention\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/linkedin#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"LinkedIn\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok\",\"title\":\"TikTok\",\"text\":\"Publish videos and photo posts to TikTok with the Content Posting API, directly or as inbox drafts. Overview The tiktok platform publishes with TikTok's Content Posting API. You can post: One video Direct Post A photo post with 1–10 images requires pull from URL mode; TikTok allows up to 35, but a Relaycast post carries at most 10 media items Drafts sent to the creator's TikTok inbox, when your app has no Direct Post access inbox mode TikTok posts always need media; text only posts are not supported. The post content becomes the video caption or the photo description. Connect the account In In\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#overview\",\"title\":\"Overview\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#options\",\"title\":\"Options\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#examples\",\"title\":\"Examples\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#video\",\"title\":\"Video\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#photo-post-requires-tiktokpullfromurltrue\",\"title\":\"Photo post (requires TIKTOK_PULL_FROM_URL=true)\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/tiktok#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"TikTok\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube\",\"title\":\"YouTube\",\"text\":\"Upload videos to a YouTube channel with title, visibility, tags, thumbnail and an automatic first comment. Overview The youtube platform uploads one video per post to a YouTube channel with the YouTube Data API v3. The post content becomes the video description. You can set: Title, visibility public, unlisted, private , category and tags Made for kids and altered/synthetic content disclosures A custom thumbnail A first comment posted automatically after the upload Connect the account In Integrations https://social publish kappa.vercel.app/dashboard/integrations , choose YouTube and sign in wit\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#overview\",\"title\":\"Overview\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#options\",\"title\":\"Options\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#examples\",\"title\":\"Examples\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/youtube#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"YouTube\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads\",\"title\":\"Threads\",\"text\":\"Publish text, image, video and carousel posts to Threads, with reply controls, topic tags, link cards and quotes. Overview The threads platform publishes with Meta's Threads API. You can post: Text posts, optionally with a link preview card A single image or video Carousels of up to 20 images and/or videos Quote posts One topic tag per post, and reply controls Connect the account In Integrations https://social publish kappa.vercel.app/dashboard/integrations , choose Threads and approve access. App setup self hosted 1. In the Meta App Dashboard, create an app with the Access the Threads API use\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#overview\",\"title\":\"Overview\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#options\",\"title\":\"Options\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#examples\",\"title\":\"Examples\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#carousel-quoting-another-post\",\"title\":\"Carousel quoting another post\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/threads#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"Threads\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest\",\"title\":\"Pinterest\",\"text\":\"Create image, carousel and video Pins on your Pinterest boards with the Pinterest API v5. Overview The pinterest platform creates Pins with the Pinterest API v5. You can create: Image Pins 1 image Carousel Pins 2–5 images Video Pins 1 video, with a cover image or a cover frame Every Pin is saved to a board options.boardId is required . The post content becomes the Pin description; options.title sets the Pin title and options.link the destination link. Connect the account In Integrations https://social publish kappa.vercel.app/dashboard/integrations , choose Pinterest and approve access. App se\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#overview\",\"title\":\"Overview\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#options\",\"title\":\"Options\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#examples\",\"title\":\"Examples\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#image-pin\",\"title\":\"Image Pin\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#video-pin-with-a-cover-frame\",\"title\":\"Video Pin with a cover frame\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/pinterest#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"Pinterest\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky\",\"title\":\"Bluesky\",\"text\":\"Post text, images, video, link cards and quote posts to Bluesky, connected with an app password. Overview The bluesky platform posts to Bluesky with an app password no OAuth app needed . You can post: Text posts with automatic link, mention and hashtag detection Up to 4 images, or 1 video A link preview card automatic for the first link, or a URL you choose Quote posts alone or combined with images, video or a link card Languages, extra hidden tags, content warnings, reply controls and quote controls Connect the account Bluesky uses app passwords instead of OAuth. 1. In the Bluesky app, go to \",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#overview\",\"title\":\"Overview\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#options\",\"title\":\"Options\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#examples\",\"title\":\"Examples\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#post-with-a-link-card-and-reply-limits\",\"title\":\"Post with a link card and reply limits\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#images-with-alt-text-and-a-quote\",\"title\":\"Images with alt text and a quote\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/bluesky#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"Bluesky\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business\",\"title\":\"Google Business Profile\",\"text\":\"Publish updates, events and offers with call-to-action buttons to Google Business Profile locations on Search and Maps. Overview The google business platform creates local posts on Google Business Profile locations shown on Google Search and Maps . You can post: Updates STANDARD : text with an optional photo Events EVENT : title, start and end time Offers OFFER : title, dates, coupon code, redeem link and terms An optional call to action button Book, Order online, Buy, Learn more, Sign up, Call now Connect the account In Integrations https://social publish kappa.vercel.app/dashboard/integratio\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#overview\",\"title\":\"Overview\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#post-types-media-rules\",\"title\":\"Post types \u0026 media rules\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#options\",\"title\":\"Options\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#examples\",\"title\":\"Examples\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#offer-with-a-button\",\"title\":\"Offer with a button\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#update-with-a-call-now-button\",\"title\":\"Update with a Call now button\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#analytics-comments\",\"title\":\"Analytics \u0026 comments\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/google-business#limitations-common-errors\",\"title\":\"Limitations \u0026 common errors\",\"section\":\"Google Business Profile\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitch\",\"title\":\"Twitch\",\"text\":\"Go live on a Twitch channel with Live Publish. The title is set and the stream key is read automatically. Overview Twitch is a live only platform in Relaycast. You use it as a Live Publish /docs/live destination, not as a target for POST /v1/posts . Adding a Twitch account to a post returns a validation error . When a stream starts, Relaycast: 1. sets the channel title to the stream title up to 140 characters; if this fails the stream still starts , 2. reads the channel's stream key with the Helix API, and 3. streams to Twitch's ingest at rtmp://live.twitch.tv/app . The destination's watchUrl \",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitch#overview\",\"title\":\"Overview\",\"section\":\"Twitch\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitch#connect-the-account\",\"title\":\"Connect the account\",\"section\":\"Twitch\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitch#app-setup-self-hosted\",\"title\":\"App setup (self-hosted)\",\"section\":\"Twitch\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitch#without-connecting\",\"title\":\"Without connecting\",\"section\":\"Twitch\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/platforms/twitch#recommended-video\",\"title\":\"Recommended video\",\"section\":\"Twitch\",\"text\":\"\",\"tab\":\"platforms\"},{\"href\":\"/docs/api\",\"title\":\"API Reference\",\"text\":\"Base URL, authentication, response format, errors, limits and the full list of Relaycast REST endpoints. The Relaycast API is a JSON REST API. You can call it with any HTTP client: the examples use cURL, fetch in Node.js, and Python requests . There is no official SDK. Base URL All resource endpoints are versioned under /v1 . The health endpoints /health , /ready are at the root and need no authentication. Authentication Every /v1 request needs an API key. Create one in the dashboard under API Keys https://social publish kappa.vercel.app/dashboard/api keys . Send it in either header: Header Ex\",\"tab\":\"api\"},{\"href\":\"/docs/api#base-url\",\"title\":\"Base URL\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#authentication\",\"title\":\"Authentication\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#requests\",\"title\":\"Requests\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#responses\",\"title\":\"Responses\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#errors\",\"title\":\"Errors\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#rate-limits\",\"title\":\"Rate limits\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#lists-and-limits\",\"title\":\"Lists and limits\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#idempotency\",\"title\":\"Idempotency\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#credits\",\"title\":\"Credits\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#endpoints\",\"title\":\"Endpoints\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api#request-logs\",\"title\":\"Request logs\",\"section\":\"API Reference\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts\",\"title\":\"List accounts\",\"text\":\"Return the social accounts connected to your project, with the IDs you use as post targets. Returns every connected social account in the API key's project. Use an account's id as targets .accountId when you create a post /docs/api/create post . Disconnected accounts are not returned; accounts that need reconnecting are returned with status: \\\"reconnect required\\\" . Accounts are connected in the dashboard under Integrations https://social publish kappa.vercel.app/dashboard/integrations , by your users through a connect link /docs/api/create connect link OAuth platforms , or with Connect Bluesky \",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts#headers\",\"title\":\"Headers\",\"section\":\"List accounts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts#query-parameters\",\"title\":\"Query parameters\",\"section\":\"List accounts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts#request\",\"title\":\"Request\",\"section\":\"List accounts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts#response\",\"title\":\"Response\",\"section\":\"List accounts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts#account-fields\",\"title\":\"Account fields\",\"section\":\"List accounts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-accounts#errors\",\"title\":\"Errors\",\"section\":\"List accounts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link\",\"title\":\"Create a connect link\",\"text\":\"Create a one-time hosted link your user opens to connect a social account through OAuth, without a Relaycast login. Lets your own users connect their social accounts to your project from inside your app. You create a link, send your user to its url , they approve access on the platform's consent screen, and Relaycast sends them back to your redirectUrl with the result. Your users never need a Relaycast account. 1. Your server calls this endpoint and gets a url . 2. Your app redirects the user or opens a popup to that url . 3. The user signs in to the platform and approves access. 4. Relaycast \",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link#headers\",\"title\":\"Headers\",\"section\":\"Create a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link#body\",\"title\":\"Body\",\"section\":\"Create a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link#request\",\"title\":\"Request\",\"section\":\"Create a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link#response\",\"title\":\"Response\",\"section\":\"Create a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link#back-at-your-redirecturl\",\"title\":\"Back at your redirectUrl\",\"section\":\"Create a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-connect-link#errors\",\"title\":\"Errors\",\"section\":\"Create a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-connect-link\",\"title\":\"Get a connect link\",\"text\":\"Check whether a connect link was used, and which accounts it connected. Returns a connect link /docs/api/create connect link and its outcome. Call it from your server after your user comes back to your redirectUrl , to confirm the result before you trust it. Path parameters Parameter Description id The link's id from Create a connect link /docs/api/create connect link . Request Response The same fields as when the link was created, without url . status Meaning pending Created, not opened yet. opened The user opened the link and is on the consent screen. connected Done. accountIds lists the con\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-connect-link#path-parameters\",\"title\":\"Path parameters\",\"section\":\"Get a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-connect-link#request\",\"title\":\"Request\",\"section\":\"Get a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-connect-link#response\",\"title\":\"Response\",\"section\":\"Get a connect link\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/connect-bluesky\",\"title\":\"Connect Bluesky\",\"text\":\"Connect or reconnect a Bluesky account with its handle and an app password. Signs in to Bluesky with the handle and app password, and saves the account to your project. Bluesky is the only platform you can connect with a single API call; OAuth platforms connect from Integrations https://social publish kappa.vercel.app/dashboard/integrations in the dashboard, or through a connect link /docs/api/create connect link your user opens. Create an app password in the Bluesky app under Settings → Privacy and security → App passwords . Don't use your main Bluesky password. Calling this again for the sam\",\"tab\":\"api\"},{\"href\":\"/docs/api/connect-bluesky#headers\",\"title\":\"Headers\",\"section\":\"Connect Bluesky\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/connect-bluesky#body\",\"title\":\"Body\",\"section\":\"Connect Bluesky\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/connect-bluesky#request\",\"title\":\"Request\",\"section\":\"Connect Bluesky\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/connect-bluesky#response\",\"title\":\"Response\",\"section\":\"Connect Bluesky\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/connect-bluesky#errors\",\"title\":\"Errors\",\"section\":\"Connect Bluesky\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post\",\"title\":\"Create a post\",\"text\":\"Publish now or schedule one post to up to 20 social accounts, with shared media and per-account text and options. Creates a post for one or more connected accounts. Each account becomes a target that is validated, published and tracked separately, so one platform failing doesn't affect the others. The request is validated against every target platform's rules before anything is saved. If any target is invalid, nothing is created or charged and you get a 400 listing the problems per account. On success, 1 credit per target is charged and the targets are queued: immediately with publishNow: true\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#headers\",\"title\":\"Headers\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#body\",\"title\":\"Body\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#request\",\"title\":\"Request\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#response\",\"title\":\"Response\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#idempotency\",\"title\":\"Idempotency\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#errors\",\"title\":\"Errors\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-post#after-the-post-is-created\",\"title\":\"After the post is created\",\"section\":\"Create a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-posts\",\"title\":\"List posts\",\"text\":\"Return your project's most recent posts, newest first, with their per-platform targets. Returns the most recently created posts in the API key's project, newest first, each with its targets. Posts created from the dashboard Playground are included. Headers Header Required Description x access key Yes Your API key. Or send Authorization: Bearer \u003ckey . Query parameters Parameter Type Default Description limit integer 20 Number of posts to return, from 1 to 100. Larger values are capped at 100 and negative values return 1; a missing, 0 or non numeric value uses 20. There is no cursor or offset, a\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-posts#headers\",\"title\":\"Headers\",\"section\":\"List posts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-posts#query-parameters\",\"title\":\"Query parameters\",\"section\":\"List posts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-posts#request\",\"title\":\"Request\",\"section\":\"List posts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-posts#response\",\"title\":\"Response\",\"section\":\"List posts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-posts#errors\",\"title\":\"Errors\",\"section\":\"List posts\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post\",\"title\":\"Get a post\",\"text\":\"Fetch one post with the status, platform post ID, URL and error of each target. Returns a single post and all of its targets. Poll this endpoint to follow a post through publishing, or use webhook events /docs/api/webhook events to be notified instead. Headers Header Required Description x access key Yes Your API key. Or send Authorization: Bearer \u003ckey . Path parameters Parameter Type Description id string UUID The post ID returned by Create a post /docs/api/create post . Request Response Post fields Field Type Description id string UUID Post ID. content string Shared post text. media object S\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#headers\",\"title\":\"Headers\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#path-parameters\",\"title\":\"Path parameters\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#request\",\"title\":\"Request\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#response\",\"title\":\"Response\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#post-fields\",\"title\":\"Post fields\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#target-fields\",\"title\":\"Target fields\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#statuses\",\"title\":\"Statuses\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-post#errors\",\"title\":\"Errors\",\"section\":\"Get a post\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live\",\"title\":\"Create a live stream\",\"text\":\"Start or schedule a Live Publish stream from a URL (HLS, MP4, DASH, RTMP, RTSP, SRT) or a media library video to several platforms. Creates a live stream and queues it. With startNow: true it starts within a few seconds; with scheduledFor it starts at that time. The response is the stream with status: \\\"scheduled\\\" . Follow it with Get a live stream /docs/api/get live . See Live Publish /docs/live for how sources and destinations work. Headers Header Required Description x access key Yes Your API key. Or send Authorization: Bearer \u003ckey . content type Yes application/json Body Field Type Required\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#headers\",\"title\":\"Headers\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#body\",\"title\":\"Body\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#source-url\",\"title\":\"Source URL\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#destinations\",\"title\":\"Destinations\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#request\",\"title\":\"Request\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#response\",\"title\":\"Response\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/create-live#errors\",\"title\":\"Errors\",\"section\":\"Create a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/list-live\",\"title\":\"List live streams\",\"text\":\"List the project's live streams, newest first. Query Type Description limit integer 1–100, default 20. Each item has the same shape as Get a live stream /docs/api/get live .\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-live\",\"title\":\"Get a live stream\",\"text\":\"Fetch one live stream with its status, encoding stats and the status and watch URL of each destination. Poll this endpoint every 5–10 s is plenty to follow a stream from scheduled to live to ended . Request Response Some destination fields are omitted above for brevity. Stream fields Field Type Description status string scheduled , starting , live , ending , ended , failed or canceled . source.kind string hls , dash , file , rtmp , rtsp , srt or http . startedAt string \\\\ null When media first reached a platform. durationSeconds integer Seconds streamed so far counted against live minutes . err\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-live#request\",\"title\":\"Request\",\"section\":\"Get a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-live#response\",\"title\":\"Response\",\"section\":\"Get a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-live#stream-fields\",\"title\":\"Stream fields\",\"section\":\"Get a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-live#destination-fields\",\"title\":\"Destination fields\",\"section\":\"Get a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/get-live#errors\",\"title\":\"Errors\",\"section\":\"Get a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/stop-live\",\"title\":\"Stop a live stream\",\"text\":\"End a running live stream on every platform, or cancel a scheduled one. Running starting , live , ending : the stream stops within about 5 seconds. YouTube broadcasts are completed, Facebook live videos are ended, and Twitch goes offline. The final status is ended . Scheduled : the stream is canceled status: \\\"canceled\\\" and never starts. The response is the stream same shape as Get /docs/api/get live . A running stream may still show live right after the call; poll until it is ended . Errors Status Code When 404 not found No live stream with this ID in the project. 409 not running The stream ha\",\"tab\":\"api\"},{\"href\":\"/docs/api/stop-live#errors\",\"title\":\"Errors\",\"section\":\"Stop a live stream\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/relaunch-live\",\"title\":\"Relaunch a live stream\",\"text\":\"Start a new live stream now with the same source, settings and destinations as an earlier one. Creates a new stream new ID that starts now, copying the title, description, source, loop, video mode, time limit and destinations, including custom stream keys. The original stream is unchanged. !WARNING Some platforms issue single use stream keys Instagram, for example . Relaunching with an old key fails for that destination. Create a new stream with a fresh key instead. Returns 201 with the new stream. The same checks and errors as Create a live stream /docs/api/create live apply. For example, an \",\"tab\":\"api\"},{\"href\":\"/docs/api/live-usage\",\"title\":\"Live usage\",\"text\":\"Live minutes used and remaining this month for the project. Minutes are counted per stream, rounded up, for streams started this calendar month UTC . Sending one stream to several platforms doesn't use extra minutes. When remainingMinutes reaches 0, new streams are rejected with 402 live minutes exhausted , and running streams end.\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events\",\"title\":\"Webhook events\",\"text\":\"Signed HTTP callbacks for post.scheduled, post.published, post.partial and post.failed, and how to verify them. Relaycast can POST a signed JSON event to your server when a post is scheduled, published, partially published or failed. Webhooks are configured in the dashboard, not through the API. Set up a webhook 1. Open Settings → Notifications in the dashboard https://social publish kappa.vercel.app/dashboard/settings . 2. Add a rule with the Webhook channel. 3. Enter your endpoint URL. It must be https and resolve to a public address. 4. Copy the signing secret it starts with whsec . You nee\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#set-up-a-webhook\",\"title\":\"Set up a webhook\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#events\",\"title\":\"Events\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#request\",\"title\":\"Request\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#headers\",\"title\":\"Headers\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#body\",\"title\":\"Body\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#verify-the-signature\",\"title\":\"Verify the signature\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/webhook-events#responding-and-retries\",\"title\":\"Responding and retries\",\"section\":\"Webhook events\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/health\",\"title\":\"Health \u0026 readiness\",\"text\":\"Unauthenticated liveness and readiness endpoints for load balancers, uptime checks and orchestrators. The API exposes two endpoints at the root not under /v1 that need no API key or other headers. They don't count toward your rate limit and don't appear in request logs. Liveness Returns 200 whenever the API process is up and serving requests. It doesn't check any dependency, so use it for liveness probes. Readiness Checks the database select 1 and the queue Redis PING , each with a 2 second timeout. Returns 200 when both respond, otherwise 503 . Use it for readiness probes and to decide whethe\",\"tab\":\"api\"},{\"href\":\"/docs/api/health#liveness\",\"title\":\"Liveness\",\"section\":\"Health \u0026 readiness\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/health#readiness\",\"title\":\"Readiness\",\"section\":\"Health \u0026 readiness\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/api/health#fields\",\"title\":\"Fields\",\"section\":\"Health \u0026 readiness\",\"text\":\"\",\"tab\":\"api\"},{\"href\":\"/docs/ai\",\"title\":\"AI \u0026 Integrations\",\"text\":\"Use Relaycast from AI agents, coding assistants and no-code automation tools. Relaycast is a plain REST API with JSON in and JSON out, so anything that can make an HTTP request can publish: an LLM agent with tools, a coding assistant writing an integration, or a workflow in a no code tool. This section shows the quickest route for each. Choose an approach You want to... Use Guide Let an LLM publish posts as a tool call in your app Function calling with JSON schema tools Function Calling /docs/ai/function calling Teach a coding agent Claude Code, Codex, Cursor and others how to use the API A sk\",\"tab\":\"ai\"},{\"href\":\"/docs/ai#choose-an-approach\",\"title\":\"Choose an approach\",\"section\":\"AI \u0026 Integrations\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai#the-three-calls-an-agent-needs\",\"title\":\"The three calls an agent needs\",\"section\":\"AI \u0026 Integrations\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai#guardrails-for-agents\",\"title\":\"Guardrails for agents\",\"section\":\"AI \u0026 Integrations\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai#what-agents-cant-do-through-the-api\",\"title\":\"What agents can't do through the API\",\"section\":\"AI \u0026 Integrations\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai#next-steps\",\"title\":\"Next steps\",\"section\":\"AI \u0026 Integrations\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill\",\"title\":\"Agent Skill\",\"text\":\"A ready-to-use SKILL.md that teaches coding agents how to publish with the Relaycast API. Coding agents work best when they have short, focused instructions for a task. The file below packages everything an agent needs to publish with Relaycast: the three API calls, the request format and the rules that trip people up. Copy it into your project and the agent can use the API without reading the full docs first. The skill file The description in the front matter is what an agent reads to decide when the skill applies, so keep it specific to publishing. Set up the access key The skill reads the k\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#the-skill-file\",\"title\":\"The skill file\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#set-up-the-access-key\",\"title\":\"Set up the access key\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#where-to-put-it\",\"title\":\"Where to put it\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#claude-code\",\"title\":\"Claude Code\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#codex-and-other-agents-that-read-agentsmd\",\"title\":\"Codex and other agents that read AGENTS.md\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#cursor\",\"title\":\"Cursor\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#other-tools\",\"title\":\"Other tools\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/agent-skill#keep-it-up-to-date\",\"title\":\"Keep it up to date\",\"section\":\"Agent Skill\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/function-calling\",\"title\":\"Function Calling\",\"text\":\"Tool definitions and a minimal executor that let OpenAI or Claude models publish through Relaycast. Function calling also called tool use lets a language model decide when to call your code. You describe a few tools with JSON Schema, the model replies with a tool call, your code runs the matching Relaycast request, and you send the result back to the model. This page gives you three tools that cover the whole publishing flow, an executor that runs them, and the loop for OpenAI and Anthropic models. Tool Calls Purpose list accounts GET /v1/accounts Find account IDs and platforms. create post PO\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/function-calling#tool-definitions\",\"title\":\"Tool definitions\",\"section\":\"Function Calling\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/function-calling#the-executor\",\"title\":\"The executor\",\"section\":\"Function Calling\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/function-calling#run-the-loop\",\"title\":\"Run the loop\",\"section\":\"Function Calling\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/function-calling#tips\",\"title\":\"Tips\",\"section\":\"Function Calling\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/function-calling#related\",\"title\":\"Related\",\"section\":\"Function Calling\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/llms-txt\",\"title\":\"llms.txt \u0026 Markdown Docs\",\"text\":\"Feed these docs to AI assistants with llms.txt, Markdown versions of every page, and one-click copy and open actions. Language models read Markdown far better than rendered HTML with navigation, scripts and styling around it. So every page of these docs is also available as clean Markdown, and an llms.txt file indexes them all. llms.txt https://social publish kappa.vercel.app/llms.txt https://social publish kappa.vercel.app/llms.txt follows the llms.txt https://llmstxt.org convention: a plain text Markdown index of the whole documentation, with a link and short description for every page. Give\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/llms-txt#llmstxt\",\"title\":\"llms.txt\",\"section\":\"llms.txt \u0026 Markdown Docs\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/llms-txt#markdown-for-every-page\",\"title\":\"Markdown for every page\",\"section\":\"llms.txt \u0026 Markdown Docs\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/llms-txt#copy-and-open-from-any-page\",\"title\":\"Copy and open from any page\",\"section\":\"llms.txt \u0026 Markdown Docs\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/llms-txt#tips-for-using-docs-with-assistants\",\"title\":\"Tips for using docs with assistants\",\"section\":\"llms.txt \u0026 Markdown Docs\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code\",\"title\":\"No-code (n8n, Make, Zapier)\",\"text\":\"Publish from n8n, Make or Zapier workflows with a generic HTTP request step. You can publish from any automation tool that can send an HTTP request. There's no dedicated Relaycast app or node in these tools, but you don't need one: their built in HTTP request steps call the REST API directly. Typical workflows: Publish new blog posts or RSS items to every channel. Post a product announcement when a row is added to a spreadsheet or database. Schedule a week of posts from a content calendar. Notify a team chat when a post fails, using webhook notifications /docs/notifications . What every reques\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#what-every-request-needs\",\"title\":\"What every request needs\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#before-you-start\",\"title\":\"Before you start\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#n8n\",\"title\":\"n8n\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#make\",\"title\":\"Make\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#zapier\",\"title\":\"Zapier\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#watch-out-for\",\"title\":\"Watch out for\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"},{\"href\":\"/docs/ai/no-code#react-to-publish-results\",\"title\":\"React to publish results\",\"section\":\"No-code (n8n, Make, Zapier)\",\"text\":\"\",\"tab\":\"ai\"}],\"user\":null,\"children\":\"$L17\"}]\n18:I[80597,[\"/_next/static/chunks/2corl6wyj4669.js\",\"/_next/static/chunks/08v9q1-2iyvo-.js\",\"/_next/static/chunks/3g-1_mxnc4d1c.js\",\"/_next/static/chunks/0jr6nk53yio29.js\",\"/_next/static/chunks/2yjjm-mkyykml.js\"],\"CodeCopy\"]\n19:I[22016,[\"/_next/static/chunks/2corl6wyj4669.js\",\"/_next/static/chunks/08v9q1-2iyvo-.js\",\"/_next/static/chunks/3g-1_mxnc4d1c.js\",\"/_next/static/chunks/0jr6nk53yio29.js\",\"/_next/static/chunks/2yjjm-mkyykml.js\"],\"\"]\n1a:I[80597,[\"/_next/static/chunks/2corl6wyj4669.js\",\"/_next/static/chunks/08v9q1-2iyvo-.js\",\"/_next/static/chunks/3g-1_mxnc4d1c.js\",\"/_next/static/chunks/0jr6nk53yio29.js\",\"/_next/static/chunks/2yjjm-mkyykml.js\"],\"Toc\"]\n12:[\"$\",\"$L18\",null,{}]\n13:[\"$\",\"nav\",null,{\"aria-label\":\"Pagination\",\"className\":\"mt-14 grid gap-3 border-t border-line pt-6 sm:grid-cols-2\",\"children\":[[\"$\",\"$L19\",null,{\"href\":\"/docs/platforms/pinterest\",\"className\":\"card group p-4 transition hover:border-faint\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-xs text-faint\",\"children\":\"← Previous\"}],[\"$\",\"span\",null,{\"className\":\"mt-1 block font-medium group-hover:text-accent\",\"children\":\"Pinterest\"}]]}],[\"$\",\"$L19\",null,{\"href\":\"/docs/platforms/google-business\",\"className\":\"card group p-4 text-right transition hover:border-faint\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-xs text-faint\",\"children\":\"Next →\"}],[\"$\",\"span\",null,{\"className\":\"mt-1 block font-medium group-hover:text-accent\",\"children\":\"Google Business Profile\"}]]}]]}]\n14:[\"$\",\"p\",null,{\"className\":\"mt-8 flex items-center gap-1.5 text-xs text-faint\",\"children\":[[\"$\",\"svg\",null,{\"width\":12,\"height\":12,\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.8,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"aria-hidden\":true,\"className\":\"$undefined\",\"children\":[\"$\",\"path\",null,{\"d\":\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20V2H6.5A2.5 2.5 0 0 0 4 4.5v15zM4 19.5A2.5 2.5 0 0 0 6.5 22H20v-5\"}]}],\" This page is also available as\",\" \",[\"$\",\"a\",null,{\"href\":\"/docs/platforms/bluesky.md\",\"className\":\"underline hover:text-ink\",\"children\":\"Markdown\"}],\".\"]}]\n15:[\"$\",\"aside\",null,{\"className\":\"sticky top-[6.6rem] hidden h-[calc(100vh-6.6rem)] w-60 shrink-0 overflow-y-auto py-10 pr-6 xl:block\",\"children\":[\"$\",\"$L1a\",null,{\"headings\":[{\"id\":\"overview\",\"text\":\"Overview\",\"depth\":2},{\"id\":\"connect-the-account\",\"text\":\"Connect the account\",\"depth\":2},{\"id\":\"post-types-media-rules\",\"text\":\"Post types \u0026 media rules\",\"depth\":2},{\"id\":\"options\",\"text\":\"Options\",\"depth\":2},{\"id\":\"examples\",\"text\":\"Examples\",\"depth\":2},{\"id\":\"post-with-a-link-card-and-reply-limits\",\"text\":\"Post with a link card and reply limits\",\"depth\":3},{\"id\":\"images-with-alt-text-and-a-quote\",\"text\":\"Images with alt text and a quote\",\"depth\":3},{\"id\":\"analytics-comments\",\"text\":\"Analytics \u0026 comments\",\"depth\":2},{\"id\":\"limitations-common-errors\",\"text\":\"Limitations \u0026 common errors\",\"depth\":2}]}]}]\n17:[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]\nc:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n1b:I[27201,[\"/_next/static/chunks/2corl6wyj4669.js\"],\"IconMark\"]\n9:null\ne:[[\"$\",\"title\",\"0\",{\"children\":\"Bluesky · Relaycast Docs\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Post text, images, video, link cards and quote posts to Bluesky, connected with an app password.\"}],[\"$\",\"link\",\"2\",{\"rel\":\"canonical\",\"href\":\"/docs/platforms/bluesky\"}],[\"$\",\"link\",\"3\",{\"rel\":\"alternate\",\"type\":\"text/markdown\",\"href\":\"/docs/platforms/bluesky.md\"}],[\"$\",\"meta\",\"4\",{\"property\":\"og:title\",\"content\":\"Bluesky\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:description\",\"content\":\"Post text, images, video, link cards and quote posts to Bluesky, connected with an app password.\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:type\",\"content\":\"article\"}],[\"$\",\"meta\",\"7\",{\"name\":\"twitter:card\",\"content\":\"summary\"}],[\"$\",\"meta\",\"8\",{\"name\":\"twitter:title\",\"content\":\"Bluesky\"}],[\"$\",\"meta\",\"9\",{\"name\":\"twitter:description\",\"content\":\"Post text, images, video, link cards and quote posts to Bluesky, connected with an app password.\"}],[\"$\",\"link\",\"10\",{\"rel\":\"icon\",\"href\":\"/icon.svg?icon.31_gdxml59fk9.svg\",\"sizes\":\"any\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"11\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-icon.png?apple-icon.3vencszcqb-oc.png\",\"sizes\":\"180x180\",\"type\":\"image/png\"}],[\"$\",\"$L1b\",\"12\",{}]]\n"])</script></body></html>