Turn CapCut Into a Pipeline: A Complete Guide to CapCutAPI for Python Users
“Can CapCut run itself?”
If you’ve ever stared at an hour of raw footage and needed thirty vertical clips by tomorrow, you’ve asked that exact question.
CapCutAPI answers, “Yes—and you only need a few dozen lines of Python.”
What You’ll Take Away
Your Use Case | What You’ll Learn |
---|---|
Batch-convert horizontal clips to vertical with auto-subtitles | A full working script |
Trigger CapCut remotely from any backend service | A list of production-ready HTTP endpoints |
Standardize intros, watermarks, and transitions across a team | Re-usable automation templates |
Avoid version conflicts, path issues, and Chinese-character bugs | A step-by-step troubleshooting checklist |
1. What Exactly Is CapCutAPI?
In plain English: CapCutAPI turns CapCut’s (or the international CapCut) draft file into editable JSON, lets Python modify it, and then writes the modified draft back to disk so that the mobile or desktop app sees a finished project.
Three steps:
-
Parse the draft – Every CapCut project is a folder containing draft_content.json
; CapCutAPI reads and writes that file safely. -
Batch-edit – Replace “drag clip, trim, add text” with a single API call. -
Return the draft – Copy the newly-generated folder back into CapCut’s draft directory and open the app.
2. Installation & First Run
2.1 System Requirements
Component | Minimum Version | Notes |
---|---|---|
Python | 3.8.20 | 3.9+ works, but stay consistent with the lock file |
FFmpeg | Any recent stable release | Must be reachable via the ffmpeg command |
2.2 Three-Step Setup
Step 1: Clone the repository
git clone <repo-url>
cd CapCutAPI
Step 2: Install dependencies
pip install -r requirements.txt
Step 3: Create your config file
cp config.json.example config.json
# Edit config.json to match your paths and ports
Start the server:
python capcut_server.py
When you see Server started at http://localhost:9000
, the environment is ready.
3. Core Concepts You Must Know
Concept | What It Means in CapCut | API Term |
---|---|---|
Draft | A .draft folder on disk |
draft_id |
Track | Main track, overlay track | track_id |
Asset | Video, audio, image, text | resource_id |
Effect | Filter, transition, mask | effect_id |
4. The Nine Endpoints You’ll Use Most
Re-organized for clarity:
Goal | POST Endpoint | Required Payload Snippet | Typical Response |
---|---|---|---|
Create a blank draft | /create_draft |
{"draft_name": "vlog_0719"} |
{"draft_id": "abc123"} |
Add a video to the timeline | /add_video |
"video_url":"http://cdn.com/clip.mp4" , "start":0 , "end":10 |
{"resource_id":"r1"} |
Add background music | /add_audio |
"audio_url":"bgm.mp3" , "volume":0.3 |
{"resource_id":"a1"} |
Insert a cover image | /add_image |
"image_url":"cover.jpg" , "width":1080 , "height":1920 |
{"resource_id":"i1"} |
Overlay title text | /add_text |
"text":"Summer Vlog" , "font_size":40 |
{"resource_id":"t1"} |
Auto-generate subtitles | /add_subtitle |
Same as text, add "is_ai":true |
{"subtitle_track_id":"s1"} |
Apply a transition | /add_effect |
"effect_name":"fade" , "duration":0.5 |
{"effect_id":"e1"} |
Stick an emoji on screen | /add_sticker |
"sticker_url":"emoji.png" |
{"resource_id":"st1"} |
Save the draft back to disk | /save_draft |
"draft_folder":"/Users/yourname/Drafts" |
{"local_path":"dfd_xxx"} |
5. Hands-On: Produce a 30-Second Vertical Short in One Click
5.1 Scenario
-
Input: Horizontal 1920×1080 MP4 -
Output: Vertical 1080×1920, with subtitles, background music, and a title -
Batch size: 20 clips at once
5.2 Commented Script
import requests, uuid, shutil, os
BASE = "http://localhost:9000"
draft_name = "auto_vlog_" + uuid.uuid4().hex[:6]
folder_out = "/Users/yourname/Movies/CapCut/User Data/Drafts"
# 1. Create a new draft
d = requests.post(f"{BASE}/create_draft", json={"draft_name": draft_name}).json()
draft_id = d["draft_id"]
# 2. Add the main video (fill vertical frame)
requests.post(f"{BASE}/add_video", json={
"draft_id": draft_id,
"video_url": "http://cdn.com/clip.mp4",
"start": 0,
"end": 30,
"width": 1080,
"height": 1920,
"scale": 1.78 # zoom to fit vertical
})
# 3. Add background music
requests.post(f"{BASE}/add_audio", json={
"draft_id": draft_id,
"audio_url": "http://cdn.com/bgm.mp3",
"volume": 0.25
})
# 4. Add subtitle
requests.post(f"{BASE}/add_subtitle", json={
"draft_id": draft_id,
"text": "Life Log Day 19",
"start": 0,
"end": 3,
"font_size": 36,
"font_color": "#FFFFFF"
})
# 5. Save the draft locally
path = requests.post(f"{BASE}/save_draft", json={
"draft_id": draft_id,
"draft_folder": folder_out
}).json()["local_path"]
# 6. Move it to CapCut’s draft directory
shutil.copytree(path, os.path.join(folder_out, os.path.basename(path)))
print("Done! Open CapCut and look for the draft:", os.path.basename(path))
Wrap the whole block in a for
loop over your 20 files and you’re finished.
6. Frequently Asked Questions
Q1: Does this work with both CapCut International and the Chinese剪映?
A: Yes. CapCutAPI parses the draft file format, which is identical in both versions.
Q2: I see “ffmpeg not found” in the terminal.
A: Run which ffmpeg
(macOS/Linux) or where ffmpeg
(Windows).
-
macOS: brew install ffmpeg
-
Windows: Download from https://ffmpeg.org and add the bin
folder to your PATH.
Q3: How do I view the generated draft?
A:
-
The terminal prints a folder name starting with dfd_
. -
Open CapCut → Drafts → find the matching name → open it.
Q4: Can I use my own font?
A: Place the .ttf
file in CapCut’s font folder:
-
Windows: C:\Users\<user>\AppData\Roaming\JianyingPro\Resources\Font
-
macOS: ~/Movies/CapCut/User Data/Resources/Font
Then reference the font filename in the"font"
field of/add_text
.
Q5: How do I batch subtitles with different text?
A: Store the text in a CSV. Loop over the rows and call /add_subtitle
with different text
values.
7. Pro Tips for a Smoother Pipeline
Pain Point | Simple Fix |
---|---|
Mixed resolutions | Always pass width and height in /add_video ; the API auto-scales. |
Need identical intro/outro | Pre-produce the intro and outro as separate drafts, then concatenate via /add_video . |
Team collaboration | Deploy capcut_server.py on an internal server; everyone hits the same HTTP endpoints. |
Too much console noise | Set "log_level": "warning" in config.json . |
8. Troubleshooting Checklist
When something breaks, walk through this list in order:
-
Python version: python --version
must be ≥ 3.8.20 -
FFmpeg path: ffmpeg -version
should print build info -
Port conflict: lsof -i:9000
(macOS/Linux) ornetstat -ano | findstr :9000
(Windows) -
Draft folder permissions: manually create a folder to test write access -
Non-ASCII paths: rename folders to English if you encounter encoding errors
9. Your Next Steps
-
Template everything: Turn your favorite intro, subtitle style, and color grade into reusable JSON snippets. -
CI integration: Commit the script to GitHub Actions and schedule daily renders. -
Build a dashboard: Use Streamlit or Gradio so non-coders can upload, choose a template, and hit “Generate”.
CapCutAPI already handles the hardest part—decoding and re-encoding CapCut’s draft format. From here on, it’s just LEGO bricks for your own workflow.
10. Keep Learning
-
Open example.py
in the repo, copy any snippet, and change parameters to see instant results. -
Watch the GitHub Issues tab—most edge cases are already documented. -
Need lower-level control? Open dfd_xxx/draft_content.json
in a text editor; the field names are self-explanatory.
Happy editing—no more dragging clips at 2 a.m.