LinkedIn EXPIRED_UPLOAD_URL (400): why it happens and how to retry
LinkedIn upload URLs expire, and uploading to one after uploadUrlsExpireAt fails. Re-run initializeUpload and send the Sume clip again. Here is the flow.

EXPIRED_UPLOAD_URL is a 400 on the LinkedIn Videos API that says the video upload URL is expired. The fix is to call initializeUpload again for a fresh video URN and upload instructions, then upload the file once more. It is a queue problem more than a file problem: a clip waited too long between initialize and upload.
When do LinkedIn upload URLs expire?
The initialize response carries uploadUrlsExpireAt, in milliseconds since the epoch, and LinkedIn says all upload URLs expire at the same time. Uploading to an expired URL throws a 401, and the page lists EXPIRED_UPLOAD_URL as a 400 error for the expired upload URL. The page says URLs typically expire 30 days after the upload is initialized, so a stuck pipeline can run for weeks before it hits this, which is why it often surprises teams that cache upload instructions.
| Field or error | What the page says |
|---|---|
| uploadUrlsExpireAt | Epoch milliseconds; all URLs expire at the same time |
| Typical lifetime | About 30 days from initialization |
| Upload to an expired URL | Throws a 401 |
| EXPIRED_UPLOAD_URL | 400: the video upload URL is expired |
| MEDIA_ASSET_WAITING_UPLOAD | 400: the asset is still waiting for its upload |
What is the safe retry order?
Do not reuse the old video URN after an expiry. Initialize again, take the new uploadInstructions and uploadToken, upload each part, collect the ETags, and finalize. The video file is split in 4 MB parts, and the finalize body lists the part ids in the same order as the instructions.
If you referenced the old URN in a post before the upload finished, you will hit MEDIA_ASSET_WAITING_UPLOAD. Create the post only after the video status reads AVAILABLE.
Where does the Sume clip sit meanwhile?
A finished Sume job returns its video on a media.sume.com artifact URL, and you read it back with GET /v1/jobs/:id/result. Store the job id from the submit response, as the jobs docs advise, and you can fetch the result again instead of regenerating. I could not confirm a retention period for results in the docs, so do not rely on an old link surviving indefinitely; re-read the job result when you retry.
Never regenerate to retry an upload. A new avatar render is billed again, whereas a repeat upload of the same file is just LinkedIn bandwidth. If you do need to resubmit generation after a network error, send the same Idempotency-Key as the first request.
curl https://api.sume.com/v1/jobs/job_123/result \
-H "Authorization: Bearer $SUME_API_KEY"Limits of this advice
Sume does not hold your LinkedIn upload session and does not publish for you according to the docs I read. Initialization, part upload and finalization are your code. The 30-day figure is LinkedIn's "typically" and not a guarantee, so always read uploadUrlsExpireAt from the response and compare against the clock before each part.
Sources
Related posts
More in Integrations
- 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.
- LinkedIn multiImage post: 2-20 images, alt text up to 4,086 characters
A LinkedIn multiImage post takes 2 to 20 images, JPG, GIF or PNG under 36,152,320 pixels, with per-image alt text. Make a matching set with Sume Images.
- 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.
Written by Sume