LinkedIn video ad file check in Python before initializeUpload
Check an MP4 against LinkedIn's Videos API range of 75kb to 500MB before you call initializeUpload, and print the fileSizeBytes the request needs.

Before you call LinkedIn's initializeUpload, check the file locally: it must be an MP4, between 75kb and 500MB per the Videos API page (read 2026-10-06), and the request needs its exact byte size as fileSizeBytes. The script below does that with the standard library and no network. It is useful as the last step after a Sume render or trim, because those jobs return a URL and the upload step needs a local file.
Source: LinkedIn Videos API, Microsoft Learn (read 2026-10-06). The page does not say whether kb and MB are decimal or binary, so the script treats 500MB as 500,000,000 bytes, the stricter reading, and tells you when a file sits between the two.
What LinkedIn asks for
initializeUploadRequest takes owner (a person or organization URN), fileSizeBytes, and optional uploadCaptions and uploadThumbnail booleans. The response has uploadInstructions, each with a firstByte, lastByte and uploadUrl; the first byte range is 0 to 4194303 and the next starts at 4194304, so each part is 4 MB. The same page gives 5GB as the maximum for the Videos size, but the video file range quoted above is lower, so use that one for ads.
The check
The script reads a path, rejects anything not ending in .mp4, compares the size against the bounds and prints the part count the upload will need. A part count is ceil(size / 4194304). A file between 500,000,000 and 524,288,000 bytes gets a warning rather than a pass.
import math, os, sys
PART = 4194304
LOW_DEC = 75_000
HIGH_DEC, HIGH_BIN = 500_000_000, 500 * 1024 * 1024
def check(path):
if not path.lower().endswith(".mp4"):
return "reject: not an .mp4"
size = os.path.getsize(path)
if size < LOW_DEC:
return f"reject: {size} bytes is under the 75kb floor"
if size > HIGH_BIN:
return f"reject: {size} bytes is over 500MB"
note = " (between decimal and binary 500MB, risky)" if size > HIGH_DEC else ""
parts = math.ceil(size / PART)
return f"ok: fileSizeBytes={size}, parts={parts}{note}"
if __name__ == "__main__":
print(check(sys.argv[1] if len(sys.argv) > 1 else __file__))
Why not just let LinkedIn refuse it?
A refusal costs a round trip and, worse, a half-finished upload session. The video's status can come back PROCESSING_FAILED with a processingFailureReason after you have uploaded every part, which wastes the upload time. A local check is free. It also catches the case that matters most for generated video: a render that is fine for your player but huge because you asked for 4K when 1080p would do.
| Item | Value | Where it matters |
|---|---|---|
| Format | MP4 | Reject other extensions |
| Size range | 75kb to 500MB | Check both bounds |
| Part size | 4 MB (first range 0 to 4194303) | Count parts from fileSizeBytes |
| Captions | One file, English only | For ads it must process to serve |
| Status | PROCESSING, PROCESSING_FAILED, AVAILABLE, WAITING_UPLOAD | Poll after finalizeUpload |
Where Sume fits
Make the file with the surfaces that give you control of size: a timeline render lets you set output.width, output.height and output.fps, and trim can conform them on an exact cut. Download the result, run the check, then upload. The stored post on LinkedIn's 4 MB parts and ETags walks through the finalize step. For the render options see Timeline 1.0: assemble clips into one MP4, and for the cut see Video trim: cut a range from one Sume-hosted clip.
Sources
Related posts
More in Use cases
- LinkedIn video ad thumbnail: pick a still with video frames
LinkedIn's initializeUpload takes an optional thumbnail. Pull up to 24 candidate stills from your MP4 with POST /v1/video-frames and pick one.
- Live-commerce clip webhook: verify the Sume signature in Python
Verify a Sume webhook in Python: HMAC SHA256 over timestamp.raw_body, any sume-v1 entry, a 300-second window, and reject an empty secret.
- Only 12 left badge over a product clip: compose overlay, $0.02
A low-stock badge on a product clip is $0.02 per variant with Sume compose overlay. Set position, width_ratio and margin_ratio; re-render as stock drops.
- Meta One plan prices vs 20 ad clips on Sume: $6.40
Meta One's four plans run $14.99 to $499 a month. Twenty clips through Sume's trim, caption and timeline jobs cost $6.40. What the two numbers measure.
Written by Sume