Videos API

    Upload, manage, and retrieve video content programmatically. Supports file uploads, URL imports, browser uploads, and full video lifecycle management.

    POST

    Upload Video via URL

    /videos

    Import a video from an external URL. The video will be downloaded and transcoded automatically. Use the upload base URL for this endpoint.

    Headers
    ParameterTypeRequiredDescription
    AuthorizationstringRequiredBearer token. Format: Bearer YOUR_API_KEY
    Content-TypestringRequiredMust be application/json
    Body Parameters
    ParameterTypeRequiredDescription
    urlstringRequiredPublic URL of the video file to import
    titlestringOptionalTitle for the videoDefault: Untitled
    channelKeystringOptionalChannel key to associate the video with
    projectIdstringOptionalProject ID to organize the video under
    descriptionstringOptionalVideo description
    tagsstring[]OptionalArray of tags for categorization
    optionsobjectOptionalVideo playback options (autoplay, loop, muted, etc.)
    json
    {
      "id": "fFL56RU6PjvJPeE",
      "title": "My Imported Video",
      "channelKey": "f8RMr2q4h6yNpv9",
      "status": 1,
      "created": "2024-01-15T10:30:00Z",
      "iframeLink": "https://streamvault.one/embed/fFL56RU6PjvJPeE",
      "hlsLink": "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/master.m3u8",
      "privateLink": "https://streamvault.one/v/fFL56RU6PjvJPeE",
      "duration": null,
      "image": {
        "xsUrl": "",
        "smUrl": "",
        "mdUrl": "",
        "lgUrl": ""
      }
    }
    json
    {
      "error": "url is required",
      "code": "INVALID_REQUEST"
    }
    json
    {
      "error": "Video upload limit reached for your plan",
      "code": "QUOTA_EXCEEDED",
      "limit": 50,
      "current": 50
    }
    Try it out
    POST/videos
    bash
    curl -X POST "https://api.streamvault.one/v1/videos" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "url": "https://example.com/video.mp4",
      "title": "Untitled"
    }'
    POST

    Browser Upload

    /videos/browser

    Get a tokenized upload URL for direct browser-based uploads using TUS protocol. Returns credentials for chunked resumable upload.

    Body Parameters
    ParameterTypeRequiredDescription
    titlestringOptionalTitle for the videoDefault: Untitled
    projectIdstringOptionalProject ID to organize the video under
    json
    {
      "video_id": "a1b2c3d4e5",
      "library_id": "12345",
      "tus_endpoint": "https://video.bunnycdn.com/tusupload",
      "auth_signature": "sha256-signature-hash",
      "auth_expiration_time": 1704067200,
      "put_upload_url": "https://video.bunnycdn.com/library/12345/videos/a1b2c3d4e5"
    }
    Try it out
    POST/videos/browser
    bash
    curl -X POST "https://api.streamvault.one/v1/videos/browser" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "title": "Untitled"
    }'
    GET

    List Videos

    /videos

    Retrieve a paginated list of the videos in your account, newest first by default. Page with page and size, order with sort, and narrow to one project with projectId (or to a project and everything below it with includeSubprojects).

    Query Parameters
    ParameterTypeRequiredDescription
    pageintegerOptionalPage number, starting at 1Default: 1
    sizeintegerOptionalVideos per page, 1 to 100 (a larger value is lowered to 100). limit is accepted as another name for it.Default: 20
    sortstringOptionalcreated_at, updated_at, name or sort_order; put a minus in front for descending (-name). An unknown field sorts by created_at.Default: -created_at
    projectIdstringOptionalOnly the videos in this project (its id). Videos in its sub-projects are not included unless includeSubprojects is true.
    includeSubprojectsbooleanOptionaltrue: also list the videos of every sub-project below projectId (a project plus up to 149 sub-projects). Needs projectId.Default: false
    channelKeystringOptionalAccepted, but it does not filter: every video comes back whatever you send. Narrow the list with projectId, and read channelKey on each video.

    There is no server-side title search and no status filter on this endpoint. Parameters it does not know (search, status, orderBy, itemsPerPage) are ignored, not rejected: page through with page and size and filter on your side. The answer carries total, the number of videos that match, so you know when you have them all.

    Every video in the list carries projectId, the project it sits in. With includeSubprojects=true the answer also has includeSubprojects: true and projectCount (the projects covered). See Listing sub-projects for the full answer and the limits.

    json
    {
      "items": [
        {
          "videoKey": "fFL56RU6PjvJPeE",
          "videoId": "fFL56RU6PjvJPeE",
          "channelKey": "f8RMr2q4h6yNpv9",
          "projectId": "40e78621-c780-4224-94fc-20a831110d91",
          "privateLink": null,
          "iframeLink": "fFL56RU6PjvJPeE",
          "name": "Product Demo",
          "description": null,
          "duration": 150,
          "thumbnailUrl": "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/poster.jpg",
          "posterUrl": "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/poster.jpg",
          "availableThumbnails": [
            "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/thumbs/thumb_01.jpg"
          ],
          "embedWidth": 640,
          "embedHeight": 360,
          "isPublic": true,
          "storageLocation": "b2",
          "status": { "state": "ready" },
          "created": "2024-01-15T10:30:00+00:00",
          "modified": "2024-01-15T10:35:12+00:00"
        }
      ],
      "page": 1,
      "size": 20,
      "total": 42
    }

    duration is in seconds; status.state is processing, ready or failed. A page past the last one is an empty items array that still carries the real total.

    Try it out
    GET/videos
    bash
    curl -X GET "https://api.streamvault.one/v1/videos" \
      -H "Authorization: Bearer YOUR_API_KEY"
    GET

    Get Video

    /videos/{id}

    Retrieve a single video: its keys, project, links, thumbnails, player size and processing state. The same fields as one entry of List Videos.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe video's id or key (videoId / videoKey)
    json
    {
      "videoKey": "fFL56RU6PjvJPeE",
      "videoId": "fFL56RU6PjvJPeE",
      "channelKey": "f8RMr2q4h6yNpv9",
      "projectId": "40e78621-c780-4224-94fc-20a831110d91",
      "privateLink": null,
      "iframeLink": "fFL56RU6PjvJPeE",
      "name": "Product Demo",
      "description": "A walkthrough of our product features",
      "duration": 150,
      "thumbnailUrl": "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/poster.jpg",
      "posterUrl": "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/poster.jpg",
      "availableThumbnails": [
        "https://api.streamvault.one/v1/play/fFL56RU6PjvJPeE/thumbs/thumb_01.jpg"
      ],
      "embedWidth": 640,
      "embedHeight": 360,
      "isPublic": true,
      "storageLocation": "b2",
      "status": { "state": "ready" },
      "created": "2024-01-15T10:30:00+00:00",
      "modified": "2024-01-15T10:35:12+00:00"
    }
    json
    {
      "ok": false,
      "error": "not found"
    }
    Try it out
    GET/videos/{id}
    bash
    curl -X GET "https://api.streamvault.one/v1/videos/{id}" \
      -H "Authorization: Bearer YOUR_API_KEY"
    GET

    Get Video Status

    /videos/{id}/status

    Check the transcoding/processing status of a specific video. Useful for polling after upload.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe unique video identifier
    json
    {
      "id": "fFL56RU6PjvJPeE",
      "status": 2,
      "statusLabel": "Processing",
      "encodeProgress": 65,
      "message": "Transcoding in progress"
    }
    StatusValueDescription
    Na0Not available
    Uploaded1File uploaded, waiting to process
    Processing2Transcoding in progress
    Published3Ready for playback
    Error-1Transcoding failed
    Deleted50Deleted
    Try it out
    GET/videos/{id}/status
    bash
    curl -X GET "https://api.streamvault.one/v1/videos/{id}/status" \
      -H "Authorization: Bearer YOUR_API_KEY"
    PUT

    Update Video

    /videos/{id}

    Update video metadata, options, access controls, and configuration.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe unique video identifier
    Body Parameters
    ParameterTypeRequiredDescription
    titlestringOptionalNew title for the video
    descriptionstringOptionalNew description
    tagsstring[]OptionalUpdated tags array
    projectIdstringOptionalMove to a different project
    optionsobjectOptionalPlayback options: autoplay, loop, muted, controls, pip, stickyOnScroll
    allowedDomainsstring[]OptionalDomains allowed to embed this video
    allowedCountriesstring[]OptionalISO country codes allowed to view
    blockedCountriesstring[]OptionalISO country codes blocked from viewing
    passwordstringOptionalSet a password for protected playback
    requireAuthbooleanOptionalRequire viewer authentication
    maxViewsintegerOptionalMaximum allowed view count
    expiresAtdatetimeOptionalISO 8601 expiration timestamp
    skinIdstringOptionalLegacy saved-skin id. It only touches loading color, background, corner radius and a corner logo; to style the player use PATCH /videos/{id}/player-settings
    json
    {
      "id": "fFL56RU6PjvJPeE",
      "title": "Updated Title",
      "description": "Updated description",
      "tags": ["updated", "demo"],
      "status": 3,
      "updated": "2024-01-16T08:00:00Z"
    }
    Try it out
    PUT/videos/{id}
    bash
    curl -X PUT "https://api.streamvault.one/v1/videos/{id}" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "title": "Updated Title"
    }'
    DELETE

    Delete Video

    /videos/{id}

    Permanently delete a video and all associated data (captions, chapters, CTAs, analytics).

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe unique video identifier
    json
    {
      "success": true,
      "message": "Video deleted successfully"
    }
    json
    {
      "error": "Video not found",
      "code": "NOT_FOUND"
    }
    Try it out
    DELETE/videos/{id}
    bash
    curl -X DELETE "https://api.streamvault.one/v1/videos/{id}" \
      -H "Authorization: Bearer YOUR_API_KEY"
    POST

    Copy CTA

    /videos/{id}/cta/copy

    Copy all call-to-action overlays from one video to one or more target videos.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredSource video ID to copy CTAs from
    Body Parameters
    ParameterTypeRequiredDescription
    targetVideoIdsstring[]RequiredArray of video IDs to copy CTAs to
    json
    {
      "success": true,
      "copied": 3,
      "targetVideoIds": ["vid_1", "vid_2", "vid_3"]
    }
    Try it out
    POST/videos/{id}/cta/copy
    bash
    curl -X POST "https://api.streamvault.one/v1/videos/{id}/cta/copy" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "targetVideoIds": []
    }'
    POST

    Move Videos Between Projects

    /videos/change-project

    Move one or more videos to a different project.

    Body Parameters
    ParameterTypeRequiredDescription
    videoIdsstring[]RequiredArray of video IDs to move
    projectIdstringRequiredTarget project ID
    json
    {
      "success": true,
      "moved": 2,
      "projectId": "proj_target123"
    }
    Try it out
    POST/videos/change-project
    bash
    curl -X POST "https://api.streamvault.one/v1/videos/change-project" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "videoIds": [],
      "projectId": ""
    }'
    GET

    Get Original File

    /videos/{id}/original-file

    Get a temporary signed URL to download the original uploaded video file.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe unique video identifier
    json
    {
      "url": "https://cdn.streamvault.one/original/fFL56RU6PjvJPeE/video.mp4?token=abc&expires=1704067200",
      "expiresAt": "2024-01-15T12:00:00Z"
    }
    Try it out
    GET/videos/{id}/original-file
    bash
    curl -X GET "https://api.streamvault.one/v1/videos/{id}/original-file" \
      -H "Authorization: Bearer YOUR_API_KEY"
    GET

    Get Collected Emails

    /videos/collected-emails

    Retrieve all emails collected via email gates on your videos from the last 365 days.

    Query Parameters
    ParameterTypeRequiredDescription
    videoIdstringOptionalFilter by specific video ID
    channelIdstringOptionalFilter by specific channel ID
    json
    {
      "emails": [
        {
          "email": "viewer@example.com",
          "videoId": "fFL56RU6PjvJPeE",
          "channelId": "ch_abc123",
          "subscribedAt": "2024-01-15T10:30:00Z"
        }
      ],
      "total": 150
    }
    Try it out
    GET/videos/collected-emails
    bash
    curl -X GET "https://api.streamvault.one/v1/videos/collected-emails" \
      -H "Authorization: Bearer YOUR_API_KEY"
    PUT

    Update Thumbnail

    /videos/image/{id}

    Set a video's thumbnail from an image you upload, or from the address of an image. Accepts JPEG, PNG or WebP files up to 5MB.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe video identifier: the id Get Video and List Videos give. The video's asset id and its short key work too.
    Body (multipart/form-data) - send a file or a url
    ParameterTypeRequiredDescription
    filefileOptionalImage file (JPEG, PNG or WebP, max 5MB), sent with its image content type. curl -F sets it from the file extension.
    urlstringOptionalInstead of a file: the public address of a JPEG, PNG or WebP image (max 5MB). The API downloads it. Ignored when a file is sent.

    The request must be a form (multipart/form-data; a plain url= form body works too). An image sent as the raw request body is not accepted. The answer is just { "ok": true }: the address of the new picture is the video's thumbnailUrl (see Get Video), and the same address is its posterUrl. Upload again to replace the picture: the address changes (it ends in ?v=...), so the new picture shows straight away instead of the old one being served from cache. A thumbnail you set here belongs to the file that is playing now: replacing the video's file (Replace Video) brings a generated thumbnail for the new file.

    json
    {
      "ok": true
    }
    json
    {
      "ok": false,
      "error": "unsupported format (jpeg/png/webp only)"
    }

    Other 400 answers: file too large (max 5MB), file or url required, failed to fetch url: 404 (the status your url answered), multipart parse failed (the request was not a form). 401 without a valid key; 404 for a video that is not yours.

    bash
    # Upload a file
    curl -X PUT "https://api.streamvault.one/v1/videos/image/fFL56RU6PjvJPeE" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/thumbnail.jpg"
    
    # ...or let the API download an image
    curl -X PUT "https://api.streamvault.one/v1/videos/image/fFL56RU6PjvJPeE" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "url=https://example.com/thumbnail.jpg"
    
    # The new address
    curl "https://api.streamvault.one/v1/videos/fFL56RU6PjvJPeE" -H "Authorization: Bearer YOUR_API_KEY"   # -> thumbnailUrl
    POST

    Add Captions

    /videos/captions/{id}

    Upload an SRT or VTT subtitle file for a video.

    Path Parameters
    ParameterTypeRequiredDescription
    idstringRequiredThe unique video identifier
    Body Parameters
    ParameterTypeRequiredDescription
    languagestringRequiredISO 639-1 language code (e.g. en, es, fr)
    labelstringOptionalDisplay label for the caption trackDefault: English
    srtContentstringRequiredSRT or VTT content as string
    isDefaultbooleanOptionalSet as the default caption trackDefault: false
    json
    {
      "id": "cap_xyz789",
      "videoId": "fFL56RU6PjvJPeE",
      "language": "en",
      "label": "English",
      "isDefault": true
    }
    Try it out
    POST/videos/captions/{id}
    bash
    curl -X POST "https://api.streamvault.one/v1/videos/captions/{id}" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "language": "en",
      "label": "English",
      "srtContent": "1\n00:00:00,000 --> 00:00:05,000\nHello World",
      "isDefault": true
    }'
    DELETE

    Delete Captions

    /videos/captions

    Remove a caption track from a video.

    Query Parameters
    ParameterTypeRequiredDescription
    videoIdstringRequiredThe video identifier
    captionsIdstringRequiredThe caption track identifier
    json
    {
      "success": true,
      "message": "Caption track deleted"
    }
    Try it out
    DELETE/videos/captions?videoId={videoId}&captionsId={captionsId}
    bash
    curl -X DELETE "https://api.streamvault.one/v1/videos/captions?videoId={videoId}&captionsId={captionsId}" \
      -H "Authorization: Bearer YOUR_API_KEY"