Guides / Guide
Building your own social media scheduler: the code is the easy part
Background
On paper a social scheduler is small. A table of posts, a time for each, a job that wakes up every few minutes and publishes whatever's due. You could sketch it over lunch.
What takes the time is everything around that job. Each platform decides who's allowed to post through its API, makes you prove what your app does before it lets real users connect, and in at least one case charges per post. None of that is code, and all of it sits between you and the first real post going out.
It also helps to split the job in two. Making the post (the image, the video, the words) is one problem. Getting it published on time is another. My own Marketool (in beta) only does the first half for estate agents: it builds social banners and slideshow videos for property listings from an agency's own feed or photos, and you download a PNG or MP4 ready to post. Posting it is still up to you. The rest of this guide is about the second half, the one the platforms gate.
Setup
Official APIs only, and know what each one wants
No scraping, no headless browser logging in as someone. Platforms block it, it breaks every time a page changes, and it means holding people's passwords. Use each platform's own API, and read its access rules before you promise anyone a launch date.
| Platform | What stands between you and posting |
|---|---|
| Meta (Facebook Pages, Instagram) | App Review, permission by permission. Until a permission is approved, only people with a role on your app can use it |
| Company page posting sits in the Community Management API, a vetted product with a Development tier and a Standard tier you apply to move up to | |
| X | Pay per use. At the time of writing, creating a post is $0.015 a request and a post containing a link is $0.20, billed from credits |
Those X prices will move. The X docs say current rates always live in the Developer Console, so check there, not here, before you cost anything.
Getting through Meta's App Review
Meta approves each permission separately, and it tests whether your app uses what it asks for. If a reviewer can't see the feature working, that permission is refused.
- Record a screencast for every permission you request. Start logged out, show the whole login, show the person granting the permission, then show your app using it. Leave one out and the submission gets rejected.
- Make a real API call with each permission first. Advanced access needs at least one successful call per permission, made within 30 days before you submit.
- Use a separate test app for new permissions. A live app can only use approved permissions, so you can't demonstrate a new one there.
- No audio needed. Reviewers don't listen. Use captions to point at anything that isn't obvious.
Business verification is a separate process you may also be asked for, depending on what the app does.
LinkedIn's two tiers
You start on the Development tier, which has limited API call volume. To move up to Standard, you fill in an access request and send a screen recording showing each use case you named on it. Ask for less, and there's less to demonstrate.
Posting as an individual's own profile is a narrower door than posting as a company page. Some member permissions are closed to new requests altogether, so check the current list before you design around one.
Tokens are secrets, and personal data
Every connected account gives you an access token, and most come with a refresh token. Treat them like passwords:
- Encrypt them at rest, and keep the key out of the database.
- Store which person granted each one, and when, so you can answer "who connected this?" and delete it when they leave.
- Refresh before expiry, not on failure. A job that only notices a dead token at 9am on launch day is the wrong time to find out.
- Let people disconnect, and revoke the token at the platform when they do, not just in your table.
Publishing jobs that run exactly once
Networks fail, platforms time out, and a cron job will one day run twice. The publishing step has to cope.
- Claim a post before publishing it. Mark it "publishing" in one atomic update, so a second worker can't pick up the same row.
- Store the platform's post id the moment you get it back. That's your proof it went out, and what stops a retry posting it again.
- Retry with backoff, then stop. After a set number of tries, mark it failed and tell a person. A post that silently never went out is worse than an error.
- Keep an audit row for every attempt: who scheduled it, what was sent, when, what the platform said back.
APIs and webhooks, and why most integrations need both covers the pattern for knowing when something changed on the other side.
Rate limits: read them, don't guess them
Every platform caps how much you can post. Instagram, for example, has a daily cap on posts published through the API per account, and Meta's own guide gives two different figures for it on the same page. Its API has an endpoint that reports the account's current usage, so read the limit from there instead of hard-coding a number you found in a blog post.
Edge Cases & BCP
- Review can take longer than the build. A rejected submission means fixing what the reviewer couldn't see and sending it again. Plan the launch around approval, not around the code being finished.
- A permission you have today can be withdrawn. Platforms change their rules. Build so one platform failing doesn't stop the others, and so a post queued for a platform you've lost shows as blocked, not "sent".
- Someone leaves, their token stays. If a staff member connected the company page with their own account, the link dies with their account. Connect with an account the organisation owns, and know who that is.
- Old API versions get switched off. LinkedIn, for one, retires versions on a published schedule. Put the version you call in config and diary the sunset dates.
- Sometimes the right answer is not to build it. If you post to two accounts a few times a week, the platforms' own scheduling features already do it, and none of the above is your problem. Build when you need something they can't do: many accounts, an approval step, posts made from your own data, or a record of who posted what.
Checked against the official docs on 14 October 2026: Meta App Review, Meta screen recordings, Instagram content publishing, LinkedIn Community Management API and X API pricing.