For SaaS product teams

A social media API for the video your product creates

Postdom is a social media API for adding short-form video publishing to your SaaS. Your application supplies the finished video and chooses connected TikTok, Instagram Reels, YouTube Shorts, LinkedIn, Facebook Reels, X, Snapchat Spotlight, Threads, or Bluesky accounts. Postdom handles the publishing workflow and returns each destination’s outcome, so your product can show what happened instead of treating a submitted request as a live post.

Decide the fit first

Is this the right social media API for your product?

Choose Postdom when a finished short-form video is the thing your product needs to publish, and your UI needs to explain what happened afterward.

A fit for a video publishing feature

A product-tour tool, a video editor or a content-operations app can hand off an existing video, choose connected accounts, schedule it and read the result. Your backend can follow the workflow; an authorized agent can use MCP.

Keep each destination’s status visible. One video sent to several accounts does not mean all accounts publish successfully at the same time.

Check these needs before you commit

Postdom does not generate the video. Its supported destinations are TikTok, Instagram Reels, YouTube Shorts, LinkedIn, Facebook Reels, X, Snapchat Spotlight, Threads and Bluesky. Do not plan around a complete social inbox, arbitrary-account data collection or every native platform feature.

If your roadmap depends on a specific metric, visibility setting or content type, confirm that path in the destination guide before building the UI around it.

Postdom publishes to TikTok, Instagram Reels, YouTube Shorts, LinkedIn, Facebook Reels, X, Snapchat Spotlight, Threads and Bluesky. LinkedIn, Facebook Reels, X, Snapchat Spotlight, Threads, and Bluesky do not have a reference page yet, so they are not listed below.

Choose your caller

Use an SDK from your backend, or MCP from an agent

Choose the client that fits the service you already run. An installed package gives you a caller, not connected social accounts or permission to approve posts.

Node / edge

Use Node or an edge backend when your application owns the workflow.

npm install @postdom/sdk@0.1.0
@postdom/sdk on npm

Python

Use the Python package for a Python service. Follow its own client documentation.

pip install postdom==0.1.0
postdom on PyPI

MCP

Use MCP when an authorized AI client is calling Postdom tools.

npm install @postdom/mcp@0.3.0
@postdom/mcp on npm

These pinned packages are published releases. The example below uses Node SDK methods from that release. Check your installed version’s documentation before using newer repository examples. MCP tool reference →

Start with one reviewed video

Submit the video, save its ID, then read the post

This server-side Node example submits once and reads once. It uses a video URL your integration has already confirmed is accepted and fetchable; it does not demonstrate creating a new upload.

Before you run it

  1. Have a human connect the intended social account and set its publishing policy in the workspace. Use the account-connection guide for the OAuth handoff.
  2. Store a read/write workspace key in your backend environment. Inspect workspace status and choose the exact providerAccountId returned by the SDK’s listAccounts(); do not substitute a social handle.
  3. Set POSTDOM_ACCOUNT_ID to that chosen ID, FINISHED_VIDEO_URL to the accepted asset URL, and POSTDOM_JOB_KEY to your persistent key for this unchanged logical publish.

Node SDK example · mocked verification only

import { Postdom } from "@postdom/sdk";

function env(name) {
  const value = process.env[name];
  if (!value?.trim()) throw new Error("Set " + name + " first");
  return value;
}

const postdom = new Postdom({
  apiKey: env("POSTDOM_API_KEY")
});

const submitted = await postdom.publishVideo({
  accountIds: [env("POSTDOM_ACCOUNT_ID")],
  videoUrl: env("FINISHED_VIDEO_URL"),
  caption: "A quick tour of our new workspace.",
  intent: "Publish the reviewed product tour.",
  idempotencyKey: env("POSTDOM_JOB_KEY")
});

// Save submitted.id with your job before following the outcome.
console.log({ postId: submitted.id, status: submitted.status });

const post = await postdom.getPost(submitted.id);
console.log({
  postId: post.id,
  status: post.status,
  approvalFeedback: post.approval_feedback,
  destinations: post.publishes
});

Run in your backend after setting the environment values. The client defaults to https://api.postdom.com/v1. No token, customer video or authenticated publish was used to test this example.

Have an existing stored media handle? Supply mediaHandle instead of videoUrl, not both. Check the media’s status first.

Scheduling uses the SDK’s optional publishAt value with an explicit UTC timestamp; it does not grant approval. An approved plan may bound a request through planId. Check the returned authorization rather than assuming the plan was applied. Scheduling and plan behavior →

Design the response UI

Show the state you received, not a generic success toast

getPost(id) reads the current record. Look at status, approval_feedback and every item in publishes. Open a state below for the next action your application should offer.

draftReady for a human

Show the draft. A human can publish or schedule it; do not display it as sent.

requires_approvalWaiting for approval

Hand the request to its human reviewer. No provider request has been made at this state.

changes_requestedChanges requested

Show approval_feedback to the reviewer. The read does not revise or resubmit the post.

rejectedRejected

Show the decision. Do not retry the same rejected request as if it were a transient error.

missed_approvalApproval window missed

Return control to a human to publish or reschedule. Do not silently move the agreed time.

missed_scheduleSchedule missed

Show the missed schedule and return control to a human. Reading the post does not reschedule it.

scheduledScheduled

Display scheduled_for. Continue checking inside your job’s polling budget; the video is not yet published.

publishingPublishing

Keep the post ID and read destination states. A request in progress is not proof that all destinations are live.

publishedPublished

Show each destination’s evidence and public_url when present. Private visibility does not become public because this state says published.

partialSome destinations need attention

Show successful and failed destinations separately. Preserve error_code and error_detail; do not blindly resubmit the whole post.

failedPublishing failed

Show destination errors and any returned explanation. Investigate before a deliberate retry; a read does not retry the write.

blockedStopped by policy

This run was not submitted. Show the policy reason; publishing again requires a fresh request and authorization, not an automatic retry.

unknownSubmission outcome unknown

The provider may have received this run. Preserve its ID and evidence; do not retry while its outcome is being reconciled.

Destination states are separate: queued and sent are not published. Keep each destination’s nullable URL and error fields; do not invent a public link for a private or unfinished post. Read the post and destination response fields →

Bound the wait; keep the ID

The released SDK includes waitForPublish(id), but a waiting call can time out while a post still needs human action. Its resolution is not a blanket success signal: inspect the returned state and destinations. Choose a waiting budget that fits your own job.

For application callbacks, follow the current webhook documentation. Do not assume every method in the repository exists in the installed SDK.

Retry the same request deliberately

Keep the same idempotency key for retries of one unchanged logical write. A new key is a new submission opportunity. If a request times out, read an already-known post ID before deciding whether to send again.

For partial results, preserve successful destinations and the failed destination’s error. Idempotency is not an exactly-once delivery guarantee. Read error and retry guidance →

Before onboarding customers

Map your users to the right workspace and accounts

Keep the workspace key on your backend. Associate each application tenant and publish job with the workspace and connected account IDs it is allowed to use. Validate that mapping before submitting; an account label in your UI is not authorization.

Read/write API access does not unlock human-only actions. Account OAuth consent, approvals, billing and dashboard administration stay with people. Return a clear human handoff when the workflow needs one.

Check current product availability and pricing before committing to your account model. This page does not promise automatic tenant provisioning, unrestricted white-label access or a service-level agreement.

Media and measurement

Check the asset and the fields your UI needs

A file that fits a product ceiling still needs to satisfy each destination’s video requirements. Keep those checks separate from your API request’s status.

Postdom media limits

One file
500 MiB
MIME types
video/mp4 · video/quicktime
Upload requests
20/hour
Upload volume
2000 MiB/hour

The hourly budgets apply to the workspace’s media-upload operation, not every API call. No general requests-per-minute allowance or uptime guarantee is specified here.

Limit scope and verification dates

File-size record: . MIME-type record: . The hourly budget constants have no separate verification timestamp; neither date verifies them.

The upload operation is POST /v1/media/uploads. These limits do not certify the fresh-upload path in the pinned packages; the example uses an existing accepted asset. A newer repository implementation is not proof that an installed release includes it.

Measure what is actually present

For an existing post, the SDK’s getPostPerformance(id) reads normalized snapshots. Keep each value beside its availability and capture time.

A null metric is missing, not zero. Leave it out of numeric rankings. An available field still needs a usable snapshot; publishing a video does not guarantee every metric will appear.

Check destination metric coverage →

Common integration questions

Access, outcomes and next steps

What does a social media API do?

A social media API lets software request actions or read data from social accounts. Postdom focuses on publishing supplied short-form videos, scheduling them and reading their outcomes across TikTok, Instagram Reels, YouTube Shorts, LinkedIn, Facebook Reels, X, Snapchat Spotlight, Threads and Bluesky. It is not a video generator or a complete replacement for every native platform feature.

Should I use the SDK or MCP?

Use the Node or Python SDK when your backend controls the workflow. Use MCP when an authorized AI client calls Postdom tools. Both need workspace access and connected accounts; neither gives the caller human approval authority. Match examples to the package version you install.

Will the SDK example make my video public?

Not by default. The Node publishVideo helper and MCP publish_video tool use TikTok SELF_ONLY and YouTube private settings, and mark the supplied content as AI-generated on TikTok, Instagram Reels and YouTube Shorts. Instagram uses a Reel with AI disclosure rather than a private-visibility setting. LinkedIn is sent no settings at all, so no disclosure is set for it. Facebook Reels receives only the fixed Reel format, and X, Snapchat Spotlight and Threads receive nothing; none of the four carries an AI-disclosure field, Snapchat requires a Public Profile on the account, Threads takes its audience from whether the profile is public or private, and every Bluesky post is public because the post record carries no visibility field. Confirm that those defaults match the reviewed content and intended audience before calling them.

How should I handle a successful submission?

Save the returned id and read the post. Submission is not publication: the post may need review, be scheduled or still be publishing. Show per-destination publishes and errors. A partial outcome must not become a blanket success message.

Can I safely retry a publish?

Keep one idempotency key for the same logical write, including retries of that unchanged request. Save a returned post ID and read it before deciding to submit again. A timeout does not prove nothing happened, and idempotency is not an exactly-once delivery promise.

Can a workspace key approve posts or connect accounts without a person?

No. Account OAuth consent, approvals, billing and dashboard administration remain human-controlled. A read/write key does not grant those permissions. Keep keys on your backend, use the account IDs returned for that workspace, and return the human handoff when required.

Are all analytics fields available?

No. Read each measurement with its availability record and capture time. Null means missing, not zero; an available field still needs a usable snapshot. Follow the destination coverage reference before offering a metric in your own reporting UI.

Start with the outcome your app needs to show

Connect the intended account, review the asset and test one authorized publish in your own workspace. Save the post ID and make approval, progress and failures visible before expanding the workflow.

Talk to us

Not sure where to start? Let's talk.

Tell us what your product already does for publishing and we will show you what Postdom does and does not do, against your own workflow rather than a demo account.

  • TikTok, Instagram Reels, YouTube Shorts, LinkedIn, Facebook Reels, X, Snapchat Spotlight, Threads and Bluesky — the destinations Postdom publishes to today, and no others.
  • A permanent Free plan — you can start without talking to anyone, and this offer is for when you would rather not.
  • Human approval built in — an agent cannot approve its own work or widen its own authority.

Book a demo

Tell us about your setup.

All fields are required.

Sent to support@postdom.com. Do not include passwords, agent keys, OAuth tokens, or payment-card details. Read the Privacy Policy.