Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/faraasaaay/innertube-v1/llms.txt

Use this file to discover all available pages before exploring further.

The InnerTube SDK exposes three distinct entry points for searching YouTube Music content: a typed filtered search that returns a flat list of items, a summary search that groups results by content category, and a suggestions endpoint that powers autocomplete. All three are suspend functions on the YouTube singleton and return Result-wrapped types so you can handle failures with runCatching or fold.

Overview

YouTube.search()

Returns a typed, paginated SearchResult for a specific content category using a SearchFilter constant.

YouTube.searchSummary()

Returns a SearchSummaryPage with results bucketed into labelled sections — songs, videos, albums, artists, and more.

YouTube.searchSuggestions()

Returns autocomplete query strings and recommended YTItem objects as the user types.

Basic search with a filter

YouTube.search(query, filter) sends a query to the InnerTube /search endpoint scoped to a specific content type. It returns Result<SearchResult>, where SearchResult carries a List<YTItem> and an optional continuation token for paging.

Available SearchFilter constants

ConstantContent type
SearchFilter.FILTER_SONGAudio tracks
SearchFilter.FILTER_VIDEOMusic videos
SearchFilter.FILTER_ALBUMAlbums and EPs
SearchFilter.FILTER_ARTISTArtist channels
SearchFilter.FILTER_FEATURED_PLAYLISTYouTube Music editorial playlists
SearchFilter.FILTER_COMMUNITY_PLAYLISTUser-created playlists
SearchFilter.FILTER_PODCASTPodcast shows
SearchFilter.FILTER_EPISODEIndividual podcast episodes
SearchFilter.FILTER_PROFILEUser profiles
import com.metrolist.innertube.YouTube
import com.metrolist.innertube.YouTube.SearchFilter

suspend fun searchSongs(query: String) {
    val result = YouTube.search(query, SearchFilter.FILTER_SONG)

    result.onSuccess { searchResult ->
        searchResult.items.forEach { item ->
            println("${item.title}${item.id}")
        }
        // Store the continuation token to load more results later
        val nextPage = searchResult.continuation
    }.onFailure { error ->
        println("Search failed: ${error.message}")
    }
}

Search summary

YouTube.searchSummary(query) performs an unfiltered search and automatically groups the results into labelled SearchSummary sections. The sections are sorted in a fixed order: Top result → Songs → Videos → Albums → Artists → Playlists → Podcasts → Episodes → Profiles. This is the right call when building a “top results” view.
import com.metrolist.innertube.YouTube

suspend fun showTopResults(query: String) {
    YouTube.searchSummary(query).onSuccess { page ->
        page.summaries.forEach { summary ->
            println("=== ${summary.title} ===")
            summary.items.forEach { item ->
                println("  ${item.title}")
            }
        }
    }
}
SearchSummaryPage merges sections with identical titles that appear in separate shelf renderers before sorting, so duplicate section headers are deduplicated automatically.

Pagination with continuation tokens

Both search() and searchSummary() can return more results than fit in a single response. When SearchResult.continuation is non-null, pass it to YouTube.searchContinuation() to fetch the next page. Keep paging until continuation is null or the returned items list is empty.
import com.metrolist.innertube.YouTube
import com.metrolist.innertube.YouTube.SearchFilter

suspend fun fetchAllSongs(query: String): List<com.metrolist.innertube.models.YTItem> {
    val allItems = mutableListOf<com.metrolist.innertube.models.YTItem>()

    var result = YouTube.search(query, SearchFilter.FILTER_SONG).getOrThrow()
    allItems += result.items

    while (result.continuation != null) {
        result = YouTube.searchContinuation(result.continuation!!).getOrThrow()
        if (result.items.isEmpty()) break
        allItems += result.items
    }

    return allItems
}

Search suggestions

YouTube.searchSuggestions(query) returns a SearchSuggestions object with two fields:
  • queries: List<String> — autocomplete query strings to show in a dropdown
  • recommendedItems: List<YTItem> — fully-formed YTItem objects (typically songs or artists) recommended by YouTube Music
import com.metrolist.innertube.YouTube

suspend fun autocomplete(partialQuery: String) {
    YouTube.searchSuggestions(partialQuery).onSuccess { suggestions ->
        // Show text completions
        suggestions.queries.forEach { q -> println("Suggestion: $q") }

        // Show rich recommended items (songs, artists, etc.)
        suggestions.recommendedItems.forEach { item ->
            println("Recommended: ${item.title} [${item::class.simpleName}]")
        }
    }
}

Filtering results in-memory

Once you have a List<YTItem>, two extension functions defined on YTItem let you apply additional client-side filters before presenting results to the user.

filterExplicit(enabled)

Removes items whose explicit flag is true. Pass enabled = false to keep the list unchanged (useful for toggling off a parental-controls setting without branching your UI code).

filterVideoSongs(disableVideos)

Removes SongItem entries whose isVideoSong property is true (i.e. items with a non-ATV musicVideoType). Pass disableVideos = false to keep music videos in the list.
import com.metrolist.innertube.YouTube
import com.metrolist.innertube.YouTube.SearchFilter
import com.metrolist.innertube.models.filterExplicit
import com.metrolist.innertube.models.filterVideoSongs

suspend fun searchCleanAudio(query: String, hideExplicit: Boolean, hideVideos: Boolean) {
    YouTube.search(query, SearchFilter.FILTER_SONG).onSuccess { result ->
        val filtered = result.items
            .filterExplicit(enabled = hideExplicit)
            .filterVideoSongs(disableVideos = hideVideos)

        filtered.forEach { item -> println(item.title) }
    }
}
Both extension functions are generic over <T : YTItem>, so they preserve the concrete list element type — a List<SongItem> stays a List<SongItem> after filtering.

Complete example

import com.metrolist.innertube.YouTube
import com.metrolist.innertube.YouTube.SearchFilter
import com.metrolist.innertube.models.SongItem
import com.metrolist.innertube.models.filterExplicit
import com.metrolist.innertube.models.filterVideoSongs

suspend fun fullSearchExample(query: String) {
    // 1. Get autocomplete suggestions
    YouTube.searchSuggestions(query).onSuccess { suggestions ->
        println("Query suggestions: ${suggestions.queries.take(5)}")
    }

    // 2. Run a typed search
    var result = YouTube.search(query, SearchFilter.FILTER_SONG).getOrThrow()

    // 3. Apply in-memory filters
    val songs = result.items
        .filterIsInstance<SongItem>()
        .filterExplicit(enabled = true)
        .filterVideoSongs(disableVideos = true)

    songs.forEach { song ->
        println("${song.title} by ${song.artists.joinToString { it.name }} — ${song.duration}s")
    }

    // 4. Page to next results
    if (result.continuation != null) {
        result = YouTube.searchContinuation(result.continuation!!).getOrThrow()
        result.items.forEach { println("More: ${it.title}") }
    }

    // 5. Get a summary view for the same query
    YouTube.searchSummary(query).onSuccess { page ->
        println("Summary sections: ${page.summaries.map { it.title }}")
    }
}

Build docs developers (and LLMs) love