Build private streaming archives, not noisy video feeds.
The ClosedCast API helps families, churches, organizations, coaches, and communities preserve meaningful videos in private archives that remain organized, accessible, and ready to watch.
API design principle
ClosedCast is built for continuity. The API should help people preserve what matters, organize it clearly, share it intentionally, and return to it over time.
Your first request
curl.exe -X GET "https://closedcast.com/APIv1/Ping" ^
-H "Authorization: Bearer YOUR_API_TOKEN"
Use Ping to confirm that your API token is working before building upload,
sharing, or automation workflows.
Endpoint matrix
These endpoints are grouped by the work people are trying to do: preserve videos, organize collections, invite members, search archives, and monitor activity.
General
/APIv1/Ping
Confirm API connectivity and token access.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1"
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Ping" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Account
/APIv1/Account
Return the authenticated account and organization context.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"account": {
"TenantID": "TENANT_ID",
"TenantName": "My Private Archive",
"Email": "owner@example.com"
}
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Account" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Video
/APIv1/Videos
List videos in the authenticated account.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 1,
"videos": [
{
"VideoID": "VIDEO_ID",
"CategoryID": "CATEGORY_ID",
"CategoryName": "Memories",
"Title": "Family Video",
"Description": "A private archive video",
"ThumbnailUrl": "https://videodelivery.net/VIDEO_UID/thumbnails/thumbnail.jpg",
"DurationSeconds": 6,
"Status": "ready",
"IsReady": true,
"Active": true
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Videos" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/Video?id={VideoID}
Return one video by ID.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"video": {
"VideoID": "VIDEO_ID",
"CategoryID": "CATEGORY_ID",
"CategoryName": "Training Videos",
"Title": "Introduction to Private Archives",
"Description": "",
"Tags": [],
"ThumbnailUrl": "https://videodelivery.net/VIDEO_UID/thumbnails/thumbnail.jpg",
"DurationSeconds": 1956,
"Status": "ready",
"IsReady": true,
"Active": true,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Video?id={VideoID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/CreateVideo
Create video metadata before upload.
Sample input
{
"Title": "Family Memories",
"Description": "A video worth preserving",
"CategoryID": "CATEGORY_ID"
}
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/CreateVideo" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"Title\": \"Family Memories\", \"Description\": \"A video worth preserving\", \"CategoryID\": \"CATEGORY_ID\"}"
/APIv1/UpdateVideo
Update title, description, category, tags, or archive metadata.
Sample input
{
"VideoID": "VIDEO_ID",
"Title": "Updated Title",
"Description": "Updated description",
"CategoryID": "CATEGORY_ID"
}
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/UpdateVideo" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"VideoID\": \"VIDEO_ID\", \"Title\": \"Updated Title\", \"Description\": \"Updated description\", \"CategoryID\": \"CATEGORY_ID\"}"
/APIv1/UploadVideo
Upload a video file using multipart form data.
Sample input
multipart/form-data
Title=Sunday Service
Description=Uploaded file
CategoryID=CATEGORY_ID
File=@C:\path\to\video.mp4
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/UploadVideo" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-F "Title=Sunday Service" ^
-F "Description=Uploaded file" ^
-F "CategoryID=CATEGORY_ID" ^
-F "File=@C:\\path\\to\\video.mp4"
/APIv1/UploadVideoFromFileUrl
Upload a video from a downloadable file URL. Best for Zapier and automation.
Sample input
multipart/form-data
Title=Sunday Service
Description=Uploaded file
CategoryID=CATEGORY_ID
File=@C:\path\to\video.mp4
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/UploadVideoFromFileUrl" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-F "Title=Sunday Service" ^
-F "Description=Uploaded file" ^
-F "CategoryID=CATEGORY_ID" ^
-F "File=@C:\\path\\to\\video.mp4"
/APIv1/DeleteVideo
Delete or deactivate a video.
Sample input
{
"VideoID": "VIDEO_ID"
}
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/DeleteVideo" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"VideoID\": \"VIDEO_ID\"}"
/APIv1/Playback?id={VideoID}
Return a secure playback URL for a ready video.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Playback?id={VideoID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/Download?id={VideoID}&mode=json
Prepare and return a secure MP4 download URL. Omit mode=json to receive a 302 redirect when ready.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"status": "ready",
"download": {
"VideoID": "VIDEO_ID",
"Title": "Family Video",
"FileName": "FamilyVideo.mp4",
"Format": "video/mp4",
"Url": "https://customer.cloudflarestream.com/SIGNED_TOKEN/downloads/default.mp4",
"ExpiresUtc": "2026-07-13T18:30:00Z"
}
}
Sample curl
curl.exe -i "https://closedcast.com/APIv1/Download?id=VIDEO_ID&mode=json" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/RefreshVideo
Refresh processing status from Cloudflare.
Sample input
{
"VideoID": "VIDEO_ID"
}
Sample output
{
"ok": true,
"version": "v1",
"VideoID": "VIDEO_ID",
"Status": "ready",
"IsReady": true
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/RefreshVideo" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"VideoID\": \"VIDEO_ID\"}"
Category / Collection
/APIv1/Categories
List collections for the authenticated account.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 2,
"categories": [
{
"CategoryID": "CATEGORY_ID",
"Name": "Memories",
"Active": true,
"OfferEnabled": false,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Categories" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/Category?id={CategoryID}
Return one collection by ID.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"category": {
"CategoryID": "CATEGORY_ID",
"TenantID": "TENANT_ID",
"Name": "Memories",
"OfferEnabled": false,
"Active": true,
"VideoCount": 4,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Category?id={CategoryID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/CreateCategory
Create a new collection.
Sample input
{
"Name": "Sermons"
}
Sample output
{
"ok": true,
"version": "v1",
"message": "Success"
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/CreateCategory" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"Name\": \"Sermons\"}"
/APIv1/UpdateCategory
Update collection name or settings.
Sample input
{
"CategoryID": "CATEGORY_ID",
"Name": "Sunday Sermons"
}
Sample output
{
"ok": true,
"version": "v1",
"message": "Success"
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/UpdateCategory" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"CategoryID\": \"CATEGORY_ID\", \"Name\": \"Sunday Sermons\"}"
/APIv1/DeleteCategory
Delete or deactivate a collection.
Sample input
{
"CategoryID": "CATEGORY_ID"
}
Sample output
{
"ok": true,
"version": "v1",
"message": "Success"
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/DeleteCategory" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"CategoryID\": \"CATEGORY_ID\"}"
/APIv1/GetCategoryVideos?CategoryID={CategoryID}
List videos in one collection.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"category": {
"CategoryID": "CATEGORY_ID",
"Name": "Memories"
},
"count": 1,
"videos": [
{
"VideoID": "VIDEO_ID",
"CategoryID": "CATEGORY_ID",
"CategoryName": "Memories",
"Title": "Family Video",
"Description": "A private archive video",
"Tags": null,
"ThumbnailUrl": "https://videodelivery.net/VIDEO_UID/thumbnails/thumbnail.jpg",
"DurationSeconds": 6,
"Status": "ready",
"IsReady": true,
"Active": true,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/GetCategoryVideos?CategoryID={CategoryID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/GetCategoryVideosByName?CategoryName={Name}
List videos by collection name.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"category": {
"CategoryID": "CATEGORY_ID",
"Name": "Memories"
},
"count": 1,
"videos": [
{
"VideoID": "VIDEO_ID",
"CategoryID": "CATEGORY_ID",
"CategoryName": "Memories",
"Title": "Family Video",
"Description": "A private archive video",
"Tags": null,
"ThumbnailUrl": "https://videodelivery.net/VIDEO_UID/thumbnails/thumbnail.jpg",
"DurationSeconds": 6,
"Status": "ready",
"IsReady": true,
"Active": true,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/GetCategoryVideosByName?CategoryName={Name}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
User
/APIv1/Users
List account members.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 1,
"users": [
{
"UserID": "USER_ID",
"Email": "owner@example.com",
"Status": "Active",
"FirstName": "Alex",
"LastName": "Owner",
"DisplayName": "Alex Owner",
"LastLoginUtc": null,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Users" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/GetUser?id={UserID}
Return one account member.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"user": {
"UserID": "USER_ID",
"Email": "owner@example.com",
"Status": "active",
"FirstName": "Alex",
"LastName": "Owner",
"DisplayName": "Alex Owner",
"LastLoginUtc": null,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/GetUser?id={UserID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Invites / Sharing
/APIv1/SendInvite
Invite someone to access a video or collection.
Sample input
{
"What": "Video",
"WhatID": "VIDEO_ID",
"RecipientEmail": "member@example.com",
"RecipientName": "Member Name"
}
Sample output
{
"ok": true,
"version": "v1",
"InviteID": "INVITE_ID",
"message": "Invite processed."
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/SendInvite" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"What\": \"Video\", \"WhatID\": \"VIDEO_ID\", \"RecipientEmail\": \"member@example.com\", \"RecipientName\": \"Member Name\"}"
/APIv1/Invites
List active and pending invites.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 1,
"invites": [
{
"GrantID": "GRANT_ID",
"What": "Video",
"WhatID": "VIDEO_ID",
"RecipientEmail": "member@example.com",
"RecipientName": "Member Name",
"AssignedBy": "USER_ID",
"Active": true,
"PendingActivation": true,
"ExpiresUtc": null,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Invites" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/RevokeInvite
Revoke access previously granted by invite.
Sample input
{
"InviteID": "INVITE_ID"
}
Sample output
{
"GrantID": "GRANT_ID"
}
Sample curl
curl.exe -X POST "https://closedcast.com/APIv1/RevokeInvite" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-H "Accept: application/json" ^
-d "{ \"InviteID\": \"INVITE_ID\"}"
Contacts
/APIv1/Contacts
List contacts collected through offers or access requests.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 1,
"contacts": [
{
"ContactID": "CONTACT_ID",
"Name": "Jane Smith",
"Email": "jane.smith@example.com",
"FirstName": "Jane",
"LastName": "Smith",
"Phone": "",
"What": "Video",
"WhatID": "VIDEO_ID",
"AccessGrantID": "ACCESS_GRANT_ID",
"CreatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Contacts" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/Contact?id={ContactID}
Return one contact.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 1,
"contacts": [
{
"ContactID": "CONTACT_ID",
"Name": "Jane Smith",
"Email": "jane.smith@example.com",
"FirstName": "Jane",
"LastName": "Smith",
"Phone": "",
"What": "Video",
"WhatID": "VIDEO_ID",
"AccessGrantID": "ACCESS_GRANT_ID",
"CreatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Contact?id={ContactID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
/APIv1/ContactsForItem?itemType={Video|Category}&itemID={VIDEO_ID or CATEGORYID}
List contacts connected to a video or collection.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"count": 1,
"contacts": [
{
"ContactID": "CONTACT_ID",
"Name": "Jane Smith",
"Email": "jane.smith@example.com",
"FirstName": "Jane",
"LastName": "Smith",
"Phone": "",
"What": "Video",
"WhatID": "VIDEO_ID",
"AccessGrantID": "ACCESS_GRANT_ID",
"CreatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/ContactsForItem?itemType={Video|Category}&itemID={VIDEO_ID or CATEGORYID}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Search
Search
/APIv1/Search?q={query}&limit={limit}&offset={offset}
Search accessible videos or list all, owned, shared, or recent videos using reserved query commands.
Sample input
No request body required.
Sample output
{
"ok": true,
"version": "v1",
"search": "family",
"count": 1,
"videos": [
{
"VideoID": "VIDEO_ID",
"CategoryID": "CATEGORY_ID",
"CategoryName": "Family",
"Title": "Family Video",
"Description": "A private archive video",
"Tags": ["family","vacation"],
"ThumbnailUrl": "https://videodelivery.net/VIDEO_UID/thumbnails/thumbnail.jpg",
"DurationSeconds": 125,
"Status": "ready",
"IsReady": true,
"Active": true,
"CreatedUtc": "/Date(1767225600000)/",
"UpdatedUtc": "/Date(1767225600000)/"
}
]
}
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/Search?q={query}&limit={limit}&offset={offset}" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Events
/APIv1/ZapierEvents?eventType=some.event
Return recent API events for automation polling.
Sample input
No request body required.
Sample output
[
{
"id": "EVENT_ID",
"EventID": "EVENT_ID",
"EventType": "video.created",
"ItemType": "Video",
"ItemID": "VIDEO_ID",
"ItemName": "Family Video",
"CreatedUtc": "/Date(1767225600000)/"
}
]
Sample curl
curl.exe -X GET "https://closedcast.com/APIv1/ZapierEvents?eventType=some.event" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Event List
The Events endpoint returns a chronological history of activity that occurs within your ClosedCast account. Automation platforms such as Zapier, Make, n8n, Power Automate, and AI agents can poll this endpoint to detect changes and trigger workflows. For example to poll for video created events call: https://closedcast.com/APIV1/ZapierEvents?eventType=video.created
Video
video.createdvideo.updatedvideo.deletedvideo.refreshedvideo.readyvideo.playback.requestedvideo.upload_session.createdvideo.upload_session.failed
Categories
category.createdcategory.updatedcategory.deleted
Invites & Sharing
invite.sentinvite.updatedinvite.revokedshare.accepted
Contacts & Offers
contact.createdcontact.updatedcontact.deletedcontact.capturedoffer.submitted
Search accessible videos
Search endpoint
Use the Search endpoint to find videos available to the authenticated user. Search results can include videos owned by the authenticated account and videos that have been shared directly with the user or through a shared collection.
GET /APIv1/Search?q={QUERY}
Open-ended searches match video titles, descriptions, tags, and collection names. A regular search term must contain at least two characters.
ClosedCast resolves access before searching. Videos belonging to unrelated accounts are not included in the searchable candidate set.
Open-ended text search
Pass a word or phrase through the q parameter to search all videos
accessible to the authenticated user.
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q=vacation"
Searches are case-insensitive and can match:
- Video title
- Video description
- Tags
- Collection name
Search a phrase
Use --data-urlencode when the search contains spaces, punctuation,
braces, or other characters that should be URL encoded.
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q=family vacation"
Only an exact reserved command such as {all} activates command mode.
A query such as family {all} is treated as a normal text search.
Reserved search commands
Reserved commands provide convenient archive views without requiring a text-search term. Commands are case-insensitive but must match the complete query value.
| Query | Returns | Default behavior |
|---|---|---|
q={all} |
All accessible videos | Includes active, nondeleted videos owned by the authenticated account and ready videos shared with the authenticated user. |
q={owned} |
Owned videos | Includes active, nondeleted videos owned by the authenticated account, including videos that are still processing. |
q={shared} |
Shared videos | Includes ready videos shared directly with the user or made available through a shared collection. |
q={recent} |
Recently updated videos | Returns the most recently updated ready videos across owned and shared access. The default limit is 25. |
List all accessible videos
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q={all}"
List owned videos
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q={owned}"
List shared videos
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q={shared}"
List recently updated videos
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q={recent}"
Pagination
Use limit and offset to retrieve larger result sets in pages.
The default limit is 50 for normal searches and most commands. The maximum limit is 250.
First page
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q={all}" ^
--data-urlencode "limit=50" ^
--data-urlencode "offset=0"
Second page
curl.exe --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json" ^
--data-urlencode "q={all}" ^
--data-urlencode "limit=50" ^
--data-urlencode "offset=50"
Query parameters
| Parameter | Required | Description |
|---|---|---|
q |
Yes |
A text-search term or one of the supported reserved commands:
{all}, {owned},
{shared}, or {recent}.
|
limit |
No |
Maximum number of videos to return. Defaults to 50, except
{recent}, which defaults to 25. Maximum value: 250.
|
offset |
No | Number of matching videos to skip before returning results. Defaults to 0. |
Result ordering and access
- Results are ordered by most recently updated first.
- Duplicate videos are removed before pagination.
- Inactive and deleted videos are excluded.
- Pending, revoked, and expired shares are excluded.
- Shared collection access includes videos inside that collection.
Search discovery does not automatically change permissions on other API endpoints. A video returned by Search must still pass the authorization rules enforced by the requested playback, detail, download, or update endpoint.
Example response
{
"ok": true,
"version": "v1",
"query": "{all}",
"command": "all",
"mode": "all",
"count": 2,
"totalCount": 2,
"offset": 0,
"limit": 50,
"hasMore": false,
"videos": [
{
"VideoID": "VIDEO_ID",
"Title": "Family Vacation",
"Description": "Summer vacation archive",
"CategoryName": "Family Memories",
"Status": "ready",
"IsReady": true
}
]
}
count is the number of videos returned in the current response.
totalCount is the total number of matching videos before pagination.
When hasMore is true, request the next page by increasing
offset.
Invalid search term
Normal text searches must contain at least two characters.
curl.exe -i --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
--data-urlencode "q=a"
HTTP/1.1 400 Bad Request
{
"ok": false,
"version": "v1",
"message": "Search term must be at least two characters."
}
Invalid API token
curl.exe -i --get "https://closedcast.com/APIv1/Search" ^
-H "Authorization: Bearer invalid_token" ^
--data-urlencode "q={all}"
HTTP/1.1 401 Unauthorized
{
"ok": false,
"version": "v1",
"message": "Invalid API token."
}
Common workflows
Upload from Zapier or cloud storage
Use UploadVideoFromUrl when a prior Zap step gives you a downloadable
file URL from Google Drive, Dropbox, OneDrive, Box, SharePoint, Gmail Attachments,
or Google Forms.
curl.exe -X POST "https://closedcast.com/APIv1/UploadVideoFromUrl" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-d "{\"Title\":\"Sunday Service\",\"Description\":\"Uploaded from Zapier\",\"CategoryID\":\"CATEGORY_ID\",\"FileUrl\":\"https://example.com/video.mp4\"}"
Download a video as MP4
Check status and receive a signed URL
Use mode=json for API clients, Zapier, command-line tools, and applications
that want to inspect download status before retrieving the file. ClosedCast authenticates
the request, verifies tenant access, and asks Cloudflare to prepare the MP4 when needed.
curl.exe -i "https://closedcast.com/APIv1/Download?id=VIDEO_ID&mode=json" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Accept: application/json"
Processing response
HTTP/1.1 202 Accepted
Retry-After: 10
{
"ok": true,
"version": "v1",
"status": "processing",
"download": {
"VideoID": "VIDEO_ID",
"Title": "Family Video",
"Format": "video/mp4",
"PercentComplete": 42,
"RetryAfterSeconds": 10
}
}
Download the file through a redirect
Omit mode=json and use a client that follows redirects. When the MP4 is ready,
ClosedCast returns 302 Found with a short-lived Cloudflare URL. Cloudflare then
delivers the file directly, so ClosedCast does not proxy the video bytes.
curl.exe -L "https://closedcast.com/APIv1/Download?id=VIDEO_ID" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
--progress-bar ^
-o "closedcast-video.mp4"
Ready JSON response
{
"ok": true,
"version": "v1",
"status": "ready",
"download": {
"VideoID": "VIDEO_ID",
"Title": "Family Video",
"FileName": "FamilyVideo.mp4",
"Format": "video/mp4",
"Url": "https://customer.cloudflarestream.com/SIGNED_TOKEN/downloads/default.mp4",
"ExpiresUtc": "2026-07-13T18:30:00Z"
}
}
Download response flow
The same endpoint is called repeatedly. A 202 Accepted response means Cloudflare is
preparing the downloadable MP4. Wait for the number of seconds in Retry-After or
RetryAfterSeconds, then call the endpoint again. A ready request returns either JSON
or a 302 redirect, depending on the selected mode.
GET /APIv1/Download?id=VIDEO_ID&mode=json
|
+-- 202 processing -- wait and retry
|
+-- 200 ready JSON -- download the returned Url
GET /APIv1/Download?id=VIDEO_ID
|
+-- 202 processing -- wait and retry
|
+-- 302 redirect -- Cloudflare delivers the MP4
Cloudflare Stream provides an encoded MP4 download. It is not guaranteed to be the exact original
uploaded file. Do not save a 202 JSON response using an .mp4 filename.
Refresh processing status
Refresh processing status
Videos usually move from processing to ready. Use
RefreshVideo or the scheduled processing refresh job to keep MongoDB
synchronized with Cloudflare.
curl.exe -X POST "https://closedcast.com/APIv1/RefreshVideo" ^
-H "Authorization: Bearer YOUR_API_TOKEN" ^
-H "Content-Type: application/json" ^
-d "{\"VideoID\":\"VIDEO_ID\"}"
Machine-readable API summary
This summary is intentionally structured so AI coding agents can quickly understand how to call the ClosedCast API.
product: ClosedCast
category: Private Streaming Archive
base_url: https://closedcast.com/APIv1
authentication:
type: Bearer Token
header: Authorization
example: Authorization: Bearer YOUR_API_TOKEN
core_resources:
- Account
- Videos
- Downloads
- Categories
- Users
- Invites
- Contacts
- Search
- Events
recommended_upload_for_automation:
endpoint: UploadVideoFromUrl
method: POST
reason: Works naturally with Zapier and cloud-file URLs.
video_status_flow:
- uploading
- processing
- ready
- upload_failed
download_flow:
endpoint: Download
method: GET
status_mode: /Download?id=VIDEO_ID&mode=json
redirect_mode: /Download?id=VIDEO_ID
processing_response: HTTP 202 with Retry-After
ready_json_response: HTTP 200 with short-lived Url
ready_redirect_response: HTTP 302 to Cloudflare MP4
brand_principle:
ClosedCast is built for archives, not algorithms.