Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
YouTube Video Uploader icon

YouTube Video Uploader

Upload videos to your YouTube channel from a URL with OAuth. Set title, tags, category, thumbnail, privacy and publish time. $0.05 per upload.

157 runs on Apify $0.05 per video uploaded ($50 / 1,000)
Run this in the cloudRun on Apify →

YouTube & Creator Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust method, demoMode, videoUrl (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.05 per video uploaded = $50 per 1,000

You are charged forWhenPrice
Video uploadedCharged once per video YouTube confirms was published. Runs that upload nothing — missing credentials, a rejected session, or any failure — are never charged.$0.05

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-15, and they are what you are actually charged.

Inputs

FieldWhat it doesType
methodapi = official Data API with OAuth (default, reliable; needs clientId/secret/refreshToken). browser = automate YouTube Studio with exported login cookies (works locally; cloud runs face Google's session anti-fraud).string
demoModeReturn one clearly-labeled SAMPLE row instead of uploading, a free preview of the output shape, no credentials needed. The Actor also falls back to this automatically when no credentials are supplied. Uncheck (and add credentials) to upload for real.boolean
videoUrlPublic direct URL to the video file to upload (.mp4/.mov). You host it (S3/CDN/Apify KV).string
titleYouTube title (max 100 chars).string
descriptionVideo description (hashtags appended automatically).string
tagsUp to 30 video tags (used by the API method).array
hashtagsHashtags appended to the end of the description (e.g. shorts, reddit).array
privacyStatuspublic, unlisted, or private.string
cookiesYour exported YouTube login session: a cookies array OR a Playwright storageState ({cookies,origins}) as JSON. Export with a 'Cookie-Editor'/'Get cookies.txt' extension (for .youtube.com AND .google.com), or `npx playwright codegen --save-storage`. Kept secret.string
channelIdTarget channel ID (UC...) if your account has multiple channels.string
thumbnailUrlOptional public URL to a thumbnail image.string
madeForKidsDeclare the video as made for kids (COPPA).boolean
publishAtISO datetime to auto-publish (API method + privacy=private).string
categoryIdYouTube category ID. 22 = People & Blogs, 24 = Entertainment, 23 = Comedy, 27 = Education.string
clientIdOnly for method=api. From Google Cloud Console.string
clientSecretOnly for method=api.string
refreshTokenOnly for method=api. Refresh token with the youtube.upload scope.string

What you get

A structured dataset — each result includes fields like:

_demo_noticemethodprivacyStatusscheduledForstudioUrlthumbnailSettitleuploadSecondsvideoIdvisibilitywatchUrlok

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

2 ready-to-run use cases

Schedule YouTube Video Uploads to Publish Later

Queue a video now and let YouTube flip it public at your chosen time. Scheduling requires the video stay private until then, which the actor sets for you.

Upload YouTube Shorts Automatically From a URL

Point it at a vertical MP4 and it publishes as a public Short with #shorts, your title, tags and category. Uses the official YouTube Data API.

Related tools in YouTube & Creator Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

AI Viral Clip Cutter — Long Video to Shorts iconYouTube & Creator Tools

AI Viral Clip Cutter — Long Video to Shorts

Turn a long podcast or interview into ranked vertical clips. AI scores each moment and captions follow every word. $0.20 per clip row, samples included.

3 use cases

AI Text-to-Speech Voiceover iconYouTube & Creator Tools

AI Text-to-Speech Voiceover

Turn any script into an AI voiceover file: MP3, WAV, Opus or AAC. Pick the voice, speed and format. $40.00 per 1,000 voiceovers ($0.04 each).

3 use cases

Video & Audio Transcriber — Word-Level + SRT/VTT iconYouTube & Creator Tools

Video & Audio Transcriber — Word-Level + SRT/VTT

Transcribe any video or audio URL with word-level timestamps. Download SRT, VTT and TXT. The language is found for you. $0.02 per transcribed minute.

3 use cases

AI Character Reference Bank iconYouTube & Creator Tools

AI Character Reference Bank

Make a consistent AI character reference set. You get portrait, 3/4, full body, side and expression sheets, plus a character-bible prompt.

2 use cases

YouTube Channel Scraper iconYouTube & Creator Tools

YouTube Channel Scraper

Scrape videos from any YouTube channel, no login or API key. Rows carry titles, views, dates, duration, thumbnails.

Ready to run — no setup

YouTube Comments Scraper iconYouTube & Creator Tools

YouTube Comments Scraper

Scrape YouTube comments with no login or key. Get text, likes, reply counts, author handle, verified badge and timestamp. $0.40 per 1,000.

Ready to run — no setup

See all YouTube & Creator Tools →

YouTube Video Uploader: publish a file from a URL to your own channel through the official API

Point it at a public link to your video file, give it a title and your own Google OAuth credentials, and it uploads to your channel with the description, tags, hashtags, privacy, schedule and thumbnail set in the same run. It is built to be the publish step at the end of a pipeline: render somewhere, drop the file on a CDN, hand this actor the URL.

The awkward part is Google's, not ours, and it catches almost everyone. A new Google Cloud project starts in Testing mode, where your refresh token expires after seven days, and an unverified project has every upload forced to private whatever you asked for. Publish your consent screen and get the project verified before your first public upload. The row reports privacyOverridden: true when YouTube overruled you, so at least you find out from the output rather than from your channel.

InputA public direct link to the file, a title, and your own Google OAuth credentials
OutputOne row per run, with the video id and the watch URL
CeilingOne video per run, up to 30 tags
Account neededYour own YouTube channel and your own Google Cloud project
Price$0.05 per uploaded video, flat on every plan

📺 What YouTube Video Uploader does

It downloads your file, signs in with your refresh token and calls videos.insert, then thumbnails.set if you gave it a thumbnail. Nothing about your channel is kept after the run.

Privacy fails closed. It defaults to private, so nothing goes public unless you ask for it. If you set a schedule on a public or unlisted video the actor moves it to private for you and says so in the log, because YouTube will not schedule anything else. Afterwards it reads back the privacy YouTube actually stored, which is how privacyOverridden gets filled in.

There is a second browser method that drives YouTube Studio with exported cookies instead. It was built for running on your own machine, and it ignores tags, publishAt, categoryId and madeForKids. On Apify, use the API method.

📥 What you give it

{
  "videoUrl": "https://cdn.example.com/clips/episode-12.mp4",
  "title": "How the Roman aqueducts actually worked",
  "description": "A short breakdown of gravity-fed water systems.",
  "tags": ["history", "engineering", "rome"],
  "privacyStatus": "private",
  "publishAt": "2026-06-15T14:00:00Z",
  "categoryId": "27"
}
FieldDefaultWhat it is
videoUrlnoneA public direct link to the .mp4 or .mov. You host it, and it has to be reachable without a login.
titlenoneTrimmed to YouTube's 100 characters.
descriptionnoneYour hashtags are appended to the end of it.
tagsnoneUp to 30. Anything past 30 is dropped. API method only.
hashtagsnoneAppended to the description as #tag. Non-alphanumeric characters are stripped.
privacyStatusprivatepublic, unlisted or private.
publishAtnoneISO datetime to publish itself. YouTube only schedules private videos, so the actor sets privacy to private for you and logs it.
categoryId22People & Blogs by default. 24 Entertainment, 23 Comedy, 27 Education.
thumbnailUrlnoneOptional. Custom thumbnails need a verified channel; if YouTube refuses it the upload still succeeds and thumbnailSet says false.
madeForKidsfalseThe COPPA audience declaration. It binds you, not this actor. API method only.
channelIdnoneThe UC... id, for an account that runs more than one channel.
clientId, clientSecret, refreshTokennoneYour own Google OAuth credentials, with the youtube.upload scope on the refresh token. Marked secret.
methodapiapi or browser. Leave it on api.
cookiesnoneOnly for the browser method: a cookies array or a Playwright storageState, covering both .youtube.com and .google.com. Marked secret.
proxyConfigurationApify network onOnly the browser method uses it. The API method connects directly.
demoModefalseReturns the labelled preview row instead of uploading.

📤 What you get back

One row per run. There is no real sample row published here yet, so rather than invent one, these are the fields and what each of them means:

FieldWhat it is
oktrue once the insert returned a video id.
videoId, watchUrlThe id, and the youtu.be link to it.
privacyStatusThe privacy YouTube actually stored, read back after the upload.
requestedPrivacy, privacyOverriddenWhat you asked for, and whether YouTube overruled it. This is the field that catches an unverified project.
scheduledForYour publishAt as stored, or null.
thumbnailSetWhether the custom thumbnail took. API method only.
uploadSecondsWall clock from the start of the download.
methodWhich of the two lanes ran.
studioUrlThe Studio link. Browser method only.

🧾 Reading the output

RowWhere it landsBilled
A real uploadThe dataset, ok: true with a videoIdyes
The preview rowThe run's key-value store under SAMPLE_AND_NOTICES, never the datasetno upload fee

That split is deliberate: a preview cannot end up looking like a delivery, and it cannot bill like one either.

A failure does not write a row. The run itself ends as failed, with a message naming the fix rather than a stack trace:

What went wrongWhat the message says
The refresh token expired or was revokedUsually Testing mode and the seven-day expiry. Publish your consent screen.
No channel on the accountThe signed-in account has no channel to upload to.
Quota exhaustedYour project's daily units are spent.
Forbidden, or the scope is missingThe refresh token does not carry youtube.upload.

On the browser method a failed step also saves a screenshot and the page HTML into the run's key-value store, and names them in the error.

▶️ How to run it

1. Create an OAuth client in Google Cloud Console with the YouTube Data API enabled, and generate a refresh token carrying the youtube.upload scope. 2. Move the consent screen to In production, and request the compliance audit if you intend to publish anything public. 3. Open YouTube Video Uploader, paste the three credential fields, and put your file's link in videoUrl. 4. Fill in title, pick a categoryId, and leave privacyStatus on private for the first run. 5. Click Start, then read videoId, watchUrl and privacyOverridden off the row.

Run it with no credentials at all and you get the preview row instead, so you can see the shape before setting any of this up.

💰 How much does it cost?

$0.05 per uploaded video. Flat on every Apify plan, no volume tiers.

A run that fails before the upload completes, and a preview run, are not charged that fee. It lands on uploads that reached your channel, not on attempts.

Your Google quota is separate and it is Google's, not ours: videos.insert costs about 100 units against a default of 10,000 a day, so roughly 100 uploads a day before you need an increase.

💡 What people use it for

  • The last step of a render pipeline, so the file never waits in a bucket for somebody to upload it.
  • Scheduling a batch: one run per video, each with its own publishAt, all private until their

moment.

  • Re-publishing a back catalogue with consistent titles, tags and category from your own data.
  • Posting to a second channel on the same account, named by channelId.

🚧 What it does not do

  • It cannot lift Google's private-video override. An unverified project forces every upload

private and only Google's compliance audit changes that. The row tells you it happened.

  • It does not manage your OAuth for you. There is no shared app here: the credentials, the

project and the quota are yours.

  • The browser method ignores tags, publishAt, categoryId and madeForKids, and it always

declares the video as not made for kids. If your video is child-directed, use the API method, or set the declaration yourself in Studio.

  • The API method collapses your description onto one line. Line breaks do not survive the

upload.

  • One video per run. There is no queue and no playlist step.
  • It does not wait for HD processing. A video looks soft for a while after upload and sharpens

on its own.

  • It does not check what is behind your videoUrl beyond the file type, so point it at links you

control.

🧭 Which YouTube actor do you need?

If you wantUse
A plain upload through the official APIThis one
Long-form with category, playlist, scheduling and every setting read backYouTube Uploader Pro for Videos
To publish a vertical clip as a ShortYouTube Uploader Pro for Shorts
To download a video, its audio or its subtitlesYouTube Downloader Pro
The videos a channel has already publishedYouTube Scraper

❓ Questions people ask

Why did my public upload come out private? An unverified Google Cloud project. YouTube forces private and does not tell you at upload time. Request the compliance audit, and watch privacyOverridden in the meantime.

My refresh token stopped working after a week. The consent screen is still in Testing mode, where Google expires tokens after seven days. Move it to In production.

Do I need to give you my Google account? No. You create the OAuth client, you hold the refresh token, and it is marked secret in the input.

How many can I upload a day? Google's quota decides, not this actor. The default works out at roughly 100 uploads a day.

Can I see the output before setting up OAuth? Yes. Run it with no credentials, or tick demoMode, and the preview row lands in the run's key-value store.

🆘 If something breaks

Open the Issues tab on the actor page with the run id. The failure message usually names the fix already, and on the browser method the saved screenshot in the key-value store shows where it stopped.