Skip to content

Post.publish

Put a Post live from your own LinkedIn, X, Reddit or Product Hunt account.

Action class
publish
Approval
Publishes on its own
Emits
Post.published
Sites
9 sites
Price
Free
POST https://api.sb/{your-domain}/posts/publish

Puts a Post live from your own account on one site, once every claim it makes reads from a live record. The hub’s definition of Post.publish.

Inputs

NameTypeDefaultMeaning
postPostRequiredThe Post to publish.

Outputs

FieldTypeWhat null means
postPostNever null.
post.statusstringNever null: published once the network confirms the Post is live.
post.handleHandleNever null: the account it went out from.
post.formatstringNever null: the network’s format, such as a text post, a thread or a launch.
post.outsidejsonNull in try mode and until the network returns its own id for the Post.
post.reachinteger, in peopleNull until the network reports a first reading; Metric.query reads it over time.

Effects

Action class

publish: an approval rule on publish can make it wait for your OK

Modes
  • try: Runs every check the publish meets and returns the Post as the network would show it; nothing is posted or stored.
  • send: Returns a pending Action at once; Post.published fires when the network confirms the Post is live.
  • do: Holds the call for the Mode’s hold time, then returns 202 with the pending Action while its delay window runs.
Idempotency

Only with a key: the same Idempotency-Key and input return the first Action, and the same key with other input returns 409. A Post that already holds the network’s id in outside is never posted twice: a repeat returns it as it stands.

Saved or shared

The Post keeps the network’s id and, as the network reports them, its reach and replies. Each reply arrives as a Message threaded to the Post.

Emits

Post.published with { post, handle, venue, outside, publishAt }

Performed by

Content lead

Price

Free on your own account: the platform charges nothing for the call.

Standing approval

It goes out on its own, inside the Limits of your standing approval: a Mandate granted with Mandate.authorize. One approval rule makes it wait for your OK.

On each Venue

SiteFieldsFormats
Facebookbody, link1
Google Business Profilebody, link, mediaNone.
Hacker Newstitle, link, body2
Instagrambody, format, media4
LinkedInbody, media, handle, status3
Reddittitle, body, handle3
TikTokbody, status2
Xbody, media, format2
YouTubetitle, body, tags, status1

Facebook

Through Facebook.

Our fieldFacebook’s field
Post.bodymessage
Post.linklink
  • Your role on the page. Posting needs a role that can post; a role removed in Meta’s settings ends the connection with needs-reauth.
Feed image ad, 1440 × 1800, 4:5

Google Business Profile

Through Google Business Profile.

Our fieldGoogle Business Profile’s field
Post.bodylocalPost.summary
Post.linklocalPost.callToAction.url
Post.medialocalPost.media
  • A new profile. Shows nothing your agents post until Google verifies it.

Hacker News

Through Hacker News.

Our fieldHacker News’s field
Post.titletitle (Begins “Show HN:” and runs at most 80 characters)
Post.linkurl (The page a visitor can try at once)
Post.bodyfirst comment (How you built it and what you want to hear, posted as the first comment)
  • What goes up as a Show HN. Something people can try, ideally with no signup or email; a page that only collects addresses goes up as a regular post.
  • Votes. Your agent never asks anyone to upvote or comment, on Hacker News or off it.
  • A second Show HN. Only after a real change to the product, never the same title again.
  • Launch-day replies. The agent drafts a reply to every comment within 15 minutes for the first 6 hours, and posts it under your standing approval.
Show HN Comment

Instagram

Through Instagram.

Our fieldInstagram’s field
Post.bodycaption (2,200 characters, 30 hashtags, 20 mentions)
Post.formatmedia_type (IMAGE, CAROUSEL, REELS or STORIES)
Post.mediaimage_url or video_url (A carousel holds up to 20 items, cropped to the first one’s ratio)
  • Posts through the API. 50 in a moving 24 hours, and a carousel counts as one; the agent reads what is left before each post.
  • Account type. A professional account; a personal account refuses with account-not-connected until it switches.
Feed image, 320 to 1,440 pixels wide, 4:5 to 1.91:1 Carousel Reel, 9:16 Story, 9:16

LinkedIn

Through LinkedIn.

Our fieldLinkedIn’s field
Post.bodycommentary (Mentions and hashtags keep LinkedIn’s own annotation format)
Post.mediacontent.media.id (An image, video or document is uploaded first and posted by its URN)
Post.handleauthor (urn:li:person for you, urn:li:organization for your page)
Post.statuslifecycleState (Always PUBLISHED on create; a scheduled Post is held by the platform and published at its time)
  • Replies. Read from your LinkedIn inbox every 30 minutes on weekdays, since LinkedIn sends no webhook for member messages.
  • Company page posts. Need your administrator or content admin role on the page.
Feed post Single image ad, 1200 × 628, 1200 × 1200 or 720 × 900 Document ad

Reddit

Through Reddit.

Our fieldReddit’s field
Post.titletitle (300 characters; a comment has none)
Post.bodybody or comment text
Post.handlesubreddit or parent post
  • Before each post. The agent rereads the subreddit’s sidebar and pinned posts and drafts to fit them; a post the moderators remove returns venue-rejected with their reason.
  • A new account. Posts help-only answers for its first 2 to 4 weeks in a community; mentions of your product wait until it has history there.
  • Mentions. At most 1 answer in 4 names your product, and only in subreddits that welcome it.
  • Pace. 10 answers a week across your subreddits, each within 6 hours of the post.
  • Removals. The agent checks each post signed out every week; a removed post becomes Post.withdrawn with the reason it can read.
Text or link post Comment Promoted post

TikTok

Through TikTok.

Our fieldTikTok’s field
Post.bodypost_info.title (The caption: 2,200 characters, hashtags included)
Post.statusprivacy_level (One of the options your account reports; PUBLIC_TO_EVERYONE when the browser agent posts)
  • Public posts. Each clip reaches your TikTok inbox by API, and the browser agent presses Post as you, so it goes public on your account.
  • Posts a day. TikTok caps posts a day per creator; past it a post refuses with quota-reached and runs the next day.
Video Spark Ad

X

Through X account.

Our fieldX account’s field
Post.bodytext (280 weighted characters; a link counts as 23 wherever it points)
Post.mediamedia.media_ids (Up to 4 images, or 1 GIF, or 1 video, uploaded first)
Post.formatreply.in_reply_to_tweet_id (A thread is a chain of posts, each replying to the last)
  • Each post or reply. X bills 1.5¢ through its API, and 20¢ when the text carries a link; the price shows before the call runs.
  • Monthly spend. Your standing approval holds the month’s X spend; a post past it waits with over-mandate.
  • Replies to strangers. Only to posts that describe your problem, and never twice in one thread without an answer back.
Standard post Promoted post

YouTube

Through YouTube.

Our fieldYouTube’s field
Post.titlesnippet.title (100 characters, no < or >)
Post.bodysnippet.description (5,000 bytes, so accented letters count double)
Post.tagssnippet.tags (500 characters in all, commas included)
Post.statusstatus.privacyStatus (public, unlisted or private; public when none is set)
  • Upload quota. YouTube meters uploads a day; an upload past the day’s quota refuses with quota-reached and runs after the reset at midnight Pacific.
  • Custom thumbnails and videos over 15 minutes. Need a verified channel; the agent checks before it uploads and says which step is missing.
  • Comments. Read every 30 minutes, since YouTube sends no webhook for comments.
Video

What try does

AccountWhat try does
FacebookReturns the post as your page will show it, with the time it goes live; nothing is posted or scheduled.
Google Business ProfileReturns the update or the answer as it will show on your profile; nothing posts.
Hacker NewsReturns the title, the link and the first comment as Hacker News will show them, checked for the Show HN prefix, the 80-character title and a link people can try; nothing posts.
InstagramChecks each image and video against Instagram’s specs and returns the post as it will show; no container is staged and nothing publishes.
LinkedInPosts render as LinkedIn will show them and nothing is sent; requests and messages return each person, the note and the day it goes, and no browser session opens.
RedditReturns the answer as Reddit will show it, fitted to the subreddit’s sidebar and pinned posts, with the steps the browser agent would take; no session opens and nothing posts.
TikTokChecks the clip and caption against what your account reports it allows, and returns the post as it will show; nothing reaches your inbox.
X accountRenders each post at X’s weighted count, with links at 23 characters, and returns the price X would bill; nothing is posted and nothing is billed.
YouTubeChecks the file, title, description and tags against YouTube’s limits and returns the video page as it will read; nothing uploads and no quota is spent.

Refuses when

CheckErrorFixThen call
A Post with a claim that resolves to no live recordclaims-resolveCut the claim, or name the record that backs it.Content.draft

Every call through an account can also meet the shared account refusals: grant-missing, needs-reauth, account-not-connected, over-mandate, quota-reached, venue-rejected.

The claims-resolve payload
JSON
{
  "type": "https://startupbuilder.dev/errors/claims-resolve",
  "title": "Claim with no record",
  "status": 422,
  "detail": "A Post with a claim that resolves to no live record.",
  "fix": "Cut the claim, or name the record that backs it.",
  "next": {
    "verb": "Content.draft",
    "input": {}
  },
  "instance": "https://api.sb/leaseline.app/actions/action_1"
}

When it waits

FactValue
send returnsA pending Action, reason: 'awaitingTime' while its delay window runs, then running until the network returns the Post’s id.
Delivered byPost.published

Example

Text
Publish my post about the renewal-notice checklist from my LinkedIn.

To retry, send the same Idempotency-Key: the retry returns the first answer for $0. A new key reads again.

Test values

A sk_test_ key answers these the same way every time, at $0 (every test value).

Test valueAlways returnsWhat it is for
post_test_published{"status":"published","outside":{"linkedin":"urn:li:share:7000000000000000001"}}Publishes to a test account and returns the same network id every time, so your agent’s follow-up steps run.
post_test_unresolvedRefuses with claims-resolveIts one claim names no live record, so the publish refuses before anything reaches the network.
post_test_removedRefuses with venue-rejectedThe network takes the Post down as it goes live, and its reason comes back in detail, so your removal path runs.
maxCost: 0.0001Refuses with max-costAny priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap.
rate-limited.testRefuses with rate-limitedAny call naming this hostname answers 429 with Retry-After, so your retry logic runs.
sources-busy.testRefuses with sources-busyAny call naming this hostname answers 503 as if every route were busy, and nothing is spent.

Used by