API Docs/Reference/Schedule Post
API Reference

Schedule Post

Schedule a draft for publishing now, at the next open slot, or at a specific time. Requires a paid Creator or Lifetime plan.

POSThttps://api.linkedmash.com/v1/posts/{id}/schedule

POST /v1/posts/{id}/schedule takes an existing draft and either publishes it immediately or places it in the posting queue. publish_at drives the behaviour: 'now' publishes straight to LinkedIn, 'next-slot' resolves the next free slot from the account's posting schedule, and an ISO-8601 timestamp schedules that exact time.

timezone is an IANA name and is required for everything except 'now', because a wall-clock time without a zone is ambiguous. Media can be attached at schedule time with post_type, media_url and media_mime_type if it was not attached to the draft.

Example request

Authenticate with a bearer token in the Authorization header. Create a key on the API page in your LinkedMash settings and export it as LINKEDMASH_API_KEY before running this.

curl
curl -X POST "https://api.linkedmash.com/v1/posts/drf_8f3a21c9/schedule" \
  -H "Authorization: Bearer $LINKEDMASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "publish_at": "next-slot",
    "timezone": "Europe/Berlin"
  }'

Path parameters

idstringRequired

The id of the draft to schedule.

Header parameters

AuthorizationstringRequired

Your secret API key as a Bearer token.

Body parameters

publish_atstringRequired

'now', 'next-slot', or an ISO-8601 timestamp.

timezonestringOptional

IANA timezone. Required unless publish_at is 'now'.

post_typestringOptional

Media type to attach: text, image, video, or pdf.

media_urlstringOptional

Public URL of an image, video, or PDF to attach.

media_mime_typestringOptional

MIME type of the attached media (e.g., 'image/png').

Response

{
  "status": true,
  "data": {
    "ok": true,
    "scheduleId": "sch_3a9f81d2",
    "runAtUTC": "2026-06-24T08:30:00.000Z"
  }
}

Response fields

Every response is wrapped in the same envelope: a status flag and a data payload, with meta present where there is pagination or a plan limit to report.

statusboolean

true on success. Every LinkedMash API response carries this envelope flag alongside data, so a client can branch on it without re-reading the HTTP status.

data.okboolean

true when the post was queued.

data.scheduleIdstring

Identifier for the queue entry. This — not the draft id — is what DELETE /v1/queue/{scheduleId} and the reschedule route take.

data.runAtUTCstring

The resolved publish time in UTC. Worth reading back when you sent next-slot, since that is the only way to learn which slot you got.

data.publishedboolean

Returned instead of scheduleId when publish_at was "now". That branch answers 200 rather than 201.

Choosing between now, next-slot and an explicit time

The three modes have genuinely different failure cases, so pick deliberately rather than defaulting.

1

Explicit time, for a planned calendar

Send an ISO-8601 publish_at plus an IANA timezone. This is the only mode where you know the publish moment before you call, which is what a content calendar needs.

2

next-slot, for a queue-driven workflow

Send publish_at as 'next-slot' with a timezone. The route resolves the next free slot from the account's grid and returns runAtUTC — read it back, because that is the only place the chosen time appears.

3

now, for immediate publishing

Publishes the draft's text straight away and answers 200 with published: true, not 201 with a scheduleId. Media is not attached on this path, and an empty draft is rejected with 400.

4

Keep the scheduleId

Cancelling and rescheduling both take scheduleId, not the draft id. If you do not store it you have to re-read GET /v1/queue to find it again.

Behaviour and limits

Requires a Creator or Lifetime plan

Everything under /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics sits behind one middleware that checks for an unlocked Studio, so a Reader-plan or free key gets 402 with code SUBSCRIPTION_REQUIRED before the handler runs. Bookmark and label reads are on a separate router and are not affected by this gate.

'now' publishes text only, and checks it first

The immediate path reads the draft, extracts its text, and refuses with 400 if it is empty or whitespace. It publishes that text — schedule an explicit time if the post needs media attached.

'next-slot' fails loudly when there is no slot

If the posting schedule yields no free slot the call returns 400 telling you to configure a schedule or pass an explicit time, rather than quietly picking one. Read GET /v1/queue/slots first if you want to know the time in advance.

Returns 201 with a scheduleId

A successful schedule answers 201 with scheduleId and runAtUTC. That scheduleId — not the draft id — is what DELETE /v1/queue/{scheduleId} and the reschedule route take.

'now' returns 200, not 201

The immediate-publish branch answers 200 with { id, published: true }. Branch on the publish_at you sent rather than on the status code.

Errors

Failures carry the same envelope as a success, with the reason in message and a stable machine-readable code where the status alone is ambiguous — several distinct conditions share a 402.

Status
Meaning
400Bad Request
publish_at missing; timezone missing for a non-'now' publish; empty draft text on 'now'; or no free slot available for 'next-slot'.
401Unauthorized
The Authorization header is missing or the key is not a valid LinkedMash API key. Create or rotate keys on the API page in your LinkedMash settings.
402Payment Required
Returned with code SUBSCRIPTION_REQUIRED. The content API requires a Creator or Lifetime plan; Reader and free accounts get this on every /v1/posts, /v1/queue, /v1/schedule, /v1/media and /v1/analytics call.
404Not Found
No draft with that id on this account.
500Server Error
Something failed on our side. The body carries message "Failed to schedule post". Retry once; if it persists the request is not the problem.