Facebook Pixel
ApiLinkedin posts

Schedule a LinkedIn post for later

Queues a post for publication, optionally boosting it once it goes live. Omit `scheduledAt` to publish as soon as possible; supply it to schedule for later. Prefer this over create-post whenever you want a first comment, reposts or a boost attached, since those only exist here. `scheduledAt` is an absolute UTC timestamp and must be in the future. `timezone` is an IANA name (for example "Asia/Kolkata"); it is stored with the post and decides which local day a boost slot falls on, but it never changes when the post publishes — `scheduledAt` alone does that. Media the easy way: set `mediaType` and pass `fileUrl` — a public URL to the image or video — and the server downloads it and uploads it to LinkedIn for you. No pre-signed upload, no multipart form, one call. Limit 30MB. If you already uploaded through /posts/upload/init you can pass `assetUrn` instead (or 2-9 entries in `assetUrns` for a carousel, or `assetUrn` plus `recipes` for a video). Pass `fileUrl` or the pre-uploaded URNs, never both. Documents/PDFs and polls cannot be scheduled — publish a document immediately with create-post instead. Boost (optional) fires after the post is live and needs a paid plan: free plans get 403 and can only boost an already published post from the web app. Boost targets are clamped to the plan caps rather than rejected, so read the `boost` object in the response to see what was actually applied. A full boost quota returns 409 — call get-scheduled-week first to see which days still have a slot.

POST/posts/schedule
Authentication requiredPosts

Code Examples

curl -X POST 'https://api.connectsafely.ai/linkedin/posts/schedule' \
-H 'Authorization: Bearer <your_api_key>' \
-H 'Content-Type: application/json' \
-d '{"text":"Three things we learned shipping our API this quarter.","scheduledAt":"2026-09-15T09:30:00.000Z","timezone":"Asia/Kolkata","companyUrn":"urn:li:fsd_company:105672170","fileUrl":"https://example.com/chart.png","thumbnailUrl":"https://example.com/poster.jpg"}'

Queues a post for publication, optionally boosting it once it goes live. Omit scheduledAt to publish as soon as possible; supply it to schedule for later. Prefer this over create-post whenever you want a first comment, reposts or a boost attached, since those only exist here.

scheduledAt is an absolute UTC timestamp and must be in the future. timezone is an IANA name (for example "Asia/Kolkata"); it is stored with the post and decides which local day a boost slot falls on, but it never changes when the post publishes — scheduledAt alone does that.

Media the easy way: set mediaType and pass fileUrl — a public URL to the image or video — and the server downloads it and uploads it to LinkedIn for you. No pre-signed upload, no multipart form, one call. Limit 30MB.

If you already uploaded through /posts/upload/init you can pass assetUrn instead (or 2-9 entries in assetUrns for a carousel, or assetUrn plus recipes for a video). Pass fileUrl or the pre-uploaded URNs, never both. Documents/PDFs and polls cannot be scheduled — publish a document immediately with create-post instead.

Boost (optional) fires after the post is live and needs a paid plan: free plans get 403 and can only boost an already published post from the web app. Boost targets are clamped to the plan caps rather than rejected, so read the boost object in the response to see what was actually applied. A full boost quota returns 409 — call get-scheduled-week first to see which days still have a slot.

Parameters

No parameters.

Request Body

FieldTypeRequiredDescription
accountIdstringNoWhich connected account posts. Omit to use the default account.
textstringYesThe post body (max 3,000 characters).
scheduledAtstringNoWhen to publish, as an absolute UTC timestamp in the future. OMIT IT TO PUBLISH NOW — which still gives you the first comment on its natural delay, plus reposts and boost, in a single call. The response returns status PENDING with an id; read list-scheduled-posts for publishedUrl once it goes live.
timezonestringNoIANA timezone name stored with the post and used for boost day windows. Defaults to UTC.
companyUrnstringNoOptional. Publish as a company page you administer instead of your personal profile.
mediaTypestringNoWhat you are posting. Use "image" for a carousel too (with assetUrns). Documents are not schedulable.
fileUrlstringNoPublic URL of the image or video. The server downloads it and uploads it to LinkedIn, so you do not need to upload anything yourself. Max 30MB. Use this OR assetUrn/assetUrns, not both.
assetUrnstringNoAlternative to fileUrl: an asset you already uploaded via /posts/upload/init.
assetUrnsarrayNoCarousel only: 2-9 uploaded images, each { assetUrn, altText? }. Use instead of assetUrn with mediaType "image".
recipesarrayNoFrom /posts/upload/init. Required for a pre-uploaded video; not needed with fileUrl.
thumbnailUrlstringNoPreview image shown in the ConnectSafely composer. Generated for you when you pass an image fileUrl. Pass it yourself for video, or when supplying a pre-uploaded assetUrn — without one the composer shows no media for the post (the published post is unaffected).
altTextstringNoAccessibility alt text for the image. Always set this.
firstCommentstringNoPosted as a comment 20-30 seconds after the post goes live.
repostsarrayNoOther connected accounts that reshare this post after a delay.
boostobjectNoOptional engagement boost that runs after the post publishes. Requires a paid plan.

Example

{
  "text": "Three things we learned shipping our API this quarter.",
  "scheduledAt": "2026-09-15T09:30:00.000Z",
  "timezone": "Asia/Kolkata",
  "companyUrn": "urn:li:fsd_company:105672170",
  "fileUrl": "https://example.com/chart.png",
  "thumbnailUrl": "https://example.com/poster.jpg"
}

Responses

StatusDescription
200Post scheduled
400Validation failed, the time is in the past, the account cannot post, or fileUrl could not be downloaded / was over 30MB
401Unauthorized
403Boost requires a paid plan. Free plans cannot schedule a boost at all — this is not a quota that clears with time.
409Boost quota for that window is already spent. The body carries quota usage; get-scheduled-week shows which days are still open.
500Server error
503The scheduler queue is unavailable and nothing was queued — retry.

200 Response Parameters

NameTypeDescription
successboolean
idstringScheduled post id — pass it to delete-scheduled-post to cancel.
statusstring
scheduledAtstring (date-time)
timezonestring
accountIdstring
boostobjectPresent only when a boost was attached. Shows the targets actually applied after plan caps were enforced, which may be lower than requested.

200 Example

{
  "success": true,
  "id": "12345",
  "status": "PENDING",
  "scheduledAt": "2024-01-15T10:30:00.000Z",
  "timezone": "2024-01-15",
  "accountId": "acc_12345",
  "boost": {}
}

400 Response Parameters

NameTypeDescription
errorstring

400 Example

{
  "error": "example_value"
}

401 Response Parameters

NameTypeDescription
errorstring

401 Example

{
  "error": "example_value"
}

403 Response Parameters

NameTypeDescription
errorstring

403 Example

{
  "error": "example_value"
}

409 Response Parameters

NameTypeDescription
errorstring

409 Example

{
  "error": "example_value"
}

500 Response Parameters

NameTypeDescription
errorstring

500 Example

{
  "error": "example_value"
}

503 Response Parameters

NameTypeDescription
errorstring

503 Example

{
  "error": "example_value"
}

On this page