LinkedIn Post Scheduler

A self-hosted LinkedIn automation tool that queues posts into weekly time slots and publishes them through LinkedIn's official API, built to replace a paid scheduling subscription.

The Problem

Posting on LinkedIn every day is how a lot of freelancers and small agencies find clients, and it only works if it is consistent. Writing posts in a batch and letting software publish them on schedule is the obvious answer, but the popular schedulers charge per month and their free plans cap you at around ten posts. At two posts a day across several profiles, that limit runs out in the first week.

I wanted the same workflow as the paid tools (write drafts, drop them into a queue, have them go out at set times) without the cap, running on my own server, and covering several accounts: my own profile and the agency and side projects I post for.

What I Built

A private web app with an admin panel where posts are written, previewed and queued, and a background scheduler that publishes them to LinkedIn at the right time. It talks to LinkedIn only through the official, versioned Posts API with OAuth sign-in. There is no scraping, no browser bots and no stored LinkedIn passwords, so it doesn't put the accounts at risk.

Weekly Posting Slots

Each account has its own weekly schedule, such as weekdays at 3 PM and 9 PM. "Add to queue" drops a post into the next free slot, the same way paid schedulers do.

Time Zone and DST Safe

Slots are stored as a local time plus a time zone, so a 9:00 Toronto slot stays at 9:00 Toronto time when the clocks change. Everything is saved in UTC underneath.

Several Accounts, One Panel

Accounts connect through LinkedIn sign-in. Each has its own queue, slots and token, and a minimum gap between posts stops two from landing on top of each other.

"See More" Preview

The editor shows roughly where LinkedIn will cut the post with "…more" in the feed, so the hook line stays above the fold.

Automatic First Comment

A post can carry a first comment, such as a link, that is added straight after publishing, keeping links out of the post body.

Failure and Token Alerts

If a post fails, or an account's LinkedIn access is about to expire, the owner is notified with a clear reason and what to do next.

Bulk Import and Export

Posts can be imported from and exported to JSON, so a month of content written elsewhere can be loaded into the queue in one step.

What Was Technically Involved

Never posting twice. The hardest part of any auto-publisher is what happens when something goes wrong halfway. If LinkedIn times out, the post may or may not be live. Retrying blindly creates a duplicate in front of your whole network. So the publishing job retries only when LinkedIn has clearly refused the request (rate limits and server errors), never after a network error. A post that gets stuck mid-publish is marked for review instead of being retried, and the owner is told to check LinkedIn first.

LinkedIn's text format. The Posts API treats characters like brackets, underscores and the @ sign as markup. Leave one unescaped and the post can be silently cut short. Every post goes through a formatter that escapes those characters and turns hashtags into LinkedIn's clickable hashtag format, with unit tests covering the edge cases.

Scheduling that holds up. A cron task runs every minute, claims posts that are due and hands them to a background queue. The slot finder checks each account's weekly slots against posts already scheduled and respects the minimum gap between posts. A daily task checks each account's LinkedIn access and warns a week before it expires.

Stack. Laravel 13 and PHP 8.3, a Filament admin panel (post editor, queue board, schedule view and stats), Laravel Socialite for LinkedIn sign-in, Laravel queues and the scheduler, and automated feature and unit tests for publishing, scheduling, import and formatting. It is self-hosted on a small Amazon Lightsail server.

Next. Image, PDF carousel and video posts through LinkedIn's upload API, and publishing to company pages.

What This Proves

This is the clearest example in my portfolio of integrating a third-party API properly: OAuth, versioned endpoints, rate limits, token expiry, and failure handling that protects the user from the API's worst cases. If your business depends on software that has to act on another platform reliably and on schedule, such as publishing, syncing orders or sending invoices, this is how I would build it for you.

Have a Task That Should Run Itself?

Publishing, syncing, reminders, reports: tell me what your team does by hand every week.

Start the Conversation All Case Studies
Chat on WhatsApp