Setting up a TikTok developer app
A TikTok integration needs a TikTok for Developers app with two products: Login Kit (OAuth and redirect URI) and Content Posting API with Direct Post enabled. Copy the Client key and Client secret, add scopes such as video.publish, verify a domain or URL prefix for PULL_FROM_URL, test in sandbox and pass review — until the audit, posts are limited to private viewing.
Updated:
What does a TikTok app give you?
Two values: the Client key (the app identifier, sent as client_key in OAuth requests) and the Client secret (private: exchanging codes for tokens and verifying webhook signatures). A user access token lasts 24 hours and a refresh token 365 days; the refresh token may change on every refresh, so always store the new one.
The token endpoint expects application/x-www-form-urlencoded — a JSON body is rejected.
Scopes fall into two groups: profile and video list (user.info.*, video.list) and content posting (video.upload, video.publish). Every scope beyond user.info.basic needs pre-approval in the app configuration.
How to create and configure a TikTok for Developers app
Sign up and create the app
Sign in to TikTok for Developers and create an app. TikTok recommends registering it under an organization; an individual developer account isn't recommended for real integrations.
Fill in the app details
Icon (1024×1024 px, JPEG/JPG/PNG, up to 5 MB), name, category, description (shown on the authorization page), Terms of Service URL and Privacy Policy URL — these URLs are verified for apps created after September 9, 2024. The Web platform needs your official website URL.
Add Login Kit and the redirect URI
Products → Add products → Login Kit. Redirect URI rules: an absolute
httpsaddress, static, no query parameters and no#; at most 10 URIs, each under 512 characters; theredirect_uriin the request must match a registered one exactly.Add Content Posting API and enable Direct Post
Add the Content Posting API product and enable the Direct Post configuration in its settings. Direct posting requires your app to be approved for the
video.publishscope and the user to grant it.Add scopes
In the Scopes section add only the scopes your integration actually uses (table below). Copy the Client key and Client secret from the Credentials section.
Verify URL ownership for PULL_FROM_URL
In the URL properties widget add and verify a Domain (for example
cdn.example.com— all paths under it) or a URL prefix (https://+ host + path +/). The media URL must usehttps, must not redirect and must stay reachable during the download (up to one hour after the task starts). Otherwise the API returnsurl_ownership_unverified(403). Uploading the file yourself (FILE_UPLOAD) needs no verification.Configure the webhook callback URL
Set the callback URL in the app settings (HTTPS only). The endpoint must respond with 200 immediately; otherwise TikTok treats the delivery as failed and retries for up to 72 hours with exponential backoff. Delivery is at least once — deduplicate events.
Test in sandbox
Sandbox is a restricted environment for trying integrations without submitting for review. Run the full login and posting flow there with test accounts — that's also where you record the demo video.
Submit for review with a demo video
Explain in detail how each product and scope is used in your app. Provide at least one demo video (up to 5, each up to 50 MB) showing the complete end-to-end flow, UI and user interactions; for web apps the domain in the video must match the website URL. The website must be fully developed, with Terms of Service and Privacy Policy links visible without opening a menu. Lifting the private-viewing restriction for Direct Post is a separate Content Posting API audit.
How to connect the TikTok app to Socialift
“Kalitlar” (Keys) → “TikTok app”
In the dashboard open “Kalitlar” and the “TikTok app” card. Copy the Redirect URI from the “Konsolga ko'chiring” (Copy to console) block into the Login Kit settings character for character — even a trailing
/matters.Enter the Client key and Client secret
“Scope'lar” (Scopes) is optional: when empty,
user.info.basic,user.info.profile,user.info.stats,video.list,video.upload,video.publishare requested. “Saqlash va tekshirish” (Save and verify) makes Socialift request a client access token from TikTok's token endpoint to check the key.Copy the Webhook URL
After saving, the card shows a Webhook URL — paste it into TikTok's callback URL field. Events are verified by signature with your Client secret. The card also shows a “Webhook verify token” row, but TikTok has no such field — you can ignore it.
Connect the account
In “Ulanishlar” (Connections) click “Ulash” (Connect) on the TikTok card. The access token lives 24 hours — “Token'ni yangilash” (Refresh token) renews it with the refresh token. Try the posting methods in Playground with
SELF_ONLY.
Which scopes do you need and why?
| Scope | What it allows | In the SDK |
|---|---|---|
user.info.basic | Profile: open id, avatar, display name | tt.me |
user.info.profile | profile_web_link, profile_deep_link, bio_description, is_verified | tt.me |
user.info.stats | Likes, follower, following and video counts | tt.me |
video.list | Read the user's public videos | tt.videos, tt.video, tt.iter_videos |
video.upload | Send content to the creator as a draft to edit and post in TikTok | tt.upload_video |
video.publish | Post content directly to the user's profile | tt.creator_info, tt.publish_video, tt.publish_photos |
Call creator_info before posting: privacy_level must be one of the returned privacy_level_options, otherwise you get privacy_level_option_mismatch.
TikTok keys in the Python SDK
TikTok.from_env() reads TIKTOK_CLIENT_KEY and TIKTOK_CLIENT_SECRET.
import asyncio
import secrets
from socialift import TikTok
REDIRECT_URI = "https://example.com/auth/tiktok/callback" # identical to the Login Kit entry
async def main() -> None:
# TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, SOCIALIFT_LICENSE_KEY
async with TikTok.from_env() as tt:
print(tt.login_url(redirect_uri=REDIRECT_URI, state=secrets.token_urlsafe(32)))
bundle = await tt.exchange_code(input("code: "), redirect_uri=REDIRECT_URI)
info = await tt.creator_info(bundle.access_token) # required before posting
print(info["privacy_level_options"])
result = await tt.publish_video(bundle.access_token, video_url="https://cdn.example.com/reel.mp4",
title="Hello TikTok!", privacy_level="SELF_ONLY", wait=True)
print(result)
asyncio.run(main())Explicitly: TikTok(client_key="...", client_secret="..."). video_url must come from a verified domain; to upload the file yourself, pass bytes or a file path to video=.
In the SDK, socialift.webhooks.verify_tiktok_request(client_secret, body, headers) verifies the webhook signature — body must be the raw request bytes.
Common mistakes
- The redirect URI differs from the Login Kit entry:
http, a trailing/or a query parameter. - Posting publicly before the audit — content is limited to private viewing, and a public account gets
unaudited_client_can_only_post_to_private_accounts. creator_infoisn't called, orprivacy_levelisn't in the returned list.PULL_FROM_URLfrom an unverified domain or a redirecting URL —url_ownership_unverified.- The old refresh token is kept after a refresh — the next attempt is rejected.
- JSON sent to the token endpoint — it needs
application/x-www-form-urlencoded. - The domain in the demo video doesn't match the website URL, or a selected product isn't shown.
- The webhook endpoint does heavy work and returns 200 late — TikTok retries and duplicates appear.
Frequently asked questions
Where do I find the TikTok client key and client secret?
In TikTok for Developers, in the Credentials section of your app page. The Client key is TikTok's counterpart of Meta's App ID under a different name. In the Socialift dashboard they go into the “Client key” and “Client secret” fields of the “TikTok app” card.
Why is my video posted via the TikTok API private?
All content posted by unaudited API clients is restricted to private viewing. To lift the restriction your client must pass the Content Posting API audit. That's why the Socialift SDK defaults privacy_level to SELF_ONLY.
Do I have to verify a domain for PULL_FROM_URL?
Yes. To pull media by URL, add a Domain or URL prefix property to your app and verify ownership, otherwise you get url_ownership_unverified. Uploading the file in chunks yourself (FILE_UPLOAD) has no such requirement.
How long does a TikTok access token last?
The access token lasts 24 hours and the refresh token 365 days. The refresh token returned on refresh may differ from the previous one — always store the new value. The Socialift dashboard has a “Token'ni yangilash” (Refresh token) button; the SDK has tt.refresh_token(...).
What should the TikTok review demo video show?
The full flow on the website or app where the integration lives: sign-in, granting permissions and every selected product working in the UI. If the app isn't approved yet, record it in sandbox; for web apps the domain in the video must match the website URL.