- Wednesday
Social Media Posting API: Routing Is the Easy Part (The Permissions Are Not)
- Mark Fulton
- Automation, Social Media, API Integration
- 0 comments
Every write-up on this subject answers the same question: how do I send one request and have it land on six platforms? That is a routing problem, and routing is the part that already works. You can solve it in an afternoon with a switch statement.
The reason people still get stuck is that publishing to a social platform is not one problem. It is four, and only the first one is code. Who is allowed to post at all. When your working integration quietly expires. What the platform will accept as a post. And who decides what gets said.
I run marketing automation across roughly fourteen launched products and three blogs. Social distribution is part of that. I went through this evaluation, read the platform documentation, priced the work, and made a choice most guides will never recommend, because the guides are written by companies selling the thing they recommend. Here is the whole decision, including the parts that argue against building it.
What a social media posting API actually gives you
The official interface a platform publishes so your code can create a post without a person opening the app. Meta has one for Instagram and Facebook. LinkedIn has one. X has one. Each is a real, documented, supported product.
What you get is narrow and specific: a way to submit content that a particular account is allowed to publish, in a format that platform accepts, at a rate it permits. What you do not get is a general-purpose broadcast pipe. Every platform treats posting as a privileged action tied to a verified identity, and the shape of that privilege differs enough that "one call, many networks" is a marketing description rather than an engineering one.
That is not a complaint. It is the design. Posting is how spam enters a network, so the write path is where every platform puts its friction.
Why routing is the easy part
Take the naive version of this project. You have a piece of content. You want it on LinkedIn, X, Instagram and a Facebook page. You write a function per platform, a small dispatcher, and some retry logic for the inevitable rate-limit response. That is a day of work and it is genuinely straightforward.
Then you try to run it and discover the dispatcher was never the constraint. The constraints are:
Access. Each platform decides whether your app may post on behalf of that account at all, and the answer usually depends on a role, an account type, and a review.
Expiry. Working integrations stop working on a schedule, without anyone changing code.
Format. The platform, not you, decides what counts as a valid post, and the rules are more specific than anyone expects.
Judgment. Something has to decide what the post says, and something has to decide whether it ships.
Those four are the article. The dispatcher is a footnote.
What does it take to get permission to post on each platform?
This is the gate that ends most projects, and it is the one you can research before writing any code.
Posting through the Posts API needs an OAuth permission, and which one you need depends on who the author is. Posting as a person needs the member-level social write permission. Posting as a company page needs the organization-level one, and LinkedIn's Posts API documentation restricts that permission to organizations where the authenticated member holds one of three specific page roles: administrator, direct sponsored content poster, or content admin. If the person who authorized your app is not one of those three on that page, the call fails with an access-denied response and no amount of retrying fixes it.
There is a second thing in that same permissions list worth reading twice. The read equivalent for member posts is marked restricted and available to approved users only. Write access and read access are not symmetric. Plenty of people build assuming they can read back what they published and find out late that they cannot.
Every request also carries a version header in year-month form. Hold that thought, because it becomes the second gate.
Meta's content publishing documentation is blunt about the prerequisites. You need an Instagram professional account connected to a Facebook Page, and Page Publishing Authorization has to be completed before you can publish. Then you need the right permission pair, which differs depending on whether you authenticate through Instagram login or Facebook login.
None of that is exotic if you are posting for your own business. It becomes a real cost if you are building this for clients, because you are now walking every client through an account-type conversion, a page connection and an authorization flow before you can deliver anything. That is a support burden, and it happens per customer, forever.
X
The posting endpoint documents its limits directly: ten thousand posts per twenty-four hours at the app level, and one hundred per fifteen minutes per user, with custom limits for enterprise customers. For a solo operator those ceilings are irrelevant. If you are building a scheduling product for other people, the app-level number is the one that matters, because your customers share it.
The shape they have in common
Strip the details and every platform is asking the same three questions. Is this a verified identity rather than an anonymous script. Does the human who authorized this app actually have the authority to publish for that account. And has this application been reviewed for what it claims to do.
You can answer all three. It just takes calendar time you have to plan for, and it is per platform, and it does not end after launch.
Why do social API integrations break when nothing changed?
This is the failure mode that surprises people, because it presents as a bug with no cause. Nobody deployed. Nobody touched the credentials. It worked last month and today it returns errors.
Three things expire on their own.
The API version. LinkedIn's Posts API documentation currently carries a deprecation notice stating that the July 2025 marketing version has been sunset, and recommending migration to the latest versioned APIs to avoid disruptions. Read that as a maintenance contract: the header you hardcoded has a shelf life, and when the version behind it is retired, your integration stops. This is not a bug you can debug from your own logs. It is a calendar event that happened to someone else's schedule. The general guides skip this entirely, and dated version headers are the single most predictable way one of these systems dies.
The token. Access tokens expire, refresh tokens expire on longer cycles, and the refresh flow is the part nobody tests, because you only find out it is broken on the day it is needed.
The human's role. Your app posts to a company page because a specific person with an admin role authorized it. That person changes jobs. Their role is removed. Your integration was never granted anything of its own, and it goes down with them. If you build this for clients, that is not an edge case, it is a quarterly occurrence.
The practical answer is small. Write down every expiry date you know about the moment you learn it, and give the system a heartbeat: a scheduled job that publishes something harmless to a private or test target on a fixed cadence and shouts when it fails. Without that, you find out your posting pipeline is dead when you notice the feed has been quiet for two weeks. I have written before about how a weekly measurement loop decides what happens next, and the same logic applies here. A pipeline nobody checks is a pipeline nobody can trust.
What can you actually publish?
Here is where the general write-ups get thin, and where a few hours in the real documentation pays for itself. The platform decides what a post is, in more detail than you would guess.
Meta's content publishing docs state that Instagram accounts are limited to one hundred API-published posts within a rolling twenty-four hour window, and that a carousel counts as a single post. The figures that circulate for that limit in the wider ecosystem disagree with each other and with the documentation, which is a reasonable warning about where to get your numbers.
The same page carries three constraints that will break a generated pipeline on day one. JPEG is the only supported image format, and extended variants are not supported. Filters are not supported. Shopping tags are not supported. Media has to sit on a publicly reachable server at the moment you publish, so the image cannot live behind your auth.
That first one deserves emphasis if you are generating images with a model. Image tooling produces PNG by default. Your generation step and your publishing step have to agree on format, or the whole run fails at the last hop for a reason the error message will not make obvious.
LinkedIn has its own set. The Posts API does not scrape URLs when you create an article post, and the documentation says so plainly, explaining that scraping introduces unpredictability in how a post will appear. The consequence is concrete: if you post a link and supply nothing else, you do not get the rich preview card you see when a person shares that same link by hand. You have to upload a thumbnail image, then set the title and description yourself. Organic carousels are not supported at all, only sponsored ones. And mentions only render as mentions when your text matches the entity name exactly, case sensitively, otherwise it silently degrades to plain text.
Silently is the operative word in most of these. A generated post that violates a format rule usually publishes as something worse rather than failing loudly.
The design conclusion is the one that changes how you build: your generator cannot produce one asset and one caption. It has to produce a per-platform bundle, because the platforms do not accept the same object. That is more work than the switch statement, and it is where the real engineering lives.
Unified posting API, direct integrations, or a relay?
There are three answers, and the published advice covers two of them, because the third does not have a vendor.
Direct integrations. You build against each platform yourself. You get everything that platform offers, you own the review process, and you own the maintenance forever. This is right if posting is your product, or if you need a capability the middle layers do not expose.
A unified posting API. A vendor maintains the per-platform integrations and gives you one endpoint. This is a real time saving and I am not going to pretend otherwise. What you are buying is someone else's maintenance. What you are also accepting, and what their own guides tend not to spell out, is that your publishing now depends on their uptime, their continued access to each platform, and their app's standing with those platforms. Your account trust is downstream of a company you do not control. That is a fine trade for a business built on posting volume. It is a strange trade for a solo operator posting a few times a day.
A hosted automation relay. A workflow platform sits between your code and the networks, holds the platform connections, and exposes a webhook. Your system does one authenticated request to your own endpoint and the relay fans out.
That third one is what I run. My own social publishing goes through a webhook into a hosted automation that holds the platform connections, and my agent's job ends at producing the payload. I want to be precise about why, because it is not a technical superiority argument. It is arithmetic. Direct integrations would have cost me an app review per platform, a maintenance obligation with no end date, and a category of silent failure I would have to build monitoring for. The volume that would justify that cost is not volume I have. So I bought the boring option and spent the time on the half that actually differentiates the output, which is what the posts say.
The decision rule I would give anyone: multiply the number of platforms by how often the integration will need attention, then ask what depends on it. If the answer is a personal brand and a handful of products, do not build integrations. If the answer is a product other people pay for, build them or buy a vendor with a contract.
How do you keep automated social posts from reading as automated?
Every guide on this subject stops when a post object reaches the network. That is the plumbing. The content is the product, and it is where automated social output earns its reputation for being obviously automated.
Three rules do most of the work.
Generate per platform from the source, never chain. Take the original material and write each platform's version from it independently. Do not write the LinkedIn post and then ask for a shortened X version, because compression of a compression loses the specifics first, and the specifics are the only reason anyone stops scrolling.
Encode the platform's real constraints as hard limits. X caps a post at 280 characters and a link consumes twenty-three of them regardless of its actual length, so the budget is 280 minus your links minus anything else fixed. LinkedIn, Facebook and Instagram render markdown literally, so asterisks and hash symbols show up as asterisks and hash symbols. Line breaks need to be doubled to survive as visible spacing. These are not style preferences, they are the difference between a post that looks written and one that looks generated.
Keep a written voice specification and a banned list. This is the mechanism that actually raises quality, and it is unglamorous. A file that says how you write, with concrete examples of accepted and rejected phrasing, plus an explicit list of the openers and constructions that keep leaking in. Mine bans a specific set of hook patterns because I kept catching them in drafts. Every one of those bans exists because something got through once.
If you want the full version of that build, the training session this article grew out of walks through the whole loop: finding a timely topic, composing the platform-specific versions, generating the image, and routing it to the right channels. The replay is available instantly, including the step-by-step instructions and the assets, so you can watch it and build the same day. It is also part of what comes with the Reinventing AI Accelerator, where the live sessions and the vault of finished apps, tools and agents live together.
Where the human belongs in an automated posting pipeline
I do not let a model press publish. Not because the writing is bad. Because publishing is the one step in the chain that cannot be undone.
A bad draft costs nothing. A bad database write can be restored. A published post can be deleted in ten seconds and screenshotted in five, and the deletion does not travel. Everything upstream of the send button is reversible, and the send button is not, which is the entire reason the gate goes exactly there and nowhere else.
There is a policy dimension too. Platforms distinguish between automation that helps a real account operate and automation that manufactures activity, and the line is drawn at inauthentic behavior rather than at whether an API was involved. Using a documented posting endpoint is sanctioned. Firing near-identical content across a set of accounts on a timer is what abuse detection is built to find, and it does not care that you used the official interface to do it.
So my pipeline ends in a queue, not a publish call. The agent researches, drafts, generates the image, formats per platform, and puts the result somewhere I can read it. I read it and I send it. The cost is a few minutes a day. What it buys is that nothing goes out under my name that I have not seen, which is the same reasoning I applied to the send step of an automated newsletter and to the approval gate in my repurposing workflow. The pattern generalizes: automate everything reversible, gate everything that is not.
How to build this in a weekend
Pick the platforms that actually matter and drop the rest. Two done well beats six done badly, and each additional network is a permanent maintenance obligation rather than a one-time build.
Read the publishing documentation for each one before you write code. Account type, permission, page role, media format, rate limit. An hour of reading here saves the week you would otherwise spend debugging a constraint that was documented all along.
Decide direct, vendor, or relay using the volume arithmetic, and write down why, so that when you revisit it in six months you are arguing with a reason instead of a habit.
Build the generator as a per-platform bundle producer, not a one-caption broadcaster. Source material in, a distinct object per network out, each one obeying that platform's real limits.
End the pipeline in a queue with a human send, and add a heartbeat that tells you when the connection has quietly expired.
What I stopped doing
I stopped chaining posts from each other, for the reason above. I stopped trying to hit every network, because the two that actually produce conversations for me were carrying the whole result while the others carried maintenance. I stopped treating a successful API response as proof the post looked right, after watching formatting decisions arrive in the feed as literal punctuation. And I stopped scheduling posts at exactly the top of the hour, which is a small thing that makes an account read like a person rather than a cron job.
Start here
If you want the version with the working system attached rather than the concepts, that training session is the fastest path. The full replay is available instantly, with the no-code instructions and the assets, so nothing is theoretical.
Members of the Reinventing AI Accelerator get that session plus the live training every week and the vault of AI apps, tools and agents that come out of them. If you are building your own systems and you would rather start from something already running than from an empty file, that is what it is for. One small ask: pick the single platform where your buyers actually are, and build the pipeline for that one first.
Frequently asked questions
Can I post to Instagram programmatically without a Facebook Page?
No. Meta's content publishing documentation requires an Instagram professional account connected to a Facebook Page, with Page Publishing Authorization completed before publishing. Personal Instagram accounts have no API publishing path. If you are doing this for clients, budget for walking each of them through that conversion.
Do I need app review to post to LinkedIn?
You need the correct OAuth permission, and for company pages the person who authorizes your application must hold an administrator, direct sponsored content poster, or content admin role on that page. Note also that reading back member posts uses a permission LinkedIn marks as restricted and available only to approved users, so write access does not imply read access.
How many posts per day can I publish through these APIs?
It varies per platform and the numbers you see quoted secondhand are frequently wrong. Meta documents a limit of one hundred API-published posts per Instagram account in a rolling twenty-four hour window, with a carousel counting as one. X documents ten thousand posts per twenty-four hours at the app level and one hundred per fifteen minutes per user. Check the current documentation before you design around any of these, because they move.
Is automated posting against the platform rules?
Publishing through a platform's documented API is sanctioned. What gets accounts actioned is inauthentic behavior: duplicated content fired across multiple accounts, engagement patterns no person would produce, volume that exists to game distribution. The interface you used is not the test. The behavior is.
Should I build direct integrations or use a unified posting API?
Multiply the number of platforms by the ongoing maintenance each will need, then ask what depends on the pipeline. If posting is your product, own the integrations or buy a vendor you have a contract with. If you are one operator distributing your own work, a hosted relay costs less attention than either and frees you to spend the time on the content, which is the part your audience actually sees.
Subscribe Now for More AI Insights
Subscribe for Updates from Reinventing AI
Stay current on the most cutting-edge AI solutions for ambitious entrepreneurs and marketers!