Videos

Video Actions – Publish, Finalize & Corrections

Take actions on TokPortal videos via API. Publish, finalize, request corrections, unschedule, and reset video slots.

Video Actions

These endpoints let you take actions on individual videos within a bundle — publish, finalize, request corrections, or unschedule.

Publish a Video

Publish a single configured video on an already-active bundle. Use this after adding new video slots to an accepted bundle, configuring them, and wanting the account manager to start working on them.

POST /bundles/:id/videos/:position/publish

The bundle must be in published, published_priority, or accepted status. The video must be in configured status.

curl -X POST https://app.tokportal.com/api/ext/bundles/{id}/videos/3/publish \
  -H "X-API-Key: sk_xxx"

Response:

{
  "data": {
    "video_id": "uuid",
    "position": 3,
    "bundle_id": "uuid",
    "status": "published"
  }
}

If the target date went stale

A slot can sit configured until its target_publish_date reaches today. Publishing does not reject that — it moves the slot forward to the earliest allowed day and tells you it did:

{
  "data": {
    "video_id": "uuid",
    "position": 3,
    "bundle_id": "uuid",
    "status": "published",
    "date_adjusted": true,
    "original_date": "2026-08-24",
    "new_date": "2026-08-27",
    "hint": "The earliest target date in this batch was already today or in the past at publish time, so the whole batch was shifted forward by the same number of days — original pacing, gaps and order are preserved. Use PATCH /bundles/{id}/videos/{position} to reschedule."
  }
}
FieldTypeDescription
date_adjustedbooleanPresent only when the date was moved. Absent means the schedule you sent survived untouched.
original_datestringThe stale date the slot carried, YYYY-MM-DD.
new_datestringThe day it was moved to, YYYY-MM-DD.
hintstringWhat happened and how to change it.

INFO: These four fields were documented long before they existed Until 2026-08-26 the underlying procedure never returned them and the slot published on its stale date, landing in the manager's calendar as instantly-due work. They are real now.

Publish All Configured Videos

Publish all configured videos on a bundle at once. Useful after batch-configuring multiple new slots.

POST /bundles/:id/videos/publish-all
curl -X POST https://app.tokportal.com/api/ext/bundles/{id}/videos/publish-all \
  -H "X-API-Key: sk_xxx"

Response:

{
  "data": {
    "bundle_id": "uuid",
    "videos_published": 3,
    "video_ids": ["uuid1", "uuid2", "uuid3"]
  }
}

Stale dates are moved forward, not rejected

If the earliest target date in the call has already reached today or the past, the whole set slides forward by the same number of days before publishing — pacing, gaps and order are preserved. If the earliest date is still in the future, nothing moves. The publish never fails because of the adjustment.

The move respects the 3 videos per day per bundle cap: if the earliest allowed day is already full, the slot spills to the next day, and so on.

{
  "data": {
    "bundle_id": "uuid",
    "videos_published": 3,
    "video_ids": ["uuid1", "uuid2", "uuid3"],
    "dates_adjusted": 2,
    "adjusted_videos": [
      { "video_id": "uuid1", "position": 1, "previous_date": "2026-08-24", "new_date": "2026-08-27" },
      { "video_id": "uuid2", "position": 2, "previous_date": "2026-08-25", "new_date": "2026-08-27" }
    ],
    "hint": "The earliest target date in this batch was already today or in the past at publish time, so the whole batch was shifted forward by the same number of days — original pacing, gaps and order are preserved. Use PATCH /bundles/{id}/videos/{position} to reschedule."
  }
}
FieldTypeDescription
dates_adjustedintegerHow many slots were moved. Present only when at least one was.
adjusted_videosarrayOne entry per moved slot: { video_id, position, previous_date, new_date }.
hintstringWhat happened and how to change it.

WARNING: earliest_allowed_date no longer exists on this response It was documented but never returned. adjusted_videos replaces it and is strictly more useful: a single "earliest allowed" day could not describe a set of slots that were spread over several days by the per-day cap. If your integration reads earliest_allowed_date, read adjusted_videos[].new_date instead.

TIP: Typical workflow for adding videos to an active bundle

  1. POST /bundles/:id/add-video-slots — Add new slots (credits debited)
  2. PUT /bundles/:id/videos/batch — Configure the new videos
  3. POST /bundles/:id/videos/publish-all — Publish them so the manager can start

Finalize a Video

POST /bundles/:id/videos/:position/finalize

Marks a video as finalized, completing its lifecycle. Once finalized, no further changes can be made to the video.

A video can only be finalized when its current status is in_review.

WARNING: 72-hour review window Delivered work sits in review and auto-finalizes about 72 hours (72h01) after the video listing enters in_review. If you do not finalize the video or request corrections during that window, TokPortal changes its status to finalized on its own. Once finalized, no further corrections can be requested and the manager's payout is released.

This happens regardless of auto_finalize_videos — that flag does not switch automatic finalization off. If you need control over a delivery, act inside the window with this endpoint or with Request Corrections.

curl -X POST https://app.tokportal.com/api/ext/bundles/bundle_abc123/videos/1/finalize \
  -H "X-API-Key: sk_xxx"

Response:

{
  "data": {
    "video_id": "uuid",
    "position": 1,
    "bundle_id": "bundle_abc123",
    "status": "finalized"
  }
}

Error — invalid status transition:

{
  "error": {
    "code": "VIDEO_INVALID_STATUS",
    "message": "This video is not in a valid status for this action.",
    "details": {
      "current_status": "configured",
      "required": "in_review"
    }
  }
}

Request Corrections

POST /bundles/:id/videos/:position/corrections

Sends the video back to the account manager with correction instructions. The video must currently be in_review; its status becomes pending_corrections.

Corrections can only be requested inside the 72-hour review window described above, which closes regardless of auto_finalize_videos.

FieldTypeRequiredDescription
commentstringYesInstructions describing what needs to be changed (1-2,000 characters).
fieldsobjectNoBoolean flags for the affected areas: video_content, description, video_editing, and/or sound. Omitted fields are not flagged.
curl -X POST https://app.tokportal.com/api/ext/bundles/bundle_abc123/videos/2/corrections \
  -H "X-API-Key: sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "comment": "Sound only: replace the current sound with the official campaign track. Do not change the video or caption.",
    "fields": {
      "sound": true
    }
  }'

Response:

{
  "data": {
    "video_id": "uuid",
    "position": 2,
    "bundle_id": "bundle_abc123",
    "status": "pending_corrections"
  }
}

Unschedule a Video

POST /bundles/:id/videos/:position/unschedule

Reverts a video back to configured status (cancels scheduling). Works on published, configured, or accepted videos.

curl -X POST https://app.tokportal.com/api/ext/bundles/bundle_abc123/videos/3/unschedule \
  -H "X-API-Key: sk_xxx"

Response:

{
  "data": {
    "video_id": "uuid",
    "position": 3,
    "bundle_id": "uuid",
    "status": "configured"
  }
}

Error — invalid status:

{
  "error": {
    "code": "VIDEO_INVALID_STATUS",
    "message": "Invalid video status for this action.",
    "details": {
      "current_status": "finalized",
      "allowed": ["published", "configured", "accepted"],
      "hint": "Only published, configured, or accepted videos can be unscheduled."
    }
  }
}

Reset a Video

POST /bundles/:id/videos/:position/reset

Clears all configuration from a video slot — description, URL, dates, sound, editing instructions, and all platform-specific fields — returning it to a blank state. The slot itself is preserved and can be reconfigured with PUT /bundles/:id/videos/:position.

Only works on pending or configured videos. If a video is published or accepted, use unschedule first, then reset.

curl -X POST https://app.tokportal.com/api/ext/bundles/bundle_abc123/videos/3/reset \
  -H "X-API-Key: sk_xxx"

Response:

{
  "data": {
    "video_id": "uuid",
    "position": 3,
    "bundle_id": "uuid",
    "status": "configured",
    "message": "Video has been reset to blank state. You can reconfigure it with PUT /bundles/:id/videos/:position."
  }
}

Error — invalid status:

{
  "error": {
    "code": "VIDEO_INVALID_STATUS",
    "details": {
      "current_status": "accepted",
      "allowed": ["pending", "configured"],
      "hint": "Only pending or configured videos can be reset. Use unschedule first if the video is published or accepted."
    }
  }
}

TIP: To fully clear a published or accepted video

  1. POST /bundles/:id/videos/:position/unschedule — reverts to configured
  2. POST /bundles/:id/videos/:position/reset — clears all configuration

Action Summary

ActionEndpointAllowed From StatusResult Status
PublishPOST .../publishconfiguredpublished
FinalizePOST .../finalizein_reviewfinalized
CorrectionsPOST .../correctionsin_reviewpending_corrections
UnschedulePOST .../unschedulepublished, configured, acceptedconfigured
ResetPOST .../resetpending, configured(blank, same status)
Fix DownloadPOST .../fix-downloadany (requires download_issue: true)(same status, issue cleared)

See also: Fix Download Link for full details on detecting and fixing broken links.