⚡ AutomationsAI|Portal de Cursos →

Verificando acesso...

MÓDULO 3.6

🎵 TikTok Content Posting API

A integração mais espinhosa das redes: portal de desenvolvedor, app review rigoroso, upload em chunks e dezenas de limites técnicos. Quando vale fazer — e quando deixar manual.

6
Tópicos
35
Minutos
Avançado
Nível
Prático
Tipo
1

🏢 TikTok Developer Portal

Tudo começa em developers.tiktok.com. Crie uma conta TikTok comum primeiro (pessoal ou business), depois faça login no portal e crie um App. Não use a mesma conta que recebe posts: a conta dev é só pra gerenciar credenciais.

Cada App tem Client Key e Client Secret, e precisa declarar quais produtos usa — para postar, é o Content Posting API. Sem ele habilitado, todos os endpoints retornam scope_not_authorized.

# Checklist do portal
1. developers.tiktok.com → Login → Manage Apps
2. Create App
   - Name, description, category, icon (512x512)
   - URL do site (não pode ser localhost em produção)
3. Configuration
   - Redirect URI: https://seu-dominio.com/oauth/tiktok/callback
   - Add Products: Login Kit + Content Posting API
4. Anote Client Key + Client Secret (vai no .env)

# Scopes obrigatórios pra postar
user.info.basic
video.upload         # gera o upload, fica em rascunho
video.publish        # publica direto no feed (precisa de unaudited|audited)

💡 Dica prática

Use a Sandbox antes de submeter pra review. Em sandbox os endpoints funcionam só pra contas adicionadas como Target users dentro do App — perfeito pra testar fluxo OAuth + upload sem precisar de aprovação.

Conceitos-chave

App

Entidade que agrupa credenciais e produtos contratados.

Products

Cada API (Login, Content Posting, Display) é ativada separadamente.

Sandbox

Ambiente de teste limitado a usuários-alvo do app.

Scopes

Permissões pedidas no OAuth — granular por endpoint.

2

🛡️ App Review rigoroso

Pra sair de sandbox e atingir contas reais, você submete o App pra audit. TikTok é a plataforma mais rigorosa entre as grandes — recusas são comuns na primeira tentativa. Eles exigem vídeo demo do fluxo, política de privacidade publicada, justificativa escrita do uso de cada scope e, frequentemente, um teste interativo com revisor.

O produto Content Posting API tem dois modos: unaudited (posta como rascunho privado, abre o app pro usuário publicar) e audited (publica direto). Comece pelo unaudited — review mais leve.

📋 Checklist de submissão

  • Vídeo demo (2-3 min): tela cheia mostrando login OAuth, escolha de vídeo, preview, post. Sem cortes suspeitos.
  • Privacy Policy URL: precisa mencionar TikTok, dados coletados, retenção e direito de exclusão.
  • Terms of Service URL: público, próprio domínio.
  • Justificativa de scope: uma frase clara por scope ("video.publish para permitir agendamento automático que o usuário configura na nossa UI").
  • App funcionando: URL de produção viva — bots do review acessam.

✓ Aumenta chance de aprovação

  • Vídeo demo nítido, com áudio explicando cada passo.
  • Privacy Policy específica pra integração TikTok.
  • Site funcional com signup público real.
  • Começar pelo modo unaudited (rascunho).

✗ Recusa quase certa

  • Justificativas genéricas ("preciso do scope X").
  • Privacy Policy template copiado, sem TikTok.
  • App ainda em localhost ou staging quebrado.
  • Submeter direto em audited sem histórico de uso.

Conceitos-chave

Audit

Revisão manual + automática antes de liberar produção.

Unaudited mode

Posta como rascunho — usuário finaliza no app TikTok.

Audited mode

Publica direto, sem confirmação no celular.

Demo video

Prova visual de que o fluxo respeita os termos.

3

📤 Direct Post vs Photo Post

A Content Posting API tem dois endpoints distintos, com payloads diferentes. Escolher errado dá 400 invalid_param.

Video Post (/v2/post/publish/video/init/) recebe um único arquivo de vídeo. Photo Post (/v2/post/publish/content/init/ com media_type=PHOTO) recebe URLs públicas de imagens — vira o carrossel/photo mode.

# DIRECT POST (vídeo) — modo PULL_FROM_URL
POST https://open.tiktokapis.com/v2/post/publish/video/init/
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "post_info": {
    "title": "Meu vídeo agendado pela API #demo",
    "privacy_level": "SELF_ONLY",      // ou PUBLIC_TO_EVERYONE
    "disable_duet": false,
    "disable_comment": false,
    "disable_stitch": false,
    "video_cover_timestamp_ms": 1000
  },
  "source_info": {
    "source": "PULL_FROM_URL",
    "video_url": "https://cdn.seu-app.com/video.mp4"
  }
}
# PHOTO POST (carrossel) — até 35 fotos
POST https://open.tiktokapis.com/v2/post/publish/content/init/
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "media_type": "PHOTO",
  "post_mode": "DIRECT_POST",
  "post_info": {
    "title": "Carrossel da semana",
    "description": "Resumo visual #mkblogs",
    "privacy_level": "PUBLIC_TO_EVERYONE",
    "auto_add_music": true
  },
  "source_info": {
    "source": "PULL_FROM_URL",
    "photo_cover_index": 0,
    "photo_images": [
      "https://cdn.seu-app.com/1.jpg",
      "https://cdn.seu-app.com/2.jpg",
      "https://cdn.seu-app.com/3.jpg"
    ]
  }
}

🔒 Dica prática

No modo unaudited, force privacy_level: "SELF_ONLY". Tentar PUBLIC_TO_EVERYONE sem audit retorna unaudited_client_can_only_post_to_private_accounts.

Conceitos-chave

PULL_FROM_URL

TikTok baixa o arquivo da sua CDN (mais simples).

FILE_UPLOAD

Você sobe o arquivo em chunks (mais controle).

privacy_level

Visibilidade do post — varia com audit status.

photo_cover_index

Qual foto do array vira capa do carrossel.

4

📦 Upload em chunks (FILE_UPLOAD)

Quando você não tem CDN pública (ou o vídeo é privado), use FILE_UPLOAD. O fluxo é três passos: init (TikTok devolve upload_url), PUT dos chunks no upload_url, e polling de status até PUBLISH_COMPLETE.

1

Initialize

Declare tamanho total, número de chunks e tamanho do chunk (5MB-64MB, último pode ser menor).

POST /v2/post/publish/video/init/
{
  "source_info": {
    "source": "FILE_UPLOAD",
    "video_size": 47284736,
    "chunk_size": 10000000,
    "total_chunk_count": 5
  }
}
# → { "upload_url": "...", "publish_id": "v_..." }
2

Upload dos chunks (PUT multipart)

Um PUT por chunk, com Content-Range e Content-Length corretos.

PUT {upload_url}
Content-Type: video/mp4
Content-Length: 10000000
Content-Range: bytes 0-9999999/47284736

<binary chunk>
# Repita para cada chunk, ajustando o range
3

Status polling

Após o último chunk, faça polling até o estado virar PUBLISH_COMPLETE ou FAILED.

POST /v2/post/publish/status/fetch/
{ "publish_id": "v_..." }
# status: PROCESSING_UPLOAD | PROCESSING_DOWNLOAD
#       | PUBLISH_COMPLETE | FAILED

⚙️ Dica prática

Se o vídeo tem até 64MB, mande tudo num chunk só — simplifica drasticamente o código. Multi-chunk só se justifica acima desse tamanho. E sempre confira que o total_chunk_count × chunk_size bate (ou supera) o video_size.

Conceitos-chave

init

Pede upload_url e publish_id antes de mandar bytes.

Content-Range

Header HTTP que indica o intervalo de bytes do chunk.

publish_id

ID rastreável do post até PUBLISH_COMPLETE.

Polling

Consultar status repetidamente (intervalo 5-10s).

5

📏 Limites e dimensões

TikTok rejeita silenciosamente vídeos que não batem com a especificação — o status fica FAILED com um motivo curto. Antes de subir, valide localmente com ffprobe.

📐 Especificação técnica

  • Container: MP4, MOV, WebM (MP4 é o seguro).
  • Codec: H.264 (vídeo) + AAC (áudio).
  • Duração: mínimo 3s, máximo 10 minutos (contas verificadas, até 60 min).
  • Tamanho do arquivo: até 4GB (mas mantenha < 500MB pra evitar timeouts).
  • Aspect ratio recomendado: 9:16 (vertical, 1080×1920). Outros funcionam mas perdem alcance.
  • Frame rate: 23-60 fps.
  • Bitrate: ≥ 516 kbps; recomendado 6-10 Mbps.
  • Fotos (carrossel): JPG/WebP, até 35 imagens, máx 20MB cada.
# Validar antes de submeter
ffprobe -v error -show_entries \
  stream=codec_name,width,height,duration,r_frame_rate,bit_rate \
  -of default=noprint_wrappers=1 video.mp4

# Converter pra spec ideal se precisar
ffmpeg -i input.mov \
  -c:v libx264 -preset slow -crf 22 \
  -c:a aac -b:a 192k \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" \
  -movflags +faststart \
  output.mp4

Conceitos-chave

Aspect ratio

9:16 vertical é o nativo do TikTok.

faststart

Move moov atom pro início — player não precisa baixar tudo.

ffprobe

Inspeciona container, codec e duração sem decodar.

Rate limit

6 posts por minuto por usuário; cobra reflow.

6

🤔 Quando vale a pena

Toda essa burocracia tem custo. Pergunta honesta: o seu volume justifica? Se você posta 2-3 vídeos por semana, o tempo investido em audit + manutenção da integração paga menos do que publicar manual no celular.

✓ Vale automatizar

  • Alto volume: 5+ posts/dia ou múltiplas contas geridas.
  • Pipeline de conteúdo já em vídeo 9:16 padronizado.
  • Equipe que aprova posts num dashboard central.
  • Audiência específica que justifica TikTok como canal principal.
  • Já tem domínio + privacy policy + site público.

✗ Deixe manual

  • Volume baixo (< 3/semana) — agendar no celular resolve.
  • Sem domínio público nem privacy policy pronta.
  • Conteúdo precisa de trends, sons populares, edição reativa.
  • TikTok é só "mais um canal" e não a praça principal.
  • Sem tempo pra 1-2 ciclos de revisão até aprovação.

🎯 Caminho do meio

O Postiz já tem integração TikTok pronta — basta colar Client Key + Client Secret do seu app. Faz sentido passar pelo audit (porque você precisa de credenciais reais mesmo usando Postiz), mas pula a parte de escrever o cliente HTTP. É o melhor custo-benefício pra maioria dos casos.

Conceitos-chave

Custo-benefício

Tempo de audit + dev vs. tempo de postar manual.

Volume crítico

Ponto onde automação paga a complexidade.

Postiz como ponte

Reuso de cliente já feito — só traga credenciais.

Trend reactivity

Manual ganha quando o conteúdo depende de tendências.

🎯 Resumo do Módulo

Developer Portal navegado — App criado em developers.tiktok.com, Content Posting API habilitada, Client Key/Secret salvos.
Review compreendido — vídeo demo, privacy policy específica, justificativa de scope e diferença unaudited vs. audited.
Endpoints distinguidos — Video Post (vídeo único) vs. Photo Post (carrossel de até 35 imagens).
Upload em chunks dominado — fluxo init → PUT → status, com Content-Range correto e polling de publish_id.
Limites técnicos mapeados — MP4/H.264/AAC, 9:16, 3s-10min, validação com ffprobe e normalização com ffmpeg.
Decisão calibrada — sabe quando automatizar (volume + canal principal) e quando deixar manual.

🎉 Você terminou a Trilha 3 — Redes Sociais!

Agora você conhece os portais, OAuth e APIs de Instagram, X, Bluesky, LinkedIn, YouTube e TikTok. Próxima trilha: blogs — Ghost, WordPress headless, Hashnode, Dev.to e como publicar conteúdo longo de forma automatizada.