Skip to content
reelspanDocs

Publish

Post a document

Publish a PDF, PowerPoint or Word file to LinkedIn as a swipeable document post, from a file, a link or an earlier upload, now or scheduled.

POSTapi.reelspan.com/v1/posts/documentTry it →

LinkedIn shows a document (PDF, PowerPoint or Word) as a carousel readers swipe through, page by page, under the post. Send the file as multipart/form-data with the profile in user and platform[]=linkedin.

A first document

curl -X POST https://api.reelspan.com/v1/posts/document \
  -H "Authorization: Bearer $REELSPAN_API_KEY" \
  -H "Idempotency-Key: q3-report-post" \
  -F "user=my-brand" \
  -F "platform[]=linkedin" \
  -F "title=Q3 report" \
  -F "description=Our quarter in 12 slides: what grew, what didn't, and what's next." \
  -F "[email protected]"

The document

  • Format: PDF, PowerPoint (.pptx, .ppt) or Word (.docx, .doc). Reelspan reads the type from the file's own bytes, not its name or Content-Type. Other files, spreadsheets included, are refused with 400 UNSUPPORTED_MEDIA.
  • Size: up to 100 MB. LinkedIn takes up to 300 pages.
  • Where from: a file in document, a public https URL in document (Google Drive and Dropbox share links work), or document_media_id from an upload made with kind=document. Without any of them the answer is 400 MEDIA_REQUIRED.
curl -X POST https://api.reelspan.com/v1/posts/document \
  -H "Authorization: Bearer $REELSPAN_API_KEY" \
  -F "user=my-brand" \
  -F "platform[]=linkedin" \
  -F "title=Q3 report" \
  -F "document=https://example.com/q3-report.pdf"

Title and post text

The two texts do different jobs:

  • title names the document; LinkedIn shows it on the document itself. It is required (400 TITLE_REQUIRED without it) and is cut to 400 characters. document_title names the document differently from the post's title if you need both.
  • The post text above the document is linkedin_description, else description, else linkedin_title, else title.

LinkedIn only

Documents go to LinkedIn only. Naming any other network gets 400 UNSUPPORTED_POST_TYPE and nothing is posted. The sandbox network doesn't take documents either, so to try this without publishing, use a test key with a LinkedIn account connected to the profile.

Settings

Field What it does
visibility PUBLIC (the default), CONNECTIONS, LOGGED_IN or CONTAINER, passed to LinkedIn as given. linkedin_visibility works too.
first_comment Posted as the first comment once the post is live. linkedin_first_comment works too.
target_linkedin_page_id Post as a LinkedIn Company Page instead of the member.

Reelspan doesn't have LinkedIn's company-page access yet, so GET /v1/linkedin/pages returns an empty list for now and posting as a Company Page may be refused by LinkedIn. Posting as the connected member works.

The response

LinkedIn processes the document before it can be posted, which can take a while for a long document. When it finishes within the request, the LinkedIn result also names the document:

{
  "success": true,
  "request_id": "a3e0c5d7b9f14e2a8c6b0d4f2e8a1c3b",
  "results": {
    "linkedin": {
      "success": true,
      "url": "https://www.linkedin.com/feed/update/urn:li:share:72…/",
      "post_id": "urn:li:share:72…",
      "document_urn": "urn:li:document:D4E…",
      "content_type": "application/pdf",
      "file_size": 2481152,
      "filename": "q3-report.pdf"
    }
  },
  "usage": { "count": 5, "limit": null, "last_reset": "2026-11-01T00:00:00.000Z" }
}

When it takes longer than 59 seconds, or you sent async_upload=true, the answer has a message and the request_id; follow it with Post status or a webhook.

Later or repeated

scheduled_date with timezone, add_to_queue=true, or repeat_every with repeat_times work as for every other post; a scheduled answer is 202 with a job_id. See Scheduled posts.

Parameters

  • Idempotency-Keystring · header

    Makes retries safe: the same key within 24 hours returns the first answer (X-Idempotency-Key works too)

  • X-Request-Idstring · header

    Your own request_id (8-100 letters, digits, _ or -), and the idempotency key when none is sent

  • X-External-Idstring · header

    Same as the external_id field, for your own reference

Request body

multipart/form-data

  • userstringrequired

    Profile username

  • platform[]string[]required

    linkedin

  • documentstring

    The PDF, PowerPoint (PPTX, PPT) or Word (DOCX, DOC) file (binary) or a public https URL; up to 100 MB and 300 pages

  • document_media_idstring

    A document uploaded earlier with POST /v1/media/upload?kind=document

  • titlestringrequired

    The document’s title on LinkedIn (up to 400 characters)

  • descriptionstring

    The post text above the document

  • visibilitystring

    PUBLICCONNECTIONSLOGGED_INCONTAINER

  • target_linkedin_page_idstring

    Post as this Company Page

  • first_commentstring
  • async_uploadstring

    truefalse

  • scheduled_datestring
  • timezonestring
  • repeat_everystring

    dayweekmonth

  • repeat_timesstring

Responses

200 Per-platform results, or a request_id when it runs in the background

{
  "success": true,
  "request_id": "string"
}

202 Scheduled

{
  "success": true,
  "job_id": "string",
  "request_id": "string",
  "scheduled_date": "string"
}

400 Invalid request

{
  "success": false,
  "message": "string",
  "error": "string",
  "error_code": "string"
}

Something unclear or missing? Write to [email protected] and we’ll fix the page.