Supported Platforms
Connect channels in the Schedulin dashboard, then post to any of them through the API. Each
channel's platform (from GET /v0/social-accounts) is one of the slugs below.
curl https://api.schedulin.app/v0/platforms \ -H "x-api-key: $SCHEDULIN_API_KEY"
Platforms
| Platform | platform | Caption limit | Media | platformConfiguration |
|---|---|---|---|---|
| X (Twitter) | twitter | 25,000 | — | Optional |
instagram | 2,200 | 1–10 images/videos | Optional | |
facebook | 63,206 | Up to 10 images/videos | Optional | |
linkedin | 3,000 | Up to 20 (a video or document goes alone) | Optional | |
| Threads | threads | 500 (emojis count by UTF-8 bytes) | Up to 20 images/videos | Optional |
| TikTok | tiktok | 2,200 | 1–35 images/videos | Optional (defaults applied) |
| YouTube | youtube | 5,000 | Exactly 1 video | Required |
pinterest | 800 | 1–5 images/videos | Required | |
reddit | 40,000 | Up to 20 images/videos | Required | |
| Bluesky | bluesky | 300 graphemes | Up to 4 images or 1 video | Optional |
| Mastodon | mastodon | 500 | Up to 4 images/videos | Optional |
| Telegram | telegram | 4,096 (1,024 with media) | Up to 10 images/videos | Optional |
| Discord | discord | 1,980 | Up to 10 | Required (channel) |
| Slack | slack | 100,000 | — | Required (channel) |
| Twitch | twitch | 500 | — | Optional |
| Kick | kick | 500 | — | Optional |
| DEV.to | devto | 100,000 | — | Required (title) |
| Hashnode | hashnode | 10,000 | — | Required (title, publication_id) |
| WordPress | wordpress | 100,000 | — | Required (title) |
| Dribbble | dribbble | 40,000 | Exactly 1 image | Required |
| Whop | whop | 50,000 | — | Required |
In the Media column, "—" means the API enforces no media count rule up front; the platform's own limits still apply at publish time (Twitch and Kick, for example, post chat messages, so media isn't used).
This table lists the generally available platforms. The platform enum in the API reference
(and the response of GET /v0/platforms) is longer: it also includes beta and not-yet-released
platforms such as snapchat, lemmy, nostr, or farcaster. A slug being in the
enum doesn't mean you can connect it. Only post to channels that GET /v0/social-accounts
actually returns.
Omitting a required platformConfiguration returns 400 (platformConfiguration is required for <platform>); an invalid one returns 400 listing the offending fields.
Drafts (action: "draft") only need a caption or at least one media file. Platform rules
(caption limit, media rules, platformConfiguration) are checked when the draft is scheduled
or published — POST /v0/posts/{id}/publish, a PUT that sets status to SCHEDULED or
PROCESSING, or adding it to the queue — and that request returns 400 if the post doesn't
pass.
Required settings
YouTube
{ "title": "How we schedule 1,000 posts a day", "categoryId": "28", "visibility": "public" }
visibility is public, unlisted, or private. Optional fields include tags,
madeForKids, notifySubscribers, publishAt, and containsSyntheticMedia.
{ "board_ids": ["1234567890"], "title": "Spring lookbook", "link": "https://example.com" }
A board is required — pass board_ids (or a single boardId). List the channel's boards
with GET /v0/social-accounts/{id}/pinterest-boards. Optional: board_section_id, title,
description, link, alt_text.
{ "subreddit": "programming", "title": "We open-sourced our scheduler" }
Optional: flair_id / flair_text, nsfw, spoiler, sendreplies, and link_url for a
link post. Subreddit rules (required flair, allowed post types) are checked before
publishing.
Discord and Slack
{ "channel": "123456789012345678" }
Discord and Slack posts go to one channel, so channel (the channel id) is required. A post
without it is rejected with 400, like any other missing required configuration.
List the channels the account's bot can post in, then pass one id. The list only includes
channels the bot is allowed to send messages to — a channel that's missing usually means the
bot lacks permission there (add it to the channel, or grant it Send Messages in Discord):
curl https://api.schedulin.app/v0/social-accounts/acc_123/discord-channels \ -H "x-api-key: $SCHEDULIN_API_KEY" # Slack: /v0/social-accounts/{id}/slack-channels
{ "items": [{ "id": "123456789012345678", "name": "announcements" }] }
In the SDKs these are socialAccounts.listDiscordChannels / listSlackChannels
(social_accounts.list_discord_channels / list_slack_channels in Python). OAuth apps need
the social-accounts:read scope. From the CLI, use schedulin accounts discord-channels <id>
or schedulin accounts slack-channels <id>, and posts create --channel <id> sets the field
for you.
Dribbble
{ "title": "Dashboard redesign" }
The image must be 400×300, 800×600, or 1600×1200.
Whop
{ "experience": "exp_XXXXXXXX" }
experience is the forum to post in. Find it with
GET /v0/social-accounts/{id}/whop-companies, then
GET /v0/social-accounts/{id}/whop-forums?companyId=....
Common optional settings
TikTok
Every field has a default, so platformConfiguration can be omitted. Before posting, call
GET /v0/social-accounts/{id}/tiktok-creator-info (CLI: schedulin accounts tiktok-info <id>)
to get the privacy levels the account allows and its maximum video duration:
{ "data": { "creator_username": "yourbrand", "privacy_level_options": ["FOLLOWER_OF_CREATOR", "MUTUAL_FOLLOW_FRIENDS", "SELF_ONLY"], "max_video_post_duration_sec": 600, "...": "..." }, "error": { "code": "ok", "message": "", "log_id": "…" } }
TikTok always includes the error object; "code": "ok" means the call succeeded.
Set privacy_status to one of that account's privacy_level_options. TikTok rejects a
privacy level the account doesn't offer. In the example above PUBLIC_TO_EVERYONE isn't
listed, so a public post would fail.
{ "privacy_status": "FOLLOWER_OF_CREATOR", "allow_comment": true, "allow_duet": true, "allow_stitch": true, "is_ai_generated": false }
privacy_status accepts TikTok's values as-is (PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS,
FOLLOWER_OF_CREATOR, SELF_ONLY) plus lowercase shorthands that map onto them:
| Shorthand | Sent to TikTok as |
|---|---|
public (the default) | PUBLIC_TO_EVERYONE |
friends, mutual_follow_friends | MUTUAL_FOLLOW_FRIENDS |
follower_of_creator | FOLLOWER_OF_CREATOR |
private, self_only | SELF_ONLY |
Because the default is public, omitting platformConfiguration only works for accounts
whose options include PUBLIC_TO_EVERYONE.
Other fields: disclose_your_brand, disclose_branded_content, auto_add_music,
and photo_cover_index (photo posts).
Set is_draft: true for TikTok's Upload mode. The post isn't published: TikTok sends the
media to the creator's TikTok inbox, where they finish and post it in the app (within 24
hours). TikTok ignores the privacy and interaction settings in this mode. The post still
reaches COMPLETED, with externalId: null and url pointing at the TikTok inbox.
placement is reels (default), feed, or stories. Also: first_comment,
collaborators, share_to_feed, location, trial_reel_type.
placement is feed (default), reels, or stories. Also: first_comment, location.
X (Twitter)
poll ({ "options": [...], "duration_minutes": 1440 }), reply_settings,
quote_tweet_id, in_reply_to_tweet_id, and community_id. For threads, use the post's
parts array — see Create a thread.
Caption length: GET /v0/platforms reports captionMaxLength: 25000 for X. That's X
Premium's long-post limit, and it applies to the top-level caption and to each part inside
parts. Accounts without Premium are still held to X's 280-character limit, which X enforces
when the post publishes.
Keep X captions within what the account allows, or split them into a thread.
visibility (PUBLIC by default), first_comment, poll, and article (link preview).
Posts publish from the connected member's personal profile — posting as a Company Page isn't
supported, and author_kind: "organization" is rejected.
Threads
reply_control, topic_tag, poll, quote_post_id, link_attachment.
Bluesky
langs, labels, external (link card), quote_post_uri, reply_to, threadgate,
postgate.
Telegram
disable_link_preview, disable_notification.
See GET /v0/platforms for each platform's full schema.