TikTok API Permission Scopes Explained

Every TikTok API scope in 2026, the exact fields each one returns, and why users can grant only part of what you asked for.

Ronak Shah
Growth at Phyllo
September 24, 2026
3D TikTok app icon beside toggle switches, two switched on and two off
Summarize this article with AI
GeminiChatGPTClaudePerplexityGrok

Every TikTok API scope in 2026, the exact fields each one returns, and why users can grant only part of what you asked for.

This is some text inside of a div block.
  • TikTok API scopes can be granted partially: a user may approve user.info.basic and decline user.info.stats, so read the scope field in the token response.
  • 4 scopes cover most builds: user.info.basic for identity, user.info.profile for username and bio, user.info.stats for counts, video.list for videos.
  • Publishing needs 2 different scopes: video.upload drops a draft in the creator's inbox, video.publish posts directly.
  • Approval and authorisation are separate gates: TikTok approves your app to ask, then each user still grants each scope.
  • Access tokens last 24 hours and refresh tokens 365 days, and neither refreshes itself.

TikTok scopes are more granular than most platforms and they behave differently in 1 way that catches people out: a user can approve some of the scopes you requested and decline the rest.

TikTok's own documentation states it plainly. Users have the right to agree to only a subset of the scopes you requested. Your app then receives a token that works for part of what you built and fails for the rest, with no error at authorisation time.

What follows is every scope family, the exact fields each scope returns, the 2 gates between you and a user's data, and how to handle a partial grant. Everything here is from TikTok's developer documentation as of July 2026.

How do TikTok scopes differ from Meta scopes?

3 differences matter in practice, and the first one changes how you write your code.

  • Partial grants are allowed. A user can approve user.info.basic and decline user.info.stats. Your integration has to cope with holding a valid token that cannot reach half the fields your UI renders.
  • Scopes are bundled into products. You do not request scopes freely. You add a product in the developer portal, such as Login Kit or Content Posting API, and that product carries its scopes. Content Posting API requires Login Kit, so the order matters.
  • Field-level protection is explicit. TikTok protects sensitive fields with additional scopes rather than returning nulls. Request the field without the scope and the call fails rather than returning an empty value.

If you are comparing the 2 platforms directly, we mapped Meta's equivalent list in Instagram API permission scopes.

What does each Login Kit scope return?

These are the read scopes, and this table is the scope-to-field mapping most guides skip. Fields are requested through the fields query parameter on /v2/user/info/, and each one is gated by a specific scope.

ScopeWhat it coversFields it returns
user.info.basicIdentity and avataropen_id, union_id, avatar_url, avatar_url_100, avatar_large_url, display_name
user.info.profilePublic profile detailusername, bio_description, profile_web_link, profile_deep_link, is_verified
user.info.statsAccount statisticsfollower_count, following_count, likes_count, video_count
video.listThe creator's video listThe list of videos posted by the authorising user, with their metadata

2 notes on this table. user.info.basic is added by default to every app that has Login Kit, so you do not request it separately, and it is the only scope TikTok Minis supports alongside user.info.open_id.

The open_id and union_id distinction matters if you operate several apps. open_id is unique to a user within 1 application, so the same person has a different open_id in each of your apps. union_id is persistent for that user across every app under the same developer account. If you need to recognise a returning creator across products, union_id is the field to key on.

What does each Content Posting scope do?

2 scopes, and choosing the wrong one produces a product that behaves nothing like the one you specified.

ScopeWhat it doesWhen to use it
video.uploadUploads content to the creator's TikTok inbox as a draft. The creator reviews and posts it themselvesReview workflows, agency approval flows, and any product where the creator wants the final say
video.publishPosts content directly, either immediately or scheduledScheduling tools and programmatic publishing where the creator has already approved the content in your product

Content Posting API requires Login Kit as a prerequisite, so add Login Kit to your app first. And note that until your app passes its production audit, content published through the API is forced to private visibility regardless of the privacy setting the user chose at the consent screen. That trips people up during testing, because the flow completes successfully and the post is invisible.

The publishing flow itself is 3 calls rather than 1, and the rate limits are strict. We covered both in the TikTok API integration guide and the TikTok API rate limits guide.

If you want the fields without running an app audit for every platform, our per-platform coverage list is public. See the coverage list

What are the Research API scopes?

3 scopes, gated behind institutional eligibility rather than a standard app review. Commercial product building is not permitted under Research API terms.

ScopeWhat it grants
research.data.basicAccess to TikTok public data for research purposes
research.adlib.basicAccess to public commercial data, meaning the ad library, for research purposes
research.data.u18euAccess to data from European users under 18, alongside other public data, for research purposes

If you are a commercial platform and someone suggests the Research API as a shortcut to public data, it is not one. Using research credentials for a commercial use case risks losing access entirely.

What are the Data Portability scopes?

8 scopes, split across 4 data categories and 2 request types. This is the route a user takes to export their own data to your product, and it exists because of data portability obligations rather than as a general access mechanism.

Data categorySingle requestOngoing requests
Everything availableportability.all.singleportability.all.ongoing
Posts and profileportability.postsandprofile.singleportability.postsandprofile.ongoing
Activity dataportability.activity.singleportability.activity.ongoing
Direct messagesportability.directmessages.singleportability.directmessages.ongoing

The single and ongoing split is the important part. A .single scope authorises 1 export. An .ongoing scope authorises repeated exports on the user's behalf. Request .single when you need a one-time import and .ongoing only when your product genuinely needs to keep pulling, because the broader permission is a harder ask at the consent screen.

What other scope families exist?

2 more, both narrow, and worth knowing so you do not go looking for them in the wrong product.

  • Local Service: local.product.manage to create and manage product listings, local.shop.manage to create and manage local shops, and local.voucher.manage to validate and redeem vouchers.
  • TikTok Minis: supports only user.info.basic and user.info.open_id. If you are building a Mini, the rest of this reference does not apply to you.

Why does approval not give you access?

Because there are 2 independent gates, and clearing 1 tells you nothing about the other.

  1. App-level approval. You add the product in the developer portal and request the scopes. TikTok approves your app to ask for them. This is the gate people think of as "getting access".
  2. User-level authorisation. Each individual user has to grant each scope at the consent screen. TikTok's documentation is explicit that being approved for a scope alone does not give you access to a user's data.

While your app is in sandbox, only accounts you have added as target users can connect at all. A sandbox integration can therefore work perfectly for your team and fail for every real user, which is the same shape of surprise Meta produces with Standard Access.

How do you handle a partial scope grant?

By reading the scope field that comes back with the token, and degrading the UI rather than throwing errors. The token response tells you exactly what you were granted.

// Token response. Note the scope field.
{
  "data": {
    "access_token": "act.example12345Example12345Example",
    "expires_in": 86400,            // 24 hours
    "refresh_token": "rft.example12345Example12345Example",
    "refresh_expires_in": 31536000, // 365 days
    "open_id": "abcdefgh-1a2b-123c4-ab12-abc123abc1234",
    "scope": "user.info.basic"      // NOT what you requested
  }
}

That last line is the whole point. You may have requested 4 scopes and been granted 1. Store what you were granted, not what you asked for, and check it before every call.

REQUESTED = ["user.info.basic", "user.info.profile",
             "user.info.stats", "video.list"]

# Fields, keyed by the scope that unlocks them
FIELD_SCOPE = {
    "open_id": "user.info.basic",
    "display_name": "user.info.basic",
    "avatar_url": "user.info.basic",
    "username": "user.info.profile",
    "bio_description": "user.info.profile",
    "is_verified": "user.info.profile",
    "follower_count": "user.info.stats",
    "likes_count": "user.info.stats",
    "video_count": "user.info.stats",
}

def fields_for(granted_scope_string):
    granted = set(granted_scope_string.split(","))
    return [f for f, s in FIELD_SCOPE.items() if s in granted]

# On connect, store the GRANTED scopes against the account
granted = token_response["data"]["scope"]
account.granted_scopes = granted

# Then request only the fields you are entitled to
fields = fields_for(granted)
GET f"/v2/user/info/?fields={','.join(fields)}"

# And tell the user what is missing, rather than showing a zero.
missing = set(REQUESTED) - set(granted.split(","))
if "user.info.stats" in missing:
    show_reconnect_prompt("follower and like counts")

The last 3 lines are the part that saves support tickets. A follower count of 0 because a scope was declined looks identical to a creator with no followers. Showing a reconnect prompt instead tells the user something true and gives them a way to fix it.

Which scopes does your product need?

What you are buildingScopesProducts to add
Creator profile displayuser.info.basic, user.info.profileLogin Kit
Analytics or media kituser.info.basic, user.info.profile, user.info.stats, video.listLogin Kit
Scheduling tool, direct postingAbove plus video.publishLogin Kit and Content Posting API
Review and approval workflowAbove plus video.uploadLogin Kit and Content Posting API
Creator sign-in onlyuser.info.basicLogin Kit
Academic researchresearch.data.basicResearch API, institutional eligibility required
User data importA portability.* scope matched to the data categoryData Portability API

Request the smallest set that your product visibly uses. Over-requesting slows the audit, and on TikTok it also increases the chance a user declines part of the request at the consent screen, which puts you straight back into partial grant handling.

What does no scope unlock?

3 things, and none of them are permission problems. No approval widens any of them.

What you cannot getWhy
Audience demographicsTikTok's native developer API does not return age, gender or location breakdowns for a creator's audience. There is no scope for it
Data on a creator who has not authorised your appEvery user.info.* and video.* scope is scoped to the authorising user. Nothing in this list reaches a third party
Commercial use of Research API dataThe Research API is limited to qualifying institutions, and its terms do not permit commercial product building

The first row is the one that reshapes roadmaps. If your product promises audience demographics on TikTok, the native API is not the route, and no amount of scope approval changes that. We set out where that boundary sits across platforms in authenticated versus public social data.

What are the most common scope mistakes?

  • Assuming you were granted what you requested. The most common and the most avoidable. Read the scope field on every token.
  • Requesting a field without its scope. The call fails rather than returning null, so a single unscoped field in your fields parameter breaks the whole request.
  • Confusing video.upload with video.publish. 1 puts a draft in the creator's inbox, the other posts to their profile.
  • Adding Content Posting API before Login Kit. It is a prerequisite, and the portal will not let you skip it.
  • Keying on open_id across several apps. Use union_id if you need to recognise the same creator in more than 1 of your products.
  • Testing only in sandbox. Only your registered target users can connect, and published content is forced private until the production audit passes.

Where does Phyllo fit?

We run this layer for you. When a creator connects their TikTok account through your product, Phyllo's TikTok API handles the scope requests, the partial grant logic, the 24 hour token refresh cycle and the app audit, and returns normalised fields through the same schema that serves 25+ other platforms.

The audience demographics TikTok's native API does not expose are among the fields we surface for authenticated creators. Per-platform field coverage is public at getphyllo.com/coverage and the API reference needs no sales call.

Where we are not the answer: if TikTok is your only platform and you have engineering capacity, request the scopes yourself. TikTok charges nothing for the API and the documentation is solid. The case for a layer begins at the second platform, because every one of them names its scopes differently, expires its tokens differently and reviews apps differently.

The short version

Add Login Kit first, because everything else depends on it. Request the smallest scope set your product visibly uses, and remember that user.info.basic arrives by default.

Then write your integration on the assumption that you will be granted less than you asked for. Store the scope value from the token response, build your field requests from it, and show the creator a reconnect prompt when something is missing rather than a zero that looks like real data.

Want TikTok fields without running the audit, the scope logic and the 24 hour refresh cycle yourself? Get a demo

What are the TikTok API scopes?

The main read scopes are user.info.basic, user.info.profile, user.info.stats and video.list. Publishing uses video.upload and video.publish. Other families cover Research, Portability and Minis.

Can TikTok users approve only some of the scopes I request?

Yes. TikTok's documentation states users may agree to only a subset of the scopes requested. The token response carries a scope field listing what was granted, so store and check that instead.

What is the difference between video.upload and video.publish?

video.upload sends content to the creator's TikTok inbox as a draft for them to review and post. video.publish posts directly to their profile, immediately or on a schedule. Pick by workflow.

Which scope returns TikTok follower count?

user.info.stats. It returns follower_count, following_count, likes_count and video_count. Requesting those fields without that scope makes the whole call fail rather than returning empty values.

What is the difference between open_id and union_id?

open_id identifies a user within 1 application, so the same person has a different value in each of your apps. union_id persists for that user across every app under the same developer account.

Do I need approval for TikTok API scopes?

Yes, and approval is only the first of 2 gates. TikTok approves your app to request a scope, then each user must grant it at the consent screen. In sandbox, only registered target users can connect.

How long do TikTok access tokens last?

Access tokens expire after 86,400 seconds, which is 24 hours. Refresh tokens last 31,536,000 seconds, which is 365 days. Neither refreshes automatically, so you need a background refresh job.

Table of Content
See Phyllo in action
  • No Credit card required
  • GDPR and SOC Compliant
  • 30-min Onboarding
Book a Demo

Be the first to get insights and updates from Phyllo. Subscribe to our blog.

Ready to get started?

Sign up to get API keys or request us for a demo