Platforms
Connect a LinkedIn personal profile, publish text, images, video and document posts with a first comment, and keep the account connected.
Publish text, images, video and documents as a LinkedIn member.
Quick Reference
| Property | Value |
|---|---|
| Account types | Personal profiles, not company pages |
| Connection method | OAuth |
| Post types | text, image, multi_image, video, document |
| Max media per post | 20 |
| Text limit | 3,000 characters |
| Threads | No |
| Quotes | No |
| Remote delete | |
| Comments | No |
| Likes | No |
| Reposts | No |
| Bookmarks | No |
| Direct messages | No |
| Post analytics | No |
| Account analytics | No |
Only personal profiles connect, and every post is public. LinkedIn has no comments, likes, inbox or analytics here, but takes a first comment.
Connect
Connect in Dashboard → Connections, or with a connect session. Each account posts as one member. Other members connect their own accounts.
Permissions
| Scope | Used for |
|---|---|
openid | LinkedIn sign-in |
profile | Name and photo |
w_member_social | Posting, media, first comments and deletes |
Staying Connected
canAutoRenew tells you when to reconnect.
canAutoRenew | Access | Reconnect |
|---|---|---|
true | Renews itself for up to 1 year | When status leaves active, or within a year |
false | Ends at tokenExpiresAt, after 60 days | Before tokenExpiresAt |
Scheduled posts need a live account
A post due after access ends fails with TOKEN_INVALID. Check tokenExpiresAt before you schedule, and reconnect if the post is due later.
Each reconnect starts a new 60 days. Access also ends if the member removes Onepostly. A reconnect keeps the id. Then publish failed posts again.
Publish
import { Configuration, PostsApi } from "@onepostly/sdk";
const postsApi = new PostsApi(
new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);
const response = await postsApi.createPost({
createPostBody: {
"text": "The 2027 State of Social Publishing report",
"mediaKind": "document",
"media": [
{
"url": "https://cdn.onepostly.com/media/state-of-publishing-2027.pdf"
}
],
"accounts": [
{
"accountId": "acc_YOUR_LINKEDIN_ACCOUNT_ID"
}
]
},
});
console.log(response);{
"groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
"data": [
{
"id": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
"groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
"accountId": "acc_YOUR_LINKEDIN_ACCOUNT_ID",
"platform": "linkedin",
"source": "onepostly",
"status": "publishing",
"text": "The 2027 State of Social Publishing report",
"mediaKind": "document",
"media": [
{
"url": "https://cdn.onepostly.com/media/state-of-publishing-2027.pdf"
}
],
"thread": [],
"scheduledFor": null,
"timezone": null,
"options": {},
"platformPostId": null,
"url": null,
"error": null,
"publishedAt": null,
"metrics": null,
"createdAt": "2027-03-15T09:00:00.000Z",
"updatedAt": "2027-03-15T09:00:00.000Z"
}
]
}A LinkedIn post has no url. Build it from platformPostId. The link is https://www.linkedin.com/feed/update/ plus the platformPostId.
Post Types
mediaKind | Publishes | Media |
|---|---|---|
text | Text post | None, text required |
image | Image post | 1 image |
multi_image | Image set | 2 to 20 images |
video | Video post | 1 video |
document | Swipeable document | 1 PDF, PPT, PPTX, DOC or DOCX |
- Text goes up to 3,000 characters. Without
mediaKind, the files decide. storiesreturns400 VALIDATION_ERROR.- A video in an image set fails with
INVALID_MEDIA.
The first 200 characters of the text become a video or document title. A document without any text is titled Document.
Videos take longer, and slow ones fail with MEDIA_PROCESSING_TIMEOUT.
Text Formatting
Text is posted exactly as written. @name stays plain text, with no mention. *, _, ~, | and brackets show as typed too, not as formatting.
#word becomes a hashtag, and line breaks are kept.
Duplicate Content
LinkedIn rejects a repeat of a post the member already made. It fails with PUBLISH_FAILED. Change the text, then post again.
Options
Options go under linkedin.
Prop
Type
First Comment
firstComment adds a comment from the member, on any post type. If LinkedIn refuses the comment, the post still publishes without it.
import { Configuration, PostsApi } from "@onepostly/sdk";
const postsApi = new PostsApi(
new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);
const response = await postsApi.createPost({
createPostBody: {
"text": "Version 3.0 is out.",
"mediaKind": "image",
"media": [
{
"url": "https://cdn.onepostly.com/media/release-3.jpg"
}
],
"accounts": [
{
"accountId": "acc_YOUR_LINKEDIN_ACCOUNT_ID",
"linkedin": {
"firstComment": "Release notes: https://example.com/changelog"
}
}
]
},
});
console.log(response);{
"groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
"data": [
{
"id": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
"groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
"accountId": "acc_YOUR_LINKEDIN_ACCOUNT_ID",
"platform": "linkedin",
"source": "onepostly",
"status": "publishing",
"text": "Version 3.0 is out.",
"mediaKind": "image",
"media": [
{
"url": "https://cdn.onepostly.com/media/release-3.jpg"
}
],
"thread": [],
"scheduledFor": null,
"timezone": null,
"options": {
"linkedin": {
"firstComment": "Release notes: https://example.com/changelog"
}
},
"platformPostId": null,
"url": null,
"error": null,
"publishedAt": null,
"metrics": null,
"createdAt": "2027-03-15T09:00:00.000Z",
"updatedAt": "2027-03-15T09:00:00.000Z"
}
]
}Media Requirements
These are LinkedIn's limits, on top of the Media URL Requirements.
| Media | Formats | Max size |
|---|---|---|
| Images | JPEG, PNG and GIF | 30 MB |
| Videos | MP4 | 500 MB |
| Documents | PDF, PPT, PPTX, DOC and DOCX | 100 MB |
A file outside these formats and sizes is refused. See Platform Limits.
Images
| Property | Requirement |
|---|---|
| Per post | 1, or 2 to 20 on multi_image |
Videos
| Property | Requirement |
|---|---|
| Min size | 75 KB |
| Duration | 3 s to 30 min |
| Per post | 1, alone |
Documents
| Property | Requirement |
|---|---|
| Max pages | 300 |
| Per post | 1, alone |
The URL must send a document Content-Type. See Supported Formats.
Scheduling, Editing and Deleting
Scheduling and editing work as usual. Published posts cannot be edited. With canAutoRenew: false, reconnect before any post due after tokenExpiresAt. Deleting removes the post. A post already gone counts as deleted.
Engagement
LinkedIn has no comments, likes, reposts or bookmarks here. Those calls return UNSUPPORTED_PLATFORM. Use a first comment instead.
Inbox
LinkedIn has no inbox through Onepostly.
Analytics
LinkedIn reports no metrics here. A post reads pending, then unsupported for good. Account stats and insights return UNSUPPORTED_PLATFORM.
Limitations
Not available for LinkedIn through Onepostly.
- Company pages
- Polls, articles, reshares and quotes
- Threads and Stories
- Mentions,
@namestays plain text - Visibility, every post is public
- Custom video thumbnails or captions
- Editing a published post
- A post
url - Comments, likes and messages
- Analytics
- Sync of outside posts
Errors
Breaking a rule on this page returns 400 VALIDATION_ERROR and creates nothing. A file outside the formats and sizes is refused as Platform Limits describes. LinkedIn's other limits are checked at publish and fail with INVALID_MEDIA. Every code is in Errors, with its cause and fix.
| Code | Cause | Fix |
|---|---|---|
TEXT_REQUIRED | A text post with no text | Add text or media |
INVALID_MEDIA | Too many files, mixed video, or a video under 75 KB | See Media Requirements |
MEDIA_UPLOAD_FAILED | LinkedIn could not take the file | Check it opens, then post again |
MEDIA_PROCESSING_TIMEOUT | The video took too long | Use a smaller or shorter file |
PUBLISH_FAILED | Rejected, such as a duplicate | Read error.message |
QUOTA_EXCEEDED | LinkedIn's daily post or delete limit | Try again after it resets |
DELETE_PERMISSION | LinkedIn refused the delete | Reconnect, then delete again |