ContentHosting
Developer Reference

API Documentation

Everything you need to integrate ContentHosting into your platform. Authenticate, upload, and embed videos via our REST API.

Authentication

The API supports two authentication methods:

1. API Key — pass your key in the X-API-Key header. This works for all /api/* endpoints.

2. Session Cookie — sign in via /auth/signin and use the returned ch_session cookie for subsequent requests. This is used by the web dashboard.

curl -H "X-API-Key: YOUR_KEY" \
  https://contenthosting.org/api/videos

Sign Up

POST/auth/signup

Create a new user account and start a session.

FieldTypeDescription
emailstringValid email address
passwordstringMinimum 8 characters, max 128
// Response 201
{ "ok": true, "userId": "uuid-here" }

Sign In

POST/auth/signin

Authenticate and receive a session cookie.

FieldTypeDescription
emailstringRegistered email address
passwordstringAccount password
// Response 200
{ "ok": true, "userId": "uuid-here" }

Sign Out

POST/auth/signout

Destroy the current session. Requires a valid session cookie.

// Response 200
{ "ok": true }

Current User

GET/auth/me

Get profile data for the authenticated user. Requires session cookie.

// Response 200
{ "user": { "id": "...", "email": "...", "createdAt": 1712... } }

Upload Presign

POST/api/upload/presign

Get a presigned URL to upload a video file directly to cloud storage. Requires API key or session.

FieldTypeDescription
fileNamestringOriginal file name
mimeTypestringe.g. video/mp4
fileSizenumberFile size in bytes
titlestring?Optional video title
descriptionstring?Optional description
// Response 200
{
  "objectKey": "videos/owner/...",
  "presignedUrl": "https://...",
  "expiresInSeconds": 900
}

Upload Complete

POST/api/upload/complete

Finalize a video upload after the file has been PUT to the presigned URL.

FieldTypeDescription
objectKeystringThe key from presign response
titlestringVideo title (1-200 chars)
fileSizenumberFile size in bytes
mimeTypestringFile MIME type
descriptionstring?Optional description
durationnumber?Duration in seconds
// Response 201
{
  "ok": true,
  "videoId": "uuid",
  "status": "ready",
  "defaultPlayer": "jwplayer",
  "embedUrl": "https://.../player/jwplayer?video=uuid",
  "embeds": { "jwplayer": "<iframe ...>", ... }
}

List Videos

GET/api/videos

Retrieve all videos owned by the authenticated user or API key.

// Response 200
{ "videos": [ { "id": "...", "title": "...", "status": "ready", ... } ] }

Get Embed Code

GET/api/embed/:videoId

Get embed markup and iframe URLs for all supported player types. No auth required.

// Response 200
{
  "defaultPlayer": "jwplayer",
  "embedUrl": "https://.../player/jwplayer?video=id",
  "embeds": {
    "jwplayer": "<iframe ...>",
    "plyr": "<iframe ...>",
    "videojs": "<iframe ...>",
    "fluidplayer": "<iframe ...>"
  }
}

Stream Media

GET/media/:videoId

Direct video stream with byte-range support. Returns the video file with proper Content-Type and Accept-Ranges headers. No auth required.

Player Types

ContentHosting supports four self-hosted, iframe-isolated video players:

PlayerURL PathNotes
JW Player/player/jwplayer?video=IDDefault player; feature-rich
Plyr/player/plyr?video=IDLightweight, accessible
Video.js/player/videojs?video=IDExtensible, plugin ecosystem
Fluid Player/player/fluidplayer?video=IDFill-to-container playback