Skip to main content

Upload Video

Upload video to various social media platforms using this endpoint.

Endpoint

POST /api/upload

Headers

NameValueDescription
AuthorizationApikey your-api-key-hereYour API key for authentication

Common Parameters

NameTypeRequiredDescription
userStringYesUser identifier
platform[]ArrayYesPlatform(s) to upload to (e.g., "tiktok", "instagram", "linkedin", "youtube", "facebook", "twitter", "threads", "pinterest")
videoFileYesThe video file to upload (can be a file upload or a video URL)
titleStringYesDefault title of the video
descriptionStringNoOptional extended text used only on LinkedIn commentary, Facebook descriptions, YouTube descriptions, and Pinterest notes. Ignored elsewhere.
scheduled_dateString (ISO-8601)NoOptional date/time (ISO-8601) to schedule publishing, e.g., "2024-12-31T23:45:00Z". Must be in the future (≤ 365 days). Omit for immediate upload.
async_uploadBooleanNoIf true, the request returns immediately with a request_id and processes in the background. See Upload Status.

Important: If you set async_upload to false but the upload takes longer than 59 seconds, it will automatically switch to asynchronous processing to avoid timeouts. In that case, use the request_id with the Upload Status endpoint to check the upload status and result.

Platform-Specific Titles

The title parameter serves as a fallback. To set a custom title for a particular platform, use the optional [platform]_title parameter. If provided, it will override the main title for that platform.

Example Optional Parameters:

  • instagram_title: "Check out my latest reel on Instagram! #reels"
  • facebook_title: "Excited to share this new video with my Facebook friends and family."
  • tiktok_title: "New TikTok video just dropped! 🔥"
  • linkedin_title: "A professional insight on the latest industry trends, discussed in this video."
  • x_title: "New video out now! 📢"
  • youtube_title: "My new YouTube video is live!"
  • pinterest_title: "An inspiring video pin."

Platform-Specific Parameters

TikTok

For more information about Tiktok API parameters, visit the Tiktok API documentation.

NameTypeRequiredDescriptionDefault
tiktok_titleStringNoSpecific title for the TikTok post. Fallbacks to title.title
privacy_levelStringNoPrivacy setting ("PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "FOLLOWER_OF_CREATOR", "SELF_ONLY")"PUBLIC_TO_EVERYONE"
disable_duetBooleanNoDisable duet featurefalse
disable_commentBooleanNoDisable commentsfalse
disable_stitchBooleanNoDisable stitch featurefalse
post_modeStringNoDIRECT_POST: Directly post the content to TikTok user's account or MEDIA_UPLOAD: Upload content to TikTok for users to complete the post using TikTok's editing flow. Users will receive an inbox notification.DIRECT_POST
cover_timestampIntegerNoTimestamp in milliseconds for video cover1000
brand_content_toggleBooleanNoSet to true for paid partnerships that promote third-party brands.false
brand_organic_toggleBooleanNoSet to true when promoting the creator's own business.false
is_aigcBooleanNoIndicates if content is AI-generatedfalse

The global description field is ignored for TikTok uploads.

Instagram

For more information about Instagram API parameters, visit the Instagram Graph API documentation.

NameTypeRequiredDescriptionDefault
instagram_titleStringNoSpecific title for the Instagram post. Fallbacks to title.title
media_typeStringNoType of media ("REELS" or "STORIES")"REELS"
share_to_feedBooleanNoWhether to share to feedtrue
collaboratorsStringNoComma-separated list of collaborator usernames-
cover_urlStringNoURL for custom video cover-
audio_nameStringNoName of the audio track embedded in your video-
user_tagsStringNoComma-separated list of user tags-
location_idStringNoInstagram location ID-
thumb_offsetStringNoTimestamp offset for video thumbnail-

Note on Instagram audio_name

  • Scope: Reels only, and only for the original audio embedded in your uploaded video. It does not let you pick licensed/trending music from Instagram’s library via API.
  • Limit: You can rename only once (when creating the Reel via API, or later from the audio page if you are the audio owner).
  • Behavior: The Reel is published using the audio embedded in your video and displays the name you provide in audio_name.

The global description field is ignored for Instagram video uploads.

LinkedIn

For more information about LinkedIn API parameters, visit the LinkedIn Marketing API documentation.

NameTypeRequiredDescriptionDefault
linkedin_titleStringNoSpecific title for the LinkedIn post. Fallbacks to title.title
linkedin_description or descriptionStringNoSent as the LinkedIn commentary. If omitted, we reuse title.title
visibilityStringYesVisibility setting ("CONNECTIONS", "PUBLIC", "LOGGED_IN", "CONTAINER")"PUBLIC"
target_linkedin_page_idStringNoLinkedIn page ID to upload videos to an organization"107579166"

YouTube

For more information about YouTube API parameters, visit the YouTube Data API documentation.

NameTypeRequiredDescriptionDefault
youtube_titleStringNoSpecific title for the YouTube video. Fallbacks to title.title
youtube_description or descriptionStringNoPopulates snippet.description. If omitted, we send title.title
tagsArrayNoArray of tags[]
categoryIdStringNoVideo category"22"
privacyStatusStringNoPrivacy setting ("public", "unlisted", "private")"public"
embeddableBooleanNoWhether video is embeddabletrue
licenseStringNoVideo license ("youtube", "creativeCommon")"youtube"
publicStatsViewableBooleanNoWhether public stats are viewabletrue
madeForKidsBooleanNoWhether video is made for kidsfalse
thumbnailFileNoCustom thumbnail image to set after upload. Accepts a multipart image file or a public URL. Formats: JPG/PNG/GIF/BMP. Max 2 MB. If both thumbnail (file) and thumbnail_url are provided, the file takes precedence. YouTube custom thumbnails are not supported for Shorts; they only apply to standard YouTube videos.-
thumbnail_urlString (URL)NoAlternative to provide the thumbnail as a public URL.-
selfDeclaredMadeForKidsBooleanNoExplicit declaration that the video is made for children (different from madeForKids)false
containsSyntheticMediaBooleanNoDeclaration that the video contains synthetic or AI-generated contentfalse
defaultLanguageStringNoLanguage of title and description (BCP-47 code, e.g., "es", "en")-
defaultAudioLanguageStringNoLanguage of the video audio (BCP-47 code, e.g., "es-ES", "en-US")-
allowedCountriesStringNoComma-separated list of country codes where the video is allowed (e.g., "US,CA,MX")-
blockedCountriesStringNoComma-separated list of country codes where the video is blocked (e.g., "CN,RU")-
hasPaidProductPlacementBooleanNoDeclaration that the video includes paid product placementsfalse
recordingDateStringNoRecording date and time of the video (ISO 8601 format, e.g., "2024-01-15T14:30:00Z")-

Important: YouTube custom thumbnails are not supported for Shorts; they only apply to standard YouTube videos.

Notes about new YouTube parameters:

  • Region restrictions: allowedCountries and blockedCountries cannot be used simultaneously. Country codes must be ISO 3166-1 alpha-2 (e.g., "US", "CA", "MX").
  • Language settings: defaultLanguage affects title and description display, while defaultAudioLanguage specifies the spoken language in the video. Use BCP-47 codes (e.g., "es" for Spanish, "es-ES" for Spain Spanish).
  • Legal declarations: selfDeclaredMadeForKids is more specific than madeForKids for COPPA compliance. containsSyntheticMedia provides transparency for AI-generated content. hasPaidProductPlacement ensures FTC compliance.

Facebook

For more information about Facebook API parameters, visit the Facebook Graph API documentation.

NameTypeRequiredDescriptionDefault
facebook_titleStringNoSpecific title for the Facebook post. Fallbacks to title. Note: If facebook_media_type is "STORIES", this field is ignored.title
facebook_description or descriptionStringNoSent as description for the video. Note: If facebook_media_type is "STORIES", this field is ignored.title
facebook_page_idStringYesFacebook Page ID where the video will be posted-
facebook_media_typeStringNoType of media ("REELS" or "STORIES")"REELS"
video_stateStringNoDesired state of the video ("DRAFT", "PUBLISHED")"PUBLISHED"

Note: If facebook_page_id is not provided, we will automatically use the user's only connected Page (if exactly one exists). If multiple Pages are connected, the API returns a helpful error with an available_pages list so you can choose one. Posting to personal Facebook profiles via API is not supported by Meta; only Pages can be posted to.

Threads

For more information about Threads API parameters, visit the Threads API documentation.

NameTypeRequiredDescriptionDefault
threads_titleStringNoSpecific title for the Threads post. Fallbacks to title.title

The global description field is ignored for Threads video uploads.

X (Twitter)

For more information about X API parameters, visit the X API Post Creation documentation.

NameTypeRequiredDescriptionDefault
x_titleStringNoSpecific title for the tweet. Fallbacks to title.title
x_long_text_as_postBooleanNoWhen true, publishes long text as a single post. Otherwise, creates a thread.false
reply_settingsStringNoControls who can reply to the tweet ("following", "mentionedUsers", "subscribers", "verified")-
geo_place_idStringNoPlace ID for adding geographic location to the tweet-
nullcastBooleanNoWhether to publish without broadcasting (promotional/promoted-only posts)false
for_super_followers_onlyBooleanNoTweet exclusive for super followersfalse
community_idStringNoCommunity ID for posting to specific communities-
share_with_followersBooleanNoShare community post with followersfalse
direct_message_deep_linkStringNoLink to take the conversation from public timeline to private Direct Message-
tagged_user_idsArrayNoArray of user IDs to tag in the media (max 10 users)[]

The global description field is ignored for X uploads.

How X (Twitter) Thread Creation Works (Advanced Logic)

Note: The following describes the default thread creation logic. To override this and post long text as a single post, set the x_long_text_as_post parameter to true.

The system is engineered to create well-formatted, natural-looking threads on X (formerly Twitter). Instead of simply splitting text at every line break, it intelligently groups paragraphs to create more readable tweets.

Here's the step-by-step logic:

Intelligent Paragraph Grouping (Primary Method):

The function first identifies distinct paragraphs (any text separated by a blank line). It then combines as many of these paragraphs as possible into a single tweet, filling it up to the 280-character limit without exceeding it. The double newline (\n\n) between combined paragraphs is preserved for formatting. This results in fewer, more substantial tweets that flow naturally, just as if a person had written them.

Handling Exceptionally Long Paragraphs:

If a single paragraph is, by itself, longer than the 280-character limit, a more granular splitting logic is automatically triggered for that paragraph only:

  • Split by Line Break: The system first attempts to break the paragraph down by its individual line breaks (\n).
  • Split by Word: If any of those single lines are still too long, it will split them by words as a final resort.

Media Attachment:

For posts that include photos or videos, all media is attached only to the first tweet of the thread. The subsequent tweets in the thread will be text-only replies.

Pinterest

NameTypeRequiredDescriptionDefault
pinterest_titleStringNoSpecific title for the Pinterest Pin. Fallbacks to title.title
pinterest_description or descriptionStringNoPopulates pin.description. If omitted, we reuse title.title
pinterest_board_idStringYesPinterest board ID to publish the video to.-
pinterest_linkStringNoDestination link for the video Pin.-
pinterest_cover_image_urlStringNoURL of an image to use as the video cover.-
pinterest_cover_image_content_typeStringNoContent type of the cover image (e.g., image/jpeg, image/png), used if pinterest_cover_image_data is provided.-
pinterest_cover_image_dataStringNoBase64 encoded cover image data, used if pinterest_cover_image_content_type is provided.-
pinterest_cover_image_key_frame_timeIntegerNoTime in milliseconds of the video frame to use as cover.-

Example Requests

Upload a Video to TikTok

curl \
-H 'Authorization: Apikey your-api-key-here' \
-F 'video=@/path/to/your/video.mp4' \
-F 'title="Your Video Title"' \
-F 'user="test"' \
-F 'platform[]=tiktok' \
-X POST https://api.upload-post.com/api/upload

Upload a Video to YouTube Using URL

curl \
-H 'Authorization: Apikey your-api-key-here' \
-F 'video="https://example.com/videos/myvideo.mp4"' \
-F 'title="Your Video Title"' \
-F 'description="Your video description"' \
-F 'user="test"' \
-F 'platform[]=youtube' \
-F 'tags[]=tutorial' \
-F 'tags[]=howto' \
-F 'categoryId="22"' \
-X POST https://api.upload-post.com/api/upload

Upload a Video to YouTube With Custom Thumbnail

curl \
-H 'Authorization: Apikey your-api-key-here' \
-F 'video=@/path/to/your/video.mp4' \
-F 'title="Your Video Title"' \
-F 'description="Your video description"' \
-F 'user="test"' \
-F 'platform[]=youtube' \
-F 'thumbnail_url="https://example.com/images/thumbnail-1280x720.jpg"' \
-X POST https://api.upload-post.com/api/upload

Upload to YouTube with thumbnail file

curl -X POST https://api.upload-post.com/api/upload \
-H "Authorization: Apikey <API_KEY>" \
-F "user=<profile_username>" \
-F "platform[]=youtube" \
-F "title=Demo video" \
-F "description=Description" \
-F "video=@/path/video.mp4;type=video/mp4" \
-F "thumbnail=@/path/thumbnail.jpg;type=image/jpeg"

Responses

  • 200 OK (synchronous, finished fast)
{
"success": true,
"results": {
"instagram": {
"success": true,
"url": "https://instagram.com/p/...",
"container_id": "1789...",
"video_was_transcoded": true,
"changes": {},
"prevalidation_metadata": {}
},
"linkedin": {
"success": false,
"error": "Expired access token"
}
},
"usage": {
"count": 12,
"limit": 100,
"last_reset": "2025-09-01T10:00:00.000Z"
}
}
  • 200 OK (asynchronous/background started, including sync→background fallback)
{
"success": true,
"message": "Upload initiated successfully in background.",
"request_id": "1a2b3c4d5e...",
"total_platforms": 3
}
  • 202 Accepted (scheduled)
{
"success": true,
"job_id": "scheduler_job_123",
"scheduled_date": "2025-09-22T10:00:00Z"
}
  • 400 Bad Request
    • Missing user, platform[], video file/URL, invalid scheduled_date, invalid platform values, Pinterest without pinterest_board_id.
{ "success": false, "message": "Username required in form data" }
  • 401 Unauthorized
{ "success": false, "message": "Invalid or expired token" }
  • 403 Forbidden (e.g., TikTok on Free plan)
{ "success": false, "message": "TikTok uploads are not available on the Free plan. Please upgrade to a paid plan." }
  • 404 Not Found (e.g., user not found after auth)
{ "success": false, "message": "User not found" }
  • 429 Too Many Requests (monthly limit exceeded; includes current usage)
{
"success": false,
"message": "This upload would exceed your monthly limit.",
"usage": { "count": 10, "limit": 10, "last_reset": "..." }
}
  • 500 Internal Server Error
{ "success": false, "error": "Detailed error message" }

Notes

  • When async or when sync falls back to background, use GET /api/uploadposts/status?request_id={request_id} to poll progress.
  • Per-platform results may include: url, publish_id, container_id, post_id, video_urn, video_reel_id, video_id, image_urns, post_ids, video_was_transcoded, changes, prevalidation_metadata, or error.