Configure TikTok

View .md

Complete BYOK setup for TikTok: configure Login Kit, Direct Post, video.publish, media URL ownership, credentials and audit.


Dravo uses TikTok Login Kit for OAuth and the Content Posting API Direct Post flow. The adapter accepts one video or a photo carousel, queries Creator Info, sends the media with PULL_FROM_URL, and polls publish status until the post is delivered or failed.

Platform configuration verified against TikTok's official documentation on June 24, 2026.

Configuration summary

SettingValue
Dravo platformtiktok
Required productsLogin Kit; Content Posting API with Direct Post
Callbackhttps://api.dravo.dev/v1/oauth/tiktok/callback
Publish scopesuser.info.basic, video.publish
Analytics scopesuser.info.stats, video.list
Client identifierTikTok Client key
Client secretTikTok Client secret
Media transferPULL_FROM_URL
Visibility before auditPrivate (SELF_ONLY)
Current Dravo publishingOne video, or a JPEG/WEBP photo carousel

The callback is fixed for every Dravo customer. Do not replace api.dravo.dev with your product domain.

Step 1: Prepare the TikTok developer account

1.1 Register at TikTok for Developers

Navigation: TikTok for DevelopersLog in or Sign up.

  1. Sign in with the account that should administer the integration.
  2. Accept TikTok's developer terms.
  3. Complete the requested developer or organization profile.
  4. Verify email, organization and contact information when required.

1.2 Prepare the required public pages

Before creating the app, publish:

  1. Your product website.
  2. Privacy Policy.
  3. Terms of Service.
  4. User data-deletion or disconnect instructions.

TikTok uses these during product review and audit. Keep them accessible without an employee login.

1.3 Prepare a test creator account

  1. Use a dedicated TikTok account with harmless content.
  2. Confirm you can sign in normally and publish a private video manually.
  3. Keep the account available for the audit screencast and reviewer steps.

Step 2: Create the TikTok app

2.1 Open Manage apps

Navigation: TikTok for Developers → profile menu → Manage apps.

  1. Choose Connect an app or Create app, depending on the portal label.
  2. Enter a recognizable app name.
  3. Choose the appropriate category and describe the publishing use case.
  4. Select the owning organization when prompted.
  5. Create the app and open its configuration page.

2.2 Complete Basic information

Navigation: Manage apps → select app → Basic information or App details.

  1. Add the app icon and description.
  2. Enter the official website.
  3. Add Privacy Policy and Terms of Service URLs.
  4. Add support/contact information.
  5. Save the changes.

2.3 Find the Products section

Navigation: Manage apps → select app → Products.

The app must expose two separate products:

  1. Login Kit for account authorization.
  2. Content Posting API for Direct Post.

Adding one does not enable the other.

Step 3: Configure Login Kit and the callback

3.1 Add Login Kit for Web

Navigation: Manage apps → select app → Products → Login Kit → Add/Configure.

  1. Add Login Kit to the app.
  2. Select Web as the platform.
  3. Open the Login Kit configuration panel.

3.2 Register Dravo's redirect URI

Navigation: Login Kit → Web → Redirect URI.

  1. Choose Add URI.

  2. Paste this exact value:

    TEXT
    https://api.dravo.dev/v1/oauth/tiktok/callback
  3. Save the product configuration.

  4. Reopen it and confirm the URI remains listed.

TikTok's Web Login Kit rules require the URI to:

  1. Be absolute and use HTTPS.
  2. Be shorter than 512 characters.
  3. Contain no query parameters.
  4. Contain no fragment (#...).
  5. Match the redirect_uri used in the token exchange exactly.

Dravo's fixed callback satisfies these requirements. Do not register your frontend return_url in TikTok.

3.3 Enable identity and profile-stat access

Navigation: Login Kit → Scopes or Products → Login Kit → Configure.

  1. Find user.info.basic.
  2. Add or enable the scope.
  3. Find user.info.stats if you will use Dravo account analytics.
  4. Add or enable it as well.
  5. Confirm the selected scopes appear in the Login Kit product configuration.

Dravo uses user.info.basic to store the TikTok open id, display name and avatar. Dravo uses user.info.stats for profile metrics such as follower count, following count, likes count and video count.

Step 4: Enable Content Posting and Direct Post

4.1 Add the Content Posting API

Navigation: Manage apps → select app → Products → Content Posting API → Add.

  1. Add the product.
  2. Open its configuration panel.
  3. Select or enable Direct Post.

Do not select only Content Upload. Upload-to-drafts uses video.upload and is a different flow from Dravo's Direct Post adapter.

4.2 Request video.publish and video analytics access

Navigation: Content Posting API → Direct Post → Scopes or the app's Scopes section.

  1. Find video.publish.
  2. Choose Apply, Request access or the equivalent portal action.
  3. Describe how users deliberately select and publish their own videos.
  4. Find video.list if you will use Dravo post analytics.
  5. Describe that Dravo reads public video metrics for videos published by the connected creator.
  6. Confirm the selected scopes are attached to the app.

Both conditions must be true: the app has access to video.publish, and the TikTok creator grants it during OAuth.

4.3 Keep development privacy on SELF_ONLY

TikTok states that posts from unaudited API clients are private-only. Dravo therefore defaults to SELF_ONLY. This is expected during Steps 4–8 and is not an OAuth error.

Step 5: Verify the video domain or URL prefix

Dravo currently sends PULL_FROM_URL, so TikTok must recognize the final video URL as owned by your TikTok developer app.

5.1 Choose a verification type

Navigation: Manage apps → select app → Content Posting API → URL properties. The portal may label it Domain verification or URL ownership.

Choose one:

  1. Domain — covers the verified host and its child subdomains according to TikTok's domain rules.
  2. URL prefix — covers only URLs below an exact https://host/path/ prefix.

For example, TikTok documents that verifying static.example.com covers video.static.example.com, but not the parent example.com.

5.2 Prove ownership

  1. Enter the domain or URL prefix used by your final video URLs.
  2. Choose one of the verification methods offered by TikTok.
  3. Add the requested DNS record or verification file to the media host.
  4. Return to TikTok and choose Verify.
  5. Confirm the property shows as verified before publishing.

Use a media domain your organization controls. A shared storage domain cannot be verified merely because a particular object URL is publicly accessible.

5.3 Validate the final media URL

The video URL must:

  1. Use HTTPS.
  2. Be beneath the verified domain or exact URL prefix.
  3. Return the video directly without an HTTP 3xx redirect.
  4. Remain accessible throughout TikTok's download window, which can last up to one hour.
  5. Use a hostname rather than an IP address for URL-prefix verification.

Ingesting into Dravo does not automatically satisfy TikTok ownership. If the resulting storage host cannot be verified by your organization, serve the video from your own verified media domain.

Step 6: Copy the TikTok credentials into Dravo

6.1 Reveal Client key and Client secret

Navigation: TikTok for Developers → Manage apps → select app → Basic information → Credentials. Some portal versions show the credential block directly on App details.

  1. Copy Client key — this is Dravo's client_id.
  2. Choose Show or the copy control beside Client secret.
  3. Complete any requested security verification.
  4. Copy Client secret — this is Dravo's client_secret.
  5. Confirm both values belong to the app configured in Steps 2–5.

6.2 Save them from the Dravo dashboard

Navigation: Dravo Dashboard → Connections → OAuth apps → Add OAuth app.

  1. Select TikTok.
  2. Enter a name such as Production TikTok App.
  3. Paste TikTok's Client key into Client ID.
  4. Paste TikTok's Client secret into Client Secret.
  5. Confirm the fixed callback, publish scopes and analytics scopes shown by Dravo.
  6. Save the OAuth app.

6.3 Save them through the API

Endpoint: POST /v1/oauth-apps.

Shell
curl -X POST https://api.dravo.dev/v1/oauth-apps \
  -H "Authorization: Bearer $DRAVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "tiktok",
    "name": "Production TikTok App",
    "client_id": "TIKTOK_CLIENT_KEY",
    "client_secret": "TIKTOK_CLIENT_SECRET",
    "allowed_return_urls": [
      "https://app.acme.com/settings/connections"
    ]
  }'

Dravo encrypts the Client secret and never returns it.

Step 7: Connect a TikTok account

7.1 Connect from the dashboard

Navigation: Dravo Dashboard → Connections → Connected accounts → Connect account.

  1. Select TikTok.
  2. Choose the OAuth app saved in Step 6.
  3. Choose Connect with OAuth.
  4. Sign in as the TikTok creator prepared in Step 1.
  5. Grant user.info.basic and video.publish.
  6. Allow TikTok to return the browser to Dravo.

7.2 Connect from your backend

Endpoint: GET /v1/oauth/tiktok/start.

Shell
curl --get "https://api.dravo.dev/v1/oauth/tiktok/start" \
  -H "Authorization: Bearer $DRAVO_API_KEY" \
  --data-urlencode "oauth_app_id=YOUR_OAUTH_APP_ID" \
  --data-urlencode "capabilities=publish,analytics" \
  --data-urlencode "return_url=https://app.acme.com/settings/connections"

Redirect the browser to authorize_url. The frontend return_url belongs to Dravo's allowlist and is not the Login Kit redirect URI.

If you omit capabilities, Dravo requests the default publish scope set only. Use capabilities=publish,analytics when the connected account should power the analytics endpoints.

Step 8: Verify a private test post

8.1 Verify identity and scopes

Dashboard: Dravo Dashboard → Connections → Connected accounts. API: GET /v1/accounts?platform=tiktok.

  1. Confirm the handle/open id belongs to the intended creator.
  2. Confirm connection_type is oauth.
  3. Confirm oauth_app_id identifies the intended TikTok app.
  4. Confirm user.info.basic and video.publish are present.
  5. If analytics should work, confirm user.info.stats and video.list are also present.
  6. Confirm token health is active.

8.2 Publish from the verified media property

Navigation: Dravo Dashboard → Playground.

  1. Select only the new TikTok account.
  2. Use a short video whose final URL belongs to the verified property from Step 5.
  3. Keep privacy on SELF_ONLY.
  4. Publish the post.
  5. Confirm the private video appears on the intended TikTok account.

8.3 Initialization versus completion

TikTok returns a publish_id when Direct Post is initialized, then processes the video asynchronously. Dravo does not stop there: it polls status/fetch until the post is delivered (PUBLISH_COMPLETE / SEND_TO_USER_INBOX) or failed, so the job result reflects the real outcome, not just initialization.

Step 9: Submit the Content Posting audit

9.1 Open the audit application

Navigation: Manage apps → select app → Content Posting API → Direct Post → Submit for review/audit.

Login Kit approval and Content Posting audit are separate. Public posting stays restricted until the Direct Post client passes audit.

9.2 Prepare the reviewer journey

Provide:

  1. A precise explanation of user-initiated Direct Post.
  2. A screencast showing TikTok Login Kit consent.
  3. Content selection, preview and explicit final confirmation.
  4. Privacy, comments, duet and stitch controls shown to the creator.
  5. The analytics view if you request user.info.stats or video.list.
  6. A private test post and the resulting status.
  7. Disconnect and data-deletion behavior.
  8. Test credentials and exact reviewer steps.

9.3 Retest after audit

  1. Wait until TikTok marks the app audited/approved.
  2. Reconnect the test account if the granted scope or app state changed.
  3. Query the creator's currently available privacy levels.
  4. Test a permitted public/friends privacy value.
  5. Keep SELF_ONLY as the fallback when a creator does not expose another value.

Supported features and current limitations

CapabilityCurrent supportNotes
One videoYesSingle MP4/MOV via video/init. Text-only posts are rejected.
Photo carouselYesOne or more JPEG/WEBP images via content/init (PNG is rejected).
Direct PostYesUses video.publish.
Account analyticsYesRequires user.info.stats; returns follower, following, likes and video counts.
Post analyticsYesRequires video.list; available when TikTok exposes a public numeric video id.
Pull from URLYesFinal URL ownership must be verified in TikTok.
Creator Info preflightYesDravo queries Creator Info before posting and validates the request against it.
Status confirmationYesDravo polls status/fetch until the post is delivered or failed.
AIGC / branded contentYesis_aigc, brand_content_toggle, brand_organic_toggle.
Draft uploadNoDravo does not use MEDIA_UPLOAD; it posts directly.
Default privacySELF_ONLYMatches unaudited-client restrictions.
TitleYesVideo truncated to 2,200; photo title to 90, description to 4,000.
Comment/duet/stitch optionsAvailable as overridesThe creator's own disabled settings always win.

Publish flow and platform_options

Dravo follows TikTok's official three-step Direct Post flow on every publish:

  1. Creator Info: queries creator_info/query to read the creator's allowed privacy levels and interaction settings.
  2. Init: starts the Direct Post with PULL_FROM_URL once the request is valid. A single video uses video/init; one or more images use content/init with media_type: PHOTO.
  3. Status: polls status/fetch until PUBLISH_COMPLETE or SEND_TO_USER_INBOX (delivered) or FAILED (reported with TikTok's reason).

Media: send one video (MP4/MOV) or one or more images (JPEG/WEBP, PNG is rejected) in media_urls. Mixing video and images in one post is not allowed.

Tune the post through platform_options.tiktok:

JSON
{  "account_ids": ["YOUR_TIKTOK_ACCOUNT_ID"],  "text": "My caption",  "media_urls": ["https://verified.acme.com/clip.mp4"],  "platform_options": {    "tiktok": {      "privacy_level": "SELF_ONLY",      "disable_comment": false,      "disable_duet": false,      "disable_stitch": false,      "is_aigc": false,      "brand_content_toggle": false,      "brand_organic_toggle": false,      "video_cover_timestamp_ms": 1000,      "photo_cover_index": 0,      "auto_add_music": false    }  }}
OptionApplies toMeaning
post_modevideoDIRECT_POST (default) publishes; MEDIA_UPLOAD sends a draft to the creator's inbox to finish in the TikTok app. Inbox works without app audit.
privacy_levelbothMust be one the creator allows. Default SELF_ONLY.
disable_comment / disable_duet / disable_stitchvideoDisable interactions (duet/stitch are video-only).
is_aigcbothLabel the post as AI-generated content.
brand_content_togglebothPaid partnership promoting a third party.
brand_organic_togglebothPromotes the creator's own business.
video_cover_timestamp_msvideoFrame (ms) used as the cover.
photo_cover_indexphotoIndex of the cover image (default 0).
auto_add_musicphotoLet TikTok add background music.

Notes:

  1. privacy_level must be one the creator allows, or Dravo returns invalid_privacy_level (before calling init) listing the permitted values. Unaudited apps can only use SELF_ONLY.
  2. If the creator has comments, duet or stitch disabled, Dravo forces the matching disable_* to true regardless of the value you send, because TikTok rejects a request that re-enables them.
  3. Branded content cannot be private: brand_content_toggle: true with privacy_level: "SELF_ONLY" returns invalid_brand_content_privacy. Use a public or friends privacy level (which also needs an audited app).
  4. post_mode: "MEDIA_UPLOAD" skips the creator-info preflight (the creator sets privacy when finishing the post in the app). It supports video only; with a photo it returns unsupported_post_mode.
  5. TikTok does not support first_comment: the Content Posting API cannot create comments. If sent, the post still publishes and a notice appears in the result's warnings.

Troubleshooting

TikTok rejects the redirect URI

  1. Open Login Kit → Web → Redirect URI.
  2. Confirm the URI is the fixed Dravo HTTPS callback.
  3. Remove query parameters, fragments and trailing changes.
  4. Confirm the same URI remains configured after saving.

scope_not_authorized or missing video.publish

  1. Open Products → Content Posting API → Direct Post.
  2. Confirm video.publish is attached/approved for the app.
  3. Disconnect and reconnect the creator after changing the scope.

TikTok analytics are empty or partial

  1. Confirm user.info.stats is enabled for account/profile metrics.
  2. Confirm video.list is enabled for public video metrics.
  3. Start OAuth with capabilities=publish,analytics or connect from the Dravo dashboard.
  4. Reconnect the creator after changing scopes; existing tokens keep the old grant.
  5. For post analytics, confirm the publish result has a public numeric video id. Some Direct Post status responses expose only a publish_id, which is not enough for the video query endpoint.

Every post is private

This is expected before the Content Posting audit. Keep SELF_ONLY during development and complete Step 9 before testing public privacy.

url_ownership_unverified

  1. Inspect the final video URL, including redirects.
  2. Confirm it falls below the verified domain or URL prefix.
  3. Confirm the property still shows verified in TikTok.
  4. Do not assume a shared Dravo/Supabase storage domain belongs to your app.

TikTok cannot download a verified URL

Serve the final HTTPS object without redirects, authentication or a short-lived expiry. Keep it reachable for at least the documented download window.

invalid_privacy_level

Dravo returns this before calling init when the privacy_level you requested is not in the creator's allowed list. The error message lists the permitted values. Pick one of those, or use SELF_ONLY. Unaudited apps can only use SELF_ONLY.

invalid_brand_content_privacy

You set brand_content_toggle: true (paid partnership) with privacy_level: "SELF_ONLY". Branded content cannot be private. Use a public or friends privacy level, which also requires an audited app.

A photo post is rejected for format

TikTok photo carousels accept JPEG and WEBP only. PNG is rejected, so Dravo returns unsupported_media_format before calling TikTok. Convert PNGs to JPEG first.

The post comes back failed

When status/fetch returns FAILED, Dravo surfaces TikTok's fail_reason (for example picture_size_check_failed or a spam/media error) in the job result. Fix the underlying media or privacy issue and republish; the publish_id is not reusable.

Official documentation

Next, read Configure OAuth and connect accounts for the shared browser flow and Posts for the unified post payload.