PUT the file, wait for processing, then schedule it to all target platforms at staggered times. A month of daily content across 8 platforms takes one scripting session instead of 30 daily uploads.Batching is the highest-leverage habit in content operations: record 10–30 videos in one day, then let automation drip them out. The bottleneck was always the upload grind — here's how to remove it.
The Bulk Upload Workflow
Step 1 — Organize with Folders
Create a folder per campaign or content series so your media library stays navigable at 100+ files. Every upload accepts a folderId, title, and tags for later search.
Step 2 — Upload in a Loop (Presigned Flow)
Each file follows a strict 3-step sequence:
import requests
for path in video_files:
# 1. Create a presigned slot
slot = dohoo_create_presigned_upload(
filename=path.name,
contentType="video/mp4",
folderId=42,
tags=["july-batch"]
)
# → { "uploadUrl": "...", "videoId": 813, "fileUrl": "https://mediastorage.dohoo.ai/..." }
# 2. PUT the ORIGINAL bytes — same Content-Type, no re-encoding
with open(path, "rb") as f:
requests.put(slot["uploadUrl"], data=f,
headers={"Content-Type": "video/mp4"})
# 3. Poll processing status for large files
while dohoo_get_upload_status(fileId=slot["videoId"])["status"] != "ready":
time.sleep(5)
Two rules that save hours of debugging:
- Presigned URLs are short-lived (minutes). Create the slot immediately before the
PUT, not in a separate pre-pass. If the PUT is rejected as expired, just request a fresh slot. - Upload original bytes. Don't compress or transcode "to be safe" — DOHOO processes media server-side, and client-side re-encoding only degrades quality.
Files already hosted somewhere? Skip the PUT entirely: dohoo_upload_from_url makes the server fetch each file directly.
Step 3 — Schedule the Batch
Distribute posts with a fixed interval. Important pattern: the interval is between videos, not between platforms — each video goes to all selected platforms with the same target time. Final appearance can vary slightly by network.
base = datetime(2026, 7, 14, 14, 0) # Video 1 → all platforms at 14:00
for i, file_url in enumerate(uploaded):
slot = base + timedelta(hours=2 * i) # Video 2 → 16:00, Video 3 → 18:00...
for platform in ["tiktok", "instagram", "youtube", "facebook", "linkedin"]:
schedule_with_platform_tool(platform, fileUrl=file_url,
scheduledAt=slot.isoformat(),
timezone="America/New_York")
Step 4 — Audit the Batch
After scheduling, read the calendar back — never trust a loop blindly:
{ "status": "all", "period": "month", "limit": 100 }
Anything marked failed returns its errorMessage, so a broken token on one account never silently kills a third of your calendar.
Realistic Throughput
| Batch size | Manual (8 platforms) | DOHOO bulk flow |
|---|---|---|
| 10 videos | ~5 hours | ~20 min |
| 30 videos | ~15 hours | ~45 min |
FAQ
How many videos can I upload in one session?
Batching is supported, but monthly upload quotas, pending-post queue limits, and per-network rolling caps still apply.
Can AI run this loop for me?
Yes — through DOHOO's MCP connector, Claude executes the upload → poll → schedule loop from a plain-language instruction. See the Claude MCP guide.
Do I need to convert videos per platform?
A vertical H.264 MP4 is a useful common source, but verify duration, file size, and placement rules for every selected destination.
What if one upload in the batch fails?
Each file is independent — one failure never blocks the batch, and the scheduled-posts audit shows exactly which item needs a retry.