One REST API for publishing, comments, media and analytics across 15 social platforms.
Unlimited connected accounts, no per-account charges. The API is closed. The tooling around it is open, and it is all here.
Docs • OpenAPI spec • MCP server • Get an API key • Status
npm install bundlesocialimport { Bundlesocial } from 'bundlesocial';
const bundle = new Bundlesocial(process.env.BUNDLE_SOCIAL_API_KEY!);
await bundle.post.postCreate({
requestBody: {
teamId: '<TEAM_ID>',
title: 'Hello world from bundle.social',
status: 'SCHEDULED',
postDate: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
socialAccountTypes: ['TWITTER', 'LINKEDIN', 'INSTAGRAM'],
data: {
TWITTER: { text: 'Hello world from bundle.social!' },
LINKEDIN: { text: 'Hello world from bundle.social!' },
INSTAGRAM: {
type: 'POST',
text: 'Hello world from bundle.social!',
uploadIds: ['<UPLOAD_ID>'],
},
},
},
});No SDK, no problem. Base URL https://api.bundle.social, everything under /api/v1, an x-api-key header, that is the whole contract:
# 0. Is anything on fire? This one needs no key.
curl https://api.bundle.social/api/v1
# 1. Which teams does this key own? teamId is the workspace every other call hangs off.
# Every id in the API - teams, uploads, posts, accounts - is a UUID v4.
curl https://api.bundle.social/api/v1/team \
-H "x-api-key: $BUNDLE_SOCIAL_API_KEY"
# 2. Schedule a post to the accounts connected to one of them.
# postDate is any ISO 8601 timestamp; status is DRAFT or SCHEDULED.
curl -X POST https://api.bundle.social/api/v1/post \
-H "x-api-key: $BUNDLE_SOCIAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"teamId": "<TEAM_ID>",
"title": "Hello from bundle.social",
"status": "SCHEDULED",
"postDate": "2027-01-15T15:00:00.000Z",
"socialAccountTypes": ["TWITTER"],
"data": { "TWITTER": { "text": "Hello from bundle.social" } }
}'Same request, same auth, same error contract for every one of them. You change one entry in socialAccountTypes, not one integration.
| Platform | socialAccountTypes value |
|---|---|
INSTAGRAM |
|
| TikTok | TIKTOK |
| YouTube | YOUTUBE |
FACEBOOK |
|
LINKEDIN |
|
| Twitter / X | TWITTER |
| Threads | THREADS |
| Snapchat | SNAPCHAT |
PINTEREST |
|
REDDIT |
|
| Bluesky | BLUESKY |
| Mastodon | MASTODON |
| Discord | DISCORD |
| Slack | SLACK |
| Google Business | GOOGLE_BUSINESS |
Note
The platform list and its enum values come from the socialAccountTypes enum in the published OpenAPI spec, which is the contract that decides what you can actually post to. If a README anywhere lags a platform behind, the enum is the contract.
One key, one base URL, 114 paths in the published spec. A sample of the surface:
| Area | Endpoints | Does |
|---|---|---|
| Publish | POST /api/v1/post · /post/{id}/retry · /post/reference-key/{key} |
Schedule or publish, per-platform overrides under data.<PLATFORM>, retries, your own idempotency key |
| Media | /upload · /upload/from-url · /upload/multipart/* |
Images, video and documents up to 5 GB, multipart or straight from a URL, transcoding handled |
| Accounts | /social-account/connect · /create-portal-link · /set-channel · /refresh-channels |
Hosted OAuth or your own UI, page/channel/location selection, token refresh you never see |
| Analytics | /analytics/social-account · /analytics/post · /analytics/post/bulk · /analytics/*/raw |
Normalized views, impressions, likes and demographics, plus the untouched platform payload |
| Comments | /comment · /comment/import · /comment/import/comments/{id}/action |
Auto first comments, comment import, moderation actions |
| Import | /post-history-import · /post-csv-import |
Backfill posts and analytics from before you connected; bulk-create from CSV |
| Platform extras | /misc/youtube/* · /misc/linkedin/* · /misc/reddit/* · /misc/google-business/* |
Edit and delete after publish, playlists, thumbnails, LinkedIn mentions, subreddit flairs, GBP hours and reviews |
| Plumbing | GET /api/v1 · /organization/usage/* · /team |
Live per-platform health, usage metering, teams as tenants |
Tip
Building multi-tenant? A team per customer is the pattern - accounts, posts and daily limits are scoped to a team, while API keys and webhooks are org-wide. Start at the API introduction. Prefer to generate your own client? The spec is public and complete.
| Package | Install | Version |
|---|---|---|
| Node.js SDK | npm install bundlesocial |
|
| CLI | npm install -g bundlesocial-cli |
|
| MCP server | npx bundlesocial-mcp |
The SDK is generated from the OpenAPI spec. Need Python, Go or anything else? Point your generator at the spec, or ask us.
Python quickstart, no SDK required
import os, requests
from datetime import datetime, timedelta, timezone
BASE = "https://api.bundle.social/api/v1"
HEADERS = {"x-api-key": os.environ["BUNDLE_SOCIAL_API_KEY"]}
post_date = (datetime.now(timezone.utc) + timedelta(hours=1)).isoformat()
r = requests.post(
f"{BASE}/post",
headers=HEADERS,
json={
"teamId": os.environ["BUNDLE_SOCIAL_TEAM_ID"],
"title": "Hello world from bundle.social",
"status": "SCHEDULED",
"postDate": post_date,
"socialAccountTypes": ["TWITTER", "LINKEDIN"],
"data": {
"TWITTER": {"text": "Hello world from bundle.social!"},
"LINKEDIN": {"text": "Hello world from bundle.social!"},
},
},
)
r.raise_for_status()
print(r.json())A runnable version lives in bundlesocial-examples/python.
| What | How |
|---|---|
| MCP server | npx bundlesocial-mcp - a local stdio server exposing the whole API as MCP tools, for Claude Code, Claude Desktop, Cursor and any other MCP client |
| CLI | npx bundlesocial-cli - JSON on stdout, human status on stderr, so it pipes into jq, into CI, into cron and into shell-out agents. Requires Node 20+ |
| MCP agent example | A working agent wired to the MCP server, ready to clone |
| Make.com | No-code TikTok workflow built on the REST API |
| Postman workspace | The whole API, importable, no local setup |
Runnable code, not pseudocode. The fastest way to see what the API can carry.
| Project | Stars | What it is |
|---|---|---|
| bundlesocial-examples | Every example below, one repo. Each directory is independent - clone it and run the one that matches your runtime | |
nextjs/ |
Full-stack SaaS integration: connect flow, composer, scheduling | |
express/ |
Node backend: server-side publishing and webhook handling | |
python/ |
Scripts and backend jobs straight against the REST API | |
mcp-agent/ |
An AI agent posting through the MCP server | |
cli-github/ |
CI/CD automation driving the CLI from GitHub Actions |
Also in this org
| Repo | What it is |
|---|---|
| bundlesocial-node | Source of the typed TypeScript SDK, generated from the OpenAPI spec |
| bundlesocial-docs | The MDX behind info.bundle.social. Typo in the docs? PR it here |
Anything not listed on this page is an experiment, a fork or an archive.
- Create an account and generate a key under API Keys in the dashboard.
export BUNDLE_SOCIAL_API_KEY=pk_live_...- Create a team, connect an account, paste either snippet above.
Connected accounts are unlimited on every plan, so step 3 never turns into a per-seat conversation.
Pricing · Changelog · Webhooks · Rate limits · Platform limits · Status
Bugs and feature requests go in the issue tracker of the relevant repo above.