TL;DR, Quick Answer
7 min readTikTok's Media Transfer Guide sets four chunk rules: each chunk is at least 5 MB and no more than 64 MB, the final chunk may run up to 128 MB, there must be between 1 and 1000 chunks, and total_chunk_count equals video_size divided by chunk_size "rounded down to the nearest integer." Rounding up is the bug that breaks most first integrations. TikTok's own whole-upload example then sends a 4,194,304 byte chunk, under its own 5 MB floor, and the docs never say whether MB means 1,000,000 or 1,048,576 bytes. There is no dedicated error code for bad chunk arithmetic: the init call returns 400 invalid_param, and a mismatched PUT returns 400 or 416.
What does the TikTok API chunk_size field do?
The TikTok API chunk_size field tells TikTok's servers how many bytes each PUT request will carry when you transfer a video with source: "FILE_UPLOAD". You declare it once, in the body of the init call, before a single byte of video moves. Everything TikTok validates afterwards is checked against that declaration.
Three fields travel together inside source_info, and TikTok describes them like this:
| Field | Type | TikTok's description |
|---|---|---|
video_size | int64 | "The size of the video to be uploaded in bytes." |
chunk_size | int64 | "The size of the chunk in bytes." |
total_chunk_count | int64 | "The total number of chunks." |
Both init endpoints accept them. /v2/post/publish/inbox/video/init/ is the Upload endpoint, which drops a draft into the creator's inbox. /v2/post/publish/video/init/ is the Direct Post endpoint, which publishes straight to the profile. The Upload reference marks all three fields "true for FILE_UPLOAD". The Direct Post reference marks video_size "true for FILE_UPLOAD" and leaves the required column empty for chunk_size and total_chunk_count. TikTok never states that the two fields are optional on Direct Post, and the chunk rules it publishes are written once for both endpoints, so treat the blank cells as a formatting artefact and send all three.

What is the minimum and maximum TikTok chunk size?
Each chunk must be at least 5 MB and no larger than 64 MB, with one exception at the end of the file. TikTok's Media Transfer Guide states it as follows:
"Each chunk must be at least 5 MB but no greater than 64 MB, except for the final chunk, which can be greater than
chunk_size(up to 128 MB) to accommodate any trailing bytes."
Three more sentences in the same list finish the rule set:
| Rule | TikTok's wording |
|---|---|
| Small files | "Videos with a total size less than 5 MB must be uploaded as a whole, with chunk_size equal to the entire video's byte size." |
| Large files | "Videos with a total size greater than 64 MB must be uploaded in multiple chunks." |
| Chunk count | "There must be a minimum of 1 chunk and a maximum of 1000 chunks." |
| Ordering | "File chunks must be uploaded sequentially." |
The ordering rule is the one people discover late. Chunks cannot be fanned out across workers, because TikTok tracks a single byte offset per upload task and answers 416 RequestedRangeNotSatisfiable when a Content-Range header arrives out of order.
How is total_chunk_count calculated?
Divide and round down, never up. TikTok's exact sentence:
"The value of
total_chunk_countshould be equal tovideo_sizedivided bychunk_size, rounded down to the nearest integer."
TikTok's worked example is a 50,000,123 byte file with a chunk_size of 10,000,000. Fifty million divided by ten million is five point zero zero zero zero one two three, so total_chunk_count is 5, not 6. The 123 trailing bytes do not get their own request. They ride along in the fifth chunk, which is therefore 10,000,123 bytes, slightly larger than the chunk_size you declared:
| Request | Content-Range | Bytes in this chunk | Status |
|---|---|---|---|
| 1 | bytes 0-9999999/50000123 | 10,000,000 | 206 |
| 2 | bytes 10000000-19999999/50000123 | 10,000,000 | 206 |
| 3 | bytes 20000000-29999999/50000123 | 10,000,000 | 206 |
| 4 | bytes 30000000-39999999/50000123 | 10,000,000 | 206 |
| 5 | bytes 40000000-50000122/50000123 | 10,000,123 | 201 |
This is where a ceiling function quietly breaks an integration. Rounding up gives a sixth chunk of 123 bytes, which is both a chunk TikTok is not expecting and a chunk far below the 5 MB floor. The same logic explains why TikTok permits a final chunk of up to 128 MB: with a 64 MB chunk_size, the leftover bytes merge into the last full chunk and can push it towards twice the declared size.
The whole-upload case is the degenerate version of the same formula. A 4,194,304 byte file with chunk_size 4,194,304 divides to exactly 1, so total_chunk_count is 1 and the single PUT returns 201 Created instead of 206.
- total_chunk_count = 5
- Chunk 5 carries the trailing 123 bytes, 10,000,123 bytes total
- The final PUT returns 201 Created
- total_chunk_count = 6
- Chunk 6 is 123 bytes, a request TikTok never expects
- 123 bytes sits far under the 5 MB floor
Where do TikTok's own chunk rules contradict each other?
Three gaps sit on the same documentation page, and each one costs a debugging session.
The floor contradicts the example. TikTok writes that "each chunk must be at least 5 MB" and then publishes a whole-upload example in which the only chunk is 4,194,304 bytes, which is 4 MB. The carve-out is real, since sub 5 MB videos "must be uploaded as a whole", but the floor is written as an absolute a few lines above the example that violates it. The workable reading: the 5 MB floor applies to every chunk of a multi-chunk upload, and a single-chunk upload is exempt.
AdaptlyPost
Start 7-Day FREE Trial
All-platform analytics
Social Inbox
AI-powered assistant
MB is never defined. TikTok uses MB for the floor, the ceiling and the final-chunk allowance without saying whether it means 1,000,000 or 1,048,576 bytes. Its two examples do not agree either. The chunked example uses a decimal 10,000,000 byte chunk; the whole-upload example uses a binary 4,194,304 byte file. A 5,000,000 byte chunk is 5 MB by the decimal reading and 4.77 MiB by the binary one. TikTok publishes no answer, so the safe move is to clear both bars at once and never send a non-final chunk under 5,242,880 bytes.
The 1000 chunk cap can never be reached. TikTok caps video files at "Maximum of 4GB" and caps chunk counts at 1000, while flooring chunks at 5 MB. A 4 GB file split into 5 MB chunks is 800 requests on the decimal reading and 819 on the binary one. Both sit comfortably under 1000, so the chunk-count cap is dead weight unless TikTok raises the file-size limit. The limit that actually binds your loop is the one-hour lifetime of the upload_url, exactly as it does with Instagram's resumable upload protocol.

What errors come back when the chunk arithmetic is wrong?
TikTok publishes no dedicated error code for chunk maths. The init call answers 400 with error code invalid_param and the description "Check error message for details.", which pushes the diagnosis into the free-text message field and the log_id. Everything more specific happens at transfer time, on the PUT to upload_url:
| HTTP code | Status | TikTok's description |
|---|---|---|
| 201 | Created | "All parts are uploaded. TikTok will start the posting process." |
| 206 | PartialContent | "The current chunk has been successfully processed. There are additional chunks yet to be uploaded." |
| 400 | BadRequest | "Malformated request headers, or BYTE_SIZE_OF_THIS_CHUNK does not reflect the true byte size of the binary in the request body." |
| 403 | Forbidden | "The upload_url has expired." |
| 404 | NotFound | "TikTok cannot find a valid upload task given the upload_url." |
| 416 | RequestedRangeNotSatisfiable | "Content-Range does not reflect the actual upload progress." |
| 5xx | InternalServerError | "Gateway connection error or TikTok Internal error. You should retry submitting this chunk." |
Read those two client errors carefully, because they separate cleanly. A 400 means the bytes in the body do not match what Content-Length claims about this one chunk. A 416 means the chunk is the wrong chunk: the offsets in Content-Range are not where TikTok's cursor currently sits. Bad total_chunk_count arithmetic almost always surfaces as 416 on the request after the one that should have been last.
Recovery does not require restarting the file. TikTok returns the progress cursor on every response header as Content-Range: bytes 0-{UPLOADED_BYTES}/{TOTAL_BYTE_LENGTH}, and /v2/post/publish/status/fetch/ returns the same number as uploaded_bytes. Resume from that offset while the upload_url is still inside its one-hour window, then poll for PUBLISH_COMPLETE.
Three limits bracket the whole exercise and are worth checking before you compute a single chunk. Videos cap at 4 GB and 10 minutes through the API, which matters more than it sounds given how far TikTok's in-app video length ceiling has moved. Captions cap at 2200 UTF-16 runes in post_info.title, the same number covered in the TikTok caption character limit. And PULL_FROM_URL skips this entire chunking dance, which is why TikTok tells developers that server-side files should never use FILE_UPLOAD at all.
Frequently asked questions
Does chunk_size have to be identical for every chunk?
Yes for every chunk except the last one. TikTok's chunk rules let only the final chunk run past the chunk_size you declared at init, "up to 128 MB", to absorb trailing bytes that do not divide evenly.
What happens if total_chunk_count is one higher than TikTok expects?
The upload fails at the extra request, not at init. TikTok has already received the full TOTAL_BYTE_LENGTH by then, so the surplus PUT arrives with offsets past the end of the file and returns 416 RequestedRangeNotSatisfiable with the description "Content-Range does not reflect the actual upload progress."
Is TikTok's 5 MB minimum 5,000,000 or 5,242,880 bytes?
TikTok does not say. The Media Transfer Guide writes "5 MB" with no byte figure, and its two examples use decimal and binary sizes respectively. Sending at least 5,242,880 bytes per non-final chunk satisfies either interpretation.
Can chunks be uploaded in parallel?
No. TikTok states that "File chunks must be uploaded sequentially", and the server tracks one upload offset per task, so a chunk that arrives ahead of its predecessor is rejected with 416 rather than buffered.
Does PULL_FROM_URL need chunk_size and total_chunk_count?
No. Those three fields are marked "true for FILE_UPLOAD" only. With source: "PULL_FROM_URL" you send video_url instead, TikTok downloads the file itself, and the init response contains no upload_url at all.
How long is the upload_url valid?
One hour. TikTok's note on both init endpoints reads: "The upload_url is valid for one hour after issuance. The upload must be completed in this time range." After that, further chunks return 403 Forbidden, and the fix is a fresh init call rather than a retry, in the same way a stale LinkedIn upload URN forces a new registration.
Does a video between 5 MB and 64 MB have to be split into multiple chunks?
TikTok's multi-chunk rule only triggers above 64 MB, and the single-chunk rule only covers files under 5 MB. A file in that middle range fits inside one chunk without breaking either limit, so a single PUT with chunk_size equal to the file's size satisfies both rules. Nothing in the Media Transfer Guide forces a split before the file crosses 64 MB.
Is chunk_size required on TikTok's Direct Post endpoint?
TikTok's Direct Post reference leaves the required column blank for chunk_size and total_chunk_count, unlike the Upload endpoint, which marks all three fields true for FILE_UPLOAD. TikTok never states the two fields are optional on Direct Post, and it publishes one set of chunk rules for both endpoints. Treat the blank cells as a documentation gap and send all three fields regardless of which init endpoint you call.
AdaptlyPost
Start 7-Day FREE Trial
All-platform analytics
Social Inbox
AI-powered assistant
What's the longest video TikTok's API accepts?
4 GB and 10 minutes, the two caps TikTok lists before chunk math even starts. That ceiling matters because TikTok's in-app upload limit has grown well past it, so a video that fits in the app can still be rejected through the API. Check both limits before you compute a single chunk_size value.
What should I do when a chunk upload returns a 5xx error?
Retry the same chunk. TikTok's own description for the 5xx status reads "Gateway connection error or TikTok Internal error. You should retry submitting this chunk," and the upload_url stays valid for that retry as long as it's still inside its one-hour window. There's no need to recompute chunk_size or restart the file for a server-side error.
Put this into practice with AdaptlyPost
Was This Article Helpful?
Let us know what you think!
See us more often in Google
One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.
Before you go...
AdaptlyPost
Schedule your content across all platforms
Manage all your social media accounts in one place with AdaptlyPost.
All-platform analytics
Social Inbox
AI-powered assistant
Related Glossary Terms


Why TikTok API pull_from_url Domain Verification Rejects Your Host
TikTok API pull_from_url domain verification is a DNS check on the host you send. Fail it and every init call returns url_ownership_unverified.


The TikTok AI Generated Label Is Two Different Labels
The TikTok AI generated label comes two ways: a creator label you apply with is_aigc, and an auto label from AI effects or C2PA that you cannot remove.


What Instagram's content_publishing_limit Endpoint Returns
Instagram's content_publishing_limit endpoint returns quota_usage plus a config block holding quota_total 50 and quota_duration 86400 seconds.
Related Articles


Every Limit the Instagram Reels API Puts on Your Video
The Instagram Reels API caps a reel at 15 minutes and 300 MB and rejects anything but MOV or MP4. Every documented spec, plus the error each violation returns.


The Instagram Resumable Upload Session and the rupload Host
An Instagram resumable upload starts with upload_type=resumable on /media, then a POST to rupload.facebook.com carrying offset and file_size headers.


Why a LinkedIn Access Token Expires After 60 Days
Every LinkedIn access token runs 60 days and expires_in returns 5184000. Refresh token rules, what kills a token early, and how Meta's 60 days differ.

