Skip to content
QPost

TikTok says url_ownership_unverified

Your media URL works in a browser, but TikTok's Content Posting API refuses it with 403 url_ownership_unverified. PULL_FROM_URL only downloads from URLs your app has proved it owns, and the proof is set up in the developer portal, not in code.

Checked against the platform's official documentation on 2026-10-21. These rules change; confirm against the docs before relying on them.

The rule

With source: "PULL_FROM_URL", TikTok downloads the video itself. It only does that from a path you own, and it checks three things:

  • Ownership. The URL falls under a Domain or URL prefix property added to your app in the developer portal's URL properties, which you have manage or write access to.
  • https, no redirects. Any 3xx response makes the URL invalid. A short link or a CDN that redirects to the real file fails.
  • Available for the whole download. TikTok gives the download up to an hour; a signed URL that expires sooner can fail part-way.

Two ways to verify

Domain property (recommended). Add the signature string TikTok gives you as a DNS record on the domain. Once verified, every path on the domain and its subdomains counts as yours. Verifying static.example.com covers video.static.example.com, but not example.com.

URL prefix property. https:// + host + path + /, and the host must be a domain, not an IP. Only URLs that start with exactly that prefix count, so verifying https://example.com/videos/user/ does not cover https://example.com/videos/2023/user/clip.mp4.

The common trap: media sits on a storage provider's shared hostname (a bucket URL on the provider's domain). You can't verify a domain you don't control, so those URLs can never pass. Put a domain of your own in front of the bucket, or stop pulling and push the bytes.

Or push the file: FILE_UPLOAD

With source: "FILE_UPLOAD" you send the bytes to the upload_url TikTok returns, and no ownership check applies. The chunking rules:

  • Each chunk is 5–64 MB; the final chunk may be up to 128 MB to absorb the remainder.
  • Files under 5 MB go up in one request; files over 64 MB must be chunked.
  • 1 to 1,000 chunks, uploaded in order. total_chunk_count is the size divided by the chunk size, rounded down.

This is also the right choice when media comes from a generation API (its URLs are on the provider's domain) or from the user's device.

How QPost avoids it

QPost downloads whatever media you pass, from any public URL or as base64, and re-hosts it on its own verified storage before handing it to TikTok. An expiring URL from a video model or a signed storage link works as-is, and the ownership check never comes up.

Questions people arrive with

What does url_ownership_unverified mean in the TikTok API?

You asked TikTok to fetch media with source PULL_FROM_URL, but the URL isn't under a domain or URL prefix your app has verified. TikTok answers 403 url_ownership_unverified and doesn't download anything.

Can I use a signed S3 or Cloud Storage URL with PULL_FROM_URL?

Only if its host is one you have verified, and the URL is https and doesn't redirect. A storage provider's shared hostname, such as a bucket on the provider's own domain, can't be verified as yours. Serve media from a domain you control, or upload the bytes with FILE_UPLOAD.

Why does verifying example.com not cover my CDN subdomain?

It does cover subdomains: verifying a domain covers every path on it and its subdomains. What it doesn't cover is the parent. Verifying static.example.com does not make example.com owned.

What are the limits for FILE_UPLOAD instead?

Chunks of 5 to 64 MB (the final chunk can be up to 128 MB), between 1 and 1,000 chunks, uploaded in order. Files under 5 MB go up in a single request. Videos can be up to 4 GB.

Related guides

If you'd rather not run the review yourself

QPost is already audited by TikTok and handles the OAuth, token refresh and media hosting for TikTok, Instagram and YouTube. Your users connect their own accounts, and you publish through one REST API or an MCP server. Free while in beta.