Creating content
Content is not created directly — instead, you create content by uploading or importing media:- Upload — You have a video file. Upload it directly from a client or server. Best for user-generated content or files on disk.
- Import — You have a URL (cloud storage, TikTok, etc.). ShortKit fetches and processes the media for you. Best for migrating existing content or server-side workflows.
- Live Stream — You’re broadcasting in real time. ShortKit creates a content item for the stream that appears in the feed while the broadcast is live, and the recording remains afterward.
The content object
Attributes
string
Unique identifier (UUID) for the content item.
string
One of
"video", "carousel", "video_carousel", or "live_stream".The following four fields are present on content items returned by the feed endpoint. They are not included in content management API responses (
GET /v1/content/:id, GET /v1/content).boolean
true while a live stream is broadcasting, false otherwise. Only meaningful when contentType is "live_stream". See Live Streams.string | null
The underlying live stream’s UUID for items where
contentType is "live_stream". Use this when you need to address the live stream itself — for example, to end it or create clips from it. null for non-live items.string | null
Current state of the underlying live stream. One of
"idle", "active", or "ended". null for non-live items. See Lifecycle for state semantics.integer
Concurrent viewer count for live streams, refreshed on every feed read.
0 for non-live items and for live streams that are not currently being watched.string
Display title shown in the feed. Max 200 characters.
string | null
Optional longer description. Max 2000 characters.
string
Tracks media processing. One of
pending, processing, ready, or error. See Upload lifecycle below.string
Controls whether content appears in the feed. Either
published or unpublished. See Publish lifecycle below.number | null
Video duration in seconds. Set automatically when processing completes.
null for carousels.string | null
HLS streaming URL for video playback. Available once
uploadStatus is ready. null for carousels. An empty string ("") for protected content — the streaming URL is withheld until a signed URL is issued via the playback-token endpoint.boolean
When
true, playback is gated behind a short-lived signed streaming URL and streamingUrl is withheld (returned as an empty string ""). Issue a signed URL via the playback-token endpoint, or let the SDK handle it automatically. See Protected Content.string | null
Thumbnail image URL. For videos, auto-generated from the first frame. For carousels, the first image.
string | null
Editorial section (e.g.,
"Sports", "News"). Max 200 characters. Passed through to the feed for use in your UI.string | null
Content author name. Max 200 characters. Passed through to the feed for use in your UI.
string[]
Tags for categorization and filtering. Use these to filter content in the List Content endpoint.
object
Arbitrary key-value pairs passed through to the feed. Use this for article URLs, campaign IDs, deep links, or any app-specific data your client needs at render time.ShortKit automatically populates one reserved key:
language— BCP 47 language code detected from the video’s audio track (e.g."en","es","ja"). Set asynchronously after processing completes."und"indicates no speech was detected. You can filter the feed by this key usingFeedFilter.metadata.
object[]
Caption tracks attached to this content. Each track contains:
id— Unique identifierlanguage— ISO 639-1 code (e.g.,"en")label— Display name (e.g.,"English CC")source— Either"generated"(auto-generated) or"uploaded"url— URL to the caption filetrackId— Track identifier (used to resolve the caption URL)status—"preparing"or"ready"createdAt— ISO 8601 timestamp
object[]
Carousel images. Each image contains:
id— Unique identifierimageUrl— URL to the imagealtText— Accessibility textposition— Display order (0-indexed)createdAt— ISO 8601 timestamp
string | null
ISO 8601 timestamp. Content won’t appear in the feed before this time, even if
publishStatus is published. null means no scheduling constraint.string | null
ISO 8601 timestamp. Content is automatically removed from the feed after this time.
null means no expiration.integer | null
Video width in pixels. Set automatically after processing.
null for carousels.integer | null
Video height in pixels. Set automatically after processing.
null for carousels.string | null
Aspect ratio string (e.g.,
"9:16", "16:9"). Set automatically after processing. null for carousels.number | null
Maximum frame rate of the video (e.g.,
30, 60). Set automatically after processing. null for carousels.string | null
Video quality tier. Either
"basic" or "plus". Set automatically after processing. null for carousels.string | null
Maximum resolution tier. One of
"audio-only", "SD", "HD", "FHD", or "UHD". Set automatically after processing. null for carousels.string
ISO 8601 creation timestamp.
string
ISO 8601 timestamp of the last modification.
Carousel-specific attributes
These fields are only present on image carousel content items.number | null
Seconds between automatic image transitions. When set, the carousel advances automatically.
null means manual swipe only.Video carousel-specific attributes
Video carousels are created withcontentType: "video_carousel". Unlike regular videos, video carousels are containers that reference existing video content items. They become ready immediately (no processing needed).
Videos are managed through dedicated endpoints after the carousel is created:
POST /v1/content/{id}/videos— Add video references to the carousel (max 10 videos)PUT /v1/content/{id}/videos/order— Reorder videos within the carouselDELETE /v1/content/{id}/videos/{entry_id}— Remove a video from the carousel
title, description, author, section, articleUrl) separate from the individual videos it contains. In the feed response, the videos array contains full ContentItem objects for each referenced video.
Empty video carousels (no videos added) are automatically excluded from the feed response.
Upload lifecycle
TheuploadStatus field tracks media processing — from the moment you initiate an upload or import to when the media is playable.
Videos move through the full lifecycle:
pending → processing → ready.
Image carousels skip processing entirely — images are served directly, so carousels are ready immediately after creation.
Video carousels are also ready immediately — they reference existing video content items that are already processed.
uploadStatus only tracks whether the media file is processed. It does not control whether content appears in your feed — that’s handled by publishStatus.Publish lifecycle
ThepublishStatus field controls whether content is visible in your feed. It is independent of uploadStatus — content must be both ready and published to appear.
Auto-publish
By default, organizations have auto-publish enabled. When auto-publish is on, content is automatically set topublished as soon as its uploadStatus reaches ready. This means uploaded content appears in the feed without any additional API calls.
If you turn auto-publish off (via organization settings), new content starts as unpublished. You then publish it manually by updating the content item:
Scheduling and expiration
Even whenpublishStatus is published, content only appears in the feed when the current time falls within its schedule window:
publishAt— If set, content is held back until this time. Useful for embargo or coordinated launches.expiresAt— If set, content is automatically pulled from the feed after this time. Useful for time-sensitive promotions or breaking news.
uploadStatusisreadypublishStatusispublishedpublishAtisnullor in the pastexpiresAtisnullor in the future
Deletion
Deleting a content item viaDELETE /v1/content/{id} archives it. Archived content is immediately removed from the feed and excluded from list results by default. The underlying media assets are cleaned up asynchronously.