Skip to main content

Bundles

A bundle groups an account configuration and optional video configuration for a specific country and platform. Bundles are the core unit of work in the TokPortal API.

Authentication

All endpoints require an API key passed via the X-API-Key header.

X-API-Key: tok_live_xxx

Base URL

https://app.tokportal.com/api/ext

Bundle Types

TypeDescription
account_onlyAccount creation and setup only. No videos.
account_and_videosAccount creation with video uploads.
videos_onlyVideo uploads on an existing account.

Lifecycle

Bundles follow a strict lifecycle:

pending_setup → published → accepted → completed

For bundles that include videos, the video phase adds intermediate states:

accepted → in_review → finalized → completed
StatusDescription
pending_setupBundle created, awaiting configuration.
publishedConfiguration complete, submitted for processing.
acceptedAccount work has been accepted by an operator.
in_reviewVideos are being reviewed.
finalizedVideos have been finalized.
completedAll work is done.

Platforms

PlatformValue
TikToktiktok
Instagraminstagram
YouTubeyoutube

Options

OptionDescriptionRestrictions
niche_warmingWarm the account by engaging with niche-relevant content before publishing.Cannot combine with deep_warming.
deep_warmingExtended warming with deeper engagement signals.Instagram only. Cannot combine with niche_warming.
moderationEnable content moderation on the account.
editingInclude video editing services.
auto_finalize_videosAutomatically finalize videos once ready.

Endpoints

MethodPathDescription
POST/bundlesCreate a bundle
GET/bundlesList all bundles
GET/bundles/:idGet a single bundle
PATCH/bundles/:idUpdate bundle settings
GET/bundles/:id/publish-readinessCheck publish-readiness
POST/bundles/:id/publishPublish a bundle
POST/bundles/:id/unpublishUnpublish a bundle

Computed State Fields

Both GET /bundles and GET /bundles/:id return a set of read-only computed fields to make integration logic simpler. These derive from the underlying bundle / account / video state — you do not need to recompute them client-side.

FieldTypeDescription
is_publishedbooleantrue once the bundle has been published (status is published, published_priority, accepted, or completed).
account_configuredbooleantrue when the bundle's account is in configured or finalized status (i.e., publish-eligible).
videos_totalintegerNumber of video slots on the bundle.
videos_configured_countintegerNumber of video slots whose status indicates they have been configured (any of configured, in_review, pending_corrections, accepted, published, finalized).
next_actionstring | nullSuggested next step in the configure → publish flow. One of configure_account, configure_videos, publish_bundle, or null if no action is required.

next_action is the recommended primary signal for an integration:

  • configure_account — call PUT /bundles/:id/account to set the account fields.
  • configure_videos — call PUT /bundles/:id/videos/batch (or per-position) to fill the video slots.
  • publish_bundle — call POST /bundles/:id/publish (or pass auto_publish: true on the next video configuration call).
  • null — the bundle is already past setup; nothing to do.

List Bundles

Retrieve all bundles for your organization.

GET /bundles

Query Parameters

ParamTypeDescription
statusstringFilter by bundle status: pending_setup, published, accepted, completed, etc.
bundle_typestringFilter by type: account_only, account_and_videos, videos_only.
account_statusstringFilter by account listing status: pending, configured, in_review, finalized. Useful for finding bundles with accounts ready to finalize.
platformstringFilter by platform: tiktok, instagram, youtube.
external_refstringFilter by your external reference.
pageintegerPage number (default: 1).
per_pageintegerResults per page (default: 25, max: 100).

Example

# List all bundles with accounts awaiting finalization
curl -X GET "https://app.tokportal.com/api/ext/bundles?account_status=in_review" \
-H "X-API-Key: tok_live_xxx"

Response

{
"data": [
{
"id": "bnd_abc123",
"bundle_type": "account_and_videos",
"platform": "tiktok",
"country": "US",
"status": "accepted",
"account_status": "in_review",
"videos_quantity": 5,
"edits_quantity": 0,
"used_edits": 0,
"credit_cost": 60,
"external_ref": "campaign-42",
"existing_account_id": null,
"auto_finalize_videos": true,
"wants_niche_warming": true,
"wants_deep_warming": false,
"wants_moderation": false,
"is_published": true,
"account_configured": true,
"videos_total": 5,
"videos_configured_count": 5,
"next_action": null,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}
]
}

Get Bundle

Retrieve a single bundle by ID.

GET /bundles/:id

Example

curl -X GET https://app.tokportal.com/api/ext/bundles/bnd_abc123 \
-H "X-API-Key: tok_live_xxx"

Response

{
"data": {
"id": "bnd_abc123",
"bundle_type": "account_and_videos",
"platform": "tiktok",
"country": "US",
"status": "published",
"videos_quantity": 3,
"edits_quantity": 0,
"used_edits": 0,
"credit_cost": 40,
"external_ref": "campaign-42",
"existing_account_id": null,
"auto_finalize_videos": false,
"wants_niche_warming": true,
"wants_deep_warming": false,
"wants_moderation": false,
"is_published": true,
"account_configured": true,
"videos_total": 3,
"videos_configured_count": 3,
"next_action": null,
"account": {
"username": "cooluser123",
"visible_name": "Cool User",
"biography": "Just vibes.",
"profile_picture_url": "https://example.com/pic.jpg"
},
"videos": [
{
"id": "vid_xyz",
"position": 1,
"status": "pending",
"name": "Video 1"
}
],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T12:00:00Z"
}
}

Update Bundle

Update settings on an existing bundle. You can modify auto_finalize_videos, external_ref, and title at any time, regardless of bundle status.

PATCH /bundles/:id

Request Body

All fields are optional. At least one must be provided.

FieldTypeDescription
auto_finalize_videosbooleanToggle auto-approval of videos.
external_refstring | nullYour own reference ID. Max 200 characters. Must be unique per user. Set to null to clear.
titlestring | nullBundle title. Max 200 characters. Set to null to clear.

Example

curl -X PATCH https://app.tokportal.com/api/ext/bundles/bnd_abc123 \
-H "X-API-Key: tok_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"auto_finalize_videos": false,
"external_ref": "campaign-42-updated"
}'

Response

{
"data": {
"id": "bnd_abc123",
"title": "My Campaign",
"auto_finalize_videos": false,
"external_ref": "campaign-42-updated",
"updated_at": "2026-02-10T14:30:00Z"
}
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORNo fields provided, or invalid values.
404BUNDLE_NOT_FOUNDBundle does not exist.
403BUNDLE_NOT_OWNEDBundle belongs to another user.
409DUPLICATE_EXTERNAL_REFAnother bundle already uses this external_ref.

Check Publish-Readiness

Returns whether a bundle is currently ready for POST /bundles/:id/publish, and if not, the list of blockers that publish would raise. Read-only — no side effects, no credit charge. Useful to surface "what's missing" in your UI before attempting publish.

GET /bundles/:id/publish-readiness

Example

curl -X GET https://app.tokportal.com/api/ext/bundles/bnd_abc123/publish-readiness \
-H "X-API-Key: tok_live_xxx"

Response — ready

{
"data": {
"bundle_id": "bnd_abc123",
"ready": true,
"blockers": []
}
}

Response — blockers present

{
"data": {
"bundle_id": "bnd_abc123",
"ready": false,
"blockers": [
{
"code": "ACCOUNT_MISSING_FIELDS",
"message": "Account is missing required fields.",
"details": { "missing_fields": ["profile_picture_url"] }
}
]
}
}

Blocker Codes

CodeMeaning
BUNDLE_ALREADY_PUBLISHEDThe bundle is already published or accepted.
BUNDLE_NOT_IN_SETUPThe bundle's status is not pending_setup (e.g., draft, cancelled).
ACCOUNT_MISSINGNo account configuration exists yet for the bundle.
ACCOUNT_NOT_CONFIGUREDThe account exists but its status is not yet configured or finalized.
ACCOUNT_MISSING_FIELDSThe account is missing one or more required fields (username, visible_name, profile_picture_url).