LinkedIn Images API: initializeUpload, upload expiry and image status
LinkedIn's Images API: initializeUpload returns an uploadUrl, expiry and image URN, then status moves to AVAILABLE. The flow and how to prep the file on Sume.

To post an image on LinkedIn through the API, call POST /rest/images?action=initializeUpload with an owner URN, upload the bytes to the returned uploadUrl before uploadUrlExpiresAt, and then wait until the image status is AVAILABLE. The same image URN goes into your post. Sume can make the file; the upload dance is on your side.
What does the flow return?
The initialize call responds with a value holding uploadUrl, uploadUrlExpiresAt (a millisecond timestamp) and the image URN. The page lists the statuses PROCESSING, PROCESSING_FAILED, AVAILABLE and WAITING_UPLOAD, and notes that a downloadUrl returned on reads expires.
| Item | Detail |
|---|---|
| Initialize | POST /rest/images?action=initializeUpload |
| Response | uploadUrl, uploadUrlExpiresAt, image URN |
| Statuses | PROCESSING, PROCESSING_FAILED, AVAILABLE, WAITING_UPLOAD |
| Pixels | fewer than 36,152,320 |
| Formats | JPG, GIF, PNG; GIF up to 250 frames |
How should I schedule the steps?
Generate the image first and keep the bytes, since the upload URL expires and you do not want to regenerate on a retry. Then initialize, upload, poll the status, and only then create the post. A PROCESSING_FAILED status means re-uploading under a new initialize call.
- Generate once, store the file.
- Initialize close to upload time.
- Poll until AVAILABLE.
- Use the same URN for the post.
How do I make the file?
For a feed image, 4:5 or 1:1 in PNG or JPEG works. Request it from Sume Images and download it.
import json, os, urllib.request
body = {
"model": "bytedance-seed/seedream-4.5",
"prompt": "clean abstract header graphic in teal and white, no text",
"aspect_ratio": "4:5",
"output_format": "jpeg"
}
req = urllib.request.Request(
"https://api.sume.com/v1/images",
data=json.dumps(body).encode(),
headers={
"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json",
},
method="POST",
)
print(urllib.request.urlopen(req).read().decode())What should I verify?
Send the version header LinkedIn requires and check the API version policy. See the images guide for Sume's parameters.
Sources
Related posts
More in Integrations
- LinkedIn: reuse one uploaded video in a feed post and a sponsored ad
LinkedIn says a video uploaded through the Videos API can be reused across post formats. Upload your Sume avatar clip once, then reference its URN twice.
- LinkedIn video status PROCESSING_FAILED: read the reason, fix the clip
LinkedIn Videos API returns PROCESSING_FAILED with a processingFailureReason. Probe your Sume clip first and re-upload a clean file instead of guessing.
- LinkedIn Videos API templateName and linkbackContext (202602+)
LinkedIn added templateName and linkbackContext to initializeUpload from version 202602. They credit the tool that made a video. What to send for a Sume render.
- Lovable custom MCP connector for Sume: API key, chat only
Add Sume's hosted MCP server to Lovable as a custom connector with a bearer API key. It informs project chat only and does not power published apps.
Written by Sume