Skip to main content
shortkit provides multiple methods to ingest content, from simple drag-and-drop uploads to automated pipelines integrating with your existing systems.

Upload methods

MethodBest ForAuth Required
Direct uploadClient-side uploads from browsers/appsSecret key (to create session)
Server-side uploadServer-to-server uploadsSecret key
URL-based ingestContent from cloud storage or URLsSecret key
Admin PortalManual uploads by team membersPortal login
Automated pipelineIntegration with DAM/CMS systemsSecret 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.
1

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"
  }
}
2

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();
3

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:
  1. Go to Content → Upload in the Admin Portal
  2. Drag and drop video files (or click to browse)
  3. Fill in metadata (title, description, tags)
  4. Set scheduling if needed
  5. 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

Metadata

Required fields

title
string
required
Content title. Used in Admin Portal, analytics, and optionally in SDK overlays.

Optional fields

description
string
Content description.
tags
string[]
Tags for filtering and categorization (e.g., “politics”, “sports”).
locale
string
Content language (ISO 639-1). Used for geo-targeting and caption selection.
geoTargeting
object
Geographic targeting rules.
publishAt
datetime
Scheduled publish time (ISO 8601). Content remains “scheduled” until this time.
expiresAt
datetime
Expiry time (ISO 8601). Content is automatically archived after this time.
customMetadata
object
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

Example with full metadata

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