n8n upload to TikTok with the HTTP Request node

n8n has no TikTok node in its docs. Upload with HTTP Request nodes: query creator info, init a Direct Post with FILE_UPLOAD, then PUT the bytes.

5 min readSume
All posts

To upload to TikTok from n8n, use HTTP Request nodes against TikTok's Content Posting API: query the creator's info, initialize a Direct Post with FILE_UPLOAD, then PUT the video bytes to the upload_url TikTok returns. n8n's node docs list no TikTok node, and TikTok's PULL_FROM_URL only takes a URL on a domain or URL prefix you have verified, so the workflow downloads the file and pushes it.

TikTok's rules are quoted from its Direct Post reference and Media Transfer Guide, n8n's from its HTTP Request node docs, and the Sume facts from Runs and results, all read on 2026-09-28. Sume has no TikTok or n8n connector; every step is a plain HTTPS call.

Is there an n8n TikTok node?

Not among n8n's built-in nodes: its documentation index goes from TheHive 5 straight to TimescaleDB. n8n describes the HTTP Request node as the way to query data from any app or service with a REST API, so that is the TikTok node. Before the workflow can post, TikTok needs:

  • A registered app with the Content Posting API product and its Direct Post configuration turned on.
  • Approval for the video.publish scope, and a TikTok user who has authorized your app for it. Their access token goes in an n8n generic credential (Header auth) as Authorization: Bearer ….
  • An audit before anything goes public: all content posted by unaudited clients is restricted to private viewing mode.

Which nodes does the upload need?

Start from a workflow that already holds a finished Sume run, such as the one in n8n AI video workflow with a Wait node, whose last HTTP Request node reads GET /v1/format-runs/{run_id}. Name that node Read run, then add four HTTP Request nodes in this order, so the downloaded file sits on the item the upload node receives:

From TikTok's Direct Post reference and Get Started, n8n's HTTP Request node docs, and Sume's Runs and results, read 2026-09-28.
NodeRequestKey settings
Creator infoPOST https://open.tiktokapis.com/v2/post/publish/creator_info/query/Returns privacy_level_options and max_video_post_duration_sec
InitPOST https://open.tiktokapis.com/v2/post/publish/video/init/JSON body below; returns publish_id and upload_url
DownloadGET the receipt's primary_output_urlResponse Format: File, Put Output in Field: data. No Sume key needed: the URL is public
UploadPUT the Init node's upload_urlSend Body: n8n Binary File, Input Data Field Name data; Content-Type, Content-Length, and Content-Range headers
{
  "post_info": {
    "title": "Three tips for better sleep #sleep",
    "privacy_level": "SELF_ONLY",
    "brand_content_toggle": false,
    "is_aigc": true
  },
  "source_info": {
    "source": "FILE_UPLOAD",
    "video_size": {{ $('Read run').item.json.data.artifacts[0].size_bytes }},
    "chunk_size": {{ $('Read run').item.json.data.artifacts[0].size_bytes }},
    "total_chunk_count": 1
  }
}

What goes in the init and upload requests?

n8n's $() expression returns a named node's data, and .item the item that produced the current one, which is how the Init body reads the receipt two nodes back.

  • video_size is the file's size in bytes. Sume lists every file on the receipt's artifacts[] with url, content_type, and size_bytes; the code assumes the video is the first entry, so check that its url matches primary_output_url.
  • privacy_level must be one of the privacy_level_options the creator-info call returned; SELF_ONLY here keeps test posts private.
  • brand_content_toggle is marked required in TikTok's field table; set it to true only for a paid partnership that promotes a third-party business. is_aigc: true labels the post as AI-generated content in its description.
  • One chunk works up to 64 MB: TikTok wants files under 5 MB sent whole, and files over 64 MB in multiple chunks of 5–64 MB, uploaded in order.
  • On the Upload node, Content-Range is bytes 0-{size minus 1}/{size}, and Content-Type is the artifact's content_type; Sume's Timeline renders MP4 by default. The upload_url is valid for one hour.

What errors should the workflow expect?

TikTok answers with an error.code; anything other than ok means the request did not succeed. Codes worth handling in an automated workflow:

  • unaudited_client_can_only_post_to_private_accounts: an unaudited app can only post to a private account, and the init call is blocked.
  • access_token_invalid (401): the user's access token is invalid or has expired, so update the n8n credential.
  • url_ownership_unverified: you tried PULL_FROM_URL with a URL outside your verified domains. A media.sume.com URL is on Sume's domain, which is why this build pushes the file (which URL TikTok can pull).
  • spam_risk_too_many_posts: the user's daily post cap from the API is reached.
  • rate_limit_exceeded (429): each user access token is limited to 6 init requests per minute, so space out a batch with the node's Batching option.
  • After the upload, check progress with TikTok's Get Post Status endpoint and the publish_id from Init.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume