The VideoToPrompt.org API enables developers to integrate video-to-prompt generation directly into applications, workflows, and automated pipelines. Whether you're building a creative tool, an automation workflow, or a production system that needs to process video content at scale, this guide covers everything you need to get started and build reliable integrations.
API Base URL: https://api.videotoprompt.org/v1
Authentication: Bearer token (API key)
Format: JSON request/response
Rate limit: Depends on plan (see Pricing section)
Authentication
The VideoToPrompt API uses API key authentication. All requests must include your API key in the Authorization header.
API Keys
- Sign up or log in at VideoToPrompt.org
- Navigate to Settings → API Keys
- Click "Generate New API Key" and give it a descriptive name
- Copy the key immediately — it will only be shown once
- Store it securely (use environment variables, never hardcode in source code)
Authorization Header
Header format:
Authorization: Bearer YOUR_API_KEY_HERE
Content-Type: application/json
OAuth 2.0
For applications that need to act on behalf of users (e.g., integrating VideoToPrompt into a multi-user SaaS product), OAuth 2.0 is supported:
- Authorization endpoint:
https://videotoprompt.org/oauth/authorize - Token endpoint:
https://api.videotoprompt.org/oauth/token - Supported grant types: authorization_code, refresh_token
- Scopes:
analyze:read,analyze:write,account:read
Rate Limits and Quotas
| Plan | Requests/min | Analyses/day | Max video length | Max file size |
|---|---|---|---|---|
| Free | 5 | 20 | 2 min | 100 MB |
| Starter | 20 | 200 | 10 min | 500 MB |
| Pro | 60 | 2,000 | 30 min | 2 GB |
| Enterprise | Custom | Custom | Custom | Custom |
Rate limit headers are included in every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1717200000
API Endpoints
POST /analyze/upload — Video File Upload
Upload a video file directly for analysis. Use multipart/form-data encoding.
Request:
POST /v1/analyze/upload
Content-Type: multipart/form-data
{
"video": [binary file data],
"platform": "midjourney",
"style_depth": "detailed",
"include_negative": true,
"language": "en"
}
Parameters:
video(required): Video file, max size per planplatform: "midjourney" | "stable-diffusion" | "dalle3" | "sora" | "runway" | "generic" (default: "generic")style_depth: "basic" | "standard" | "detailed" | "comprehensive" (default: "standard")include_negative: boolean — include negative prompt (SD/MJ only) (default: false)language: ISO 639-1 language code for output (default: "en")
POST /analyze/url — URL-Based Analysis
Analyze a video from a public URL (YouTube, Vimeo, direct video URLs).
POST /v1/analyze/url
Content-Type: application/json
{
"url": "https://www.youtube.com/watch?v=EXAMPLE",
"platform": "stable-diffusion",
"style_depth": "detailed",
"timestamp_start": 30,
"timestamp_end": 90
}
Additional URL parameters:
url(required): Public video URLtimestamp_start: Start time in seconds (default: 0)timestamp_end: End time in seconds (default: full video, limited by plan)
GET /analyze/{analysis_id} — Retrieve Results
Video analysis is asynchronous. Use this endpoint to poll for results after submitting an analysis request.
GET /v1/analyze/ANALYSIS_ID_HERE
Response:
{
"id": "ana_abc123",
"status": "completed",
"created_at": "2025-06-01T12:00:00Z",
"completed_at": "2025-06-01T12:00:15Z",
"platform": "midjourney",
"prompt": {
"text": "A sun-drenched coastal village...",
"negative": "blurry, low quality, watermark...",
"parameters": "--ar 16:9 --v 6 --style raw",
"full": "A sun-drenched coastal village... --ar 16:9 --v 6 --style raw",
"style_analysis": {
"dominant_colors": ["#F4A261", "#2A9D8F", "#264653"],
"lighting": "golden hour, warm directional",
"mood": "warm, nostalgic, Mediterranean",
"camera": "wide angle, low angle"
}
}
}
Status Values
pending— Job queued, not yet startedprocessing— Analysis in progresscompleted— Results readyfailed— Analysis failed (see error field)
Code Examples
Python Example
import requests
import time
import os
API_KEY = os.environ.get("V2P_API_KEY")
BASE_URL = "https://api.videotoprompt.org/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Analyze a YouTube video
def analyze_video_url(url, platform="midjourney"):
payload = {
"url": url,
"platform": platform,
"style_depth": "detailed",
"include_negative": True
}
response = requests.post(
f"{BASE_URL}/analyze/url",
headers=headers,
json=payload
)
response.raise_for_status()
return response.json()["id"]
# Poll for results
def get_analysis_result(analysis_id, max_wait=120):
start_time = time.time()
while time.time() - start_time < max_wait:
response = requests.get(
f"{BASE_URL}/analyze/{analysis_id}",
headers=headers
)
result = response.json()
if result["status"] == "completed":
return result["prompt"]
elif result["status"] == "failed":
raise Exception(f"Analysis failed: {result.get('error')}")
time.sleep(3) # Poll every 3 seconds
raise TimeoutError("Analysis timed out")
# Full workflow
analysis_id = analyze_video_url(
"https://www.youtube.com/watch?v=EXAMPLE",
platform="stable-diffusion"
)
print(f"Analysis started: {analysis_id}")
prompt = get_analysis_result(analysis_id)
print(f"Generated prompt: {prompt['text']}")
print(f"Negative prompt: {prompt['negative']}")
JavaScript/Node.js Example
const API_KEY = process.env.V2P_API_KEY;
const BASE_URL = 'https://api.videotoprompt.org/v1';
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
async function analyzeVideoUrl(url, platform = 'midjourney') {
const response = await fetch(`${BASE_URL}/analyze/url`, {
method: 'POST',
headers,
body: JSON.stringify({
url,
platform,
style_depth: 'detailed',
include_negative: true
})
});
if (!response.ok) throw new Error(`API error: ${response.status}`);
const data = await response.json();
return data.id;
}
async function pollForResult(analysisId, maxWaitMs = 120000) {
const startTime = Date.now();
while (Date.now() - startTime < maxWaitMs) {
const response = await fetch(
`${BASE_URL}/analyze/${analysisId}`,
{ headers }
);
const result = await response.json();
if (result.status === 'completed') return result.prompt;
if (result.status === 'failed') throw new Error(result.error);
await new Promise(resolve => setTimeout(resolve, 3000));
}
throw new Error('Analysis timed out');
}
// Usage
const analysisId = await analyzeVideoUrl(
'https://vimeo.com/EXAMPLE',
'dalle3'
);
const prompt = await pollForResult(analysisId);
console.log('Prompt:', prompt.text);
cURL Example
# Analyze a video URL
curl -X POST https://api.videotoprompt.org/v1/analyze/url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://youtube.com/watch?v=EXAMPLE","platform":"midjourney"}'
# Check result (replace ANALYSIS_ID with returned id)
curl https://api.videotoprompt.org/v1/analyze/ANALYSIS_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Webhook Integration
Instead of polling, you can configure webhooks to receive analysis results asynchronously when they complete.
Setting Up Webhooks
- Go to Settings → Webhooks in your VideoToPrompt dashboard
- Add your endpoint URL (must be publicly accessible HTTPS)
- Choose which events to receive:
analysis.completed,analysis.failed - Set a webhook secret for payload verification
Webhook Payload
POST https://your-server.com/webhook
X-V2P-Signature: sha256=HMAC_SIGNATURE
{
"event": "analysis.completed",
"timestamp": "2025-06-01T12:00:15Z",
"data": {
"id": "ana_abc123",
"prompt": { ... same structure as GET response ... }
}
}
Batch Processing
The batch endpoint allows you to submit multiple video analyses in a single API call, with results returned together when all are complete.
POST /v1/analyze/batch
{
"analyses": [
{"url": "https://example.com/video1.mp4", "platform": "midjourney"},
{"url": "https://example.com/video2.mp4", "platform": "dalle3"},
{"url": "https://youtube.com/watch?v=ABC", "platform": "stable-diffusion"}
],
"webhook_url": "https://your-server.com/batch-complete"
}
Error Handling
The API uses standard HTTP status codes. All errors include a JSON body with details:
| Status Code | Error Type | Description and Handling |
|---|---|---|
| 400 | bad_request | Invalid parameters — check your request body |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Action not permitted on this plan |
| 404 | not_found | Analysis ID doesn't exist |
| 429 | rate_limit_exceeded | Wait for X-RateLimit-Reset time |
| 500 | server_error | Retry with exponential backoff |
| 503 | service_unavailable | Temporary outage — retry after delay |
Production Best Practices
- Never hardcode API keys: Use environment variables or a secrets management service
- Implement exponential backoff: For 429 and 5xx errors, retry with increasing delays
- Use webhooks over polling: Polling is fine for development; webhooks are more efficient in production
- Cache results: Analysis results don't change — cache them to avoid redundant API calls for the same video
- Validate webhook signatures: Always verify the HMAC signature to confirm the webhook came from VideoToPrompt
- Handle partial failures in batch: Some items in a batch may fail while others succeed; handle each result individually
- Monitor rate limits proactively: Track your usage and upgrade plans before hitting limits in production
Use Case Examples
- Social media scheduler: Automatically generate AI images for posts by analyzing inspiration videos, then passing prompts to DALL-E 3 or Midjourney API
- Creative brief generator: Marketing agencies can analyze client reference videos and automatically generate style briefs and AI concept images
- Video catalog processing: Process entire libraries of video content to extract visual style metadata and searchable prompt tags
- E-commerce product visualization: Analyze existing product videos to generate prompts for creating AI product images in new contexts and settings
- Content moderation enrichment: Combine with content analysis to classify video content by visual style and aesthetic properties
The VideoToPrompt API is designed to scale with your needs — from single analyses in development to batch processing thousands of videos per day in production. Start with the free tier to explore capabilities, and upgrade as your integration grows. For enterprise volumes or custom requirements, contact the team directly through the website.