Skip to main content

TypeScript SDK

Use the SDK when you control the TypeScript runtime and want the least abstraction between your app or agent and the platform publishers. The REST server, Scheduler app, CLI, and MCP server all build on this package.

Install​

The SDK is public on npm and does not require a GitHub token or custom package registry. Install it with your normal package manager:

npm install @simple-post/sdk
# or
yarn add @simple-post/sdk
# or
pnpm add @simple-post/sdk

Quick start​

Set TELEGRAM_BOT_TOKEN to your bot token and TELEGRAM_CHAT_ID to a channel username (such as @mychannel) or numeric chat ID. Add the bot to that chat with permission to post. The example passes the chat ID explicitly; the SDK does not load it automatically.

telegram-quickstart.ts
import { post } from "@simple-post/sdk";

const botToken = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;
if (!botToken || !chatId) throw new Error("Set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID");

const results = await post({
content: { text: "Hello from SimplePost" },
platforms: ["telegram"],
options: { telegram: { chatId, credentials: { botToken } } },
});

const result = results.get("telegram");
console.log(result);

A successful Telegram result contains the message ID and error: "NO_ERROR". post() returns a Map keyed by the requested platforms; inspect every result because multi-platform publishing can partially fail. See Telegram setup for bot creation and permissions.

The quickstart is checked against published SDK 1.3.3. Platform guides distinguish that release from newer hosted/core behavior; see release scope.

Posting model​

The SDK uses a Post payload. Other interfaces translate their own inputs into this model; REST account IDs and MCP message fields are not SDK fields. After configuring credentials for X, YouTube, and Instagram, plus public media storage:

await post({
content: {
text: "Check out this video",
media: [
{
type: "video",
path: "./video.mp4",
title: "Launch demo",
},
],
},
platforms: ["x", "youtube", "instagram"],
options: {
common: { logLevel: "info", strictMode: false },
youtube: { privacyStatus: "unlisted" },
},
});

Media can be a local path where the runtime can read the file, or a public url. Some platforms, especially Instagram and Threads, require public media URLs under the hood. SimplePost can upload temporary public media when storage is configured.

Provider setup​

SDK users usually manage provider credentials themselves. You can provide credentials in two ways:

  • Environment variables, which are convenient for local tools and single-account services.
  • options.<platform>.credentials, which is better when your app stores per-user OAuth tokens.

Start with the platform guide for each provider you want to post to:

PlatformKeyGuide
XxX setup
TelegramtelegramTelegram setup
InstagraminstagramInstagram setup
FacebookfacebookFacebook setup
ThreadsthreadsThreads setup
TikToktiktokTikTok setup
YouTubeyoutubeYouTube setup
PinterestpinterestPinterest setup
LinkedInlinkedinLinkedIn setup
BlueskyblueskyBluesky setup

Common patterns​

Text post​

await post({
content: { text: "Hey, this is a simple post" },
platforms: ["x", "facebook"],
});

Media post​

await post({
content: {
text: "Here are some photos",
media: [
{ type: "image", path: "./image1.jpg" },
{ type: "image", path: "./image2.jpg" },
],
},
platforms: ["x", "instagram"],
});

X reply or thread segment​

await post({
content: { text: "Great point." },
platforms: ["x"],
options: {
x: { replyToId: "1234567890" },
},
});

Telegram channel​

Telegram requires the chatId option for every post — it is not read from any env var. The bot token is read from TELEGRAM_BOT_TOKEN or supplied through options.telegram.credentials.botToken.

await post({
content: { text: "Hello Telegram" },
platforms: ["telegram"],
options: {
telegram: { chatId: "@mychannel", parseMode: "HTML" },
},
});

Strict mode​

By default, SimplePost adapts content to platform limits when it can. For example, a platform with a lower image limit may receive fewer images than another platform. Enable strict mode to fail instead:

await post({
content: { text: "Cross-platform post" },
platforms: ["x", "bluesky"],
options: {
common: { strictMode: true },
},
});

Token refresh​

Some OAuth providers rotate refresh tokens. X is the most important case: every successful X refresh returns a new refresh token and invalidates the old one. The SDK does not persist refreshed credentials for you. If a result contains extraData.refreshedCredentials, store those values before the next post.

const refreshed = results.get("x")?.extraData?.refreshedCredentials;

if (refreshed) {
await saveUserTokens(refreshed);
}

Examples​

The repository includes examples under core/examples, including:

  • examples/x/postThread.ts
  • examples/instagram/postCarousel.ts
  • examples/tiktok/postVideo.ts
  • examples/youtube/postVideoFull.ts
  • examples/all/postVideo.ts

Run examples from the core/examples workspace after setting the relevant provider credentials.

For video publishing, install FFmpeg so ffprobe is on PATH, or set an absolute FFPROBE_PATH. The SDK measures the file before uploading; failed inspection returns a validation error. See validation coverage.