# VidCap API > Video transcription and summarization SaaS that processes YouTube videos using AI. Base URL: `https://vidcap.xyz` ## Authentication All authenticated endpoints require one of: - **API Key**: Pass via `X-API-Key` header - **Session**: Cookie-based session authentication ``` X-API-Key: your-api-key-here ``` --- ## Health ### GET /api/v1/healthz Health check endpoint. **Auth**: None **Response 200**: ```json { "status": "OK" } ``` --- ## AI ### GET /api/v1/ai/models Get available AI models for summarization. **Auth**: None **Response 200**: ```json { "models": [ "meta-llama/llama-3.1-405b", "openai/chatgpt-4o-latest", "openai/gpt-4o-mini", "google/gemini-2.0-flash-001", "google/gemini-flash-1.5", "google/gemini-pro-1.5", "anthropic/claude-3.5-haiku", "anthropic/claude-3.5-sonnet" ] } ``` --- ## YouTube ### GET /api/v1/youtube/info Get and save YouTube video information. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | cache | boolean | No | true | Use cached data if available | **Response 200**: ```json { "success": true, "data": { "title": "Video Title", "description": "Video description...", "duration": 360, "thumbnail": "https://...", "channel": "Channel Name", "uploadDate": "2024-01-15" } } ``` **Errors**: - `url is required` - Missing URL parameter --- ### GET /api/v1/youtube/media Get available media formats for a YouTube video. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | YouTube video URL | **Response 200**: ```json { "success": true, "data": { "videoFiles": [ { "format": "mp4", "quality": "1080p", "size": 52428800, "url": "https://..." } ], "audioFiles": [ { "format": "m4a", "quality": "128kbps", "size": 5242880, "url": "https://..." } ] } } ``` --- ### GET /api/v1/youtube/download Download and save YouTube video to CDN storage. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | YouTube video URL | **Response 200**: ```json { "success": true, "data": { "id": "uuid-string", "title": "Video Title", "url": "https://youtube.com/watch?v=...", "videoUrl": "https://cdn.vidcap.xyz/videos/...", "sourceId": "dQw4w9WgXcQ" } } ``` --- ### GET /api/v1/youtube/caption Get video captions/transcript. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | locale | string | No | en | Language code (en, vi, ja, etc.) | | model | string | No | - | AI model for processing | | ext | string | No | - | Caption format: json3, srv1, srv2, srv3, ttml, vtt | | cache | boolean | No | true | Use cached captions | **Response 200**: ```json { "success": true, "data": [ { "text": "Hello everyone", "start": 0.0, "duration": 2.5 }, { "text": "Welcome to the video", "start": 2.5, "duration": 3.0 } ] } ``` --- ### GET /api/v1/youtube/summary Get AI-generated summary of video content. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | locale | string | No | en | Target language code | | model | string | No | - | AI model (see /api/v1/ai/models) | | screenshot | string | No | 0 | Generate screenshots: "1" to enable | | cache | boolean | No | true | Use cached summary | | download | string | No | 0 | Download video: "1" to enable | | debug | boolean | No | false | Enable debug mode | **Response 200**: ```json { "success": true, "data": { "id": "uuid-string", "videoId": "dQw4w9WgXcQ", "name": "Video Title", "content": "## Summary\n\nThis video covers...", "description": "Brief overview...", "conclusion": "Key takeaways...", "keywords": ["keyword1", "keyword2"] } } ``` --- ### POST /api/v1/youtube/summary-custom Get AI-generated summary with custom prompt. **Auth**: `X-API-Key` **Request Body** (JSON): ```json { "url": "https://youtube.com/watch?v=...", "locale": "en", "model": "google/gemini-2.0-flash-001", "screenshot": "0", "cache": true, "download": "0", "prompt": "Focus on the technical details and code examples" } ``` | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | locale | string | No | en | Target language code | | model | string | No | - | AI model to use | | screenshot | string | No | 0 | Generate screenshots | | cache | boolean | No | true | Use cached summary | | download | string | No | 0 | Download video | | prompt | string | No | - | Custom prompt for summarization | **Response 200**: ```json { "success": true, "data": "Custom summary based on your prompt..." } ``` --- ### GET /api/v1/youtube/article Convert video content to article format. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | locale | string | No | en | Target language code | | model | string | No | - | AI model to use | **Response 200**: ```json { "success": true, "data": "# Article Title\n\n## Introduction\n\nArticle content in markdown..." } ``` --- ### GET /api/v1/youtube/screenshot Get screenshot from video at specific timestamp. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | second | string | No | 0 | Timestamp in seconds or YouTube format (1m30s) | **Response 200**: ```json { "success": true, "data": { "url": "https://youtube.com/watch?v=...", "second": 90, "image_url": "https://cdn.vidcap.xyz/screenshots/..." } } ``` --- ### GET /api/v1/youtube/screenshot-multiple Get multiple screenshots at different timestamps. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | Yes | - | YouTube video URL | | second | string | No | 0 | Comma-separated timestamps (e.g., "10,30,60,120") | **Response 200**: ```json { "success": true, "data": { "url": "https://youtube.com/watch?v=...", "image_urls": [ "https://cdn.vidcap.xyz/screenshots/...", "https://cdn.vidcap.xyz/screenshots/..." ], "seconds": [10, 30, 60, 120] } } ``` --- ### GET /api/v1/youtube/comments Get YouTube video comments. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | string | No* | - | YouTube video URL | | videoId | string | No* | - | YouTube video ID | | order | string | No | time | Sort: "time" or "relevance" | | format | string | No | plainText | Text format: "plainText" or "html" | | pageToken | string | No | - | Pagination token | | includeReplies | boolean | No | false | Include comment replies | | hl | string | No | en | Language code for localization | *Either `url` or `videoId` is required. **Response 200**: ```json { "success": true, "data": { "nextPageToken": "QURTSl9pMU...", "data": [ { "id": "comment-id", "videoId": "dQw4w9WgXcQ", "textOriginal": "Great video!", "authorDisplayName": "User Name", "authorProfileImageUrl": "https://...", "likeCount": 42, "publishedAt": "2024-01-15T10:30:00Z", "totalReplyCount": 5, "replies": [] } ] } } ``` **Errors**: - 400: `Either 'url' or 'videoId' is required` - 400: `Invalid YouTube URL format` - 404: `Video not found` - 403: `Comments are disabled for this video` - 429: `API rate limit exceeded` - 502: `Failed to fetch comments from external service` --- ### GET /api/v1/youtube/search Search YouTube videos. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | q | string | Yes | - | Search query | | maxResults | number | No | 10 | Results count (1-50) | | order | string | No | relevance | Sort: relevance, date, viewCount, rating | | pageToken | string | No | - | Pagination token | | videoDuration | string | No | any | Filter: short, medium, long, any | | publishedAfter | string | No | - | ISO date filter (YYYY-MM-DD) | **Response 200**: ```json { "success": true, "data": { "items": [ { "id": "dQw4w9WgXcQ", "title": "Video Title", "description": "Video description...", "thumbnailUrl": "https://i.ytimg.com/vi/...", "videoUrl": "https://youtube.com/watch?v=...", "publishedAt": "2024-01-15T10:30:00Z", "channelId": "UC...", "channelTitle": "Channel Name", "viewCount": 1000000, "duration": "PT5M30S" } ], "nextPageToken": "CAUQAA", "prevPageToken": null, "totalResults": 1000000 } } ``` **Errors**: - 400: `Query parameter 'q' is required` - 500: `Search failed: ...` --- ## Video ### GET /api/v1/video/:videoId Retrieve a video by internal ID. **Auth**: `X-API-Key` **Path Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | videoId | string | Yes | Internal video UUID | **Response 200**: ```json { "success": true, "data": { "id": "uuid-string", "provider": "YOUTUBE", "sourceId": "dQw4w9WgXcQ", "title": "Video Title", "url": "https://youtube.com/watch?v=...", "videoUrl": "https://cdn.vidcap.xyz/...", "duration": 360, "createdAt": "2024-01-15T10:30:00Z" } } ``` **Errors**: - `videoId is required` - `Video not found` --- ### GET /api/v1/video Retrieve a video by various identifiers. **Auth**: `X-API-Key` **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | video_id | string | No* | Internal video UUID | | youtube_url | string | No* | Full YouTube URL | | youtube_id | string | No* | YouTube video ID | *At least one parameter is required. **Response 200**: Same as GET /api/v1/video/:videoId **Errors**: - `video_id, youtube_url, or youtube_id is required` - `Video not found` --- ## API Keys ### GET /api/v1/api_key List all API keys for authenticated user. **Auth**: Session (cookie) **Response 200**: ```json { "status": 1, "data": [ { "id": "uuid-string", "name": "My API Key", "key": "uuid-api-key", "userId": "user-uuid", "expiresAt": "2025-01-15T00:00:00Z", "createdAt": "2024-01-15T10:30:00Z" } ] } ``` --- ### POST /api/v1/api_key Create a new API key. **Auth**: Session (cookie) **Request Body** (JSON): ```json { "name": "My New API Key", "expiresAt": "2025-12-31T23:59:59Z" } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | name | string | No | Key name (default: "Untitled") | | expiresAt | string | No | ISO datetime for expiration | **Response 200**: ```json { "status": 1, "data": { "id": "uuid-string", "name": "My New API Key", "key": "generated-uuid-key", "userId": "user-uuid", "expiresAt": "2025-12-31T23:59:59Z", "createdAt": "2024-01-15T10:30:00Z" } } ``` --- ### DELETE /api/v1/api_key/:id Delete an API key. **Auth**: Session (cookie) **Path Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | Yes | API key UUID | **Response 200**: ```json { "status": 1, "data": { "id": "uuid-string", "name": "Deleted Key", "displayCreatedAt": "Jan 15, 2024 10:30 AM" } } ``` --- ## User ### PATCH /api/v1/user Update user profile. **Auth**: `X-API-Key` or Session **Request Body** (JSON): ```json { "name": "New Name", "email": "newemail@example.com" } ``` **Response 200**: ```json { "status": 1, "data": { "id": "user-uuid", "name": "New Name", "email": "newemail@example.com", "updatedAt": "2024-01-15T10:30:00Z" } } ``` --- ## Orders ### GET /api/v1/order/status/:checkoutId Get order status by Polar checkout ID. **Auth**: `X-API-Key` **Path Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | checkoutId | string | Yes | Polar checkout ID | **Response 200**: ```json { "success": true, "data": { "id": "order-uuid", "status": "completed", "userId": "user-uuid" } } ``` **Errors**: - `Order ID is required` - `Order not found` --- ## Try Now (Public) Rate-limited public endpoints for demo purposes. **Rate Limit**: 5 requests per hour per IP **Referer Required**: Must originate from same domain ### GET /api/v1/try-now/caption Get video captions without authentication. **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | YouTube video URL | | locale | string | No | Language code | **Response 200**: Same as /api/v1/youtube/caption --- ### GET /api/v1/try-now/summary Get video summary preview without authentication. **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | YouTube video URL | **Response 200**: ```json { "success": true, "data": { "id": "uuid-string", "videoId": "dQw4w9WgXcQ", "title": "Video Title", "summary": "Summary content...", "description": "Brief overview...", "conclusion": "Key takeaways...", "previewOnly": true } } ``` --- ### GET /api/v1/try-now/media Get media formats without authentication. **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | YouTube video URL | **Response 200**: Same as /api/v1/youtube/media --- ### GET /api/v1/try-now/search Search YouTube videos without authentication (limited results). **Query Parameters**: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | Yes | Search query | **Response 200**: ```json { "success": true, "data": { "items": [...], "previewOnly": true } } ``` **Note**: Limited to 5 results. --- ## Common Response Format ### Success Response ```json { "success": true, "data": { ... } } ``` ### Error Response ```json { "success": false, "message": "Error description" } ``` ### Legacy Format (API Keys, User) ```json { "status": 1, "data": { ... } } ``` --- ## Error Codes | HTTP Code | Description | |-----------|-------------| | 200 | Success (check `success` field for actual status) | | 400 | Bad Request - Invalid parameters | | 401 | Unauthorized - Missing or invalid authentication | | 403 | Forbidden - Access denied or comments disabled | | 404 | Not Found - Resource not found | | 429 | Too Many Requests - Rate limit exceeded | | 500 | Internal Server Error | | 502 | Bad Gateway - External service error | --- ## Rate Limiting - **Authenticated endpoints**: Based on user subscription plan - **Try Now endpoints**: 5 requests per hour per IP - **Timeout**: 10 minutes for video processing endpoints --- ## Supported Formats ### Caption Formats - `json3` - YouTube JSON format - `srv1`, `srv2`, `srv3` - SubRip variants - `ttml` - Timed Text Markup Language - `vtt` - WebVTT ### Video Duration Filters - `short` - Under 4 minutes - `medium` - 4-20 minutes - `long` - Over 20 minutes - `any` - All durations ### Search Order Options - `relevance` - Most relevant first - `date` - Newest first - `viewCount` - Most viewed first - `rating` - Highest rated first --- ## Links - Website: https://vidcap.xyz - API Docs: https://vidcap.xyz/docs/api - GitHub: https://github.com/topgroup/vidcap