Publishing to a LinkedIn Company Page
This tutorial walks through publishing posts, articles, and news to a LinkedIn Company Page from PowerMarketing — end to end, with visual diagrams of every step. It covers both supervision modes:
What “article” means here. LinkedIn's long-form Articles (the Pulse editor, with a hero image and a title above the body) have no public API and cannot be automated by anything — PowerMarketing included. A PowerMarketing article publishes as a feed post. Give the post a Link URL and it goes out as a LinkedIn article card: your title, a description, and the link, optionally with an image as the thumbnail. Give it only an Image and it publishes as an image post. With neither, it is plain text, where the first line acts as the headline. For writing that will not fit in 3,000 characters, set Publish as → Document and the whole article goes out as a PDF the feed opens inline — see Long-form posts.
- A — With approval: the AI writes the draft, a human reviews it in the Decision Inbox, and only an explicit Approve sends it live.
- B — Without approval: news is written and published automatically by the agent crew, with no human in the loop (with safety fallbacks).
Human action AI Agent Approval gate Auto-publish Live on page
The Two Scenarios at a Glance
Both scenarios share the same setup and the same agent crew — they differ only at the moment of publishing: a human gate (Track 2) or none (Track 1).
One-Time Setup (required for both scenarios)
You only do this once per brand. It connects PowerMarketing to your LinkedIn Company Page so the Publisher agent can post on its behalf.
Step 1 — Create a LinkedIn developer app with company-page access
Create the app on LinkedIn
At linkedin.com/developers, create an app and associate it with your Company Page (LinkedIn requires the app to be linked to the Page you'll post to). You will need these products / scopes:
- Community Management API (Development Tier is enough) — this is the one that matters. It grants
r_basicprofile,w_member_social,rw_organization_admin,w_organization_socialandr_organization_social: everything PowerMarketing needs for both personal and Company Page posting. - Share on LinkedIn — also grants
w_member_social. Harmless to have, not required if you have Community Management API.
PowerMarketing does not use OpenID Connect. It identifies the connected member through r_basicprofile and /v2/me, not openid and /v2/userinfo. That is deliberate: LinkedIn does not offer “Sign In with LinkedIn using OpenID Connect” to every app — on apps that already hold Community Management API its Request access button is greyed out — and an app asking for a scope it was not granted has its entire authorize request rejected with unauthorized_scope_error. The scope set above is the one that works with Community Management API alone.
Request Community Management API FIRST, on an app with nothing else on it. LinkedIn greys out its Request access button on any app that already has other products — their own FAQ states that Development Tier access is only granted to “new developer applications that don't have access to other API products”. If you add Share on LinkedIn or Sign In with OIDC first, you are locked out and must start a new app. Correct order: (1) create the app on your Company Page, (2) add no products, (3) request Community Management API — Development Tier, (4) after approval, add Sign In with OIDC and Share on LinkedIn. Set a Privacy policy URL in Settings before submitting the request.
Personal posting now needs Community Management API too. It supplies r_basicprofile, which is how PowerMarketing identifies the member. Without it, Connect Personal Account fails with Scope "r_basicprofile" is not authorized for your application — the same way a missing w_organization_social blocks Connect Company Page.
In the app's Auth tab, add the exact Redirect URL that PowerMarketing shows you in Step 2 (copy it verbatim — a mismatch is the #1 cause of connection failures).
Find your Organization (Company Page) ID
Open your Company Page as an admin. The numeric ID appears in the admin URL, e.g. linkedin.com/company/2385451/admin/dashboard/. That number — and only that number — is your Organization ID.
Do not use your App ID here. The LinkedIn Developer Portal shows your App ID as a bare number too (it is also in the Community Management API approval email), and the two are indistinguishable once pasted. Using the App ID produces 403 FORBIDDEN — Accessing the resource is forbidden on every Company Page publish, with nothing wrong anywhere else: the connection shows as healthy, the scopes are right, and you can be a Super admin of the page. PowerMarketing now checks the stored id against the pages you administer and corrects it automatically, but the number to look for is the one in the page URL.
Step 2 — Save your LinkedIn app credentials in PowerMarketing
Go to Settings → Credentials. In the LinkedIn App card, paste your Client ID and Client Secret, confirm the pre-filled Redirect URI, and click Save. Saving unlocks the two Connect buttons.
Step 3 — Connect the Company Page
Click “Connect Company Page”
A dialog asks for your Organization ID — paste the number from Step 1. You can also change it later without reconnecting: Settings → Credentials → Company Page ID is editable, and Choose from my pages… lists the pages LinkedIn says you administer, by name, so you never have to type the number at all.
Authorize on LinkedIn
You're redirected to LinkedIn's consent screen. Because this is an organization connection, PowerMarketing requests the organization scopes (rw_organization_admin, w_organization_social, r_organization_social) on top of r_basicprofile and w_member_social. Note rw_organization_admin, not r_organization_admin — LinkedIn does not issue the read-only name, and asking for it fails the whole request. Approve, and LinkedIn sends you back to PowerMarketing.
Confirm the connection
You'll land back on Settings with a success banner, and the credential appears in your connected-accounts list tagged Company Page. PowerMarketing stores the access token and will post as urn:li:organization:<your-id>.
urn:li:person:…). Everything else in this tutorial is identical — just connect the Company Page instead.Scenario A — Posting a Post, Article, or News with approval
This is Track 2: the AI drafts, you review, you approve. It's the default for strategic content (post, article) and for anything where you keep a human in the loop. Use it whenever brand voice and accuracy matter and you want the final say before it's public.
Add a calendar entry on the Content Calendar
Open Calendar, click a date, and create an entry. Choose a content type of post or article (or news if you want it reviewed), set the platform to LinkedIn, and write the topic. To force review even for an auto-eligible type, tick Require approval.
Prefer the AI to plan for you? Use ✦ Plan this week to have the Planner propose a set of entries you approve as one decision.
Dispatch — the agents write the draft
At the brand's dispatch time the scheduler runs automatically, or you can trigger it now from the Command Center's Dispatch panel (or Run dispatch). The ContentDispatcher creates the post row and the ContentCreator writes it. Because the type requires review, the post is queued as a pending decision rather than published.
Review it in the Decision Inbox
Open Decisions. Each pending item shows the AI draft and the target platform. You can ask the built-in assistant to Explain, Recommend (approve/reject), or list Risks — and edit the copy on the Posts/Publish page before approving.
(Optional) Run a Pre-flight check
On the Publish page you can run a pre-flight review before approving. It checks the LinkedIn character limit (3,000) deterministically and runs an AI quality pass (hook strength, CTA, hashtags, compliance risks).
Approve → it publishes
Click Approve. The post's status flips to approved, the Publisher agent sends it to LinkedIn as your organization, and the status becomes published with a link back to the live post. You'll see it in Posts and on your Company Page.
video, reel, email, newsletter, and broadcast are always Track 2 — they can never be auto-published, regardless of settings.Scenario B — Publishing News without approval
This is Track 1: the agent crew writes and publishes with zero human action. It's designed for time-sensitive, lightweight content — news, trend_scan, short_post, repurposed — where speed beats a review cycle. Here we enable it for news.
You can test this by hand. Pick News as the content type in Create (or on a Calendar entry) and it follows exactly the same Track 1 path as planner output. Choosing News also selects the trend-scan writing angle automatically — there is no separate mode to set.
Enable News for auto-publish (one-time)
Go to Settings → Automation → Publication Rules and switch on News in the auto-publish matrix, then Save. This adds news to the brand's auto-publish content types — the single switch that turns Track 1 on for news.
Add a news calendar entry — leave “Require approval” OFF
Create a calendar entry with content type news, platform LinkedIn, and make sure Require approval is unchecked. (Ticking it would override the rule and force Track 2.)
Let it run — fully automatic
At the brand's dispatch time the scheduler fires (no clicks needed). The Dispatcher writes the post, the publication rules say “auto”, the post is marked approved internally, and the Publisher posts it to your Company Page immediately. You'll find it in Posts as published and summarised in the Command Center's overnight bar.
ai_draft and dropped into the Decision Inbox so you can review and publish it manually. Nothing is ever lost silently.Long-form Posts — Getting Past 3,000 Characters
LinkedIn caps a post's text at 3,000 characters, and its long-form Articles editor has no public API. An article longer than the cap therefore has three possible homes, and PowerMarketing offers all three:
| Route | What the reader sees | When to use it |
|---|---|---|
| Trim | An ordinary post. | The argument fits, once the padding is gone. |
| Link card set a Link URL |
A short post above a card with your title and the link. | The full piece already lives on your site or blog. |
| Document Publish as → Document |
A short post above a PDF reader the feed opens inline, page by page. | The full piece exists only here, and you want it read in the feed rather than on another site. |
How a document post is built
- Write the draft as normal on Create. Headings (
## …) and bullets (- …) are rendered as headings and bullets in the PDF, not printed. - Set Publish as → Document. The preview replaces the text card with the real PDF and tells you how many pages it runs to.
- The first paragraph becomes the post text — the words that appear above the document in the feed. Everything after it travels in the PDF. Write that paragraph as the hook; it is the only part most people read before deciding to open the document.
- Publish as usual. The PDF is rendered and uploaded at publish time, so a last-minute edit is always included.
One limitation worth knowing. The PDF uses the same typeface as PowerMarketing itself, which covers Western European languages and standard punctuation but has no emoji. If the draft contains one, the preview says exactly which character cannot be drawn. The emoji stays in the post text above the document — it is only absent from the PDF.
Decision Logic — “Will this post auto-publish?”
For social posts, the auto-vs-approval decision is made at dispatch time from three inputs — the autopilot dial governs nurture email, not social posts, so the switches that matter here are the content type, your Publication Rules, and the per-entry toggle:
- If ① is yes → always Review (cannot be auto-published, ever).
- Else if ② is ticked → Review (per-entry override).
- Else if ③ the content type is enabled in Publication Rules → Auto-publish.
- Otherwise → Review (the default for anything not explicitly enabled).
Reference Tables
Content type → default track
| Content type | Default | Notes |
|---|---|---|
news, trend_scan, short_post, repurposed | Auto-eligible ⚡ | Auto-publishes only if you enable it in Publication Rules and the entry isn't marked Require approval. |
post, article, story, carousel | Review 👁 | Not auto-eligible by default — goes to the Decision Inbox. |
video, reel, email, newsletter, broadcast | Always Review 🔒 | Hard rule — can never be auto-published, regardless of settings. |
LinkedIn specifics
| Item | Value |
|---|---|
| Character limit (pre-flight check) | 3,000 — applies to the post text. A document post's text is only its first paragraph, so the article itself is not measured against it. |
| Post shapes | plain text; image post when an Image is attached; article card when a Link URL is set (a link wins over a bare image and uses it as the thumbnail); document when Publish as is set to Document (a document wins over both) |
| Documents | PDF, rendered by PowerMarketing at publish time. LinkedIn accepts up to 300 pages and 100 MB; a draft over either is refused before anything is uploaded. |
| Image formats | JPG, PNG, GIF — uploaded to LinkedIn at publish time, 10 MB limit |
| Markdown | Stripped before publishing — LinkedIn renders ** and ## literally. The preview shows the stripped text. |
| Company Page author | urn:li:organization:<org-id> |
| Personal profile author | urn:li:person:<member-id> |
| Visibility | PUBLIC, main feed |
| Personal scopes | r_basicprofile, w_member_social |
| Company Page scopes | the above plus rw_organization_admin, w_organization_social, r_organization_social |
| Member identity | GET /v2/me (not the OpenID /v2/userinfo) |
| API version header | Linkedin-Version: 202608 — expires yearly, see below |
Troubleshooting
| Symptom | Likely cause & fix |
|---|---|
| “Connect” buttons are greyed out | You haven't saved the Client ID/Secret yet. Save the LinkedIn App card first (Step 2). |
| OAuth fails with a redirect error | The Redirect URL in your LinkedIn app's Auth tab must match the Redirect URI shown in PowerMarketing exactly (scheme, host, path, no trailing slash differences). |
| Authorized, but posting fails as the organization | The app is missing the Community Management API products, or the connecting user isn't an admin of the Page. Re-request the org scopes and reconnect. |
| A news post didn't auto-publish | Check: News is enabled in Publication Rules, the entry's “Require approval” is unchecked, and the LinkedIn token is still valid. If publishing failed, the post is waiting in the Decision Inbox. |
| Pre-flight shows “over the limit” | Trim the copy below 3,000 characters before approving, or have the AI shorten it. |
403 FORBIDDEN posting as the organization, though you are a Page admin | The stored Company Page ID is almost certainly your App ID. The error names the URN it tried — compare it with the number in linkedin.com/company/<id>/. Fix it in Settings → Credentials → Company Page ID, or use Choose from my pages…. |
426 NONEXISTENT_VERSION — “Requested version … is not active” | The pinned Linkedin-Version has passed LinkedIn's one-year support window and all publishing stops. Bump LINKEDIN_API_VERSION in app/services/social_adapters/linkedin.py to the latest listed at LinkedIn's versioning page. tests/test_linkedin_api_version.py fails a year ahead of the sunset as the reminder. |
unauthorized_scope_error on connect | The app was not granted one of the scopes requested. LinkedIn rejects the whole request if any single scope is unauthorized, so the named scope is only the first one it noticed. Confirm the app holds Community Management API. |
| Published successfully but nothing appears on LinkedIn | Check Publish History for a View post link. No link means LinkedIn returned no post id — PowerMarketing now treats that as a failure rather than reporting success. |
| Token expired | Reconnect the Company Page (Settings → Credentials → Connect Company Page) to refresh the access token. |