Перейти к содержимому
Socialift
Руководство

Как публиковать посты в LinkedIn через API

Чтобы публиковать в LinkedIn через API от имени участника, подключите к приложению два открытых продукта — Sign In with LinkedIn using OpenID Connect и Share on LinkedIn, — запросите openid profile email w_member_social, получите sub участника из /v2/userinfo и отправьте POST на /rest/posts с автором urn:li:person:{sub} и заголовком LinkedIn-Version. Для страниц компаний нужен проверяемый Community Management API.

Обновлено:

Что нужно для публикации в LinkedIn через API?

Приложение разработчика LinkedIn с двумя открытыми продуктами, access token участника со scope w_member_social и person URN участника. Share on LinkedIn выдаёт w_member_social без специального одобрения; Sign In with LinkedIn using OpenID Connect даёт openid, profile и email, чтобы определить участника. Публикация от имени страницы компании — отдельная программа с проверкой.

LinkedIn называет Open Permissions единственными разрешениями, доступными всем разработчикам без специального одобрения. Для публикации это profile, email и w_member_social. Всё остальное — от постов организации до чтения активности участника — требует одобрения LinkedIn.

Открытые scopes для идентификации — openid, profile и email из OpenID Connect; данные участника берутся из endpoint'а /v2/userinfo.

Продукты и разрешения LinkedIn для публикации

Продукты и разрешения LinkedIn для публикации — Таблица возможностей по платформам
Продукт или программаРазрешенияДоступЧто даёт
Sign In with LinkedIn using OpenID Connectopenid, profile, emailОткрытый, подключается во вкладке ProductsИдентификация участника: sub, имя, фото, email
Share on LinkedInw_member_socialОткрытый, подключается во вкладке ProductsПосты, комментарии и лайки от имени участника
Community Management APIw_organization_social, r_organization_social и другиеС проверкой: сначала Development tier, затем Standard tierПосты страниц компаний, комментарии, аналитика
Чтение постов участникаr_member_socialЗакрыт — LinkedIn не принимает заявкиПосты, комментарии и лайки участника
Messages APIнетТолько для одобренных партнёровСообщения между участниками

естьнетТаблицу можно прокрутить вбок

Lead Sync (лид-формы LinkedIn) — отдельная программа со своей заявкой. Socialift не предоставляет сообщения и лид-формы LinkedIn.

Как опубликовать первый пост в LinkedIn через API

  1. Создайте приложение и подключите продукты

    В LinkedIn Developer Portal откройте My Apps, создайте приложение и во вкладке Products добавьте Sign In with LinkedIn using OpenID Connect и Share on LinkedIn.

  2. Настройте redirect URL

    Во вкладке Auth возьмите Client ID и Client Secret и добавьте абсолютный HTTPS redirect URL. Query-параметры в нём LinkedIn игнорирует, а адреса с # не принимает.

  3. Отправьте участника на авторизацию

    Перенаправьте на https://www.linkedin.com/oauth/v2/authorization с response_type=code, client_id, redirect_uri, state и scope через пробел, например openid profile email w_member_social.

  4. Обменяйте код в течение 30 минут

    Проверьте state, затем отправьте форму с grant_type=authorization_code, code, client_id, client_secret и redirect_uri на https://www.linkedin.com/oauth/v2/accessToken. Код живёт 30 минут.

  5. Получите person URN

    Вызовите GET https://api.linkedin.com/v2/userinfo с токеном. Поле sub — идентификатор участника; автор поста — urn:li:person:{sub}.

  6. Создайте пост

    Отправьте POST на https://api.linkedin.com/rest/posts с заголовками LinkedIn-Version: YYYYMM и X-Restli-Protocol-Version: 2.0.0. В ответе 201 ID поста приходит в заголовке x-restli-id.

Вход и публикация на Python

Явно задайте api_version — поддерживаемый релиз YYYYMM: LinkedIn не подставляет последнюю версию автоматически.

linkedin_post.py
import os
from socialift import LinkedIn

REDIRECT_URI = "https://app.example.com/oauth/linkedin/callback"

def client() -> LinkedIn:
    return LinkedIn(
        client_id=os.environ["LINKEDIN_CLIENT_ID"],
        client_secret=os.environ["LINKEDIN_CLIENT_SECRET"],
        api_version=os.environ.get("LINKEDIN_API_VERSION", "202609"),
    )

async def authorize_url(state: str) -> str:
    async with client() as li:   # scopes по умолчанию: openid profile email w_member_social
        return li.login_url(redirect_uri=REDIRECT_URI, state=state)

async def publish(code: str) -> str:
    async with client() as li:
        bundle = await li.exchange_code(code, redirect_uri=REDIRECT_URI)
        me = await li.me(bundle.access_token)
        post = await li.create_post(
            bundle.access_token,
            author=li.person_urn(me.id),
            text="Опубликовали журнал изменений API за сентябрь.",
            visibility="PUBLIC",
        )
        return post["id"]   # urn:li:share:… или urn:li:ugcPost:…

create_post принимает visibility со значением PUBLIC или CONNECTIONS и читает URN нового поста из заголовка ответа x-restli-id — в теле ответа его нет.

article_url= и article_title= прикрепляют ссылку на статью. Posts API не сканирует URL, поэтому пост покажет только то, что вы отправили: метод задаёт ссылку и заголовок, без миниатюры.

Posts API и устаревший ugcPosts

Posts API и устаревший ugcPosts — Таблица возможностей по платформам
ПараметрPosts APIugcPosts (устаревший)
EndpointPOST /rest/postsPOST /v2/ugcPosts
СтатусАктуальный; LinkedIn указывает, что он заменяет ugcPostsВсё ещё приведён в гайде Share on LinkedIn
Заголовок версииLinkedIn-Version: YYYYMM обязателенБез версий
Заголовок протоколаX-Restli-Protocol-Version: 2.0.0X-Restli-Protocol-Version: 2.0.0
Текст постаcommentaryspecificContent → com.linkedin.ugc.ShareContent → shareCommentary
МедиаURN из Images, Videos и Documents API; посты MultiImage и PollАссеты через /v2/assets?action=registerUpload
ID созданного постаЗаголовок x-restli-id, 201Заголовок X-RestLi-Id, 201

Для новой интеграции выбирайте /rest/posts: у LinkedIn есть отдельное руководство по миграции с ugcPosts на Posts API.

Как работает заголовок LinkedIn-Version

Версионируемые API LinkedIn находятся под https://api.linkedin.com/rest/, и каждый запрос обязан содержать LinkedIn-Version в формате YYYYMM. Версии выходят ежемесячно, каждая поддерживается минимум год. На момент написания статьи последняя версия — 202609 (сентябрь 2026 года).

LinkedIn не переключает на новую версию сам: без заголовка или с выведенной из поддержки версией возвращается ошибка. Документация сейчас предупреждает, что версия 202510 будет отключена 15 октября 2026 года; более старых версий в списке поддерживаемых уже нет.

Endpoint'ы /v2/, например /v2/userinfo, не версионируются. В Socialift SDK версия задаётся один раз на клиент через api_version= (или LINKEDIN_API_VERSION при LinkedIn.from_env()) и отправляется с каждым запросом к /rest/ вместе с X-Restli-Protocol-Version: 2.0.0. Пересматривайте её хотя бы раз в год.

Токены LinkedIn: срок жизни и обновление

Токены LinkedIn: срок жизни и обновление — Таблица возможностей по платформам
ЭлементПоведение LinkedInSocialift SDK
Код авторизацииЖивёт 30 минут; используйте сразуexchange_code
Access token60 дней (expires_in = 5184000); около 500 символов, закладывайте хранение на 1000+Результат exchange_code
Программный refresh tokenТолько одобренным партнёрам (Marketing Developer Platform); действует 365 дней, при обновлении срок не сбрасываетсяrefresh
Refresh token нетПовторите авторизацию; окно согласия пропускается, если участник залогинен в LinkedIn и токен ещё не истёкlogin_url
Смена scopesЗапрос другого набора scopes аннулирует ранее выданные access tokenнет
Статус токенаPOST /oauth/v2/introspectToken возвращает active, status, expires_at, scopeintrospect

естьнет

Проверка токена, повторная авторизация и удаление поста

linkedin_tokens.py
# client() и REDIRECT_URI — из linkedin_post.py

async def ensure_active(token: str, state: str) -> str | None:
    async with client() as li:
        info = await li.introspect(token)
        if info.get("active"):
            return None
        return li.login_url(redirect_uri=REDIRECT_URI, state=state)   # отправляем участника заново

async def remove_post(token: str, post_urn: str) -> None:
    async with client() as li:
        await li.delete_post(token, post_urn)

delete_post кодирует URN в пути запроса, как требует LinkedIn. Удаление идемпотентно: повторное удаление уже удалённого поста снова вернёт 204.

Посты от имени страницы компании: Community Management API

Для публикации от имени организации автор — urn:li:organization:{id}, а токену нужен w_organization_social. Это разрешение ограничено участниками с ролью ADMINISTRATOR, DIRECT_SPONSORED_CONTENT_POSTER или CONTENT_ADMIN на странице и выдаётся только через Community Management API.

Доступ к Community Management API проверяется. Сейчас LinkedIn выдаёт его только зарегистрированным юридическим лицам для коммерческих сценариев: подтверждается рабочий email, указываются юридическое название, адрес, сайт и политика конфиденциальности, а супер-администратор страницы LinkedIn подтверждает приложение. Сначала выдаётся Development tier с ограниченным объёмом вызовов; для Standard tier нужна запись экрана по каждому сценарию. Заявку на Development tier подают для нового приложения без других API-продуктов.

После одобрения тот же вызов create_post работает с URN организации в author, а posts(token, author=...) со scope r_organization_social выводит посты организации.

Данные участников из этих API подпадают под Marketing API Terms LinkedIn: их нельзя использовать для продаж, рекрутинга или обогащения данных CRM, а данные об активности участников можно хранить не дольше 48 часов.

Чего LinkedIn API не даёт

Чтение собственных постов участника требует r_member_social, а LinkedIn обозначает это разрешение как закрытое и не принимает заявки. На практике для большинства приложений li.posts() с person URN вернёт 403; SDK превращает его в PermissionError с пояснением.

Отправка сообщений доступна только одобренным партнёрам, и даже тогда сообщение должно быть связано с конкретным действием участника — автоматическая или запланированная отправка запрещена. Данные лид-форм относятся к отдельной программе Lead Sync. Socialift не предоставляет сообщения и лид-формы LinkedIn.

Лимиты считаются по дням: в документации Share on LinkedIn указано 150 запросов в день на участника и 100 000 на приложение, сутки считаются по UTC.

← Назад в блог

Частые вопросы

Можно ли через Share on LinkedIn публиковать на странице компании?

Нет. Share on LinkedIn даёт w_member_social только для постов от имени участника. Для страницы компании нужен w_organization_social, который выдаётся через Community Management API участникам с ролью администратора или контент-менеджера страницы.

Сколько действует access token LinkedIn?

Сейчас все access token выдаются на 60 дней. Программные refresh token получают только одобренные партнёры; остальные повторяют авторизацию, и если участник залогинен в LinkedIn, а токен ещё действует, окно согласия пропускается.

ugcPosts API в LinkedIn устарел?

LinkedIn указывает, что Posts API заменяет ugcPosts API, и даёт руководство по миграции. Новые интеграции должны использовать /rest/posts с заголовком LinkedIn-Version.

Почему LinkedIn отклоняет запрос из-за версии?

В запросе к /rest/ нет заголовка LinkedIn-Version или указанная версия выведена из поддержки. Каждая версия поддерживается минимум год — обновите заголовок до поддерживаемого значения YYYYMM.

Можно ли читать свои посты или статистику LinkedIn через API?

Для чтения постов участника нужен r_member_social, а это закрытое разрешение. Статистика постов участников входит в сценарии проверяемого Community Management API.

Можно ли отправлять сообщения в LinkedIn через API?

Messages API доступен только одобренным партнёрам, и каждое сообщение должно следовать из конкретного действия участника. Socialift с сообщениями LinkedIn не работает.

Источники

  1. LinkedIn — Posts API
  2. LinkedIn — Sign In with LinkedIn using OpenID Connect
  3. LinkedIn — 3-legged OAuth flow
  4. LinkedIn — Programmatic refresh tokens
  5. LinkedIn — API versioning
  6. LinkedIn — Community Management overview

Связанные страницы