# Skiv API and Product Reference > Skiv hosts, streams, and searches video. It provides an embeddable player, automatic transcription, search inside videos, collections, and paid video memberships. An optional AI assistant answers questions about a library with timestamps. This file combines the integration guidance, the API reference, the product documentation, and the oEmbed endpoint. The HTML versions at https://skiv.com/api and https://skiv.com/docs add code samples in more languages and video walkthroughs. The short index is https://skiv.com/llms.txt. ## Integration guidance ### What exists and what does not Skiv publishes no npm or PyPI packages. Integration goes through the REST API, the embed scripts served from `https://skiv.com/static/js/`, and oEmbed. Do not invent endpoints, SDK packages, or CDN URLs; use only what this file documents. ### API hosts and authentication - Storage, collections, search, and authentication use `https://skiv.com/api`. - Standalone AI analysis uses `https://api.skiv.com`. - Use each endpoint's documented full URL. Do not append storage paths to the AI analysis host. - Authenticated requests send `Key: YOUR_KEY` as a header. Never send the key as a Bearer token, query parameter, or cookie. - Two calls need no existing key: creating a key with email and password, and searching a public channel. ### Embedding Prefer the standard HTML embed or the `SkivPlayer` constructor. Use the iframe embed only when the host platform blocks scripts or requires isolation. Load `https://skiv.com/static/js/embed-player.min.js` once per page; it initializes every `skiv-video-player` container it finds. For searchable collections, load `https://skiv.com/static/js/embed-search.min.js` and call `SkivCollection` as shown in the product reference. That bundle already contains the player, so do not load both scripts. Use only the documented constructors, attributes, methods, and events. A destroyed player instance cannot be reused; create a new one instead. ### Uploads and video data Video IDs (`svid`) are short identifiers such as `8KsbyKv`. File IDs (`fid`) are long hashes. Each endpoint documents which one it takes. Uploads are private by default. Set `visibility` explicitly when a video must be reachable outside the owner's account. Wait until the video reports `"ingesting": false` before relying on transcripts or other analysis data. Fetch current metadata instead of hard-coding CDN URLs; the `url` field can change. ### Search Search prefixes select a modality: `s:` speech, `f:` faces, `t:` on-screen text, `o:` objects, `a:` actions, `z:` sounds, `n:` title, and `d:` description. Prefixes combine (`f:musk o:car`). An unprefixed query searches every modality. To search several videos, use owned-video, collection, or channel search. Do not loop over the per-video search endpoint. ### Long-running analysis jobs Analysis endpoints return a job ID. Poll as the API reference describes, stop on `done` or `error`, and report errors instead of retrying them. Results expire one hour after completion. ## Pricing and plan conditions The current source for prices and plan limits is https://skiv.com/pricing. Plan limits are storage size, not video count; how many videos fit depends on file sizes. Annual prices are monthly equivalents billed yearly. Every plan has a 14-day free trial. A card is required but is not charged until the trial ends. Bandwidth is unlimited under a fair-use policy. The AI assistant is a paid add-on. Player customization and other features vary by plan, so check the pricing comparison before promising a feature. Enterprise plans are arranged through https://skiv.com/contact. --- # Skiv API Reference API reference for uploading, managing, searching, and analyzing video. See the [HTML API reference](https://skiv.com/api) for additional endpoint details and examples. ## API hosts - **Storage, collections, search, and authentication:** `https://skiv.com/api` (for example, `https://skiv.com/api/files/upload`). - **Standalone AI analysis:** `https://api.skiv.com` (for example, `https://api.skiv.com/speech`). Use the full URL documented for each endpoint; do not append `/api/files/...` to the AI analysis host. **Authentication:** Use the `Key: YOUR_KEY` header for requests that require authentication. Creating a key with email/password does not require an existing key. Public channel search does not require authentication. ## Authentication ### Create a key with email/password ``` POST https://skiv.com/api/auth/login Content-Type: application/json {"email": "your-email@example.com", "passwd": "your-password"} ``` **Parameters:** - `email` (string, required) -- your Skiv email - `passwd` (string, required) -- your Skiv password **Response:** ```json {"key": "2tHIVrn7GIghYCzVCvpgtf295d1e32d5"} ``` ### Create a key with an existing key ``` POST https://skiv.com/api/auth/keys Key: YOUR_KEY ``` ### Using a key Pass the key via the `Key` header on authenticated requests. --- ## Errors | Code | Meaning | |------|---------| | 200 | OK | | 400 | Bad request -- missing or invalid parameter | | 401 | Unauthorized -- invalid API key | | 402 | Payment required -- not enough credits | | 404 | Not found | | 405 | Method not allowed | | 429 | Too many requests -- rate limit reached | | 500 | Server error | Error response: ```json {"error": "file_not_provided"} ``` --- ## API Flow (Long-Running Jobs) Long-running analysis requests return a job ID. Poll the same endpoint with that ID, following the status handling below. ### 1. Submit a job ``` POST https://api.skiv.com/speech Key: YOUR_KEY Content-Type: multipart/form-data file=@input.wav ``` Response: ```json {"id": "72787541f3fc8170207ea446a22f60ce4130d950cbebcc058dd53bd321419beb"} ``` ### 2. Fetch results ``` GET https://api.skiv.com/speech/{job_id} Key: YOUR_KEY ``` Pending: ```json {"status": "pending"} ``` Done: ```json {"status": "done", "transcript": "we choose to go to the moon in this decade"} ``` A job can also return `"status": "error"`. Stop polling on `done` or `error`; surface errors to the caller instead of treating them as pending. Recommended client behavior (not server-enforced timing): poll with a delay, use capped backoff for transient failures, and set a deadline or cancellation option. Honor `Retry-After` when present. Stop on non-retryable HTTP errors or unexpected status values and report the response. Do not poll indefinitely or automatically resubmit a failed job. Results are available for 1 hour after completion. --- ## Videos ### POST Upload a video ``` POST https://skiv.com/api/files/upload Key: YOUR_KEY Content-Type: multipart/form-data file=@video.mp4 ``` **Request body:** - `file` (file, required) -- video file **Query parameters:** - `collection` (string) -- collection ID to add video to - `visibility` (string) -- `private` (default), `hidden`, `password`, `unlisted`, `public` **Supported formats:** AVI, MOV, MP4, OGG, WMV, WEBM, MKV, 3GP, M4V, MPEG **Response:** ```json { "fid": "b47a65b9351e38e6eb86780b09f3e9f9b8e9d795f1af5111f2f34a7f31f9e157", "svid": "8KsbyKv", "filename": "The_Solar_System.mp4", "title": "The Solar System", "description": "", "url": "https://cdn.skiv.com/w/b47a65b9.../data", "duration": 426.84, "width": 1280, "height": 720, "size": 251126000, "tcreated": 1559655942, "visibility": "public", "media": "video", "ingesting": false } ``` **Response fields:** - `fid` (string) -- file ID (long hex hash) - `svid` (string) -- video ID (short alphanumeric) - `filename` (string) -- original filename - `title` (string) -- video title (derived from filename) - `description` (string) -- video description - `url` (string) -- CDN data URL - `duration` (float) -- duration in seconds - `width` (int) -- width in pixels - `height` (int) -- height in pixels - `size` (int) -- file size in bytes - `tcreated` (int) -- upload timestamp (Unix time) - `visibility` (string) -- visibility level - `media` (string) -- `video` or `audio` - `ingesting` (boolean) -- true if still being processed ### POST Cut a clip ``` POST https://skiv.com/api/files/cut Key: YOUR_KEY ``` **Parameters:** - `svid` (string, required) -- source video ID - `start` (float, required) -- start time in seconds - `end` (float, required) -- end time in seconds - `title` (string) -- clip title (default: source title) - `description` (string) -- clip description - `visibility` (string) -- visibility (default: source visibility) Response is the same as upload, plus `cut_svid`, `cut_start`, `cut_end`. Note: `fid` and `url` won't be present until ingestion finishes. ### POST Update a video ``` POST https://skiv.com/api/files/set/{fid} Key: YOUR_KEY Content-Type: application/json {"title": "New Title", "visibility": "public"} ``` **Parameters:** - `title` (string) -- video title - `description` (string) -- video description - `visibility` (string) -- visibility level - `domains` (list) -- list of domains to restrict embedding to ### DELETE Delete a video ``` DELETE https://skiv.com/api/files/delete/{fid} Key: YOUR_KEY ``` ### GET List videos ``` GET https://skiv.com/api/files/videos Key: YOUR_KEY ``` Returns an array of video objects with all upload fields plus: - `mature` (boolean) -- flagged for mature content - `own` (boolean) -- belongs to the key owner - `views` (int) -- view count - `twatched` (int) -- total time watched in seconds ### GET Get a video ``` GET https://skiv.com/api/files/videos/{svid} Key: YOUR_KEY ``` Returns a single video object (same fields as list). ### POST Update video cover/thumbnail From a video frame: ``` POST https://skiv.com/api/files/set/{fid}/cover?t={time_in_seconds} Key: YOUR_KEY ``` From an uploaded image: ``` POST https://skiv.com/api/files/set/{fid}/cover Key: YOUR_KEY Content-Type: multipart/form-data file=@thumbnail.jpg ``` Supported image formats: PNG, JPEG, JPG. ### POST Upload subtitles ``` POST https://skiv.com/api/files/subtitles/{svid} Key: YOUR_KEY Content-Type: multipart/form-data subtitles=@Japanese.vtt ``` **Query parameters:** - `name` (string) -- subtitle track name **Supported formats:** SRT, VTT **Response:** ```json {"id": "N3wfN01lm", "name": "Japanese"} ``` ### POST Update subtitles ``` POST https://skiv.com/api/files/subtitles/{svid}/{subtitle_id}/set Key: YOUR_KEY name=NewName ``` ### POST Delete subtitles ``` POST https://skiv.com/api/files/subtitles/{svid}/{subtitle_id}/delete Key: YOUR_KEY ``` ### GET List subtitles ``` GET https://skiv.com/api/files/subtitles/{svid} Key: YOUR_KEY ``` Response: ```json {"N3wfN01lm": "Javanese"} ``` ### GET Download subtitles ``` GET https://skiv.com/api/files/subtitles/{svid}/{subtitle_id} Key: YOUR_KEY ``` --- ## Collections ### GET List collections ``` GET https://skiv.com/api/files/collections Key: YOUR_KEY ``` **Response fields:** - `name` (string) -- collection name - `scid` (string) -- collection ID - `path` (string) -- parent collection ID (empty string = root) - `tcreated` (int) -- creation timestamp - `visibility` (string) -- visibility level - `videos` (list) -- videos in the collection ### GET Get a collection ``` GET https://skiv.com/api/files/collections/{scid} Key: YOUR_KEY ``` ### POST Create a collection ``` POST https://skiv.com/api/files/collections Key: YOUR_KEY Content-Type: application/json {"name": "My Collection", "visibility": "public"} ``` **Parameters:** - `name` (string, required) -- collection name - `visibility` (string, required) -- visibility level - `parent` (string) -- parent collection ID for nesting ### DELETE Delete a collection ``` DELETE https://skiv.com/api/files/collections/{scid} Key: YOUR_KEY ``` ### POST Move a collection ``` POST https://skiv.com/api/files/collections/{scid}/move Key: YOUR_KEY Content-Type: application/json {"scid": "parent_collection_id"} ``` ### POST Add a video to a collection ``` POST https://skiv.com/api/files/collections/{scid}/add Key: YOUR_KEY Content-Type: application/json {"svid": "8KsbyKv"} ``` ### DELETE Remove a video from a collection ``` DELETE https://skiv.com/api/files/collections/{scid}/{svid} Key: YOUR_KEY ``` --- ## Search AI-powered multimodal search. Find people, speech, objects, text, actions, and sounds, and jump to the second when they happen. ### Modality prefixes | Prefix | Modality | Example | |--------|----------|---------| | `s:` | Speech | `s:quarterly revenue` | | `f:` | Faces | `f:musk` | | `t:` | On-screen text | `t:warning` | | `o:` | Objects | `o:car` | | `a:` | Actions | `a:dancing` | | `z:` | Sounds | `z:applause` | | `n:` | Title | `n:solar system` | | `d:` | Description | `d:tutorial` | Combine prefixes: `f:musk o:car` finds moments where Elon Musk appears next to a car. ### GET Search owned videos ``` GET https://skiv.com/api/search?q=hello+world Key: YOUR_KEY ``` **Response:** array of `[svid, [timestamps]]` ```json [["8KsbyKv", [1.23, 3.45]]] ``` ### GET Search a channel ``` GET https://skiv.com/api/search/channel/{channel_id}?q=hello+world ``` No authentication required for public channels. ### GET Search a collection ``` GET https://skiv.com/api/search/collection/{scid}?q=hello+world ``` ### GET Search within a video ``` GET https://skiv.com/api/search/video/{svid}?q=hello+world ``` --- ## Speech Transcribe audio and video files. ``` POST https://api.skiv.com/speech Key: YOUR_KEY Content-Type: multipart/form-data file=@input.wav ``` - Supported formats: MP4, MP3, WAV, FLAC - Max file size: 5 GB - Max duration: 5 hours - Follows the API Flow (async job) **Response (done):** ```json {"status": "done", "transcript": "we choose to go to the moon in this decade"} ``` ## Align Word-level alignment of transcript with audio. ``` POST https://api.skiv.com/align Key: YOUR_KEY Content-Type: multipart/form-data file=@input.wav&phrase=All men are created equal. I have a dream. ``` **Parameters:** - `file` (file, required) -- audio or video file - `phrase` (string, required) -- transcript to align **Response (done):** ```json { "status": "done", "words": [ {"word": "all", "start": 0.15, "end": 0.37}, {"word": "men", "start": 0.37, "end": 0.65} ] } ``` ## Sounds Classify sound types. Supported: speech, music, applause, laughter, silence. ``` POST https://api.skiv.com/sounds Key: YOUR_KEY Content-Type: multipart/form-data file=@input.wav ``` Follows the API Flow (async job). ## Colors Identify colors in images. ``` POST https://api.skiv.com/colors Key: YOUR_KEY Content-Type: multipart/form-data file=@image.jpg ``` ## Faces Detect faces in video. Similar faces are grouped; known faces are labeled. ``` POST https://api.skiv.com/faces Key: YOUR_KEY Content-Type: multipart/form-data file=@video.mp4 ``` Follows the API Flow (async job). ## Objects Recognize common objects in images. ``` POST https://api.skiv.com/objects Key: YOUR_KEY Content-Type: multipart/form-data file=@image.jpg ``` ## Text (OCR) Find and recognize text in images. ``` POST https://api.skiv.com/text Key: YOUR_KEY Content-Type: multipart/form-data file=@image.jpg ``` ## Actions Recognize actions (dancing, flying, driving, etc.) in video. ``` POST https://api.skiv.com/actions Key: YOUR_KEY Content-Type: multipart/form-data file=@video.mp4 ``` Follows the API Flow (async job). ## Scenes Detect shot boundaries and cluster scenes in video. ``` POST https://api.skiv.com/scenes Key: YOUR_KEY Content-Type: multipart/form-data file=@video.mp4 ``` Follows the API Flow (async job). ## Related Concepts Explore concepts and discover related terms. ``` POST https://api.skiv.com/concepts Key: YOUR_KEY Content-Type: application/json {"concept": "solar system"} ``` ## Sentiment Detect how positive or negative text is. ``` POST https://api.skiv.com/sense Key: YOUR_KEY Content-Type: application/json {"text": "This is a great video"} ``` --- # Skiv Documentation Guides for uploading, embedding, searching, and managing video on Skiv. --- ## Getting Started ### Add Video Upload videos by drag-and-drop or clicking the upload button. Videos are indexed automatically after upload. Supported formats: AVI, MOV, MP4, OGG, WMV, WEBM, MKV, 3GP, M4V, MPEG. ### Record Record your screen or camera directly to your Skiv account: 1. Click **Record** 2. Choose **Screen** or **Camera** 3. Grant browser permissions 4. Click **Record** to start, **Stop** to finish 5. Click **Upload** to save ### Account - **Change username:** User icon > Settings > edit NAME - **Change channel URL:** User icon > Settings > edit USERNAME - **Change password:** User icon > Settings > PASSWORD > Change - **Reset password:** Sign in > Forgot your password? > follow email link - **Add/change card:** User icon > Settings > Plan > Add new card - **Stop auto-billing:** User icon > Settings > Plan > remove all cards - **Delete account:** User icon > Settings > Plan > Delete > confirm via email --- ## Library ### Basic Operations Switch to **Studio** mode (user icon > Studio) to manage videos. - **Rename:** Select video > bottom bar > Rename - **Download:** Select video > bottom bar > Download - **Change visibility:** Select video > bottom bar > Visibility > choose level - **Delete:** Select video > bottom bar > Delete ### Collections Organize videos into searchable, hierarchical collections. - **Create:** Click + icon > name the collection - **Add videos:** Select videos > bottom bar > Add to collection - **Nested collections:** Collections can contain sub-collections ### Channel Your public profile page at `skiv.com/{username}`. Displays your public videos and collections. ### Share - **Share link:** Select video > Share > copy link - **Embed code:** Select video > Share > embed icon > Copy - **Domain restrictions:** Limit which domains can embed your videos - **Visibility levels:** Private, Hidden, Password, Unlisted, Public ### Portals Branded video storefronts with subscriptions and plans. --- ## Player Stream videos in 4K with DASH/HLS streaming, cast to any screen using Chromecast or AirPlay, and search for anything inside your videos. ### Features - **Video search:** Click Search > type query > results appear on timeline > click to navigate - **Subtitles:** Settings icon > Subtitles > select track - **Quality:** Settings icon > Quality > select resolution - **Speed:** Settings icon > Speed > select rate - **Chromecast / AirPlay:** Click cast icon > select device - **Keyboard shortcuts:** Space (play/pause), arrow keys (seek), M (mute), F (fullscreen) ### Player Customization - Custom logos and colors - Calls to action (Plus plan and above) - Branded themes ### Player Integrations - **WordPress:** Use the embed code in a Custom HTML block - **Squarespace:** Use the embed code in a Code block - **Wix:** Use the HTML iFrame component - **Kajabi:** Paste embed code in custom code sections --- ## Embedded Player ### Standard Embed ```html
``` Include the script tag only once per page, even with multiple players. ### iframe Embed ```html ``` ### Standard Embed Attributes | Attribute | Description | |-----------|-------------| | `data-video` | Video ID | | `data-width` | Player width (pixels or `"100%"`) | | `data-height` | Player height | | `data-autoplay` | `"1"` to autoplay, `"visible"` to play when in viewport | | `data-loop` | `"1"` to loop | | `data-start` | Start time in seconds | | `data-resume` | `"1"` to resume from last position | | `data-volume` | Volume 0-100 | | `data-consent` | `"1"` to skip content warnings | | `data-share` | `"1"` to show share button | | `data-subtitles` | `"auto"` for auto-generated, or track name. Auto-translate: `Chinese`, `French`, `German`, `Portuguese`, `Spanish` | | `data-shortcuts` | `"0"` to disable keyboard shortcuts | | `data-download` | `"1"` to enable download button | | `data-controls` | Comma-separated +/- prefixes: `fullscreen`, `subtitles`, `volume`, `settings`, `chromecast`, `airplay` | | `data-playlist` | Collection ID or comma-separated video IDs | | `data-ld` | `"0"` to disable JSON-LD structured data | | `data-ad` | VAST/VPAID/VMAP tag URL | ### JavaScript SDK ```html ``` #### SkivPlayer Parameters | Parameter | Description | |-----------|-------------| | `container` | HTML element or CSS selector | | `video` | Video ID | | `autoplay` | `true` or `'visible'` | | `loop` | `true` to loop | | `start` | Start time in seconds | | `resume` | `true` to resume | | `volume` | 0-100 | | `width` | Pixels (int) or relative (string) | | `height` | Pixels (int) or relative (string) | | `title` | `false` to hide | | `search` | `false` to hide search | | `links` | `false` to disable Skiv links | | `sizing` | `'fill'`, `'fit'`, or `'cover'` | | `logo` | `false` to hide branding | | `style` | `'minimal'` or `'no-controls'` | | `consent` | `true` to skip content warnings | | `linkedData` | `false` to disable JSON-LD | | `share` | `true` to show share | | `subtitles` | `'auto'` or track name | | `shortcuts` | `false` to disable | | `download` | `true` to enable | | `controls` | Array: `['-fullscreen', '+subtitles']` | | `playlist` | Collection ID or array of video IDs | | `ad` | VAST/VPAID/VMAP tag URL | #### Methods | Method | Description | |--------|-------------| | `play()` | Play | | `pause()` | Pause | | `seek(time)` | Jump to time (seconds) | | `search(query, seek)` | Search content; `seek=true` jumps to first result | | `on(event, listener)` | Add event listener | | `off(event, listener)` | Remove event listener | | `setVideo(id)` | Load different video | | `setSpeed(rate)` | Set playback speed | | `setVolume(vol)` | Set volume 0-100 | #### Events | Event | Data | Description | |-------|------|-------------| | `play` | -- | Playing | | `pause` | -- | Paused | | `ended` | -- | Ended | | `metadata` | `{title, description, width, height}` | Metadata ready | | `timeupdate` | `currentTime` | Position changed | | `search` | `query` | Search performed | | `speed` | `rate` | Speed changed | ### Embedding Video Data Embed metadata (description, transcript, detected content) directly into your page: ```html
``` Available `data-content` values: `description`, `speech`, `objects`, `scenes`, `sounds`, `text`, `actions`. --- ## Embedded Collections Embed a public collection using `SkivCollection`. Replace the example collection ID with your own. Load `embed-search.min.js` once per page; it includes the player, so a separate `embed-player.min.js` script is unnecessary: ```html
``` --- ## Search Search speech, text, faces, objects, and concepts across your videos. Modality prefixes: `s:` (speech), `f:` (faces), `t:` (text), `o:` (objects), `a:` (actions), `z:` (sounds), `n:` (title), `d:` (description). --- ## Video Pages Standalone HTML video page templates available for download. Layouts include: - **Centered video** -- video centered on page - **Video + title + description** -- video with metadata below - **Video + transcript** -- side-by-side player and transcript --- ## Tools ### Immersive View Full-screen focused viewer with transcript and metadata panel. ### Label & Edit Edit transcripts, tags, and AI-generated metadata for your videos. ### Cut Clips Trim clips from videos and share specific moments. --- ## Integrations ### Zoom Send new Zoom cloud recordings to Skiv with Zapier: 1. Make sure your Zoom plan supports cloud recording and enable it in Zoom's Recording & Transcript settings. 2. Open the [Zoom to muse.ai Zap template](https://zapier.com/shared/send-new-zoom-cloud-recordings-to-museai/e5336ce2972d89f8ffdf99fab2aaa520a08448b6). The listing uses Skiv's former name, muse.ai. 3. In Skiv, go to **Settings > API Keys**, create a key, and paste it into Zapier when prompted. 4. Connect both accounts and turn on the Zap. New Zoom cloud recordings will upload to your Skiv library. See the [Zoom integration guide](https://skiv.com/docs#app-integrations) for full setup instructions. ### API Full programmatic access. See the [API Reference](https://skiv.com/api) or [API markdown](https://skiv.com/api.md). --- ## FAQ Common questions about limits, formats, and features are answered at [skiv.com/docs#faq](https://skiv.com/docs#faq). --- # oEmbed ``` GET https://skiv.com/oembed?url={video_url} ``` `url` is the URL-encoded address of a Skiv video page, such as `https://skiv.com/v/8KsbyKv`. No authentication is required for videos the requester can view. The JSON response follows oEmbed 1.0 with `type` set to `video`. It includes `provider_name`, `provider_url`, `url`, `title`, `description`, `width`, `height`, `thumbnail_url`, `thumbnail_width`, `thumbnail_height`, and `html`. The `html` field is a responsive iframe embed of the video. Errors: `400` with `{"error": "wrong_url"}` when `url` is not a Skiv video URL, and `404` with `{"error": "not_found"}` when the video does not exist or is not viewable.