TikTok API — SKILL.md
Raw skill file that agents receive when using this skill
---
name: "TikTok API"
description: "Skill for TikTok API — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "social"
agents: ["claude-code", "codex", "gemini"]
tags: ["tiktok-api", "social", "auto-generated"]
---
# TikTok API
---
name: TikTok API
description: Use when integrating with TikTok's API for content creation, user management, analytics, or social media automation. Essential for building TikTok apps, managing business accounts, or analyzing video performance.
metadata:
author: skynet
version: 1.0.0
category: social
---
# TikTok API
## Overview
TikTok API enables developers to build applications that interact with TikTok's platform, including video uploads, user authentication, analytics, and content management.
## Prerequisites
```bash
# Install required dependencies
npm install axios form-data
# or
pip install requests requests-oauthlib
```
## Authentication Setup
### OAuth 2.0 Flow
```javascript
// 1. Redirect user to authorization URL
const authUrl = `https://www.tiktok.com/auth/authorize/
?client_key=${CLIENT_KEY}
&scope=user.info.basic,video.list
&response_type=code
&redirect_uri=${REDIRECT_URI}
&state=${STATE}`;
// 2. Exchange code for access token
const tokenResponse = await fetch('https://open-api.tiktok.com/oauth/access_token/', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_key: CLIENT_KEY,
client_secret: CLIENT_SECRET,
code: authCode,
grant_type: 'authorization_code'
})
});
```
### Client Credentials (App-only)
```python
import requests
def get_client_token():
response = requests.post('https://open-api.tiktok.com/oauth/client_token/', {
'client_key': CLIENT_KEY,
'client_secret': CLIENT_SECRET,
'grant_type': 'client_credentials'
})
return response.json()['access_token']
```
## Core API Operations
### User Information
```javascript
// Get user profile
async function getUserProfile(accessToken) {
const response = await fetch('https://open-api.tiktok.com/user/info/', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fields: ['open_id', 'union_id', 'avatar_url', 'display_name']
})
});
return response.json();
}
```
### Video Operations
```python
# Upload video
def upload_video(access_token, video_path, description):
with open(video_path, 'rb') as video_file:
files = {'video': video_file}
data = {
'description': description,
'privacy_level': 'SELF_ONLY', # or PUBLIC_TO_EVERYONE
'disable_duet': False,
'disable_comment': False,
'disable_stitch': False,
'brand_content_toggle': False
}
response = requests.post(
'https://open-api.tiktok.com/share/video/upload/',
headers={'Authorization': f'Bearer {access_token}'},
files=files,
data=data
)
return response.json()
# Get video list
def get_user_videos(access_token, cursor=0, max_count=20):
payload = {
'fields': ['id', 'title', 'video_description', 'duration', 'cover_image_url'],
'cursor': cursor,
'max_count': max_count
}
response = requests.post(
'https://open-api.tiktok.com/video/list/',
headers={'Authorization': f'Bearer {access_token}'},
json=payload
)
return response.json()
```
### Analytics and Insights
```javascript
// Get video analytics
async function getVideoAnalytics(accessToken, videoId, dateRange) {
const response = await fetch('https://open-api.tiktok.com/video/insights/', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
video_ids: [videoId],
fields: ['views', 'likes', 'comments', 'shares', 'reach'],
start_date: dateRange.start,
end_date: dateRange.end
})
});
return response.json();
}
// Get user analytics
async function getUserAnalytics(accessToken, dateRange) {
const response = await fetch('https://open-api.tiktok.com/user/insights/', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fields: ['profile_views', 'follower_count', 'video_views'],
start_date: dateRange.start,
end_date: dateRange.end
})
});
return response.json();
}
```
## Decision Tree: Choose API Endpoint
```
Need TikTok integration?
├── User Authentication Required?
│ ├── Yes → Use OAuth 2.0 flow
│ │ ├── Need user profile? → /user/info/
│ │ ├── Upload content? → /share/video/upload/
│ │ ├── Get user videos? → /video/list/
│ │ └── Analytics needed? → /user/insights/ or /video/insights/
│ └── No → Use Client Credentials
│ ├── Public data only? → /research/ endpoints
│ └── App functionality? → /webhook/ endpoints
├── Webhook Integration?
│ ├── Real-time updates → Configure webhook URLs
│ └── Batch processing → Use polling with /video/list/
└── Testing/Development?
├── Use Sandbox environment
└── Apply for production access
```
## Common Workflows
### Complete Video Upload Flow
```python
def complete_upload_workflow(access_token, video_path, metadata):
try:
# 1. Upload video
upload_result = upload_video(access_token, video_path, metadata['description'])
if upload_result['error']['code'] != 'ok':
raise Exception(f"Upload failed: {upload_result['error']['message']}")
share_id = upload_result['data']['share_id']
# 2. Check upload status
status_result = check_upload_status(access_token, share_id)
# 3. Get video details after processing
if status_result['data']['status'] == 'PROCESSING_DOWNLOAD':
video_id = status_result['data']['video_id']
return get_video_details(access_token, video_id)
return status_result
except Exception as e:
print(f"Upload workflow failed: {e}")
return None
def check_upload_status(access_token, share_id):
response = requests.post(
'https://open-api.tiktok.com/share/status/',
headers={'Authorization': f'Bearer {access_token}'},
json={'share_id': share_id}
)
return response.json()
```
### Batch Analytics Collection
```javascript
async function collectBatchAnalytics(accessToken, videoIds, dateRange) {
const batchSize = 20; // API limit
const results = [];
for (let i = 0; i < videoIds.length; i += batchSize) {
const batch = videoIds.slice(i, i + batchSize);
try {
const analytics = await getVideoAnalytics(accessToken, batch, dateRange);
results.push(...analytics.data);
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
console.error(`Batch ${i/batchSize + 1} failed:`, error);
}
}
return results;
}
```
## Rate Limiting and Best Practices
### Rate Limit Handler
```python
import time
from functools import wraps
def rate_limit_handler(max_retries=3, backoff_factor=2):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
response = func(*args, **kwargs)
if response.status_code == 429: # Rate limited
wait_time = backoff_factor ** attempt
print(f"Rate limited. Waiting {wait_time} seconds...")
time.sleep(wait_time)
continue
return response
raise Exception("Max retries exceeded for rate limiting")
return wrapper
return decorator
@rate_limit_handler()
def api_request(url, headers, data):
return requests.post(url, headers=headers, json=data)
```
## Troubleshooting
### Common Error Messages
**Error: `invalid_scope`**
```bash
# Check scope permissions in app dashboard
# Valid scopes: user.info.basic, user.info.profile, video.list, video.upload
```
**Error: `access_token_expired`**
```javascript
// Refresh token
async function refreshAccessToken(refreshToken) {
const response = await fetch('https://open-api.tiktok.com/oauth/refresh_token/', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_key: CLIENT_KEY,
refresh_token: refreshToken,
grant_type: 'refresh_token'
})
});
return response.json();
}
```
**Error: `video_too_large`**
```python
# Check file size (max 4GB) and duration (max 10 minutes)
import os
def validate_video(file_path):
file_size = os.path.getsize(file_path)
max_size = 4 * 1024 * 1024 * 1024 # 4GB
if file_size > max_size:
raise ValueError(f"Video too large: {file_size/1024/1024:.1f}MB > 4GB")
return True
```
**Error: `rate_limit_exceeded`**
```bash
# Implement exponential backoff
# Default limits: 100 requests per minute per app
# User-level: 50 requests per minute per user
```
### Debug Mode
```javascript
const DEBUG = true;
function debugLog(endpoint, request, response) {
if (DEBUG) {
console.log(`[${endpoint}] Request:`, request);
console.log(`[${endpoint}] Response:`, response);
}
}
```
### Environment Configuration
```bash
# .env file
TIKTOK_CLIENT_KEY=your_client_key
TIKTOK_CLIENT_SECRET=your_client_secret
TIKTOK_REDIRECT_URI=https://yourapp.com/callback
TIKTOK_SANDBOX_MODE=true
```
curl -s https://skills.skynet.ceo/api/skills/tiktok-api/skill.md