Video Moderation
BETAAnalyze video content for potential moderation issues with asynchronous processing.
https://api.safecomms.dev/moderation/videoModerate video content from a URL. The video will be queued for asynchronous processing. Use the job ID to check status and retrieve results.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| video | string | Yes | URL to the video file. Supported formats: MP4, WebM, MOV |
| language | string | No | Language of the video content. Default: "English" (English only in beta) |
| moderationProfileId | string | No | Custom moderation profile ID for applying custom rules |
| analyzeAudio | object | No | Audio analysis configuration. Null/undefined disables audio analysis. Non-null object with truthy values enables it. See Audio Options for details. |
| extractMetadata | boolean | No | Extract video metadata (duration, resolution, codec). Default: false |
| detectScenes | boolean | No | Detect scene changes in the video (Business+ tiers). Default: false |
Audio Analysis Options
The analyzeAudio field accepts an object with the following properties. Set to null or undefined to disable audio analysis entirely.
| Field | Type | Default | Description |
|---|---|---|---|
| enabled | boolean | true | Enable audio analysis |
| channel | number | 0 | Audio channel/track to analyze (0 = first track) |
| transcribe | boolean | false | Transcribe audio content to text (Business+ tiers) |
| transcriptionMode | string | "single" | "single" (Basic+) or "multiple" speakers (Pro+) |
| analyzeSentiment | boolean | false | Analyze speaker sentiment (Starter+ tiers) |
| detectTopics | boolean | false | Detect discussion topics (Starter+ tiers) |
| detectPii | boolean | false | Detect personally identifiable information (Pro+ tiers) |
| includeTimestamps | boolean | false | Include timestamps in transcription (Pro+ tiers) |
| customKeywords | string[] | null | Custom keywords to look for in audio (Business+ tiers) |
| detectDistress | boolean | false | Detect emotional distress in speech (Business+ tiers) |
| analyzeQuality | boolean | false | Analyze audio quality metrics (Business+ tiers) |
Language Support
Currently, video moderation is in beta and only supports English content. Requests with non-English video content may produce inaccurate results or errors.
Token Usage & Costs
Video moderation uses a segment-based pricing model for efficient processing. The base cost is 200 tokens, with additional costs based on video length and enabled features.
| Feature | Cost | Tier | Condition |
|---|---|---|---|
| Base Request | 200 Tokens | Basic+ | Always applied for video moderation. |
| Video Length | +25 per segment | Basic+ | Length-based cost only. Videos are split into 30-second segments. This cost is applied once per segment regardless of which features are enabled. Note: Short end segments (<10s) are merged with the previous segment to avoid additional costs. |
| Audio Analysis | +50 | Basic+ | Applied when analyzeAudio.enabled is true and video contains an audio track. |
| Audio Transcription | +25 | Business+ | Applied when analyzeAudio.transcribe is true. |
| Scene Detection | +25 | Business+ | Applied when detectScenes is true. |
| Metadata Extraction | +10 | Basic+ | Applied when extractMetadata is true. |
Cost Examples
30-second video (1 segment, audio analysis): 200 + 25 + 50 = 275 tokens
2-minute video (4 segments, audio analysis): 200 + (25 × 4) + 50 = 350 tokens
5-minute video (10 segments, audio + transcription): 200 + (25 × 10) + 50 + 25 = 525 tokens
💡 Cost Efficiency
Our segment-based approach intelligently splits videos into 30-second segments for efficient audio and metadata processing, providing cost-effective moderation without expensive frame-by-frame analysis.
Example Request & Response
Example Request
{
"video": "https://example.com/video.mp4",
"language": "English",
"moderationProfileId": "optional-profile-id",
"analyzeAudio": {
"enabled": true,
"channel": 0,
"transcribe": true,
"transcriptionMode": "single",
"analyzeSentiment": true,
"detectTopics": true,
"detectPii": false,
"includeTimestamps": true,
"customKeywords": ["keyword1", "keyword2"],
"detectDistress": false,
"analyzeQuality": false
},
"extractMetadata": false,
"detectScenes": false
}Note: To disable audio analysis, set analyzeAudio to null or omit it entirely.
Example Response (202 Accepted)
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"message": "Video analysis queued for processing"
}https://api.safecomms.dev/moderation/video/uploadUpload and moderate video content directly. Maximum file size: 500MB. Supported formats: MP4, WebM, MOV.
Request (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
| video | file | Yes | Video file. Max: 500MB. Formats: MP4, WebM, MOV |
| All parameters from the URL-based endpoint are also supported as form fields | |||
Example Response (202 Accepted)
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"message": "Video uploaded and queued for analysis"
}https://api.safecomms.dev/moderation/video/{job-id}Retrieve the status and results of a video moderation job.
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| jobId | string | Yes | The job ID returned from the video moderation request |
Job Status: Queued
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"createdAt": "2026-01-28T10:30:00Z",
"startedAt": null,
"completedAt": null,
"result": null,
"errorMessage": null
}Job Status: Processing
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"createdAt": "2026-01-28T10:30:00Z",
"startedAt": "2026-01-28T10:30:05Z",
"completedAt": null,
"result": null,
"errorMessage": null
}Job Status: Completed
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"createdAt": "2026-01-28T10:30:00Z",
"startedAt": "2026-01-28T10:30:05Z",
"completedAt": "2026-01-28T10:31:23Z",
"result": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"isClean": false,
"severity": "High",
"categoryScores": {
"violence": "High",
"nudity": "None",
"hate": "None"
},
"metadata": {
"format": "mp4",
"width": 1920,
"height": 1080,
"duration": 45.5,
"frameRate": 30.0,
"codec": "h264",
"fileSizeBytes": 12345678,
"hasAudio": true
},
"segments": [
{
"segmentNumber": 1,
"startTime": 0.0,
"endTime": 5.0,
"duration": 5.0,
"isClean": true,
"severity": "Clean",
"categoryScores": {},
"detectedContent": [],
"issues": [],
"description": "Normal content"
},
{
"segmentNumber": 2,
"startTime": 5.0,
"endTime": 10.0,
"duration": 5.0,
"isClean": false,
"severity": "High",
"categoryScores": {
"violence": "High"
},
"detectedContent": [
{
"category": "violence",
"description": "Graphic violence detected",
"confidence": 0.95,
"approximateTimestamp": 7.5
}
],
"issues": [
{
"category": "violence",
"severity": "High",
"description": "Explicit violent content",
"confidence": 0.95
}
]
}
],
"audio": {
"isClean": true,
"severity": "Clean",
"transcription": null,
"segments": [],
"issues": []
},
"scenes": [],
"issues": [
{
"timestamp": 7.5,
"type": "visual",
"category": "violence",
"severity": "High",
"description": "Graphic violence detected",
"frameNumber": 225
}
],
"summary": "Video contains high-severity violent content at 7.5 seconds",
"totalSegmentsAnalyzed": 9,
"processingTimeSeconds": 78.2
},
"errorMessage": null
}Job Status: Failed
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"createdAt": "2026-01-28T10:30:00Z",
"startedAt": "2026-01-28T10:30:05Z",
"completedAt": "2026-01-28T10:30:15Z",
"result": null,
"errorMessage": "Failed to download video from URL"
}Error Responses
400 Bad Request
{
"error": "Video URL is required.",
"statusCode": 400
}403 Forbidden
{
"error": "Video moderation is not available on your current tier. Upgrade to Basic or higher.",
"statusCode": 403
}404 Not Found
{
"error": "Video moderation job not found.",
"statusCode": 404
}413 Payload Too Large
{
"error": "Video file size exceeds the limit of 500MB for your tier.",
"statusCode": 413
}429 Too Many Requests
{
"error": "Maximum concurrent video jobs (5) reached. Please wait for existing jobs to complete.",
"statusCode": 429
}Rate Limits & Tier Restrictions
Video moderation availability and limits vary by tier:
| Tier | Max File Size | Max Duration | Concurrent Jobs | Rate Limit |
|---|---|---|---|---|
| Free | N/A | N/A | N/A | Not Available |
| Basic | 5 MB | 30 seconds | 1 job | 1 request/min |
| Starter | 10 MB | 1 minute | 1 job | 2 requests/min |
| Pro | 25 MB | 2 minutes | 2 jobs | 5 requests/min |
| Business | 100 MB | 10 minutes | 5 jobs | 15 requests/min |
| Enterprise | 500 MB | 30 minutes | 20 jobs | 60 requests/min |
Advanced Features
- Basic, Starter & Pro: Audio analysis, metadata extraction
- Business & Enterprise: All features including scene detection, audio transcription, and custom keywords