shortkit provides multiple methods to ingest content, from simple drag-and-drop uploads to automated pipelines integrating with your existing systems.
Upload methods
Method Best For Auth Required Direct upload Client-side uploads from browsers/apps Secret key (to create session) Server-side upload Server-to-server uploads Secret key URL-based ingest Content from cloud storage or URLs Secret key Admin Portal Manual uploads by team members Portal login Automated pipeline Integration with DAM/CMS systems Secret key
Direct upload
Direct upload is the recommended method for client-side uploads (web browsers, mobile apps). It allows clients to upload directly to cloud storage without routing through your servers.
Create upload session
Your server creates an upload session and receives a signed URL: curl -X POST https://api.shortkit.dev/v1/uploads \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"title": "My Video",
"description": "A great video",
"tags": ["news", "breaking"],
"customMetadata": {
"articleUrl": "https://example.com/article/123",
"authorId": "author_456"
}
}'
Response: {
"data" : {
"uploadId" : "upl_abc123xyz" ,
"uploadUrl" : "https://upload.shortkit.dev/direct/abc123..." ,
"expiresAt" : "2024-02-04T13:00:00Z"
}
}
Upload file to signed URL
The client uploads directly to the signed URL. Supports resumable uploads via the tus protocol . // Browser example
const response = await fetch ( uploadUrl , {
method : 'PUT' ,
headers : {
'Content-Type' : 'video/mp4'
},
body : videoFile
});
For large files, use a tus client: import * as tus from 'tus-js-client' ;
const upload = new tus . Upload ( file , {
endpoint : uploadUrl ,
retryDelays : [ 0 , 1000 , 3000 , 5000 ],
onProgress : ( bytesUploaded , bytesTotal ) => {
const percentage = ( bytesUploaded / bytesTotal * 100 ). toFixed ( 2 );
console . log ( ` ${ percentage } %` );
},
onSuccess : () => {
console . log ( 'Upload complete' );
}
});
upload . start ();
Receive webhook notification
When processing completes, you receive a webhook: {
"event" : "content.ready" ,
"data" : {
"contentId" : "cnt_def456" ,
"uploadId" : "upl_abc123xyz" ,
"title" : "My Video" ,
"duration" : 45.2 ,
"status" : "ready"
}
}
Server-side upload
For uploads from your server (e.g., from a processing pipeline):
curl -X POST https://api.shortkit.dev/v1/content/upload \
-H "Authorization: Bearer sk_live_your_secret_key" \
-F "[email protected] " \
-F "title=My Video" \
-F "description=A great video" \
-F "tags=news,breaking"
Response:
{
"data" : {
"contentId" : "cnt_abc123" ,
"status" : "processing" ,
"title" : "My Video"
}
}
For large files, use chunked upload:
# Create chunked upload session
curl -X POST https://api.shortkit.dev/v1/content/upload/chunked \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"filename": "video.mp4",
"fileSize": 524288000,
"title": "My Video"
}'
# Upload chunks
curl -X PUT "https://api.shortkit.dev/v1/content/upload/chunked/{uploadId}/part/1" \
-H "Authorization: Bearer sk_live_your_secret_key" \
--data-binary @chunk1.bin
# Complete upload
curl -X POST "https://api.shortkit.dev/v1/content/upload/chunked/{uploadId}/complete" \
-H "Authorization: Bearer sk_live_your_secret_key"
URL-based ingest
Ingest content from a URL (cloud storage, CDN, or any accessible endpoint):
curl -X POST https://api.shortkit.dev/v1/content/ingest \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"sourceUrl": "https://storage.example.com/videos/my-video.mp4",
"title": "My Video",
"description": "A great video",
"tags": ["news"]
}'
For protected sources, include authentication:
curl -X POST https://api.shortkit.dev/v1/content/ingest \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"sourceUrl": "https://storage.example.com/videos/my-video.mp4",
"sourceAuth": {
"type": "bearer",
"token": "source_access_token"
},
"title": "My Video"
}'
Supported source auth types:
bearer - Bearer token in Authorization header
basic - Basic authentication
header - Custom header (e.g., API key)
query - Query parameter authentication
Admin Portal upload
For manual uploads by team members:
Go to Content → Upload in the Admin Portal
Drag and drop video files (or click to browse)
Fill in metadata (title, description, tags)
Set scheduling if needed
Click Publish or Schedule
Features:
Bulk upload (multiple files at once)
Inline metadata editing
Progress indicator with resumable support
Preview before publishing
Automated ingestion
Webhook-based
Configure your DAM or CMS to send webhooks when new content is available:
# Register ingestion webhook endpoint
curl -X POST https://api.shortkit.dev/v1/ingestion/webhooks \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"name": "CMS Ingestion",
"secret": "webhook_secret_for_verification"
}'
When your system has new content, POST to:
POST https://api.shortkit.dev/v1/ingestion/webhooks/{webhookId}/ingest
X-Webhook-Signature: sha256=...
{
"sourceUrl" : "https://your-dam.com/assets/video123.mp4",
"title" : "New Video from CMS",
"metadata" : {
"cmsId" : "12345"
}
}
Bucket polling
Configure automatic ingestion from cloud storage:
curl -X POST https://api.shortkit.dev/v1/ingestion/buckets \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"type": "s3",
"bucket": "your-video-bucket",
"prefix": "uploads/",
"credentials": {
"accessKeyId": "AKIA...",
"secretAccessKey": "..."
},
"pollInterval": 300,
"deleteAfterIngest": false
}'
Supported storage:
Amazon S3
Google Cloud Storage
Azure Blob Storage
Required fields
Content title. Used in Admin Portal, analytics, and optionally in SDK overlays.
Optional fields
Tags for filtering and categorization (e.g., “politics”, “sports”).
Content language (ISO 639-1). Used for geo-targeting and caption selection.
Geographic targeting rules. Country/region codes to include.
Country/region codes to exclude.
Scheduled publish time (ISO 8601). Content remains “scheduled” until this time.
Expiry time (ISO 8601). Content is automatically archived after this time.
Arbitrary key-value pairs passed through to the SDK. Examples:
articleUrl: Link to related article
productId: Associated product for shoppable video
authorName: Content creator name
curl -X POST https://api.shortkit.dev/v1/uploads \
-H "Authorization: Bearer sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Breaking: Major Weather Event",
"description": "Live coverage of the approaching storm system",
"tags": ["weather", "breaking", "live"],
"locale": "en-US",
"geoTargeting": {
"include": ["US"],
"exclude": []
},
"publishAt": "2024-02-05T08:00:00Z",
"expiresAt": "2024-02-12T00:00:00Z",
"customMetadata": {
"articleUrl": "https://example.com/weather/storm-2024",
"severity": "high",
"region": "midwest"
}
}'
Caption upload
Upload caption tracks alongside content:
# Upload SRT file
curl -X POST https://api.shortkit.dev/v1/content/{contentId}/captions \
-H "Authorization: Bearer sk_live_your_secret_key" \
-F "[email protected] " \
-F "language=en" \
-F "label=English"
# Upload VTT file
curl -X POST https://api.shortkit.dev/v1/content/{contentId}/captions \
-H "Authorization: Bearer sk_live_your_secret_key" \
-F "[email protected] " \
-F "language=es" \
-F "label=Spanish"
Supported formats: SRT, VTT
Next steps