Workflows

YouTube Cross-Publishing

Publish Rad content to YouTube or import YouTube videos into Rad — bidirectional sync.

Grow your audience across platforms. The Rad TV API supports bidirectional YouTube sync — publish your Rad content directly to YouTube, or bring your existing YouTube library into Rad. Manage everything from one API without switching between platforms.

Prerequisites

Connect your YouTube account via OAuth before using any YouTube features.

Connect YouTube

Redirect the user to the YouTube OAuth flow:

GET https://api.rad.live/youtube/connect?token=YOUR_API_KEY&returnUrl=https://yourapp.com/callback

This redirects to Google OAuth. After approval, the user is sent back to your returnUrl.

Verify connection

{
  me {
    youtube {
      connected
      channelId
      channelTitle
      hasUploadScope
    }
  }
}

hasUploadScope must be true to publish content to YouTube.

Rad → YouTube

Publish existing Rad content to YouTube:

curl -X POST https://api.rad.live/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "query": "mutation { publishContentToYouTube(id: \"did:rad.live:content/feature/123\", privacyStatus: PUBLIC) { id status youtubeUrl } }"
  }'
const response = await fetch('https://api.rad.live/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY',
  },
  body: JSON.stringify({
    query: `
      mutation {
        publishContentToYouTube(
          id: "did:rad.live:content/feature/123"
          privacyStatus: PUBLIC
        ) {
          id
          status
          youtubeUrl
        }
      }
    `,
  }),
});

const { data } = await response.json();
const job = data.publishContentToYouTube;
console.log(job.status); // PENDING → UPLOADING → PROCESSING → COMPLETE
import requests

response = requests.post(
    "https://api.rad.live/graphql",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_API_KEY",
    },
    json={
        "query": """
        mutation {
          publishContentToYouTube(
            id: "did:rad.live:content/feature/123"
            privacyStatus: PUBLIC
          ) {
            id
            status
            youtubeUrl
          }
        }
        """
    },
)

job = response.json()["data"]["publishContentToYouTube"]
print(job["status"])

Privacy Options

ValueDescription
PUBLICVisible to everyone on YouTube
UNLISTEDAccessible via link only
PRIVATEVisible only to you

Tracking Publish Progress

YouTube uploads are background jobs. Poll the status:

{
  youtubePublishJob(id: "job-id-here") {
    id
    status
    progress
    youtubeVideoId
    youtubeUrl
    error
  }
}

Status progression: PENDINGUPLOADINGPROCESSINGCOMPLETE

YouTube → Rad

Import a Single Video

mutation {
  createContentFromYouTube(videoId: "dQw4w9WgXcQ") {
    id
    metadata { title summary }
    assets { images { url } }
  }
}

This creates a Rad content item with the YouTube video's metadata and thumbnail. You can then publish it:

mutation {
  publishContent(id: "did:rad.live:content/feature/456") {
    id
  }
}

One-Call Import + Publish

Use importYouTubeAndPublish for a single call:

mutation {
  importYouTubeAndPublish(input: {
    videoId: "dQw4w9WgXcQ"
    publish: true
  }) {
    content { id metadata { title } }
  }
}

Batch Import

Import your entire YouTube library:

mutation {
  importYouTubeLibrary(input: {
    maxResults: 50
    publishedAfter: "2024-01-01"
    autoPublish: true
  }) {
    imported
    failed
    results { videoId contentId status }
  }
}

Browse YouTube Videos

List your YouTube videos to choose which to import:

{
  youtubeVideos(limit: 20) {
    videos {
      videoId
      title
      thumbnail
      publishedAt
      duration
      viewCount
    }
    nextPageToken
    totalResults
  }
}

Disconnecting

POST https://api.rad.live/youtube/disconnect
Authorization: Bearer YOUR_API_KEY

This revokes the YouTube OAuth token and removes the connection.

Next steps

On this page