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 package is distributed from GitHub Packages. Create a GitHub personal access token with read:packages, expose it as GITHUB_TOKEN, and configure your package manager.

For npm, pnpm, and Yarn v1, add this to .npmrc:

@simple-post:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

For Yarn v2+:

npmScopes:
simple-post:
npmRegistryServer: "https://npm.pkg.github.com"
npmAuthToken: "${GITHUB_TOKEN}"

Then install:

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

Quick start

import { post } from "@simple-post/sdk";

const results = await post({
content: {
text: "Hello from SimplePost",
media: [{ type: "image", url: "https://cdn.example.com/image.jpg" }],
},
platforms: ["x", "telegram", "linkedin"],
});

console.log(results);

The result is returned per platform. Partial failures are visible, so inspect the whole map instead of assuming a multi-platform post is all-or-nothing.

Map(2) {
"x" => { id: "1947334111111111111", error: "NO_ERROR" },
"facebook" => { id: "1234567890", error: "NO_ERROR" }
}

Posting model

The SDK accepts the same content shape used by every other SimplePost interface:

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", "instagram"],
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.