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
| Setting | Value |
|---|---|
| Dravo platform | tiktok |
| Required products | Login Kit; Content Posting API with Direct Post |
| Callback | https://api.dravo.dev/v1/oauth/tiktok/callback |
| Publish scopes | user.info.basic, video.publish |
| Analytics scopes | user.info.stats, video.list |
| Client identifier | TikTok Client key |
| Client secret | TikTok Client secret |
| Media transfer | PULL_FROM_URL |
| Visibility before audit | Private (SELF_ONLY) |
| Current Dravo publishing | One 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 Developers → Log in or Sign up.
- Sign in with the account that should administer the integration.
- Accept TikTok's developer terms.
- Complete the requested developer or organization profile.
- Verify email, organization and contact information when required.
1.2 Prepare the required public pages
Before creating the app, publish:
- Your product website.
- Privacy Policy.
- Terms of Service.
- 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
- Use a dedicated TikTok account with harmless content.
- Confirm you can sign in normally and publish a private video manually.
- 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.
- Choose Connect an app or Create app, depending on the portal label.
- Enter a recognizable app name.
- Choose the appropriate category and describe the publishing use case.
- Select the owning organization when prompted.
- Create the app and open its configuration page.
2.2 Complete Basic information
Navigation: Manage apps → select app → Basic information or App details.
- Add the app icon and description.
- Enter the official website.
- Add Privacy Policy and Terms of Service URLs.
- Add support/contact information.
- Save the changes.
2.3 Find the Products section
Navigation: Manage apps → select app → Products.
The app must expose two separate products:
- Login Kit for account authorization.
- 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.
- Add Login Kit to the app.
- Select Web as the platform.
- Open the Login Kit configuration panel.
3.2 Register Dravo's redirect URI
Navigation: Login Kit → Web → Redirect URI.
-
Choose Add URI.
-
Paste this exact value:
TEXThttps://api.dravo.dev/v1/oauth/tiktok/callback -
Save the product configuration.
-
Reopen it and confirm the URI remains listed.
TikTok's Web Login Kit rules require the URI to:
- Be absolute and use HTTPS.
- Be shorter than 512 characters.
- Contain no query parameters.
- Contain no fragment (
#...). - Match the
redirect_uriused 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.
- Find
user.info.basic. - Add or enable the scope.
- Find
user.info.statsif you will use Dravo account analytics. - Add or enable it as well.
- 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.
- Add the product.
- Open its configuration panel.
- 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.
- Find
video.publish. - Choose Apply, Request access or the equivalent portal action.
- Describe how users deliberately select and publish their own videos.
- Find
video.listif you will use Dravo post analytics. - Describe that Dravo reads public video metrics for videos published by the connected creator.
- 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:
- Domain — covers the verified host and its child subdomains according to TikTok's domain rules.
- 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
- Enter the domain or URL prefix used by your final video URLs.
- Choose one of the verification methods offered by TikTok.
- Add the requested DNS record or verification file to the media host.
- Return to TikTok and choose Verify.
- 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:
- Use HTTPS.
- Be beneath the verified domain or exact URL prefix.
- Return the video directly without an HTTP 3xx redirect.
- Remain accessible throughout TikTok's download window, which can last up to one hour.
- 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.
- Copy Client key — this is Dravo's
client_id. - Choose Show or the copy control beside Client secret.
- Complete any requested security verification.
- Copy Client secret — this is Dravo's
client_secret. - 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.
- Select TikTok.
- Enter a name such as
Production TikTok App. - Paste TikTok's Client key into Client ID.
- Paste TikTok's Client secret into Client Secret.
- Confirm the fixed callback, publish scopes and analytics scopes shown by Dravo.
- Save the OAuth app.
6.3 Save them through the API
Endpoint: POST /v1/oauth-apps.
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.
- Select TikTok.
- Choose the OAuth app saved in Step 6.
- Choose Connect with OAuth.
- Sign in as the TikTok creator prepared in Step 1.
- Grant
user.info.basicandvideo.publish. - Allow TikTok to return the browser to Dravo.
7.2 Connect from your backend
Endpoint: GET /v1/oauth/tiktok/start.
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.
- Confirm the handle/open id belongs to the intended creator.
- Confirm
connection_typeisoauth. - Confirm
oauth_app_ididentifies the intended TikTok app. - Confirm
user.info.basicandvideo.publishare present. - If analytics should work, confirm
user.info.statsandvideo.listare also present. - Confirm token health is active.
8.2 Publish from the verified media property
Navigation: Dravo Dashboard → Playground.
- Select only the new TikTok account.
- Use a short video whose final URL belongs to the verified property from Step 5.
- Keep privacy on
SELF_ONLY. - Publish the post.
- 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:
- A precise explanation of user-initiated Direct Post.
- A screencast showing TikTok Login Kit consent.
- Content selection, preview and explicit final confirmation.
- Privacy, comments, duet and stitch controls shown to the creator.
- The analytics view if you request
user.info.statsorvideo.list. - A private test post and the resulting status.
- Disconnect and data-deletion behavior.
- Test credentials and exact reviewer steps.
9.3 Retest after audit
- Wait until TikTok marks the app audited/approved.
- Reconnect the test account if the granted scope or app state changed.
- Query the creator's currently available privacy levels.
- Test a permitted public/friends privacy value.
- Keep
SELF_ONLYas the fallback when a creator does not expose another value.
Supported features and current limitations
| Capability | Current support | Notes |
|---|---|---|
| One video | Yes | Single MP4/MOV via video/init. Text-only posts are rejected. |
| Photo carousel | Yes | One or more JPEG/WEBP images via content/init (PNG is rejected). |
| Direct Post | Yes | Uses video.publish. |
| Account analytics | Yes | Requires user.info.stats; returns follower, following, likes and video counts. |
| Post analytics | Yes | Requires video.list; available when TikTok exposes a public numeric video id. |
| Pull from URL | Yes | Final URL ownership must be verified in TikTok. |
| Creator Info preflight | Yes | Dravo queries Creator Info before posting and validates the request against it. |
| Status confirmation | Yes | Dravo polls status/fetch until the post is delivered or failed. |
| AIGC / branded content | Yes | is_aigc, brand_content_toggle, brand_organic_toggle. |
| Draft upload | No | Dravo does not use MEDIA_UPLOAD; it posts directly. |
| Default privacy | SELF_ONLY | Matches unaudited-client restrictions. |
| Title | Yes | Video truncated to 2,200; photo title to 90, description to 4,000. |
| Comment/duet/stitch options | Available as overrides | The 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:
- Creator Info: queries
creator_info/queryto read the creator's allowed privacy levels and interaction settings. - Init: starts the Direct Post with
PULL_FROM_URLonce the request is valid. A single video usesvideo/init; one or more images usecontent/initwithmedia_type: PHOTO. - Status: polls
status/fetchuntilPUBLISH_COMPLETEorSEND_TO_USER_INBOX(delivered) orFAILED(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:
{ "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 } }}| Option | Applies to | Meaning |
|---|---|---|
post_mode | video | DIRECT_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_level | both | Must be one the creator allows. Default SELF_ONLY. |
disable_comment / disable_duet / disable_stitch | video | Disable interactions (duet/stitch are video-only). |
is_aigc | both | Label the post as AI-generated content. |
brand_content_toggle | both | Paid partnership promoting a third party. |
brand_organic_toggle | both | Promotes the creator's own business. |
video_cover_timestamp_ms | video | Frame (ms) used as the cover. |
photo_cover_index | photo | Index of the cover image (default 0). |
auto_add_music | photo | Let TikTok add background music. |
Notes:
privacy_levelmust be one the creator allows, or Dravo returnsinvalid_privacy_level(before calling init) listing the permitted values. Unaudited apps can only useSELF_ONLY.- 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. - Branded content cannot be private:
brand_content_toggle: truewithprivacy_level: "SELF_ONLY"returnsinvalid_brand_content_privacy. Use a public or friends privacy level (which also needs an audited app). 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 returnsunsupported_post_mode.- 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'swarnings.
Troubleshooting
TikTok rejects the redirect URI
- Open
Login Kit → Web → Redirect URI. - Confirm the URI is the fixed Dravo HTTPS callback.
- Remove query parameters, fragments and trailing changes.
- Confirm the same URI remains configured after saving.
scope_not_authorized or missing video.publish
- Open
Products → Content Posting API → Direct Post. - Confirm
video.publishis attached/approved for the app. - Disconnect and reconnect the creator after changing the scope.
TikTok analytics are empty or partial
- Confirm
user.info.statsis enabled for account/profile metrics. - Confirm
video.listis enabled for public video metrics. - Start OAuth with
capabilities=publish,analyticsor connect from the Dravo dashboard. - Reconnect the creator after changing scopes; existing tokens keep the old grant.
- 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
- Inspect the final video URL, including redirects.
- Confirm it falls below the verified domain or URL prefix.
- Confirm the property still shows verified in TikTok.
- 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
- TikTok Login Kit for Web
- Manage TikTok user access tokens
- TikTok API scopes
- Get User Info
- Content Posting API — Direct Post getting started
- Content Posting media transfer and URL ownership
- Query Creator Info
Next, read Configure OAuth and connect accounts for the shared browser flow and Posts for the unified post payload.