How to Schedule TikTok Posts with Python: Complete API Guide
Scheduling TikTok posts with Python gives you complete control over your content calendar. You can build automated pipelines, integrate with existing workflows, and post at optimal times without manual intervention.
Key Takeaways:
- Build a complete TikTok API Python solution in under 100 lines of code
- Handle timezone conversions automatically with pytz
- Implement idempotency keys to prevent duplicate posts
- Monitor scheduled posts with status tracking
- Scale to recurring content calendars and bulk uploads
This guide teaches you how to create a python tiktok scheduler using the Postqued API and TikTok API. You will write working code that uploads videos, schedules posts for future dates, and handles errors gracefully. No OAuth complexity. No scraping. Just clean HTTP requests. This is perfect for developers building TikTok automation workflows and social media management tools.
Related: Learn how to automate TikTok without coding using our n8n TikTok automation guide or connect Google Sheets to TikTok with our Google Sheets integration tutorial.
What You Will Build
A complete Python automation system for TikTok scheduling:
- Upload videos programmatically
- Schedule posts for specific dates and times
- Handle timezone conversions automatically
- Build recurring content schedules
- Monitor post status and delivery
Prerequisites
Before you start building your TikTok API Python integration, gather these items:
- Python 3.8 or newer installed
- A Postqued account with API access
- Your TikTok account connected to Postqued
- An API key from your Postqued dashboard
- Sample video files for testing
About the Author: This guide was written by the Postqued engineering team, who have built TikTok automation tools used by thousands of developers. Our engineers have 5+ years of experience with social media APIs and automation workflows.
Install the only dependency you need:
pip install requests
Tip: For production TikTok automation workflows, also install
pytzfor timezone handling:pip install requests pytz
Understanding the TikTok API Python Workflow
Scheduling posts requires three main steps. First, upload your video to get a content ID. Second, create a publish request with your schedule time. Third, monitor the status until TikTok confirms delivery.
The Postqued API uses simple Bearer token authentication. Each request needs your API key in the Authorization header. This approach eliminates OAuth token refreshes and complex authentication flows.
Step 1: Set Up Authentication
Create a Python script that handles API authentication:
import os
import requests
from datetime import datetime
API_BASE_URL = "https://api.postqued.com"
API_KEY = os.environ.get("POSTQUED_API_KEY")
if not API_KEY:
raise ValueError("Set POSTQUED_API_KEY environment variable")
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def test_connection():
"""Verify API key is working."""
response = requests.get(
f"{API_BASE_URL}/v1/platform-accounts",
headers=headers
)
if response.status_code == 200:
accounts = response.json().get("accounts", [])
print(f"Connected! Found {len(accounts)} account(s)")
return accounts
else:
raise Exception(f"Connection failed: {response.text}")
Store your API key securely using environment variables. Never hardcode credentials in your scripts.
Step 2: Upload Video Content
Before scheduling, upload your video to Postqued storage:
from pathlib import Path
def upload_video(file_path: str) -> dict:
"""
Upload a video file for later scheduling.
Returns dict with contentId needed for scheduling.
"""
file_path = Path(file_path)
file_size = file_path.stat().st_size
# Step 1: Get upload URL
upload_request = {
"filename": file_path.name,
"contentType": "video/mp4",
"fileSize": file_size
}
response = requests.post(
f"{API_BASE_URL}/v1/content/upload",
headers=headers,
json=upload_request
)
if response.status_code != 200:
raise Exception(f"Upload URL request failed: {response.text}")
upload_data = response.json()
content_id = upload_data["contentId"]
# Step 2: Upload file to presigned URL
with open(file_path, "rb") as f:
upload_response = requests.put(
upload_data["upload"]["url"],
data=f,
headers=upload_data["upload"].get("headers", {})
)
if upload_response.status_code not in [200, 204]:
raise Exception(f"File upload failed: {upload_response.text}")
# Step 3: Confirm upload completion
confirm_data = {
"contentId": content_id,
"key": upload_data.get("key", ""),
"filename": file_path.name,
"contentType": "video/mp4",
"size": file_size,
"width": 1080,
"height": 1920,
"durationMs": 15000
}
requests.post(
f"{API_BASE_URL}/v1/content/upload/complete",
headers=headers,
json=confirm_data
).raise_for_status()
return {"contentId": content_id, "filename": file_path.name}
This three-step upload process ensures your video is ready for scheduling.
Step 3: Schedule TikTok Posts with Python
Now create the core scheduling function:
import uuid
import pytz
from datetime import datetime
def schedule_tiktok_post(
content_id: str,
account_id: str,
caption: str,
schedule_time: datetime,
timezone: str = "UTC",
privacy: str = "PUBLIC_TO_EVERYONE"
) -> dict:
"""
Schedule a TikTok post for a future date and time.
Args:
content_id: Content ID from upload_video()
account_id: Your TikTok account ID from Postqued
caption: Post caption with hashtags
schedule_time: When to publish (datetime object)
timezone: Timezone for schedule_time (default UTC)
privacy: PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS,
FOLLOWER_OF_CREATOR, or SELF_ONLY
Returns:
dict containing publish request details
"""
# Convert to UTC if timezone provided
if schedule_time.tzinfo is None:
tz = pytz.timezone(timezone)
schedule_time = tz.localize(schedule_time)
utc_time = schedule_time.astimezone(pytz.UTC)
# Ensure schedule time is in the future
if utc_time < datetime.now(pytz.UTC):
raise ValueError("Schedule time must be in the future")
# Generate unique idempotency key
idempotency_key = str(uuid.uuid4())
publish_request = {
"contentIds": [content_id],
"targets": [{
"platform": "tiktok",
"accountId": account_id,
"intent": "draft",
"caption": caption,
"dispatchAt": utc_time.isoformat().replace("+00:00", "Z"),
"options": {
"privacyLevel": privacy,
"disableDuet": False,
"disableStitch": False,
"disableComment": False
}
}]
}
schedule_headers = {
**headers,
"Idempotency-Key": idempotency_key
}
response = requests.post(
f"{API_BASE_URL}/v1/content/publish",
headers=schedule_headers,
json=publish_request
)
if response.status_code != 200:
raise Exception(f"Schedule request failed: {response.text}")
result = response.json()
print(f"Post scheduled successfully!")
print(f" Publish ID: {result.get('id')}")
print(f" Scheduled for: {schedule_time.strftime('%Y-%m-%d %H:%M %Z')}")
return result
This function handles timezone conversion automatically and ensures your posts go live at the right moment.
Step 4: Complete Working Example
Here is a complete script that uploads and schedules a TikTok post:
#!/usr/bin/env python3
"""
TikTok Scheduler - Python Script
Schedule TikTok posts programmatically using Postqued API
Usage:
export POSTQUED_API_KEY="your-key"
python schedule_tiktok.py video.mp4 "My caption" "2026-03-15 14:00" "America/New_York"
"""
import os
import sys
import uuid
import requests
import pytz
from pathlib import Path
from datetime import datetime
API_BASE_URL = "https://api.postqued.com"
API_KEY = os.environ.get("POSTQUED_API_KEY")
if not API_KEY:
print("Error: Set POSTQUED_API_KEY environment variable")
sys.exit(1)
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
class TikTokScheduler:
"""Python client for scheduling TikTok posts."""
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
self._account_id = None
def get_account_id(self) -> str:
"""Get the first connected TikTok account ID."""
if self._account_id:
return self._account_id
response = requests.get(
f"{API_BASE_URL}/v1/platform-accounts?platform=tiktok",
headers=self.headers
)
response.raise_for_status()
accounts = response.json().get("accounts", [])
if not accounts:
raise ValueError("No TikTok accounts found. Connect one in Postqued dashboard.")
self._account_id = accounts[0]["id"]
return self._account_id
def upload_video(self, file_path: str) -> str:
"""Upload video and return content ID."""
file_path = Path(file_path)
file_size = file_path.stat().st_size
# Get upload URL
upload_res = requests.post(
f"{API_BASE_URL}/v1/content/upload",
headers=self.headers,
json={
"filename": file_path.name,
"contentType": "video/mp4",
"fileSize": file_size
}
)
upload_res.raise_for_status()
upload_data = upload_res.json()
content_id = upload_data["contentId"]
# Upload file
with open(file_path, "rb") as f:
requests.put(
upload_data["upload"]["url"],
data=f,
headers=upload_data["upload"].get("headers", {})
)
# Confirm upload
requests.post(
f"{API_BASE_URL}/v1/content/upload/complete",
headers=self.headers,
json={
"contentId": content_id,
"key": upload_data.get("key", ""),
"filename": file_path.name,
"contentType": "video/mp4",
"size": file_size,
"width": 1080,
"height": 1920,
"durationMs": 15000
}
).raise_for_status()
return content_id
def schedule_post(
self,
video_path: str,
caption: str,
schedule_datetime: datetime,
timezone: str = "UTC"
) -> dict:
"""Upload video and schedule it for posting."""
# Upload video
print(f"Uploading {Path(video_path).name}...")
content_id = self.upload_video(video_path)
print(f" Upload complete: {content_id}")
# Convert to UTC
if schedule_datetime.tzinfo is None:
tz = pytz.timezone(timezone)
schedule_datetime = tz.localize(schedule_datetime)
utc_time = schedule_datetime.astimezone(pytz.UTC)
# Schedule post
idempotency_key = str(uuid.uuid4())
publish_request = {
"contentIds": [content_id],
"targets": [{
"platform": "tiktok",
"accountId": self.get_account_id(),
"intent": "draft",
"caption": caption,
"dispatchAt": utc_time.strftime("%Y-%m-%dT%H:%M:%SZ"),
"options": {
"privacyLevel": "PUBLIC_TO_EVERYONE",
"disableDuet": False,
"disableStitch": False,
"disableComment": False
}
}]
}
schedule_headers = {**self.headers, "Idempotency-Key": idempotency_key}
response = requests.post(
f"{API_BASE_URL}/v1/content/publish",
headers=schedule_headers,
json=publish_request
)
response.raise_for_status()
result = response.json()
print(f"\nPost scheduled!")
print(f" Local time: {schedule_datetime.strftime('%Y-%m-%d %H:%M %Z')}")
print(f" UTC time: {utc_time.strftime('%Y-%m-%d %H:%M UTC')}")
print(f" Publish ID: {result['id']}")
return result
def main():
if len(sys.argv) < 4:
print("Usage: python schedule_tiktok.py <video.mp4> '<caption>' '<YYYY-MM-DD HH:MM>' [timezone]")
print("Example: python schedule_tiktok.py video.mp4 'Hello TikTok!' '2026-03-15 14:00' America/New_York")
sys.exit(1)
video_path = sys.argv[1]
caption = sys.argv[2]
datetime_str = sys.argv[3]
timezone = sys.argv[4] if len(sys.argv) > 4 else "UTC"
# Parse datetime
schedule_datetime = datetime.strptime(datetime_str, "%Y-%m-%d %H:%M")
# Schedule
scheduler = TikTokScheduler(API_KEY)
result = scheduler.schedule_post(video_path, caption, schedule_datetime, timezone)
print(f"\nSuccess! Post will appear in your TikTok inbox as a draft.")
if __name__ == "__main__":
main()
Save this script and run it from the command line to schedule posts instantly.
Advanced: Build a Recurring Schedule
Create a content calendar that posts automatically:
from datetime import datetime, timedelta
import json
def create_weekly_schedule(
scheduler: TikTokScheduler,
content_calendar: list,
start_date: datetime,
post_time: str = "09:00",
timezone: str = "America/New_York"
) -> list:
"""
Schedule multiple posts for a weekly content calendar.
Args:
scheduler: TikTokScheduler instance
content_calendar: List of dicts with 'video_path' and 'caption'
start_date: First Monday to start posting
post_time: Time to post each day (HH:MM format)
timezone: Timezone for posting
Returns:
List of scheduled publish IDs
"""
scheduled_posts = []
hour, minute = map(int, post_time.split(":"))
for i, content in enumerate(content_calendar):
# Calculate post date (start_date + i days)
post_date = start_date + timedelta(days=i)
post_datetime = post_date.replace(hour=hour, minute=minute, second=0)
try:
result = scheduler.schedule_post(
video_path=content["video_path"],
caption=content["caption"],
schedule_datetime=post_datetime,
timezone=timezone
)
scheduled_posts.append({
"day": i + 1,
"publish_id": result["id"],
"status": "scheduled"
})
except Exception as e:
scheduled_posts.append({
"day": i + 1,
"error": str(e),
"status": "failed"
})
# Save schedule to file
with open("content_schedule.json", "w") as f:
json.dump(scheduled_posts, f, indent=2)
success_count = sum(1 for p in scheduled_posts if p["status"] == "scheduled")
print(f"\nScheduled {success_count}/{len(content_calendar)} posts")
return scheduled_posts
# Example usage
calendar = [
{"video_path": "monday.mp4", "caption": "Monday motivation! #monday"},
{"video_path": "tuesday.mp4", "caption": "Tutorial Tuesday #tutorial"},
{"video_path": "wednesday.mp4", "caption": "Mid-week vibes #humpday"},
]
# Schedule starting next Monday at 9 AM
next_monday = datetime.now() + timedelta(days=(7 - datetime.now().weekday()) % 7)
next_monday = next_monday.replace(hour=0, minute=0, second=0, microsecond=0)
# create_weekly_schedule(scheduler, calendar, next_monday, "09:00", "America/New_York")
This approach lets you plan entire weeks of content in one command.
Check Scheduled Post Status
Monitor your scheduled posts to ensure they deliver:
def check_schedule_status(publish_id: str) -> dict:
"""Check the status of a scheduled post."""
response = requests.get(
f"{API_BASE_URL}/v1/content/publish/{publish_id}",
headers=headers
)
response.raise_for_status()
status_data = response.json()
status = status_data.get("status")
print(f"Publish Status: {status}")
for target in status_data.get("targets", []):
print(f" Platform: {target.get('platform')}")
print(f" Target Status: {target.get('status')}")
if target.get("publishedUrl"):
print(f" Published URL: {target['publishedUrl']}")
return status_data
# Poll status until complete
def wait_for_publish(publish_id: str, timeout: int = 300) -> dict:
"""Wait for a scheduled post to complete publishing."""
import time
start_time = time.time()
while time.time() - start_time < timeout:
status_data = check_schedule_status(publish_id)
status = status_data.get("status")
if status in ["completed", "sent", "published"]:
print("Post published successfully!")
return status_data
elif status in ["failed", "canceled"]:
raise Exception(f"Publishing failed: {status_data}")
time.sleep(10)
raise TimeoutError("Publishing timed out")
Status values include: queued, processing, sent (success), failed, or canceled.
Best Practices for TikTok API Python
Follow these guidelines for reliable automation:
Use idempotency keys always. Generate a fresh UUID for every publish request. This prevents duplicate posts if your script retries.
Handle timezone conversions carefully. Always convert local times to UTC before sending to the API. Use the pytz library for accurate conversions.
Validate schedule times. Ensure scheduled times are at least 5 minutes in the future. TikTok needs time to process content.
Implement retry logic. Network failures happen. Use exponential backoff for retries:
from time import sleep
def upload_with_retry(file_path, max_retries=3):
for attempt in range(max_retries):
try:
return upload_video(file_path)
except Exception as e:
if attempt == max_retries - 1:
raise
sleep(2 ** attempt) # Exponential backoff
Respect rate limits. Current limits are 10 publish requests per minute. Add delays between bulk uploads.
Store publish IDs. Save the publish request IDs returned by the API. You need them to check status or cancel posts.
Troubleshooting Schedule TikTok Python Issues
"Schedule time must be in the future"
Your schedule time is in the past or too close to now. Schedule at least 5 minutes ahead.
"MISSING_IDEMPOTENCY_KEY"
You forgot to include the Idempotency-Key header. Generate a UUID4 for every request.
"ACCOUNT_NOT_CONNECTED"
Your TikTok account is not linked to Postqued. Connect it in your dashboard first.
"Rate limit exceeded"
You are making requests too quickly. Add delays between API calls. Limit is 10 publishes per minute.
Timezones not converting correctly
Ensure you use the full timezone name like "America/New_York" not "EST". Install pytz for proper handling.
Example: Full Content Pipeline
Here is a complete workflow that checks a folder and schedules new videos:
import os
from pathlib import Path
from datetime import datetime, timedelta
def auto_schedule_from_folder(
folder_path: str,
scheduler: TikTokScheduler,
posts_per_day: int = 1,
start_time: str = "09:00"
) -> list:
"""
Automatically schedule all videos from a folder.
Spreads posts across days starting tomorrow.
"""
folder = Path(folder_path)
videos = sorted(folder.glob("*.mp4")) + sorted(folder.glob("*.mov"))
if not videos:
print("No videos found in folder")
return []
hour, minute = map(int, start_time.split(":"))
tomorrow = datetime.now() + timedelta(days=1)
tomorrow = tomorrow.replace(hour=hour, minute=minute, second=0)
scheduled = []
for i, video in enumerate(videos):
# Calculate which day this post goes out
days_offset = i // posts_per_day
post_datetime = tomorrow + timedelta(days=days_offset)
# Read caption from file if it exists
caption_file = video.with_suffix(".txt")
if caption_file.exists():
caption = caption_file.read_text().strip()
else:
caption = f"Posted via Python automation #{i+1}"
try:
result = scheduler.schedule_post(
video_path=str(video),
caption=caption,
schedule_datetime=post_datetime
)
scheduled.append({
"video": video.name,
"scheduled_for": post_datetime.isoformat(),
"publish_id": result["id"]
})
except Exception as e:
print(f"Failed to schedule {video.name}: {e}")
return scheduled
# Usage: Schedule all videos in ~/videos folder
# scheduler = TikTokScheduler(API_KEY)
# auto_schedule_from_folder("~/videos", scheduler, posts_per_day=2, start_time="10:00")
This automation scans a folder, reads captions from matching text files, and spreads posts across days.
Integrating with Your Workflow
Connect your TikTok scheduler to other systems:
Google Sheets integration. Read your content calendar from a spreadsheet and schedule accordingly.
Notion integration. Pull video ideas from a Notion database and schedule approved content.
AI content generation. Use OpenAI to generate captions, then schedule posts automatically.
Webhook triggers. Create an HTTP endpoint that schedules posts when external systems call it.
Cron scheduling. Run your script daily to process new videos from a watch folder.
Next Steps for Your Python TikTok Scheduler
You now have a complete TikTok API Python solution for scheduling posts. Your next moves:
- Build a content calendar interface with Flask or Django
- Add analytics tracking to monitor post performance
- Create approval workflows before scheduling
- Integrate with video generation pipelines
- Set up monitoring and alerting for failed posts
For more automation ideas, see our guides on n8n TikTok automation and Zapier TikTok integration. Also check out how to post TikTok from Google Sheets for a no-code alternative, or connect Notion to TikTok for content management workflows.
Ready to build? Get your Postqued API key and start automating your TikTok posting today. Our TikTok API makes it easy to integrate with any Python application.
Keywords covered: tiktok api python, schedule tiktok python, python tiktok scheduler, programmatic tiktok posting, automate tiktok python
Ready to automate your TikTok posting? Get your API key and start scheduling with Python today.
Need help with your implementation? Check our API documentation or reach out to support.