Source: https://developers.tokportal.com/use-cases/no-code/n8n-tiktok-automation/
Markdown: https://developers.tokportal.com/use-cases/no-code/n8n-tiktok-automation.md

# TokPortal + n8n

**First run:** [preview one US account order](https://developers.tokportal.com/use-cases/no-code/n8n-us-account-preview) with a manual, built-in n8n workflow that reads markets and returns a dry-run quote. For an account already delivered, [validate an MP4 configuration](https://developers.tokportal.com/use-cases/no-code/mp4-delivered-account-preview). Both stop before a real order or publication. The operational templates below include real actions and are for a later, deliberate workflow.

TokPortal ships an official **n8n community node**: [`n8n-nodes-tokportal`](https://www.npmjs.com/package/n8n-nodes-tokportal) ([source](https://github.com/tokportal/n8n-nodes-tokportal)). It contains a **TokPortal** action node (bundles, videos, accounts, media, credits, webhooks, analytics, warming — 52 operations, usable as an AI Agent tool) and a **TokPortal Trigger** node that starts workflows on signed webhook events. You can still call the REST API from n8n's **HTTP Request** node (section "Without the community node" below).

Both approaches create a TikTok bundle, configure the account profile, configure one or more video slots from public video URLs, then publish the bundle. TokPortal handles the order lifecycle after publish; the API does not guarantee views, reach, or avoidance of platform enforcement.

## Option A — Community node (recommended)

### Install

1. In n8n: **Settings → Community Nodes → Install** → enter `n8n-nodes-tokportal` → confirm. (Self-hosted CLI: `cd ~/.n8n/nodes && npm install n8n-nodes-tokportal`, then restart.)
2. **Credentials → New → TokPortal API** → paste an API key from the [Developer Portal](https://app.tokportal.com/developer/api-keys). n8n tests it against `GET /me`.

### The TokPortal node

| Resource         | Operations                                                                                                                                                    |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bundle           | Create, Create Many (Bulk), Get, Get Many, Update, Publish, Unpublish, Get Publish Readiness, Configure Account, Get Account, List Videos, Publish All Videos |
| Video            | Configure (video / carousel / story), Batch Configure, Get, Patch, Publish, Unschedule, Reset                                                                 |
| Account          | Get, Get Many, List Bans, List Bundles, Get Analytics, List Video Analytics, Reveal Credentials, Retrieve Verification Code                                   |
| Media            | Create Video Upload URL, Create Image Upload URL, Upload Image From URL                                                                                       |
| Credit           | Get Balance, Get Costs, List Transactions                                                                                                                     |
| Webhook Endpoint | Create, Get, Get Many, Delete, Test, List Deliveries, List Event Types                                                                                        |
| Analytics        | Get Dashboard, Get Time Series, Get Account Drilldown, Get Video Analytics                                                                                    |
| Warming          | Generate Terms, Configure Bundle Terms, Rewarm Account, List Account Sessions, Get Session                                                                    |
| Workspace        | Get Current User, List Countries, List Platforms                                                                                                              |

A minimal "sheet row → live account" chain is four nodes: **Bundle → Create** (`account_and_videos`, platform, country, videos quantity) → **Bundle → Configure Account** (username, visible name, bio, avatar) → **Video → Configure** (position, type, video URL, caption, date) → **Bundle → Publish**. Credits are debited on Create. Reveal Credentials is a two-step operation (HTTP 428 returns `policy_version`, then re-run with the acknowledgement) — see the package README.

### The TokPortal Trigger

Add **TokPortal Trigger**, choose the events (`account.finalized`, `video.finalized`, `account.banned`, `bundle.cancelled`, `warming.session_completed`, `subscription.*`, ...) and activate. The node creates a TokPortal [webhook endpoint](https://developers.tokportal.com/webhooks) pointing at the n8n webhook URL, stores the one-time signing secret, verifies every delivery (`TokPortal-Signature: t=<ts>,v1=<HMAC-SHA256 hex>` over `<ts>.<raw body>`, 300 s tolerance) and deletes the endpoint on deactivation. Each event is emitted as one item with the full envelope (`id`, `type`, `created_at`, `data`).

### Templates

Eight importable workflows live in the repository's [`templates/`](https://github.com/tokportal/n8n-nodes-tokportal/tree/main/templates) folder (Workflows → Import from File):

1. Google Sheet → TokPortal bundles (bulk account creation)
2. Faceless channel factory (Schedule → render → configure → publish)
3. TokPortal ban → Slack alert (trigger)
4. Daily analytics digest → Slack
5. Airtable UGC queue → TokPortal videos
6. Sora/Veo output URL → TokPortal upload + schedule
7. New account delivered → notify + reveal step (manual approval)
8. Credits balance guard → top-up reminder

Prefer an AI agent driving TokPortal from n8n? Use the **MCP Client Tool** node with `https://app.tokportal.com/api/ext/mcp` and `Authorization: Bearer sk_...` — see [MCP Server](https://developers.tokportal.com/mcp).

## Option B — Without the community node (HTTP Request)

The rest of this page uses n8n's **HTTP Request** node with the public REST API. It is also the way to call endpoints the community node does not wrap (for example `POST /upload/video/direct` multipart upload — select the **TokPortal API** credential as a *Predefined Credential Type* in the HTTP Request node).

## Prerequisites

- A [TokPortal account](https://app.tokportal.com/auth/signup) with credits
- A TokPortal API key from the [Developer Portal](https://app.tokportal.com/developer/api-keys)
- n8n Cloud or self-hosted n8n
- Video files available as public/direct URLs, or uploaded through [Media Upload](https://developers.tokportal.com/media-upload)

## 1. Create the HTTP credential

Create an n8n credential for header authentication:

| Field        | Value              |
| ------------ | ------------------ |
| Header Name  | `X-API-Key`        |
| Header Value | `sk_your_key_here` |

Every TokPortal API request also needs `Content-Type: application/json` when the body is JSON.

## 2. Trigger the workflow

Typical triggers:

| Trigger           | Expected fields                                                                                                        |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Google Sheets row | `country`, `username`, `visible_name`, `bio`, `profile_picture_url`, `video_url`, `description`, `target_publish_date` |
| Webhook           | JSON payload from your CMS or internal tool                                                                            |
| Schedule          | Pull queued rows from Airtable, Sheets, or a database                                                                  |

Use the country codes returned by `GET /countries` (`USA`, `UK`, `FR`, ...): mostly ISO alpha-2, except the United States (`USA`) and the United Kingdom (`UK`), whose ISO aliases `US` and `GB` are also accepted. A country name is rejected with `INVALID_COUNTRY`.

## 3. Create a bundle

Add an **HTTP Request** node:

```json
{
  "method": "POST",
  "url": "https://app.tokportal.com/api/ext/bundles",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "bundle_type": "account_and_videos",
    "platform": "tiktok",
    "country": "US",
    "title": "n8n TikTok workflow",
    "videos_quantity": 3,
    "external_ref": "n8n-{{$json.row_id}}"
  }
}
```

Save `{{$json.data.bundle_id}}` from the response. Costs are calculated server-side and returned as `credits_charged` and `cost_breakdown`.

Reference: [Create Bundle](https://developers.tokportal.com/create-bundle)

## 4. Configure the account profile

Account configuration is required before publishing.

```json
{
  "method": "PUT",
  "url": "https://app.tokportal.com/api/ext/bundles/{{$json.data.bundle_id}}/account",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "username": "mybrand_us",
    "visible_name": "My Brand",
    "biography": "Daily product videos.",
    "profile_picture_url": "https://cdn.example.com/mybrand/profile.jpg"
  }
}
```

Reference: [Account Configuration](https://developers.tokportal.com/account-configuration)

## 5. Configure videos

If your trigger already provides a public video URL, pass it directly as `video_url`.

```json
{
  "method": "PUT",
  "url": "https://app.tokportal.com/api/ext/bundles/{{bundle_id}}/videos/1",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "video_type": "video",
    "description": "New drop is live #newarrival",
    "target_publish_date": "2026-06-05",
    "video_url": "https://cdn.example.com/videos/drop-01.mp4",
    "external_ref": "drop-01"
  }
}
```

`target_publish_date` is `YYYY-MM-DD` and has a minimum lead time: the earliest allowed date is today + 3 days while the account is still being created, and today + 1 once that account is delivered or when the bundle runs on an existing account. A bundle also accepts at most 3 videos per day; a 4th slot on the same date is rejected with `VIDEOS_PER_DAY_EXCEEDED`. Compute the date in n8n rather than hardcoding it.

For local files or browser uploads, first use [Media Upload](https://developers.tokportal.com/media-upload):

- `POST /upload/video/direct` uploads the file through TokPortal.
- `POST /upload/video` returns a presigned URL so a client can upload directly to storage.
- For 50-100 MB videos, prefer presigned upload or a stable public URL instead of routing the binary through n8n/Zapier if your automation plan has small payload limits.

Reference: [Configure Videos](https://developers.tokportal.com/configure-videos)

## 6. Publish

When the account and at least one video are configured, publish the bundle:

```json
{
  "method": "POST",
  "url": "https://app.tokportal.com/api/ext/bundles/{{bundle_id}}/publish"
}
```

If publish is blocked, call `GET /bundles/{id}/publish-readiness` or read the publish error response to see which account/video fields are missing.

Reference: [Publish & Unpublish](https://developers.tokportal.com/publish-unpublish)

## Multi-country workflows

`POST /bundles/bulk` creates multiple bundles for one `country` and one or more `platforms`. To cover several countries in n8n, loop over a country list and call the bulk endpoint once per country.

```json
{
  "method": "POST",
  "url": "https://app.tokportal.com/api/ext/bundles/bulk",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "platforms": ["tiktok"],
    "country": "US",
    "accounts_count": 5,
    "upload_accounts_count": 2,
    "videos_per_account": 10,
    "wants_advanced_warming": true,
    "advanced_warming_terms": [
      "product review",
      "unboxing haul",
      "daily lifestyle vlog",
      "home essentials",
      "amazon finds",
      "gift ideas"
    ],
    "external_ref": "n8n-q2-us"
  }
}
```

This creates 5 TikTok bundles in the selected country. The first 2 bundles include video slots; the remaining 3 are account-only bundles.

`wants_advanced_warming: true` is mandatory whenever you send `advanced_warming_terms` — the terms are never enough on their own, and a body without the flag is rejected with `ADVANCED_WARMING_FLAG_REQUIRED`. Targets are 3-30 per account, in multiples of 3, each 2-50 characters, and the same list is applied to every account of the batch. At the standard rate of 5 credits per target, the 6 targets above cost 30 warming credits per account, so 150 for the 5 accounts. If the targets are not decided yet, send `advanced_warming_terms_count` instead and configure them later with `PUT /bundles/{id}/warming-terms`.

Reference: [Create Bulk](https://developers.tokportal.com/create-bulk)

## Monitoring

Add optional n8n branches for:

- `GET /bundles/{id}` to check bundle status
- The **TokPortal Trigger** node (or [Webhooks](https://developers.tokportal.com/webhooks) + a Webhook node) to receive `bundle.*`, `account.*`, and `video.*` events
- [Analytics](https://developers.tokportal.com/analytics) after accounts and posts are live

Related guides: [Zapier](https://developers.tokportal.com/use-cases/no-code/zapier-social-media-automation), [Make](https://developers.tokportal.com/use-cases/no-code/make-tiktok-automation), [Python Quickstart](https://developers.tokportal.com/use-cases/platform-guides/python-quickstart).
