Getting started
Quickstart
From nothing to your first scheduled post in about 10 minutes. You’ll run the first post as a test, so nothing reaches your profile until you say so.
You need: a Cloudflare account (free plan, no card), a GitHub account, and a LinkedIn account that belongs to a LinkedIn Page (an empty Page works).
1. Get your LinkedIn token
About 5 minutes, once. The token comes from your own LinkedIn app, so no one else’s app ever holds it.
- On LinkedIn’s developer site, click Create app. Give it a name, any square logo, and a Page you belong to.
- In the app’s Products tab, add Share on LinkedIn and Sign In with LinkedIn using OpenID Connect.
- Open the Token Generator, pick your app,
tick
openid,profileandw_member_social, sign in and allow. - Copy the token somewhere safe, and note today’s date plus 60 days: that’s when it expires.
Generate the token after adding the products: a token made before carries none of their permissions. The details are in LinkedIn setup.
2. Deploy
About 3 minutes. Open the deploy guide: it gets the four values Cloudflare asks for ready, then sends you to Cloudflare’s set-up page. On that page:
- tick Create private Git repository: your copy will hold your drafts;
- give the project, the D1 database and the KV namespace names nothing on your account already uses;
- set
DRY_RUNto1for now.
Cloudflare copies the project into your GitHub, creates the database and the media store, and deploys. Your Worker’s URL is near the end of the build log: dashboard, your Worker, Deployments.
3. Set your timezone
Clone your new private copy, then set your timezone in scheduler.json, as an IANA name:
{ "timezone": "Europe/Paris", "defaultTime": "09:00" }
Times in your posts are read in that timezone. It’s UTC until you change it.
4. Write a test post
Create posts/texts/2026-11-12-hello.md, with today’s date and a time a few minutes ahead:
---
date: 2026-11-12
time: 09:00
status: ready
visibility: CONNECTIONS
---
**Testing my scheduler.**
This post was written in Markdown and pushed from my editor.
status: ready puts it in the queue; draft keeps it out. visibility: CONNECTIONS keeps your first real
post among your connections. Every field is in Writing posts.
5. Push
git add posts scheduler.json
git commit -m "first post"
git push
Each push deploys your Worker and syncs your posts to D1 and your media to KV. The push checks every post first: one wrong file stops the sync with the list of errors, and nothing changes.
6. Check it
curl -H "Authorization: Bearer $ADMIN_TOKEN" https://<your-worker>.workers.dev/status
Your post shows as scheduled. Once its minute has passed, it shows as posted: with DRY_RUN at 1, the
link is a fake one and nothing reached LinkedIn. What every status means, and which ones you can write
in the file, is in When posts go out.
7. Go live
In your copy’s wrangler.jsonc, set DRY_RUN to "0" and push. Don’t change it in the dashboard: the next
push deploys the value from wrangler.jsonc again.
From now on, write posts when you have time, push, and each one goes out at its minute.
What’s next
- Writing posts: images, videos, the first comment, bold hooks.
- When posts go out: the minute check, retries, every status and who sets it.
- Troubleshooting: what an error means and how to fix it.
- Renew the token every 60 days:
/statuswarns you 7 days before. See LinkedIn setup.