Overview
The Video API allows you to manage videos, check transcription status, retrieve analytics, and delete videos.
Endpoints
Get Transcribe Status
Check the transcription status of a video.
GET /api/video/transcribe/status
The unique identifier of the video
Response
Current transcription status. Can be:
"PROCESSING" - Transcription in progress
"COMPLETE" - Transcription finished
"ERROR" - Transcription failed
null - Transcription not started
Example Request
curl -X GET "https://cap.so/api/video/transcribe/status?videoId=abc123" \
-H "Authorization: Bearer <token>"
Example Response
{
"transcriptionStatus": "COMPLETE"
}
Delete Video
Permanently delete a video.
The unique identifier of the video to delete
Response
Empty response on success
Example Request
curl -X DELETE "https://cap.so/api/video/delete?videoId=abc123" \
-H "Authorization: Bearer <token>"
Example Response
This action is permanent and cannot be undone. The video and all associated data will be deleted.
Get Analytics
Retrieve view count and analytics for a video.
The unique identifier of the video
Response
Total number of views for the video
Example Request
curl -X GET "https://cap.so/api/video/analytics?videoId=abc123" \
-H "Authorization: Bearer <token>"
Example Response
Desktop Video Endpoint
The desktop app has an additional video deletion endpoint.
Delete Video (Desktop)
DELETE /api/desktop/video/delete
The unique identifier of the video to delete
Bearer token for authentication
Example Request
curl -X DELETE "https://cap.so/api/desktop/video/delete?videoId=abc123" \
-H "Authorization: Bearer <token>"
Video Schema
Videos in the database follow this structure:
Video Object
interface Video {
id: string;
ownerId: string;
name: string;
createdAt: Date;
totalComments: number;
totalReactions: number;
public: boolean;
source: "local" | "s3";
transcriptionStatus: "PROCESSING" | "COMPLETE" | "ERROR" | null;
metadata: VideoMetadata;
}
interface VideoMetadata {
customCreatedAt?: string;
sourceName?: string;
aiTitle?: string;
summary?: string;
chapters?: { title: string; start: number }[];
aiGenerationStatus?: "QUEUED" | "PROCESSING" | "COMPLETE" | "ERROR" | "SKIPPED";
enhancedAudioStatus?: "PROCESSING" | "COMPLETE" | "ERROR" | "SKIPPED";
}
Custom created date that overrides the actual createdAt timestamp
Title of the captured monitor or window
AI-generated title for the video
AI-generated summary of the content
Chapter markers generated from the transcript
Status of AI processing: QUEUED, PROCESSING, COMPLETE, ERROR, or SKIPPED
Status of audio enhancement: PROCESSING, COMPLETE, ERROR, or SKIPPED
Error Responses
401 Unauthorized
{
"error": "Unauthorized"
}
Authentication required or token invalid.
404 Not Found
{
"error": "Video not found"
}
The requested video does not exist or you don’t have permission to access it.
500 Internal Server Error
{
"error": "Internal server error",
"message": "Failed to process request"
}
An unexpected error occurred on the server.
Implementation Details
The video endpoints are defined in packages/web-api-contract/src/index.ts:63-90:
video: c.router({
getTranscribeStatus: {
method: "GET",
path: "/video/transcribe/status",
query: z.object({ videoId: z.string() }),
responses: {
200: z.object({
transcriptionStatus: z
.custom<"PROCESSING" | "COMPLETE" | "ERROR">()
.nullable(),
}),
},
},
delete: {
method: "DELETE",
path: "/video/delete",
query: z.object({ videoId: z.string() }),
responses: { 200: z.unknown() },
},
getAnalytics: {
method: "GET",
path: "/video/analytics",
query: z.object({ videoId: z.string() }),
responses: {
200: z.object({ count: z.number() }),
},
},
})
Rate Limiting
Currently, there are no rate limits on video endpoints for self-hosted instances. The production instance may implement rate limiting in the future.
Next Steps
Authentication
Learn about authentication methods
Notifications
Manage user notifications