HomeAPI Documentation

SnapVid API

Integrate video delivery into your application

Quickstart

API Access Requirements

The SnapVid API is available on Business and Enterprise plans. Upload videos, manage content, and deliver video to your users programmatically.

Base URL

https://api.snapvid.org

All endpoints require HTTPS. HTTP requests will be rejected.

Upload a video in 60 seconds

Here's a complete upload flow from start to finish:

# 1. Get a presigned upload URL
curl -X GET "https://api.snapvid.org/api/upload/presigned-url?filename=demo.mp4&filetype=video/mp4&filesize=52428800" \
  -H "X-API-Key: sv_live_your_key_here"

# Response: { "uploadUrl": "https://s3...", "videoId": 123, "videoSlug": "1717000000_abc123" }

# 2. Upload the file directly to S3
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
  -H "Content-Type: video/mp4" \
  --data-binary @demo.mp4

# 3. Complete the upload with metadata
curl -X POST "https://api.snapvid.org/api/upload/complete" \
  -H "X-API-Key: sv_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "video_id": 123,
    "title": "Product Demo",
    "description": "A walkthrough of our new feature",
    "visibility": "unlisted"
  }'

# Response includes shareable_slug — your watch URL is:
# https://snapvid.org/watch/{shareable_slug}

SnapVid automatically processes your video into HLS adaptive streaming (360p, 480p, 720p, 1080p). Processing typically takes 1-3 minutes depending on file size.

JavaScript / Node.js Example

const API_KEY = process.env.SNAPVID_API_KEY;
const BASE = "https://api.snapvid.org";

async function uploadVideo(file) {
  // 1. Get presigned URL
  const params = new URLSearchParams({
    filename: file.name,
    filetype: file.type,
    filesize: String(file.size),
  });
  const { uploadUrl, videoId } = await fetch(
    `${BASE}/api/upload/presigned-url?${params}`,
    { headers: { "X-API-Key": API_KEY } }
  ).then(r => r.json());

  // 2. Upload file to S3
  await fetch(uploadUrl, {
    method: "PUT",
    headers: { "Content-Type": file.type },
    body: file,
  });

  // 3. Complete with metadata
  const result = await fetch(`${BASE}/api/upload/complete`, {
    method: "POST",
    headers: {
      "X-API-Key": API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      video_id: videoId,
      title: "My Video",
      visibility: "unlisted",
    }),
  }).then(r => r.json());

  return result; // { success, video, shareable_slug }
}

Authentication

Authenticate all API requests using your API key. Pass it via the X-API-Key header.

API Key Authentication

curl -X GET "https://api.snapvid.org/api/my-videos" \
  -H "X-API-Key: sv_live_your_api_key_here" \
  -H "Content-Type: application/json"

Getting Your API Key

  1. Log in to your SnapVid dashboard
  2. Navigate to Settings → API Keys
  3. Click "Create Key" and give it a descriptive name
  4. Copy your key immediately. It is only displayed once.

Security: Never expose your API key in client-side code, public repos, or frontend applications. Use environment variables on your server.

Key Format

API keys follow the format sv_live_... and are 40+ characters long. You can have up to 5 active keys per account.

HeaderValue
X-API-KeyYour API key
Content-Typeapplication/json

Video Upload

Uploading a video is a 3-step process: request a presigned URL, upload the file directly to storage, then finalize with metadata. This keeps your API key secure since the file never passes through our API server.

1

Request Presigned URL

GET/api/upload/presigned-url

Query Parameters

ParameterTypeRequiredDescription
filenamestringYesOriginal filename (e.g. video.mp4)
filetypestringYesMIME type (video/mp4, video/quicktime, etc.)
filesizeintegerNoFile size in bytes (used for storage limit checks)

Response

{
  "uploadUrl": "https://s3.amazonaws.com/...",
  "key": "uploads/1717000000_abc123/1717000000_abc123.mp4",
  "videoId": 456,
  "videoSlug": "1717000000_abc123"
}
FieldDescription
uploadUrlPresigned S3 URL. PUT your file here. Expires in 1 hour.
keyStorage path (internal reference)
videoIdVideo record ID. Use this in step 3.
videoSlugInternal video identifier
2

Upload File to Storage

Upload your video file directly to the presigned URL using a PUT request. No authentication header needed for this step.

curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
  -H "Content-Type: video/mp4" \
  --data-binary @your-video.mp4

Supported formats: MP4, MOV, AVI, WebM. Max file size depends on your plan's storage limit.

3

Complete Upload

POST/api/upload/complete

Request Body

{
  "video_id": 456,
  "title": "How to Make Jollof Rice",
  "description": "Step-by-step jollof rice tutorial",
  "tags": "cooking, tutorial, nigerian-food",
  "visibility": "unlisted",
  "download_enabled": false
}
FieldTypeRequiredDescription
video_idintegerYesThe numeric videoId from step 1
titlestringNoVideo title. Becomes part of the SEO-friendly URL.
descriptionstringNoVideo description
tagsstringNoComma-separated tags for organization
visibilitystringNopublic, unlisted, private, or password. Defaults to unlisted.
download_enabledbooleanNoAllow viewers to download the video. Defaults to false.
passwordstringNoRequired when visibility is "password".
expires_atstringNoISO date string for link expiry (Pro+ plans).

Response

{
  "success": true,
  "shareable_slug": "how-to-make-jollof-rice-1717000000",
  "video": {
    "id": 456,
    "video_id": "1717000000_abc123",
    "slug": "how-to-make-jollof-rice-1717000000",
    "title": "How to Make Jollof Rice",
    "status": "uploaded",
    "visibility": "unlisted",
    "hls_url": "https://cdn.snapvid.org/uploads/.../1717000000_abc123.m3u8",
    "thumbnail_url": "https://cdn.snapvid.org/uploads/.../thumb.jpg"
  }
}

// Your shareable URLs:
// Watch: https://snapvid.org/watch/how-to-make-jollof-rice-1717000000
// Embed: https://snapvid.org/embed/how-to-make-jollof-rice-1717000000

Processing: After upload, SnapVid transcodes your video into adaptive streaming format (HLS). This typically takes 1-3 minutes. Check status via GET /api/videos/status/{video_id}.

List & Get Videos

GET/api/my-videos

Returns your videos with pagination, sorted by newest first.

Query Parameters

ParameterDefaultDescription
page1Page number (starts at 1)
page_size50Results per page (1–100)
curl -X GET "https://api.snapvid.org/api/my-videos?page=1&page_size=20" \
  -H "X-API-Key: sv_live_your_key_here"

// Response
{
  "videos": [
    {
      "id": 456,
      "video_id": "1717000000_abc123",
      "slug": "how-to-make-jollof-rice-1717000000",
      "title": "How to Make Jollof Rice",
      "description": "Step-by-step tutorial",
      "thumbnail_url": "https://cdn.snapvid.org/uploads/.../thumb.jpg",
      "hls_url": "https://cdn.snapvid.org/uploads/.../master.m3u8",
      "views": 342,
      "visibility": "unlisted",
      "status": "ready",
      "download_enabled": false,
      "created_at": "2025-04-15T10:30:00Z"
    }
  ],
  "total": 24,
  "page": 1,
  "page_size": 20,
  "total_pages": 2
}

Two IDs: Each video has a numeric id (e.g. 456) and a string video_id (e.g. "1717000000_abc123"). Most management endpoints use the numeric id. The privacy endpoint uses the string video_id. Each endpoint's docs specify which one to use.

Video Object Fields

FieldTypeDescription
idintegerDatabase ID (use for update/delete operations)
slugstringURL-friendly identifier. Used in watch/embed URLs.
hls_urlstringHLS manifest URL for adaptive streaming playback
thumbnail_urlstringVideo thumbnail image URL
statusstringprocessing, ready, or failed
visibilitystringpublic, unlisted, private, or password
viewsintegerTotal view count
GET/api/videos/by-slug/{slug}

Get a single video by its slug. Use this to check processing status or get the streaming URL.

curl -X GET "https://api.snapvid.org/api/videos/by-slug/how-to-make-jollof-rice-1717000000" \
  -H "X-API-Key: sv_live_your_key_here"

// Response
{
  "video_id": "1717000000_abc123",
  "title": "How to Make Jollof Rice",
  "description": "Step-by-step tutorial",
  "hls_url": "https://cdn.snapvid.org/uploads/.../master.m3u8",
  "thumbnail_url": "https://cdn.snapvid.org/uploads/.../thumb.jpg",
  "views": 342,
  "visibility": "unlisted",
  "status": "ready",
  "width": 1920,
  "height": 1080,
  "download_enabled": false
}
GET/api/videos/status/{videoSlug}

Poll this endpoint after upload to check when your video is ready for playback. Uses the videoSlug from step 1. Requires authentication.

curl -X GET "https://api.snapvid.org/api/videos/status/1717000000_abc123" \
  -H "X-API-Key: YOUR_API_KEY"

// Response
{
  "video_id": "1717000000_abc123",
  "status": "ready",
  "hls_url": "https://cdn.snapvid.org/uploads/.../1717000000_abc123.m3u8",
  "thumbnail_url": "https://cdn.snapvid.org/uploads/.../thumb.jpg"
}
StatusMeaning
processingVideo is being transcoded into streaming format
readyVideo is ready to stream and embed
failedProcessing failed. Try re-uploading.

Privacy & Downloads

PATCH/api/videos/{video_id}/privacy

Change who can access your video. Use the video's video_id field (the string ID, e.g. "1717000000_abc123").

curl -X PATCH "https://api.snapvid.org/api/videos/1717000000_abc123/privacy" \
  -H "X-API-Key: sv_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "visibility": "password",
    "password": "client-preview-2025",
    "password_hint": "Ask your account manager"
  }'

// Response
{
  "success": true,
  "message": "Video privacy updated to password",
  "video_id": "1717000000_abc123",
  "visibility": "password"
}

Visibility Options

ValueBehavior
publicIndexed by Google. Anyone with the URL can watch.
unlistedNot indexed. Only people with the link can watch.
passwordRequires password to watch. Great for client previews or paid content.
privateOnly visible to you in your dashboard.
PATCH/api/videos/{id}/download

Enable or disable the download button on your video player. Uses the numeric id field from the video object.

curl -X PATCH "https://api.snapvid.org/api/videos/456/download" \
  -H "X-API-Key: sv_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "download_enabled": true }'

// Response
{
  "success": true,
  "message": "Download enabled for this video",
  "video_id": "456",
  "download_enabled": true
}

Custom Thumbnails

Replace the auto-generated thumbnail with your own image. Requires Starter plan or higher.

1

Get Thumbnail Upload URL

POST/api/videos/{id}/thumbnail/presigned-url

Uses the numeric id field from the video object.

curl -X POST "https://api.snapvid.org/api/videos/456/thumbnail/presigned-url" \
  -H "X-API-Key: sv_live_your_key_here"

// Response
{
  "uploadUrl": "https://s3.amazonaws.com/...",
  "thumbnailUrl": "https://cdn.snapvid.org/uploads/.../custom_thumb.jpg",
  "videoId": 456
}
2

Upload Image & Confirm

# Upload the image file (JPEG only)
curl -X PUT "UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  --data-binary @thumbnail.jpg

# Then confirm the thumbnail update
curl -X PUT "https://api.snapvid.org/api/videos/456/thumbnail" \
  -H "X-API-Key: sv_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "thumbnail_url": "THUMBNAIL_URL_FROM_STEP_1" }'

Delete Video

DELETE/api/videos/{id}

Permanently delete a video and all associated files. Uses the numeric id field. This action cannot be undone.

curl -X DELETE "https://api.snapvid.org/api/videos/456" \
  -H "X-API-Key: sv_live_your_key_here"

// Response
{
  "message": "Video deleted successfully"
}

Warning: This permanently removes the video, streaming files, and thumbnail from storage. All existing links and embeds will stop working.

Analytics

Access view counts, unique viewers, and top-performing videos. Analytics depth depends on your plan.

GET/api/analytics

Get aggregate analytics across all your videos.

curl -X GET "https://api.snapvid.org/api/analytics" \
  -H "Authorization: Bearer YOUR_TOKEN"

// Response
{
  "analytics_level": "advanced",
  "summary": {
    "total_views": 4821,
    "unique_viewers": 1293,
    "total_videos": 24,
    "avg_views_per_video": 200.9,
    "total_watch_time_seconds": 86420.5,
    "avg_watch_time_seconds": 45.2,
    "avg_completion_rate": 68.3,
    "total_completions": 892
  },
  "top_videos": [
    {
      "video_id": "1717000000_abc123",
      "slug": "how-to-make-jollof-rice-1717000000",
      "title": "How to Make Jollof Rice",
      "views": 342,
      "status": "ready"
    }
  ],
  "views_trend": [
    { "date": "2025-04-28", "views": 45 },
    { "date": "2025-04-29", "views": 62 }
  ]
}

Note: The analytics endpoint currently requires a Bearer session token (not API key). Analytics API key support is coming soon.

Embed Player

Embed SnapVid's adaptive streaming player on any website. The player handles quality switching automatically based on the viewer's network speed.

Embed Code

<iframe
  src="https://snapvid.org/embed/{slug}"
  width="100%"
  height="100%"
  style="aspect-ratio: 16/9; border: none;"
  allow="autoplay; fullscreen; picture-in-picture"
  allowfullscreen
></iframe>

URL Parameters

ParameterDefaultDescription
autoplaytrueAuto-start video when player loads
controlstrueShow playback controls
loopfalseLoop video when it ends
mutedfalseStart muted (required for autoplay in most browsers)
start0Start playback at this time (seconds)

Example with Parameters

<iframe
  src="https://snapvid.org/embed/product-demo-1717000000?autoplay=1&muted=1&loop=1"
  width="100%"
  height="100%"
  style="aspect-ratio: 16/9; border: none;"
  allow="autoplay; fullscreen; picture-in-picture"
  allowfullscreen
></iframe>

WordPress & CMS Integration

SnapVid works with WordPress, Wix, Squarespace, Webflow, and any platform that supports HTML embeds or REST APIs. No plugins required.

Embed in WordPress

Add a Custom HTML block in the WordPress editor and paste your embed code. Works in both the Block Editor (Gutenberg) and Classic Editor.

Step 1 — Add a Custom HTML block

In WordPress Editor:
  Click "+" → Search "Custom HTML" → Add block

Step 2 — Paste your SnapVid embed code

<iframe
  src="https://snapvid.org/embed/your-video-slug"
  width="100%"
  height="100%"
  style="aspect-ratio: 16/9; border: none;"
  allow="autoplay; fullscreen; picture-in-picture"
  allowfullscreen
></iframe>

Use the API from WordPress (PHP)

Call the SnapVid API from your WordPress theme or plugin using wp_remote_get. This lets you list videos, display them dynamically, or build custom video galleries.

List your videos (with pagination)

<?php
$page = 1;
$response = wp_remote_get(
    'https://snapvid.org/api/my-videos?page=' . $page . '&page_size=20',
    array(
        'headers' => array(
            'X-API-Key' => 'your_api_key_here',
        ),
    )
);

if (!is_wp_error($response)) {
    $data = json_decode(wp_remote_retrieve_body($response), true);

    foreach ($data['videos'] as $video) {
        echo '<div class="snapvid-video">';
        echo '<h3>' . esc_html($video['title']) . '</h3>';
        echo '<iframe src="https://snapvid.org/embed/' . esc_attr($video['slug']) . '"';
        echo ' width="100%" style="aspect-ratio:16/9;border:none;"';
        echo ' allow="autoplay;fullscreen" allowfullscreen></iframe>';
        echo '</div>';
    }

    // Pagination info
    // $data['total_pages'], $data['page'], $data['total']
}

Upload a video via API

<?php
$file_path = '/path/to/video.mp4';

$response = wp_remote_post('https://snapvid.org/api/videos/upload', array(
    'headers' => array(
        'X-API-Key' => 'your_api_key_here',
    ),
    'body' => array(
        'title' => 'My Video Title',
        'file'  => new CURLFile($file_path, 'video/mp4', 'video.mp4'),
    ),
));

if (!is_wp_error($response)) {
    $result = json_decode(wp_remote_retrieve_body($response), true);
    // $result['slug'] — use this for the embed URL
}

Other Platforms

The iframe embed works anywhere you can add HTML. Here's where to paste it on popular platforms:

PlatformHow to embed
WordPressCustom HTML block or Text tab in Classic Editor
WixAdd Embed → Custom Element → Paste iframe
SquarespaceCode Block → Paste iframe
WebflowEmbed element → Paste iframe
Custom sitePaste iframe directly into your HTML

Error Handling

HTTP Status Codes

CodeMeaning
200Request succeeded
400Bad request. Check your request body or parameters.
401Unauthorized. Your API key is missing or invalid.
403Forbidden. Your plan doesn't include this feature, or you hit a limit.
404Video not found, or you don't own it.
429Rate limited. Wait and retry.
500Server error. Contact support if this persists.

Error Response Format

// Simple error
{
  "detail": "Video not found or you don't have permission"
}

// Plan limit error (403)
{
  "detail": {
    "error": "video_limit_exceeded",
    "message": "Video limit reached. Upgrade your plan.",
    "current_count": 50,
    "plan": "starter",
    "upgrade_url": "/pricing"
  }
}

// Feature not available (403)
{
  "detail": {
    "error": "feature_not_available",
    "feature": "custom_thumbnails",
    "message": "Custom thumbnails require Starter plan or higher.",
    "current_plan": "free"
  }
}

Rate Limits

Endpoint CategoryLimit
Upload (presigned URL + complete)5 requests/minute
Video management (list, get, update, delete)60 requests/minute
Analytics30 requests/minute
Thumbnail upload10 requests/minute

When rate limited, you'll receive a 429 response. Wait 60 seconds before retrying. Enterprise plans have custom rate limits.

Need Integration Help?

We help teams integrate SnapVid into their applications. Reach out and we'll get you set up.