---
title: "Configure TikTok"
description: "Complete BYOK setup for TikTok: configure Login Kit, Direct Post, video.publish, media URL ownership, credentials and audit."
section: "Platforms"
url: https://dravo.dev/docs/platforms/tiktok
---
# Configure TikTok

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](https://developers.tiktok.com/) →
**Log 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`.

```bash
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`.

```bash
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

| 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:

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
    }
  }
}
```

| 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:

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

- [TikTok Login Kit for Web](https://developers.tiktok.com/doc/login-kit-web)
- [Manage TikTok user access tokens](https://developers.tiktok.com/doc/oauth-user-access-token-management)
- [TikTok API scopes](https://developers.tiktok.com/doc/tiktok-api-scopes)
- [Get User Info](https://developers.tiktok.com/doc/tiktok-api-v2-get-user-info)
- [Content Posting API — Direct Post getting started](https://developers.tiktok.com/doc/content-posting-api-get-started)
- [Content Posting media transfer and URL ownership](https://developers.tiktok.com/doc/content-posting-api-media-transfer-guide)
- [Query Creator Info](https://developers.tiktok.com/doc/content-posting-api-reference-query-creator-info)

Next, read [Configure OAuth and connect accounts](/docs/guides/connect-accounts)
for the shared browser flow and [Posts](/docs/api/posts) for the unified post
payload.
