Create Bundle
Create a new bundle to provision an account, upload videos, or both.
POST /bundles
All fields are top-level in the request body. There is no options wrapper.
Request Body
Required
| Field | Type | Description |
|---|---|---|
bundle_type | string | "account_only", "account_and_videos", or "videos_only". |
Conditional
| Field | Type | Required When | Description |
|---|---|---|---|
country | string | account_only, account_and_videos | ISO 3166-1 alpha-2 country code. Optional for videos_only (derived from the saved account). |
account_id | string (UUID) | videos_only | The saved account ID to upload videos to. |
videos_quantity | integer | account_and_videos, videos_only | Number of video slots. Must be greater than 0. |
Optional
| Field | Type | Default | Description |
|---|---|---|---|
platform | string | "tiktok" | "tiktok" or "instagram". YouTube coming soon. |
title | string | — | Bundle title. Max 200 characters. |
edits_quantity | integer | 0 | Number of video edits. Cannot exceed videos_quantity. |
wants_niche_warming | boolean | false | Enable niche warming. Mutually exclusive with wants_deep_warming. |
wants_deep_warming | boolean | false | Enable deep warming. Instagram only. Mutually exclusive with wants_niche_warming. |
wants_moderation | boolean | false | Enable content moderation. |
niche_warming_instructions | string | — | Instructions for niche warming. Required when wants_niche_warming is true. |
moderation_notice | string | — | Optional notice for the moderation team. |
auto_finalize_videos | boolean | true | Automatically finalize videos when they are ready. |
external_ref | string | — | Your own reference ID. Max 200 characters. |
Validation Rules
wants_niche_warmingandwants_deep_warmingare mutually exclusive — you cannot enable both.wants_deep_warmingis only available oninstagram.edits_quantitycannot exceedvideos_quantity.niche_warming_instructionsis required whenwants_niche_warmingistrue.countrymust be enabled for your organization.
Response
{
"data": {
"bundle_id": "...",
"bundle_type": "account_and_videos",
"platform": "tiktok",
"country": "US",
"status": "pending_setup",
"videos_quantity": 5,
"edits_quantity": 2,
"external_ref": "my-campaign-001",
"created_at": "2026-02-10T09:00:00Z"
},
"credits_charged": 85,
"credits_remaining": 415,
"cost_breakdown": {
"account": 10,
"videos": 50,
"edits": 10,
"niche_warming": 0,
"deep_warming": 0,
"moderation": 0
}
}
| Field | Type | Description |
|---|---|---|
data.bundle_id | string | Unique identifier for the created bundle. |
data.bundle_type | string | The bundle type as submitted. |
data.platform | string | Target platform. |
data.country | string | Country code. |
data.status | string | Initial bundle status. |
data.videos_quantity | integer | Number of video slots (if applicable). |
data.edits_quantity | integer | Number of edits (if applicable). |
data.external_ref | string | Your external reference (if provided). |
data.created_at | string | ISO 8601 timestamp. |
credits_charged | integer | Credits deducted for this bundle. |
credits_remaining | integer | Your remaining credit balance. |
cost_breakdown | object | Itemized cost breakdown. |
Examples
1. Account and Videos (with niche warming)
curl -X POST https://app.tokportal.com/api/ext/bundles \
-H "X-API-Key: tok_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"bundle_type": "account_and_videos",
"platform": "tiktok",
"country": "US",
"videos_quantity": 5,
"edits_quantity": 2,
"wants_niche_warming": true,
"niche_warming_instructions": "Focus on fitness and gym content. Follow fitness influencers, like workout videos.",
"auto_finalize_videos": true,
"external_ref": "campaign-42"
}'
Response:
{
"data": {
"bundle_id": "bnd_a1b2c3d4",
"bundle_type": "account_and_videos",
"platform": "tiktok",
"country": "US",
"status": "pending_setup",
"videos_quantity": 5,
"edits_quantity": 2,
"external_ref": "campaign-42",
"created_at": "2026-02-10T09:00:00Z"
},
"credits_charged": 95,
"credits_remaining": 405,
"cost_breakdown": {
"account": 10,
"videos": 50,
"edits": 10,
"niche_warming": 15,
"deep_warming": 0,
"moderation": 0
}
}
2. Account Only
curl -X POST https://app.tokportal.com/api/ext/bundles \
-H "X-API-Key: tok_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"bundle_type": "account_only",
"platform": "instagram",
"country": "FR",
"wants_deep_warming": true,
"title": "French lifestyle account"
}'
Response:
{
"data": {
"bundle_id": "bnd_e5f6g7h8",
"bundle_type": "account_only",
"platform": "instagram",
"country": "FR",
"status": "pending_setup",
"videos_quantity": 0,
"edits_quantity": 0,
"external_ref": null,
"created_at": "2026-02-10T09:05:00Z"
},
"credits_charged": 15,
"credits_remaining": 390,
"cost_breakdown": {
"account": 10,
"videos": 0,
"edits": 0,
"niche_warming": 0,
"deep_warming": 5,
"moderation": 0
}
}
3. Videos Only (existing account)
Recommendation: Instead of creating a
videos_onlybundle, consider using the add-video-slots endpoint on an existing active bundle. This preserves the same account manager, which is better for continuity and turnaround time.
curl -X POST https://app.tokportal.com/api/ext/bundles \
-H "X-API-Key: tok_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"bundle_type": "videos_only",
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"videos_quantity": 3,
"wants_moderation": true,
"moderation_notice": "Ensure no competitor logos are visible",
"external_ref": "restock-wave-2"
}'
Response:
{
"data": {
"bundle_id": "bnd_i9j0k1l2",
"bundle_type": "videos_only",
"platform": "tiktok",
"country": "US",
"status": "pending_setup",
"videos_quantity": 3,
"edits_quantity": 0,
"external_ref": "restock-wave-2",
"created_at": "2026-02-10T09:10:00Z"
},
"credits_charged": 35,
"credits_remaining": 355,
"cost_breakdown": {
"account": 0,
"videos": 30,
"edits": 0,
"niche_warming": 0,
"deep_warming": 0,
"moderation": 5
}
}
Note:
platformandcountryare derived from the saved account when usingvideos_only.
Error Responses
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Invalid or missing fields (see details for specifics). |
400 | WARMING_CONFLICT | wants_niche_warming and wants_deep_warming cannot both be enabled. |
400 | DEEP_WARMING_INSTAGRAM_ONLY | wants_deep_warming is only available on Instagram. |
400 | EDITS_EXCEED_VIDEOS | edits_quantity exceeds videos_quantity. |
400 | COUNTRY_NOT_ENABLED | Country is not enabled for your organization. |
402 | INSUFFICIENT_CREDITS | Not enough credits to create this bundle. |
404 | ACCOUNT_NOT_FOUND | account_id does not exist or does not belong to your organization. |