October 7, 2026 · In Ayotl
Uploading a video through the YouTube API: three traps in one afternoon
An “invalid argument” that won't say which one, a permission that lets you upload but not fix, and an edit that silently switches off whatever you didn't send.
This site's code challenges also go out on YouTube: one long video and one Short a day, uploaded and scheduled by a script. The first upload, with title, description, tags, language, “not made for kids” and a publish date, came back with this:
HttpError 400: Request contains an invalid argument.
reason: INVALID_REQUEST_METADATAWith six uploads a day you can't test blindly. What worked was changing strategy: upload the video with the bare minimum (title, description, category, private) and add the rest afterwards with videos.update, which costs 50. That made it possible to test field by field. And the surprise: all four fields went through, one by one and all together. What the upload rejects, the edit accepts. Since then the script uploads in two steps.
The second trap appeared on that very edit: 403 insufficient permissions. The scope you ask for to upload videos, youtube.upload, lets you upload and nothing else: not fix a title, not change the date. You need the full youtube scope, and to authorize again.
The third is the most treacherous, because it doesn't fail. To schedule the video, only the relevant part of status was sent: private, date and “not made for kids”. Response: 200. But update **replaces the whole object**, and whatever isn't in it goes back to its default. The video ended up with embeddable: false, meaning the player embedded on the challenge page would have said “video unavailable” on launch day. The script now always sends the full status.
And some good news the documentation doesn't make clear: even if the project hasn't passed the API audit, a video uploaded as private with a publish date goes public on its own at that time. The audit is needed to upload more than six videos a day, not to publish them.