LinkedIn setup
LinkedIn publishing needs three values: an access token authorized for posting, the author to publish as, and an explicit API version. The adapter writes its own HTTP requests rather than using the restricted client SDK.
linkedin-native
Status and evidence
Syndroo 0.2.0-rc.1 is an unpublished release candidate: prepared in the repository, not published to npm, not tagged, and not deployed. LinkedIn is recorded as experimental for this candidate.
Evidence: unit tests in the core repository, including workerd coverage. The review of the official JavaScript client found redistribution restrictions, so the adapter is an independent native HTTP implementation of the posts endpoint. There is no Mock SNS end-to-end coverage for LinkedIn, and no live-account acceptance record exists. See Platform readiness and the capability record.
What you need
- A LinkedIn member account, or an organization Page you administer, depending on what you intend to publish as.
- A LinkedIn developer application with the API product access that allows posting.
- The permission your target needs. The Posts API documents
w_member_socialfor posting on behalf of an authenticated member, andw_organization_socialfor posting on behalf of an organization, where the authenticated member must hold a page role such asADMINISTRATOR,DIRECT_SPONSORED_CONTENT_POSTER, orCONTENT_ADMIN. Product access and permission names are LinkedIn's to change, so confirm them on the current documentation. - A member access token from the OAuth flow LinkedIn documents. Syndroo does not run that flow and does not refresh tokens.
- A running Worker and its API key. Either a deployment in your own Cloudflare account or a local instance. The Worker holds the platform credentials; clients hold only
SYNDROO_API_KEY. If you have not set one up yet, the first-post walkthrough covers the whole path with Bluesky.
The adapter reads three Worker secrets:
| Secret | Required | Value |
|---|---|---|
LINKEDIN_ACCESS_TOKEN | Yes | Access token authorized for posting as the author below. |
LINKEDIN_AUTHOR | Yes | The publishing author as a URN: urn:li:person:... for a member, urn:li:organization:... for a Page. One author per deployment. |
LINKEDIN_API_VERSION | Yes | An explicitly selected API version in YYYYMM form, such as 202601. There is deliberately no default. |
The version and author are validated when the Worker reads them: a missing version, a malformed URN or an empty token leaves LinkedIn unconfigured, and selecting it returns HTTP 422 with PLATFORM_NOT_CONFIGURED.
Create the token and pick an author by hand
LinkedIn's developer portal, access programs and permission names change over time. Follow the official documentation linked under Official sources while you work through this sequence.
-
Create the developer application
Create an application in the LinkedIn developer portal and associate it with the Page that owns it.
-
Request the posting access you need
Ask for the API product that permits posting. Member posting and organization posting are separate permissions and may have separate approval requirements; organization posting generally also requires a role on the Page.
-
Complete the member authorization
Run LinkedIn's OAuth flow for the member who will act for the author, requesting the posting permission. This yields the access token you will store. Check who the token acts for, because the token and the author URN must belong together or the write fails with
errorCodeAUTH. -
Pick an explicit API version
Read the versioning documentation, choose a supported version and record it as
YYYYMM. Syndroo sends exactly the version you set, so an unsupported or retired value fails at the platform instead of being silently upgraded.
Product access, review and Page permissions are outside Syndroo's control. This page makes no promise about which program you qualify for, what it costs, or how long an approval takes.
Add the secrets to the Worker
Put the values where your runtime reads secrets: Worker secrets for a deployment, .dev.vars for a local instance. Cloudflare deployment and Local development cover the exact commands for each path.
LINKEDIN_ACCESS_TOKEN="your-linkedin-access-token"
LINKEDIN_AUTHOR="urn:li:person:your-member-id"
LINKEDIN_API_VERSION="202601"
Before accepting a post, Syndroo checks that all three values exist and are well formed. It does not call LinkedIn to test the token. An expired, revoked or under-permissioned token passes that check and surfaces later as a publication failure with errorCode AUTH.
Publish and check one post
The commands below publish for real once the secrets above are configured. Set the two client variables in the terminal that will call Syndroo.
export SYNDROO_URL="https://your-worker.your-subdomain.workers.dev"
export SYNDROO_API_KEY="the-same-secret-your-worker-has"
curl -X POST "$SYNDROO_URL/v1/posts" \
-H "Authorization: Bearer $SYNDROO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: linkedin-setup-001" \
--data '{
"content": "First post from my own Syndroo Worker.",
"platforms": ["linkedin"]
}'
The accepted response is HTTP 202 with status queued:
{
"id": "post_...",
"status": "queued"
}
HTTP 202 means the request was accepted for processing. It does not confirm that LinkedIn accepted anything, and it does not prove that the Queue has not already sent the platform request, because delivery can start immediately after acceptance. Read the stored state to learn the outcome:
curl \
-H "Authorization: Bearer $SYNDROO_API_KEY" \
"$SYNDROO_URL/v1/posts/post_..."
{
"id": "post_...",
"content": "First post from my own Syndroo Worker.",
"platforms": ["linkedin"],
"status": "published",
"publications": [
{
"platform": "linkedin",
"provider": "linkedin-native",
"status": "published",
"attempts": 1,
"externalId": "urn:li:share:7000000000000000000",
"errorAmbiguous": false
}
]
}
A publication is stored as published only when LinkedIn confirms the created post. queued and publishing are not terminal; poll the same URL. Repeating the identical request with the same Idempotency-Key returns the stored result with HTTP 200 instead of creating a second post. See Idempotency-Key.
Limits, tokens and external dependencies
| Item | Recorded for 0.2.0-rc.1 |
|---|---|
| Text limit | 3,000 UTF-16 units after the adapter escapes reserved little-text characters, checked before the network call. Nothing is truncated; over-limit text fails with INVALID_CONTENT. |
| Content type | Public text only. The comment text is escaped so reserved characters stay literal, and media, documents, mentions and audience targeting are outside this version. |
| Credential maintenance | Yours. LinkedIn access tokens expire, and Syndroo neither refreshes nor renews them; obtain a new token and replace the Worker secret. LinkedIn documents a monthly API version cycle with scheduled retirements, so re-check the version you pin. |
| External dependency | LinkedIn's product access, review process, terms and rate limits apply. Syndroo controls none of them, includes no pricing of its own, and promises nothing about a current plan, quota or approval outcome. |
Check the provider's current documentation before relying on a specific permission, version or limit. Those facts change on the provider's schedule, not on this page; the links under Official sources are the references to re-check.
When something fails
A failed publication stores errorCode, errorMessage and errorAmbiguous in the post response. Read them before you act.
| What you see | What it means | What to do |
|---|---|---|
HTTP 422 PLATFORM_NOT_CONFIGURED | A secret is missing, empty, or not in the required form: a malformed author URN or a version that is not YYYYMM. | Fix the secret named above, then send the request again. Nothing was stored or queued. |
AUTH | LinkedIn rejected the token or the author: expired, revoked, missing the posting permission, or the token acts for a different member than the author URN. | Obtain a token with the right permission and author, update the secrets, and check the feed before resending. |
INVALID_CONTENT | The escaped text exceeded the UTF-16 limit, or the content was not postable as plain text, and nothing was sent. | Shorten the text and publish again with a new key. |
RATE_LIMIT | LinkedIn refused the request because of its own request limits. | Syndroo retries this automatically with backoff, up to three attempts. If it still fails, wait before trying again. |
PROVIDER_UNAVAILABLE, NETWORK or UNKNOWN, with errorAmbiguous: true | The write may have reached LinkedIn; the outcome is unknown. | Check the feed and the author's activity by hand. Syndroo never resends an ambiguous publication automatically. |
Post status partial | Some selected platforms succeeded and some failed. | Never resubmit the platforms that succeeded. The failed ones need attention only after you have excluded an ambiguous outcome. |
If a publication is failed with errorAmbiguous: true, check the author's LinkedIn activity by hand first, because the post may already exist. Only when you have confirmed that nothing was published and you still want the post should you send a new request with a new Idempotency-Key. Reusing the old key replays the stored result instead of publishing. Read Ambiguous outcomes for the reasoning.
Official sources
- Posts API and permissions
- API versioning
- Syndroo adapter source:
@syndroo/linkedin - Capability record, taken from the product repository at commit
87ba42band reviewed on 2026-09-18
This page follows the candidate's capability record and the product revision above. It was not verified against a live LinkedIn account, so re-check the official documentation when a permission, version or portal step differs from what you see.