Video API
The Video API manages standalone video content separate from live streams. It includes WebRTC video sessions (powered by Cloudflare Calls), video CRUD, albums, showcase annotations, semantic search, ML-based recommendations, and engagement analytics.
WebRTC video sessions
Video sessions use Cloudflare Calls for real-time WebRTC. Each session supports multiple participants with individual media tracks (audio, video, screen share).
Get ICE servers
GET /api/v1/video-sessions/ice-servers
Get STUN/TURN server configuration for WebRTC. No auth required.
{
"ice_servers": [
{ "urls": ["stun:stun.l.google.com:19302"] },
{ "urls": ["stun:stun1.l.google.com:19302"] },
{
"urls": ["turn:turn.ainative.studio:3478"],
"username": "ainative",
"credential": "..."
}
]
}
Create session
POST /api/v1/video-sessions/sessions
Create a new video session backed by Cloudflare Calls.
Auth required: Yes
Rate limit: 10 per minute
{
"session_name": "Team standup",
"max_participants": 10
}
Get session
GET /api/v1/video-sessions/sessions/{session_id}
Auth required: Yes
Get active sessions
GET /api/v1/video-sessions/sessions/active
Get all currently active sessions for the authenticated user.
Auth required: Yes
Get user sessions
GET /api/v1/video-sessions/sessions/user/{user_id}
Get all sessions for a specific user. Admins can access any user's sessions; regular users can only access their own.
Auth required: Yes
Update session
PUT /api/v1/video-sessions/sessions/{session_id}
Update session details. Host only.
Auth required: Yes (host only)
Delete session
DELETE /api/v1/video-sessions/sessions/{session_id}
Delete a session. Host or admin only.
Auth required: Yes
Generate session token
POST /api/v1/video-sessions/sessions/{session_id}/token
Generate a JWT access token and TURN credentials for joining the session.
Auth required: Yes
{
"token": "eyJ...",
"turn_credentials": {
"username": "...",
"credential": "...",
"ttl": 86400
},
"expires_at": "2026-04-26T10:00:00Z"
}
Get participants
GET /api/v1/video-sessions/sessions/{session_id}/participants
List all participants in a session.
Auth required: Yes
Add media track
POST /api/v1/video-sessions/sessions/{session_id}/participants/{participant_id}/tracks
Add a media track (audio, video, or screen share) to a session via WebRTC SDP offer exchange.
Auth required: Yes
{
"sdp": "v=0\r\no=...",
"type": "video"
}
type values: audio, video, screen.
Returns an SDP answer for completing the WebRTC negotiation.
Video CRUD
Create video
POST /api/v1/videos/
Upload video metadata. The actual video file must be uploaded separately to Cloudflare Stream or object storage — this endpoint registers it in the platform.
Auth required: Yes
| Field | Type | Description |
|---|---|---|
title | string | Video title |
description | string | Video description |
video_type | string | tutorial, webinar, demo, or other |
video_url | string | Video source URL |
thumbnail_url | string | Thumbnail URL |
duration | integer | Duration in seconds |
tags | string[] | Tag list |
tech_stack | string[] | Technologies shown |
project_url | string | Related project URL |
Get video
GET /api/v1/videos/{video_id}
Auth required: Yes
Update video
PUT /api/v1/videos/{video_id}
Auth required: Yes (owner only)
Delete video
DELETE /api/v1/videos/{video_id}
Auth required: Yes (owner only). Returns 204 No Content.
List videos
GET /api/v1/videos/
List videos for the authenticated user with filtering and pagination.
Auth required: Yes
Video analytics
Track view
POST /api/v1/videos/{video_id}/track-view
Track a video view event. Uses SHA-256 IP hashing — raw IP addresses are never stored.
Auth required: No (optional — logged-in user's ID is recorded if provided)
{
"watch_duration": 420,
"completion_percentage": 73.5,
"session_id": "optional-session-uuid"
}
| Field | Type | Required | Description |
|---|---|---|---|
watch_duration | integer | Yes | Time watched in seconds (≥0) |
completion_percentage | float | Yes | Percent of video watched (0–100) |
session_id | string | No | Session UUID for deduplication |
Returns a session_id to use for subsequent track-view calls in the same session.
Get video analytics
GET /api/v1/videos/{video_id}/analytics
Get engagement metrics. Only accessible by the video owner.
Auth required: Yes (owner only)
{
"video_id": "video-uuid",
"total_views": 12430,
"unique_viewers": 8901,
"avg_watch_duration": 312.4,
"avg_completion_rate": 67.2,
"likes": 432,
"shares": 89,
"comments_count": 147
}
Get aggregated analytics
GET /api/v1/videos/{video_id}/analytics/aggregated
Get time-series analytics with configurable granularity and period.
Auth required: Yes (owner only)
| Parameter | Type | Options | Description |
|---|---|---|---|
granularity | string | hourly, daily, weekly | Time bucket size |
period | string | 24h, 7d, 30d | Lookback period |
Get device breakdown
GET /api/v1/videos/{video_id}/analytics/devices
Get viewer breakdown by device type, browser, and OS.
Auth required: Yes (owner only)
Get watch time distribution
GET /api/v1/videos/{video_id}/analytics/watch-time-distribution
Get how views are distributed across completion buckets: 0–25%, 25–50%, 50–75%, 75–100%.
Auth required: Yes (owner only)
Get completion rate analytics
GET /api/v1/videos/{video_id}/analytics/completion-rate
Get detailed completion rate metrics and drop-off points.
Auth required: Yes (owner only)
| Parameter | Type | Description |
|---|---|---|
breakdown | string | Optional: device to break down by device type |
Get geographic analytics
GET /api/v1/videos/{video_id}/analytics/geography
Get geographic breakdown of viewers by country and city. Privacy-preserving — no raw IPs exposed.
Auth required: Yes (owner only)
Get dashboard overview
GET /api/v1/videos/{video_id}/analytics/dashboard
Get a comprehensive analytics dashboard including overall metrics, trends compared to the previous period, peak hours, best-performing days, and optional real-time metrics.
Auth required: Yes (owner only)
| Parameter | Type | Default | Description |
|---|---|---|---|
include_realtime | boolean | false | Include metrics from the last hour |
Likes and shares
Like a video
POST /api/v1/videos/{video_id}/like
Like a video. One like per user — returns 409 if already liked.
Auth required: Yes
{
"status": "success",
"message": "Video liked successfully",
"total_likes": 433
}
Unlike a video
DELETE /api/v1/videos/{video_id}/like
Remove a like. Returns 404 if the user has not liked the video.
Auth required: Yes
Track share
POST /api/v1/videos/{video_id}/share
Record a video share event. Auth is optional — unauthenticated shares are tracked anonymously.
Auth required: No
{
"platform": "twitter"
}
platform is optional. Common values: twitter, facebook, linkedin, email.
Video search
Semantic video search powered by ZeroDB embeddings with full-text fallback.
Search videos
POST /api/v1/projects/{project_id}/videos/search
Search for videos using natural language queries. Results are ranked by semantic similarity.
Auth required: Yes
{
"query": "python machine learning tutorial for beginners",
"category": "tutorial",
"duration_min": 300,
"duration_max": 3600,
"author": "alice",
"tags": ["python", "ml"],
"limit": 10,
"offset": 0
}
| Field | Type | Default | Description |
|---|---|---|---|
query | string | — | Natural language query (1–500 chars, required) |
category | string | — | Filter: tutorial, webinar, showcase, demo |
duration_min | integer | — | Minimum duration in seconds |
duration_max | integer | — | Maximum duration in seconds |
author | string | — | Filter by author name |
tags | string[] | — | Filter by tags (any match) |
limit | integer | 10 | Results per page (max 100) |
offset | integer | 0 | Pagination offset |
Response
{
"results": [
{
"video_id": "video-uuid",
"title": "Python ML Tutorial",
"description": "Learn machine learning with Python",
"category": "tutorial",
"duration": 2340,
"thumbnail_url": "https://...",
"url": "/videos/video-uuid",
"author": "alice",
"tags": ["python", "ml"],
"similarity_score": 0.92,
"created_at": "2026-03-15T10:00:00Z"
}
],
"total": 24,
"query": "python machine learning tutorial for beginners",
"query_time_ms": 142.3,
"limit": 10,
"offset": 0
}
Index video
POST /api/v1/projects/{project_id}/videos/{video_id}/index
Index or re-index a video for search. Videos are auto-indexed on upload and metadata updates. Use this to manually trigger indexing or fix index issues.
Auth required: Yes
{
"video_id": "video-uuid",
"title": "Python ML Tutorial",
"description": "...",
"category": "tutorial",
"duration": 2340,
"thumbnail_url": "https://...",
"author": "alice",
"tags": ["python", "ml"]
}
Indexed field weights: title 50%, description 30%, tags 20%.
Remove from search index
DELETE /api/v1/projects/{project_id}/videos/{video_id}/index
Remove a video from the search index. Does not delete the video file itself.
Auth required: Yes
Find related videos (search-based)
POST /api/v1/projects/{project_id}/videos/{video_id}/related
Find videos similar to a specific video using content-based similarity. Uses shared tags and category matching with embedding similarity where available.
Auth required: Yes
| Query parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 5 | Max results (max 20) |
category_filter | string | — | Optional category filter |
Bulk index
POST /api/v1/projects/{project_id}/videos/bulk-index
Index multiple videos in a single operation. Useful for initial migration or batch re-indexing.
Auth required: Yes
[
{
"video_id": "...",
"title": "...",
"category": "tutorial",
...
}
]
Returns a summary: { "indexed_count": 45, "failed_count": 2, "errors": [...] }.
Video recommendations
ML-based recommendation system with multiple algorithm strategies.
Get related videos
GET /api/v1/videos/{video_id}/related
Get ML-based recommendations for videos related to the given video. Results are cached for 1 hour.
Auth required: Yes
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 10 | Max recommendations (max 50) |
strategy | string | hybrid | Algorithm: content, collaborative, or hybrid |
| Strategy | Description |
|---|---|
content | Semantic similarity via vector embeddings |
collaborative | User viewing behavior patterns |
hybrid | Weighted combination of both |
{
"video_id": "source-video-uuid",
"recommendations": [
{
"video_id": "rec-video-uuid",
"title": "Advanced Python Tutorial",
"similarity_score": 0.87,
"rank": 1
}
],
"strategy": "hybrid",
"total": 10
}
Track recommendation click
POST /api/v1/videos/{video_id}/related/click
Record when a user clicks a recommendation. Used for CTR analysis and feeding data into the RLHF improvement loop.
Auth required: No (optional)
{
"recommended_video_id": "rec-video-uuid",
"rank": 1
}
Get recommendation analytics
GET /api/v1/videos/{video_id}/related/analytics
Get CTR metrics for recommendations including total impressions, clicks, average CTR, and breakdown by rank position.
Auth required: Yes
| Parameter | Type | Default | Description |
|---|---|---|---|
time_range_days | integer | 7 | Analytics lookback period (1–90 days) |
Albums
Albums group photos and videos into curated collections.
Create album
POST /api/v1/albums/
Auth required: Yes
{
"title": "Coding sessions 2026",
"description": "My recorded coding sessions",
"visibility": "public",
"cover_url": "https://..."
}
Get album
GET /api/v1/albums/{album_id}
Get album details with all items. Public albums are accessible without auth.
Auth required: No (optional)
List user albums
GET /api/v1/albums/
Get all albums for the authenticated user.
Auth required: Yes
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
page_size | integer | 20 | Items per page (max 100) |
Update album
PUT /api/v1/albums/{album_id}
Update album title, description, visibility, or cover image.
Auth required: Yes (owner only)
Delete album
DELETE /api/v1/albums/{album_id}
Delete an album and all its items. Returns 204 No Content.
Auth required: Yes (owner only)
Add item to album
POST /api/v1/albums/{album_id}/items
Add a photo or video to an album.
Auth required: Yes
{
"media_type": "video",
"media_id": "video-uuid",
"caption": "Episode 42"
}
Remove item from album
DELETE /api/v1/albums/{album_id}/items/{item_id}
Remove an item. Returns 204 No Content.
Auth required: Yes (owner only)
Reorder album items
POST /api/v1/albums/{album_id}/reorder
Change the display order of items in an album. Returns 204 No Content.
Auth required: Yes
{
"item_orders": [
{ "item_id": "item-uuid-1", "order": 0 },
{ "item_id": "item-uuid-2", "order": 1 }
]
}
Showcase videos & annotations
Showcase videos are DEMO type videos with interactive timed annotations for feature demonstrations.
Filter showcase videos
GET /api/v1/showcase-videos/showcase
Filter and search showcase demo videos. Returns only DEMO type videos.
Auth required: Yes
| Parameter | Type | Description |
|---|---|---|
tech_stack | string | Comma-separated technologies (e.g., React,Python) |
tags | string | Comma-separated tags (e.g., opensource,tutorial) |
search | string | Keyword search in title and description |
page | integer | Page number |
limit | integer | Items per page (max 100, default 10) |
GET /api/v1/showcase-videos/showcase?tech_stack=React,FastAPI&tags=tutorial&search=auth
Create annotation
POST /api/v1/showcase-videos/{video_id}/annotations
Add a timed annotation to a showcase video. Annotations appear as interactive markers during playback.
Auth required: Yes (video owner only)
{
"timestamp": 42.5,
"title": "Database connection setup",
"description": "Here we configure the SQLAlchemy engine with connection pooling",
"annotation_type": "feature",
"url": "https://docs.ainative.studio/..."
}
| Field | Type | Required | Description |
|---|---|---|---|
timestamp | float | Yes | Seconds into the video |
title | string | Yes | Annotation title |
description | string | No | Detail text |
annotation_type | string | Yes | info, feature, bug-fix, or demo |
url | string | No | Related URL |
Returns 400 if the timestamp exceeds the video duration.
List annotations
GET /api/v1/showcase-videos/{video_id}/annotations
Get all annotations for a video in chronological order (sorted by timestamp).
Auth required: Yes
| Parameter | Type | Description |
|---|---|---|
type | string | Filter: info, feature, bug-fix, or demo |
Update annotation
PATCH /api/v1/showcase-videos/{video_id}/annotations/{annotation_id}
Update an existing annotation. All fields are optional.
Auth required: Yes (video owner only)
Delete annotation
DELETE /api/v1/showcase-videos/{video_id}/annotations/{annotation_id}
Delete an annotation. Returns 204 No Content.
Auth required: Yes (video owner only)