> ## Documentation Index
> Fetch the complete documentation index at: https://docs.postqueen.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# TikTok setup

> Register the TikTok application and give PostQueen its keys

<img src="https://mintcdn.com/forceplay/LL5FipRv-7nhg1To/images/channels/tiktok.svg?fit=max&auto=format&n=LL5FipRv-7nhg1To&q=85&s=841a64b34daced44d3b78e35dd6c891f" alt="TikTok" height="44" noZoom style={{ height: "44px", marginBottom: "1.25rem" }} data-path="images/channels/tiktok.svg" />

On your own instance the TikTok app is yours: register it on TikTok for Developers, then put its client id and secret in your environment.

<Info>
  This integration requires that you have a TikTok developer account. It also requires that you have a public website, with https, and can upload files to that site to verify ownership.

  TikTok will also not allow http\:// for your app redirect URI, so you will need to be accessing PostQueen from HTTPS.
</Info>

<Warning>
  **NOTE:** Photo posts are the ones TikTok pulls from a URL, so for those your media has to be publicly reachable over HTTPS; localhost or private routes such as `/uploads` will fail. Serve your uploads through a reverse proxy (e.g. [Caddy](/reverse-proxies/caddy)) or object storage such as [Cloudflare R2](/configuration/r2) with public access. Videos are streamed up by PostQueen itself, so a private path works for those.

  Ensure the media domain is listed under your TikTok developer account's verified sites.
</Warning>

<Warning>
  TikTok approval is not the final step for Direct Post access. TikTok allows unaudited API clients to use the Direct Post API, but posts are restricted to private visibility until the API client completes TikTok's audit process for Terms of Service compliance.

  If your API client has not passed this audit, TikTok also limits Direct Post usage to up to 5 users posting in a 24-hour window, and those user accounts must be private at the time of posting. See TikTok's [Direct Post API developer guidelines](https://developers.tiktok.com/doc/content-sharing-guidelines#direct_post_api_-_developer_guidelines) for the current requirements.

  In practice this means: before your TikTok developer app passes audit, TikTok accepts nothing but **SELF\_ONLY** (private). PostQueen does not downgrade it for you, it sends the level you picked, so anything else comes back as a failed post reading `App not approved for public posting, contact support`. Set `SELF_ONLY` yourself until the audit clears, then every level becomes available.
</Warning>

<Steps>
  <Step title="Create your app">
    Go here: [https://developers.tiktok.com/apps](https://developers.tiktok.com/apps)

    <Frame>
      <img src="https://mintcdn.com/forceplay/Gsgj4WOu3HFxkte6/images/providers/tiktok/tiktok_create_app.png?fit=max&auto=format&n=Gsgj4WOu3HFxkte6&q=85&s=f97d4d3054079879629d8aaffc7d2bd2" alt="Create a new app" width="400" height="527" data-path="images/providers/tiktok/tiktok_create_app.png" />
    </Frame>

    * **App Name:** `MyPostQueen`
    * **Redirect URI:** your PostQueen callback URL, shown in the next step

    <Snippet file="oauth2redirect.mdx" />

    **Your TikTok OAuth2 Redirect URI:**

    * Production: `https://postqueen.example.com/integrations/social/tiktok`
    * Local development (HTTPS required): `https://localhost:4200/integrations/social/tiktok`
    * Docker (HTTPS required): `https://localhost:4007/integrations/social/tiktok`

    <Warning>
      Serve your local instance over HTTPS and set `FRONTEND_URL` to match. Leave it on plain `http` and she wraps the callback through `redirectmeto.com` before sending it, which makes the literal string TikTok receives `https://redirectmeto.com/http://localhost:4200/integrations/social/tiktok`. Register whichever of the two your `FRONTEND_URL` actually produces, because a mismatch stops the login on TikTok.
    </Warning>
  </Step>

  <Step title="Set a TOS and Privacy Policy">
    This needs to be on a public domain that you have access to, that is hosted on HTTPS.

    Tick "Web" for your platforms.
  </Step>

  <Step title="Add apps">
    Add the "Login Kit" and "Content Posting API" to your app.

    For "Login Kit", set the redirect URI to the same value you registered two steps back. It is one URI across the app, not a second one just for Login Kit.

    For Content posting API, enable "Direct Post".
  </Step>

  <Step title="Add scopes">
    Add all six. The connect is refused if any one of them is missing, and `video.create` is not one of them:

    * user.info.basic
    * user.info.profile
    * user.info.stats
    * video.list
    * video.upload
    * video.publish
  </Step>

  <Step title="Copy your client secret to environment variables">
    These can be found immediately after registering your application. The client ID is 16 characters long and the secret is 32 characters long.

    ```env theme={"system"}
    TIKTOK_CLIENT_ID=1234567890123456
    TIKTOK_CLIENT_SECRET=12345678901234567890123456789012
    ```

    Restart PostQueen with the updated environment variables
  </Step>

  <Step title="Add a TikTok channel in the PostQueen web interface">
    Go to the PostQueen web interface, and click on the "Add Channel" button. Select "TikTok" from the list of available channels. You should be redirected to TikTok to authorize the application.
  </Step>
</Steps>

<Check>
  The channel is in the left sidebar with its avatar and name. That is the whole confirmation: if it is in the list, she can post to it.
</Check>

## Next steps

<CardGroup cols={2}>
  <Card title="What she can post to TikTok" icon="https://mintcdn.com/forceplay/LL5FipRv-7nhg1To/images/channels/tiktok.svg?fit=max&auto=format&n=LL5FipRv-7nhg1To&q=85&s=841a64b34daced44d3b78e35dd6c891f" href="/providers/tiktok" width="64" height="64" data-path="images/channels/tiktok.svg">
    Limits, post types and settings
  </Card>

  <Card title="Configuration reference" icon="list" href="/configuration/reference">
    Every variable she reads
  </Card>

  <Card title="Connect errors" icon="plug-circle-xmark" href="/troubleshooting/oauth-connect">
    Invalid state, invalid\_grant and the rest
  </Card>

  <Card title="Another channel" icon="plug" href="/providers/overview">
    Every network, and what each one asks for
  </Card>
</CardGroup>
