Table of Contents


For a project of mine I had to upload video on youtube using the Youtube data API. I struggled a bit to get the right OAuth token and on the google generated elixir library

I detailed every step with the current 2022 google cloud interface.

The github repo for the elixir code

Setup on google cloud platform

Create project

Create google project

Enable Youtube api

Type youtube api in the search bar then click on YouTube Data api v3. enable youtube api 1

Enable it. enable youtube api 2

Click Oauth consent screen then tick external then create. setup oauth consent screen 1

Fill the mandatory fields App name, User support email and Email addresses. setup oauth consent screen 2

Add or remove scopes. setup oauth consent screen 3

Tick youtube and youtube upload then update. setup oauth consent screen 4

Add a test user this user is the google who own the youtube channel you want to upload. setup oauth consent screen 5

Create credentials

Click create credentials then OAuth client ID. create credentials 1

Choose Web application and fill the name and the return uri as This is mandatory to get the refresh token from the oauthplayground! Keep the page open you will need the client_id and client_secret. create credentials 2

Get the refresh token on google playground

Go to oauthplayground.

On the right side of the screen open the settings and input your client id and client secret. oauth playground 1

On left side tick youtube and youtube.upload then click on authorize api you will be redirected and prompted to give the youtube authorization to your app. oauth playground 2

Now click exchange the authorization code for tokens. Copy the refresh token you will need it after. oauth playground 3

Elixir code

mix new --sup upload_with_elixir
cd upload_with_elixir

Add these dependencies to your mix.exs

    {:goth, "~> 1.3-rc"},
    {:hackney, "~> 1.17"},
    {:google_api_you_tube, "~> 0.40"}

Install the deps

mix deps.get

Edit application.ex to setup goth

defmodule UploadWithElixir.Application do
  use Application

  def start(_type, _args) do
    # I just put creds here in a real project you should use config
    credentials = %{
      # Fill it with your client id
      "client_id" => "...",
      # Fill it with your client secret
      "client_secret" => "...",
      # the token we got from the oauthplayground
      "refresh_token" => "..."
    source = {:refresh_token, credentials, []}

    children = [
      {Goth, name: UploadWithElixir.Goth, source: source}

    Supervisor.start_link(children, strategy: :one_for_one)

Verify if you can get token with goth.

{:ok, %Goth.Token{ ... }}

The google lib is verbose so let’s write some function to do the insert.

defmodule UploadWithElixir do
  def video_insert do
    # get the token
    {:ok, token} = Goth.fetch(UploadWithElixir.Goth)

    # set the token
    conn =

    # The path to your video
    video_path = Path.expand("./sample.webm", __DIR__)

    # upload
      ["snippet", "status"],
        snippet: %GoogleApi.YouTube.V3.Model.VideoSnippet{
          title: "Test Video upload from elixir",
          description: "Description of the uploaded video"
        status: %GoogleApi.YouTube.V3.Model.VideoStatus{
          privacyStatus: "private"

Start iex and run the function you should get ok.

{:ok, %GoogleApi.YouTube.V3.Model.Video{ ... }}

If it does not work. There is 10,000 quota allocation an upload cost 1600. So if it does not work double check everything. Even a fail request cost 1600 you can do only 6 upload request per 24hours.

Some limitations:

  • it’s not possible to put the video as public without having you app verified by google…
  • the refresh_token will expire after 7 days