Changelog
What shipped
Every change that reached you, newest first. Things that are still open pull requests are not on this list.
#175 #176 #177 #178 #179 #180 #181 #182 #183 #184 #185
- Tags have a real charset now: 1 to 40 lowercase letters, digits, dashes, underscores, colons, dots and slashes. A tag you send is lowercased and trimmed before it is checked, so
cms:Launchandcms:launchare the same tag; anything else is400 invalid_request. - Queues can be paused.
PATCH /connections/{connectionId}/queuewith{ "paused": true }holds every queued post where it is until you resume it; resuming moves anything that fell overdue onto the connection's next free slot, one at a time, so a backlog never bursts out at once. The endpoint is strict now too: an unknown field in the body is400 invalid_requestinstead of being silently ignored. - Copy a connection's queue slots to other accounts in one action, instead of re-entering the same weekly schedule by hand for each one.
- Refusals clear themselves. A refusal that was really about a dead login (
reconnect_required), a platform outage (platform_unavailable), or a send that never confirmed (send_interrupted) now disappears from the account's warnings on its own once the account reconnects or the platform recovers, and it names the account it is about. - New accounts get a welcome message in their own language.
#146 #147 #148 #149 #150 #151 #152 #153 #154 #155 #156 #157 #158 #159 #160 #161 #162 #163 #164 #165 #166 #167 #168 #169 #170 #171 #172 #173 #174
- Reconnecting a broken login is obvious now. LinkedIn, X, Facebook, Instagram, Discord and the rest tell you before a login expires and show a Reconnect button on the card. Reconnecting just says Reconnected, and for a customer's account you can send them a reconnect link instead.
- Failures are recorded and explained, not swallowed. A failed post keeps its reason in plain words with a retry button, a platform that is only busy or down is safe to resend, and a dead webhook or bot now asks you to reconnect instead of failing forever.
- Writing a post got a real composer: one consistent design, a fix-before-resend step so a bad post never goes out twice, and an optional AI polish that uses your own Claude or OpenAI key to adjust the tone before you send.
- Connections are easier to manage. Customer-facing connect links come first, Facebook and Instagram page pickers refresh properly on reconnect, Reddit asks for your subreddit up front, and picking your LinkedIn profile and pages happens once, after a single login.
- Billing is clearer: you can see exactly which accounts are billed, only active connections are charged, VAT shows at checkout.
- Dozens of smaller fixes across the app: a working slot editor, a full-width queue calendar, a posts list that fits the page and scrolls, forgiving CSV import, working invites, and phone screens that finally fit.
#90 #91 #92 #93 #94 #95 #96 #97 #98
- Analytics. Once a post is out, yeetpost reads its numbers back off the platform and keeps every read: an hour after it goes out, then hourly for 48 hours, then daily until it is 30 days old.
GET /posts/{postId}/metricsgives you the latest read and the whole history,GET /analytics?from&togives totals, a per-day series and a per-platform split, and apost.metricswebhook fires once a post per day while the numbers are still moving. MCPget_postcarriesmetrics.latesttoo. - What each platform reports is not the same, and the API says so rather than guessing. A number a platform does not report is
null, never0. Bluesky and Mastodon report likes, reposts and replies. LinkedIn reports reactions and comments from any account, and impressions and clicks only for a company page, because that is the only surface LinkedIn answers statistics for. Discord, Telegram, Slack, SMS and email report nothing back at all. - X reads are metered, at 1 cent a read on the same monthly X spend cap as the post fees, because X charges for reads. That price is a placeholder, so X analytics is off by default: X posts are not read unless the deployment turns it on. Everything else in analytics works today and is free.
- The key management API. Minting a key for a customer stops being a dashboard errand:
POST /profiles/{profileId}/keysmints one scoped to that profile and answers the secret once,GET /profiles/{profileId}/keysandGET /keyslist keys by prefix, andDELETE /profiles/{profileId}/keys/{keyId}andDELETE /keys/{keyId}revoke. Only an unscoped key may use them, a test key mints and manages test keys only, a key minted here is always scoped to the profile in the path, and 50 live plus 50 test keys per profile is the cap. Revoking takes effect on the next request across REST, MCP and connect URLs. - Connect an MCP client with a login. Add
https://api.yeetpost.com/api/v2/mcpas a custom connector in claude.ai with no key: it discovers the authorization server, registers itself, opens a consent screen where you sign in, pick your whole account or one profile, pick live or test, and approve. yeetpost runs the OAuth 2.1 server behind that (RFC 9728 and RFC 8414 discovery, RFC 7591 registration, PKCE required, rotating refresh tokens, reuse detection). A grant is scoped and paced exactly like a key, the apps you approved are listed on the MCP screen in the console, and revoking one there kills its tokens at their next request. Clients that can hold a key keep using a key, and REST stays key-only. - Team members. An account is now a thing several people can share. Invite by email, and each member is an owner, an admin or a member: owners do everything including billing and deleting the account, admins do everything except those, members post and read and manage connections and profiles but cannot touch keys, members or billing. A user can belong to several accounts and switch between them in the sidebar. Billing does not change: every account has one owner and one bill.
- The console got a dashboard worth looking at. Posts have grid, list and calendar views, with the list as the default and 30 rows at a time; a Queues screen draws a week of every connection's slots with the queued posts on them; CSV import parses the file in your browser and shows every row before anything is sent; and an Analytics screen draws the numbers above with a 7, 30 or 90 day window.
- The console also has a dark mode now, on a sun and moon toggle in the sidebar, following your system until you pick.
- These docs are regenerated from the OpenAPI spec: 38 endpoints, including the five key management endpoints, the two analytics endpoints and the
post.metricswebhook event. - Still unpublished: the CLI in
[email protected]is not on npm, and the Node, Python and Go SDKs are not on npm, PyPI or reachable bygo get. The API, the MCP server and the console are the ways in today.
#53 #54 #55 #56 #57 #58 #60 #61 #62 #63 #64 #66 #67 #68 #69 #71 #72 #74 #75
- Discord channels are live. Create a webhook in the channel, paste the url, and posts land there under the name and avatar you gave it. 2000 characters, up to five images with alt text, no threads.
- Telegram channels are live. Make your own BotFather bot an admin of the channel and paste the token. 4096 characters, 1024 when an image is attached, png and jpeg only, threads and photo albums.
- Mastodon is live, on any instance. Type the host, approve on your own server. The character limit is your instance's own, read when you connect, and a thread rolls back if one segment is refused.
- All three are free to post to and count as one connected account each, like LinkedIn and Bluesky. Six platforms are live now, and every one has its own docs page: how to connect, what works, and the refusal you get when it does not.
- A
yeetpostCLI, and a Claude Code plugin that installs the MCP server for you. Written and merged; npm publishing next, so neither is installable from a package registry yet. - A Go SDK, hand written against the v2 API like the Node and Python ones. Written and merged; publishing next, so
go getdoes not reach it yet. - Webhooks got serious. Every delivery carries
x-yeetpost-event-idso you can dedupe, retries run 7 attempts on a backoff (1m, 5m, 30m, 2h, 6h, 12h, 24h) and then land in a dead letter state instead of disappearing, and you can replay any delivery from the console or the API. - Posting queues. Give a connection a set of daily slots and a timezone, and a post without a time goes into the next free slot instead of straight out.
- Profiles. If you are building on yeetpost and posting for your own customers, create a profile per customer, connect their accounts into it, and post with
profileId. A post that names a profile cannot reach anything outside it, connections and posts each carry their ownprofileId, and two new webhook events,connection.createdandconnection.removed, tell you when a customer's account arrives or goes. Billing does not change: every connection counts on the same per-account ladder and you get one invoice. The guide is at/docs/build-a-platform. - Hosted connect URLs.
POST /profiles/{profileId}/connectgives you a link to a page we host. Send your customer there, they connect their own account into that profile, and they land back on yourredirectUrlwith the connection id in the query. The token in the url is the whole authorization: one profile, one redirect, one use, fifteen minutes, and only its hash is stored.headless: truedrops our header and footer so the page sits inside your own popup,GET /connect-sessions/{id}says how it went if you would rather poll than read the query, andconnection.creatednow carriesconnectSessionIdso a receiver can file the connection without a browser. A test key offers the sandbox and nothing else, so the whole flow runs in CI. - Scoped API keys. Pick a customer under Scope when you create a key and that key can only ever reach that one profile: its connections, posts, media and webhooks, and nothing else. Anything outside is
404, managing profiles is the new403 forbidden, and anIdempotency-Keyis reserved inside the scope, so two of your customers can both sendorder-123on the same day. A key can also carry a list of origins its connect URLs may redirect to. Deleting a profile revokes the keys scoped to it in the same transaction that disconnects the accounts. Keys are minted in the dashboard: public key-management endpoints are next. - Delete a published post, not just cancel a scheduled one.
DELETE /posts/{postId}now takes it down on X, Bluesky, Mastodon, Telegram, Discord and LinkedIn, and fires apost.deletedwebhook. Platforms with no delete answerdelete_unsupportedand say so. - Drafts and tags.
POST /postscan store a post instead of sending it,PATCH /posts/{postId}edits it, andPOST /posts/{postId}/publishsends it under the id you already have. Tag a post on the way in and filter your history by tag on the way out. - Health and uptime.
GET /healthandGET /health/historyare public, no key needed, and report the API and every worker. The new status page reads them and shows 90 days of daily uptime, with days before sampling began marked unmeasured rather than down. - The Node, Python and Go SDKs and the CLI are all at parity with the v2 API now: images, shapes, drafts, tags, queues, profiles, connect sessions, health and the webhook signature check. Every one of them can create a profile, ask for a connect URL and read the session back. Said plainly: none of them is published. They are not on npm, not on PyPI and not reachable by
go get, so the API itself is still the way in. - The OpenAPI spec got a hygiene pass, and these docs are regenerated from it: every error code is in the enum and in the description, every code has a real example, and the three outcomes of
DELETE /posts/{postId}are titled rather than numbered.
#31 #46 #48 #49 #50 #51
- Images. Upload one with
POST /media, get an id back, attach it to a post by id. Delivered on X, LinkedIn and Bluesky, with alt text. - Post shapes. Send a thread on X and Bluesky, or a first comment on LinkedIn, from the same request that sends the post.
- Node and Python SDKs, written by hand against the v2 API rather than generated, both versioned 2.0.0. Written and merged; npm and PyPI publishing next. Until that lands they are not installable from a package registry, so the API itself is still the way in.
- Free accounts have one fair-use cap: 100 posts a day, counted in UTC across all your connections. Paid accounts have no daily cap, and sandbox posts never count toward it.
#11 #12 #19 #20 #27 #28 #30 #37 #38 #43 #45
- Bluesky is live. Connect with your handle and an app password, no OAuth dance. A self-hosted PDS works too. Bluesky posts are free to send and count as one connected account, like LinkedIn.
- X posts now bill a flat fee per post: 2 cents, or 25 cents when the post contains a link. LinkedIn, Bluesky and sandbox posts stay free. The fee is charged from your first X post, so a card has to be on file before X will send, and you can cap what you spend on X per month.
- Sandbox connections and test API keys. A test key starts with
yp_test_, reaches sandbox connections and nothing else, and a sandbox post is validated, stored and webhooked like a real one but published nowhere. Start a post with[fail]to test your error path. - Every authenticated response carries an
x-request-id, plus rate limit headers that tell you where you are in the window. Quote a request id and we can find that exact call. A Logs section in the console lists your requests per key, with secrets redacted. - The API answers browsers directly now, and takes
Authorization: Bearereverywhere it tookx-api-key. Every timestamp is ISO-8601 UTC, and the playground sends real requests instead of a preview. - Support threads in the app: message us, get a reply, see it without digging through email.
- The whole product was redesigned, dark first and monochrome.
- The API page fills its example commands in with your own key and your own connection slugs.
- The docs and the OpenAPI spec now name only the platforms that are actually live, so nothing on the page is a promise.
- Em dashes are gone from the docs, the spec descriptions and the product copy.
#10
- The v2 API.
POST /poststakes text and a list of connection slugs and fans out to all of them in one call, with a result per connection.POST /post/{slug}takes the post as a plain body, for the one-liner case. - List your connections, list and read your posts, cancel a scheduled one.
- An OpenAPI 3.1 spec at
/api/v2/openapi.json, no key needed to read it. - Send an
Idempotency-Keywith a post and a retry cannot post twice. - Signed webhooks for
post.sentandpost.failed, delivered with retries. - An MCP server with five tools, so an agent can post without any glue code.
- New pricing: posts are unlimited, and you pay per connected account. The first two accounts are free, then $5 each, $2.50 from the eleventh, $1 from the hundred and first.
- A developer console: API keys, an MCP page, and a playground.
Keeping up
There is an RSS feed of this page. The docs always describe what is live right now, and status tells you whether the API is answering. Building on the API? Watch this page: new endpoints and new platforms land here first.