yt 2.3.0+1 copy "yt: ^2.3.0+1" to clipboard
yt: ^2.3.0+1 copied to clipboard

Native Dart interface to multiple YouTube REST APIs including the Data and Live Streaming API.

Youtube REST API Client #

yt - Native Dart Client for YouTube APIs

Native Dart interface to multiple Google REST APIs, including:

Related Packages:

  • yt_cli — CLI tool for YouTube APIs
  • yt_mcp — MCP server for AI integration

pub package License: MIT github build github issues

Quick Start #

import 'package:yt/yt.dart';

void main() async {
  // Use an API key for read-only access
  final yt = Yt.withKey('[your youtube api key]');

  // Search for videos
  final results = await yt.search.list(q: 'flutter tutorial', maxResults: 5);
  for (final item in results.items) {
    print('${item.snippet?.title}');
  }
}

For write operations (uploading videos, managing broadcasts), use OAuth — see Configuration below.

Features #

  • YouTube Data API — Channels, Playlists, Videos, Search, Comments, Subscriptions, Thumbnails, Captions, and more
  • YouTube Live Streaming API — LiveBroadcasts, LiveStreams, and LiveChat
  • YouTube Analytics API — Reports, Groups, and Group Items for channel analytics
  • Members & Memberships — Channel members, membership levels, and video abuse report reasons
  • Activities — Channel activity feeds including uploads, likes, favorites, subscriptions, and playlist additions
  • Multiple auth methods — API key, OAuth 2.0 with automatic token refresh, or custom token generators
  • Cross-platform — works on all Dart/Flutter platforms including web, mobile, and desktop
  • Dart-first — manually crafted (not auto-generated) for a focused, well-documented API surface

Getting Started #

Add to your pubspec.yaml:

dependencies:
  yt: ^2.3.0

Configuration #

YouTube API access requires either an API key (read-only) or OAuth 2.0 credentials.

Action Type Authentication Requirement Why
Reading Public Data API Key or OAuth 2.0 Accesses data anyone can see (e.g., public video titles, search results).
Reading Private Data OAuth 2.0 Required Accesses data specific to a user (e.g., a user's private videos or watch history).
Writing/Modifying Data OAuth 2.0 Required Performs actions on behalf of a user (e.g., uploading, deleting, or commenting).

API Key #

Create an API key in the Google API Console, then:

final yt = Yt.withKey('[your api key]');

OAuth 2.0 #

Create OAuth credentials in the Google API Console, then generate a credentials file:

yt authorize

This creates $HOME/.yt/credentials.json. Then:

final yt = Yt.withOAuth();  // Uses default credentials file

For manual credential files, the format is:

identifier: [client id from the API console]
secret: [client secret from the API console]

Usage #

Data API #

import 'package:yt/yt.dart';

final yt = Yt.withOAuth();

var playlistResponse = await yt.playlists.list(
    channelId: '[youtube channel id]', maxResults: 25);

playlistResponse.items
    .forEach((playlist) => print('${playlist.snippet?.title}'));

Upload a Video #

final yt = await Yt.withOAuth();

final body = <String, dynamic>{
  'snippet': {
    'title': 'TEST title',
    'description': 'Test Description',
    'tags': ['tag1', 'tag2'],
    'categoryId': '22'
  },
  'status': {
    'privacyStatus': 'private',
    'embeddable': true,
    'license': 'youtube'
  }
};

final videoItem = await yt.videos.insert(
    body: body,
    videoFile: File('[path to a video to upload]'),
    notifySubscribers: false);

print(videoItem);

Live Streaming API #

import 'package:yt/yt.dart';

final yt = await Yt.withOAuth();
final br = yt.broadcast;
final th = yt.thumbnails;

// Create a broadcast
final broadcastItem = await br.insert(body: {
  'snippet': {
    'title': 'TEST Broadcast',
    'description': 'Test',
    'scheduledStartTime':
        DateTime.now().add(Duration(hours: 2)).toUtc().toIso8601String()
  },
  'status': {'privacyStatus': 'private'},
  'contentDetails': {
    'monitorStream': {
      'enableMonitorStream': false,
      'broadcastStreamDelayMs': 10
    },
    'enableDvr': true,
    'enableContentEncryption': true,
    'enableEmbed': true,
    'recordFromStart': true,
    'startWithSlate': false
  }
}, part: 'snippet,status,contentDetails');

// Bind to a stream and upload thumbnail
await br.bind(
    broadcastId: broadcastItem.id,
    streamId: '[one of your valid stream ids]');

await th.set(
    videoId: broadcastItem.id,
    thumbnail: File('[path to an image to upload]'));

Download a LiveChat #

final yt = await Yt.withOAuth();

var broadcastResponse = await yt.broadcast.list(broadcastStatus: 'active');

if (broadcastResponse.items.isNotEmpty) {
  await yt.chat.downloadHistory(
      liveBroadcastItem: broadcastResponse.items.first);
}

Analytics #

final yt = await Yt.withOAuth();

// Query channel analytics
final report = await yt.analytics.query(
  ids: 'channel==MINE',
  startDate: '2026-01-01',
  endDate: '2026-01-31',
  metrics: 'views,estimatedMinutesWatched',
  dimensions: 'day',
);

for (final header in report.columnHeaders) {
  print('${header.name} (${header.dataType})');
}

// List analytics groups
final groups = await yt.analytics.groupsList(mine: true);
for (final group in groups.items) {
  print('${group.id}: ${group.snippet.title}');
}

Activities #

final yt = Yt.withKey('[your api key]');

// List recent channel activities
final activities = await yt.activities.list(
  channelId: 'UC_x5XG1OV2P6uZZ5FSM9Ttw',
  maxResults: 10,
);

for (final activity in activities.items) {
  print('${activity.snippet?.type}: ${activity.snippet?.title}');
}
final yt = await Yt.withOAuth();

// List my recent activities
final myActivities = await yt.activities.list(
  mine: true,
  maxResults: 20,
);

for (final activity in myActivities.items) {
  print('${activity.snippet?.publishedAt}: ${activity.snippet?.title}');
}

Flutter Integration #

This package has no Flutter dependencies and works on all platforms. To authenticate with a user's own YouTube account, implement a TokenGenerator:

import 'package:google_sign_in/google_sign_in.dart';
import 'package:yt/yt.dart';

class YtLoginGenerator implements TokenGenerator {
  final GoogleSignIn _googleSignIn = GoogleSignIn(
    scopes: ['https://www.googleapis.com/auth/youtube'],
  );

  @override
  Future<Token> generate() async {
    var _currentUser = await _googleSignIn.signInSilently();
    if (_currentUser == null) _currentUser = await _googleSignIn.signIn();
    final token = (await _currentUser!.authentication).accessToken;
    if (token == null) throw Exception();
    return Token(
        accessToken: token, expiresIn: 3599, scope: null, tokenType: '');
  }
}

Then in your Flutter app:

late final Yt yt;

void _init() async {
  yt = await Yt.withGenerator(YtLoginGenerator());
}

void _getPlaylists() async {
  setState(() {
    items.addAll(await yt.playlists.list(mine: true));
  });
}

See Usage within Flutter for google_sign_in setup requirements.

Documentation #

Contributing #

Any help from the open-source community is always welcome and needed:

  • Found an issue? Please fill a bug report with details.
  • Need a feature? Open a feature request with use cases.
  • Are you a developer? Fix a bug, implement a new feature, or improve tests — send a pull request.
  • Are you using and liking the project? Promote it, or let me know and I'll cross-link your project.

If you donate 1 hour of your time, you can contribute a lot, because others will do the same — just be part and start with your 1 hour.

License #

MIT — see the LICENSE file for details.

35
likes
0
points
355
downloads

Publisher

verified publishercdavis.ca

Weekly Downloads

Native Dart interface to multiple YouTube REST APIs including the Data and Live Streaming API.

Homepage
Repository (GitHub)
View/report issues

Topics

#api #youtube #oauth2 #rest #live-streaming

Funding

Consider supporting this project:

www.buymeacoffee.com

License

unknown (license)

Dependencies

csv, dio, fling_pickle, googleapis_auth, http, http_parser, json_annotation, loggy, retrofit, stemmer, universal_io, yaml

More

Packages that depend on yt