Videos

Configure a video slot

Configures one slot as a video, carousel, or story, and schedules it. A story (TikTok/Instagram only) is a single video OR a single image (provide exactly one of video_url or story_image_url), has no description, and is verified by an account-manager screenshot. Platform-specific fields are only stored on their own platform: tiktok_sound_url on TikTok, every instagram_* field on Instagram, every youtube_* field on YouTube. A field belonging to another platform is accepted and not stored, but it is no longer discarded in silence: the response lists those names in ignored_fields, next to platform, with an ignored_fields_note explaining why. Check ignored_fields on every 200 — an empty or absent list is the only proof that everything you sent landed. Some options are paid and charged the first time they are set, never refunded: story_repost_url, instant_repost_as_story, and setting either volume field. Scheduling: target_publish_date is the FIRST day of a 2-day publishing window, never a fixed date — the end day is derived as that day + 1 and cannot be chosen, so target_publish_end_date is refused here with a hint pointing at PATCH. The window that was actually stored comes back as target_publish_start_date / target_publish_end_date. auto_publish is per-video HERE and top-level-only on the batch endpoint. Requires active TokPortal Coverage on the resolved saved account, or permanent grandfathering: a due period renews automatically at the account's stored rate immediately before execution, and nothing starts if it cannot renew. See getAccountManagedSubscription.

put/bundles/{id}/videos/{position}

Request

  • Base URL: https://app.tokportal.com/api/ext
  • URL: https://app.tokportal.com/api/ext/bundles/{id}/videos/{position}
  • Auth: API key in header X-API-Key

Path parameters

idstring uuid required

Bundle ID.

positioninteger required

1-based video slot position.

Headers

X-TokPortal-Dry-Run'true' | '1' | 'yes'

Send true (or 1/yes) to SIMULATE this call instead of executing it. A dry run performs the full validation and pricing path of the real operation and stops before the first write: no credits are debited, no rows are created, no webhooks fire, and no operator ever sees it. The response has the same shape and status as the real call and adds dry_run: true, dry_run_notice, and — on credit-spending operations — credits_would_charge carrying the real price. Errors are identical to the real call, which is the point: this is how you learn what an operation will do before paying for it. Rate limits are consumed normally, a supplied Idempotency-Key is ignored rather than burned, and identifiers returned by a dry run are synthetic (see DRY_RUN_ID_IN_LIVE_REQUEST).

Request body

video_type'video' | 'carousel' | 'story' required
descriptionstring

Required for 'video' and 'carousel'. Stories have no description.

target_publish_datestring required

YYYY-MM-DD. This is the FIRST day of a 2-day publishing window, not a fixed date: the manager may post on this day or the next. The end day is derived — always this day + 1 — and cannot be chosen here; sending target_publish_end_date is rejected. Every video response returns the resulting window as target_publish_start_date / target_publish_end_date (target_publish_date is an alias of the start). Max 3 videos per day per bundle — a 4th video on the same day is rejected with VIDEOS_PER_DAY_EXCEEDED. Minimum lead time, in UTC: the earliest allowed date is today+3 days while the bundle is still having its account created, and today+1 once that account is delivered or when the bundle runs on an existing account; an earlier date is rejected with INVALID_DATE carrying min_days_ahead and earliest_allowed (YYYY-MM-DD).

namestring
video_urlstring uri

Required for video_type 'video'. Use the public_url returned by uploadVideo / uploadVideoDirect (videos use public_url; images use storage_path).

carousel_imagesstring[]

Required for video_type 'carousel'. Use the storage_path returned by the image upload tools, NOT public_url (public_url is only correct for videos).

carousel_titlestring
story_image_urlstring uri

Story image (TikTok/Instagram). Provide exactly one of video_url or story_image_url for a story.

story_repost_urlstring uri

Optional. Make the story repost an existing post from the SAME platform (TikTok story → tiktok.com, Instagram story → instagram.com). Costs +1 credit.

tiktok_sound_urlstring uri

TikTok bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields. REQUIRED for a TikTok carousel (MISSING_FIELD otherwise), optional for a TikTok video.

volume_original_soundinteger nullable

Playback volume of the clip's own audio, as a percentage; 100 leaves it unchanged. PAID OPTION: setting either volume field costs +1 credit per video, charged once when it is first set and never refunded.

volume_added_soundinteger nullable

Playback volume of the added sound, as a percentage; 100 leaves it unchanged. PAID OPTION: setting either volume field costs +1 credit per video, charged once when it is first set and never refunded.

editing_instructionsstring
external_refstring
instagram_content_type'reel' | 'post'

REQUIRED for every Instagram slot that is not a story (MISSING_FIELD otherwise). Instagram bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields.

instagram_locationstring

Instagram bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields.

instagram_collaboratorsstring[]

Instagram bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields.

instagram_audio_namestring

Instagram bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields.

instagram_add_to_storyboolean

Instagram bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields.

ai_content_disclaimerboolean

AI content notice (free). If true, the manager will enable the platform's AI-generated content label when posting.

disclose_as_adsboolean

Disclose as ad (free). If true, the manager will enable branded-content/paid-partnership disclosure (or add #ad) when posting.

instant_repost_as_storyboolean

Instant repost as story (paid, +1 credit charged once when first enabled, no refunds). Right after posting, the manager reposts this video as a story and provides a screenshot proof. Only for video_type 'video' on TikTok/Instagram bundles. Omit to keep the current value.

youtube_titlestring

YouTube bundles only. On any other platform it is accepted but not stored, and comes back in the response's ignored_fields. YouTube bundles cannot currently be created (YOUTUBE_DELAYED).

youtube_tagsstring[]

YouTube bundles only. Elsewhere it is accepted but not stored, and comes back in the response's ignored_fields.

youtube_categorystring

YouTube bundles only. Elsewhere it is accepted but not stored, and comes back in the response's ignored_fields.

youtube_visibility'public' | 'unlisted' | 'private'

YouTube bundles only. Elsewhere it is accepted but not stored, and comes back in the response's ignored_fields.

youtube_sound_urlstring uri

YouTube bundles only. Elsewhere it is accepted but not stored, and comes back in the response's ignored_fields.

auto_publishboolean

PER-VIDEO on this single-slot endpoint: it publishes this one slot in the same call. On the batch endpoint the same flag exists only at the ROOT of the body and covers every video in the call — it is not accepted inside videos[]. A publish failure never fails the configuration: the response carries auto_publish.published and auto_publish.blockers, so read them instead of assuming the slot went live. If publishing moved a stale target date forward, auto_publish.adjusted_videos lists {video_id, position, previous_date, new_date} — read it back rather than assuming the schedule you sent survived.

Response

Configured video slot.

object required

Changes

No recorded changes to this operation across all 1 revision of this API.