YouVersion PlatformYouVersion Platform
PlatformContent LibraryDev Docs
CommunityPartnersSupport

YouVersion Platform

Build applications and integrate with the world's most popular Bible platform.

Platform Products

  • Platform Portal
  • Developer Documentation
  • App Management

Resources

  • Support
  • Press inquiries

Legal

  • Privacy Policy
  • Terms of Use

© 2026 YouVersion. All rights reserved.

  • Overview
  • API Reference
  • SDKs
  • Changelog
<  Back to Platform
SDK Introduction
Swift SDK
Kotlin SDK
    Quick StartComponents
    Guides
      SearchCopyright & AttributionMigrating to 3.0
JavaScript SDK
React SDK
React Native (Expo) SDK
Guides

Search

BibleReader includes search with nothing to configure — see Search in the reader. This guide is for apps building their own search UI on the search endpoints directly.

Requirements

  • platform-core 2.1.0 or later for YouVersionApi.search, and platform-reader 2.2.0 or later for search in BibleReader. Earlier versions have no search property, so the samples below will not compile against them.
  • A configured app key. Set up the SDK as shown in the Quick Start. The user does not have to be signed in.

To raise the versions in an existing project:

build.gradle.kts
dependencies { implementation(platform("com.youversion.platform:platform-bom:3.+")) implementation("com.youversion.platform:platform-core") implementation("com.youversion.platform:platform-ui") implementation("com.youversion.platform:platform-reader") }

The platform-bom version sets the version of every module, so raising it upgrades them together. Upgrading from 2.x crosses the 3.0 breaking changes; see Migrating to 3.0 before upgrading.

Choose a search method

All methods are suspend functions on YouVersionApi.search.

MethodReturnsUse case
unified(query, bibleId, languageRanges)SearchResultsTop verse references and related topics in one request
verses(query, bibleId)VerseSearchResultsVerse references with pagination
topics(query, languageRanges)TopicSearchResultsRelated topics and subtopics
suggestedQueries(query, languageRanges)List<SearchQuery>Suggestions while the user types
trendingQueries(languageRanges)List<SearchQuery>Queries many readers are running right now

Search for references and topics

Unified search requires both bibleId and languageRanges. The Bible version selects the text and language for verse results; the language preferences select the language for topic results.

Call search from a coroutine, such as one launched in viewModelScope:

SearchViewModel.kt
import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.youversion.platform.core.api.YouVersionApi import com.youversion.platform.core.api.YouVersionNetworkException import com.youversion.platform.core.search.models.SearchResults import java.io.IOException import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch class SearchViewModel : ViewModel() { private val _results = MutableStateFlow<SearchResults?>(null) val results: StateFlow<SearchResults?> = _results private val _error = MutableStateFlow<String?>(null) val error: StateFlow<String?> = _error private var searchJob: Job? = null fun search(query: String) { searchJob?.cancel() searchJob = viewModelScope.launch { _error.value = null try { _results.value = YouVersionApi.search.unified( query = query, bibleId = 3034, languageRanges = listOf("en"), ) } catch (e: IllegalArgumentException) { _error.value = "Check your search and try again." } catch (e: YouVersionNetworkException) { _error.value = "Search couldn't complete." } catch (e: IOException) { _error.value = "No connection. Try again when you're online." } } } }

An exception that escapes a coroutine in viewModelScope crashes the app, so catch search failures inside the coroutine. Cancel the previous search before starting a new one, so a slower, older response can't overwrite the newer query's results or error. Error handling describes each failure type.

Search returns references and metadata, without passage text. Each verse result in references is a single-verse BibleReference in the requested Bible version. Pass it to a Bible component, such as BibleCard, to fetch and display the passage with attribution. bibleId is the same Bible version id the rest of the SDK calls versionId.

Unified search returns one unpaginated set of top results grouped into references and topics. To limit the kinds of results, pass fields with "verses", "topics", or both; leave it empty to include both. Ask only for the kinds you display:

Code
YouVersionApi.search.unified( query = "faith", bibleId = 3034, languageRanges = listOf("en"), fields = listOf("topics"), )

Unified search has no pageSize, pageToken, or nextPageToken. Use verses to load more verse results.

Page through verse results

verses returns references in rank order, one page at a time. To load another page, pass the previous page's nextPageToken as pageToken, keeping the query, Bible version, intent, and page size the same:

Code
import com.youversion.platform.core.api.YouVersionApi import com.youversion.platform.core.search.models.SearchUserIntent suspend fun loadPage(pageToken: String? = null) = YouVersionApi.search.verses( query = "love", bibleId = 3034, userIntent = SearchUserIntent.text, pageSize = 25, pageToken = pageToken, ) val firstPage = loadPage() val secondPage = firstPage.nextPageToken?.let { token -> loadPage(token) }

Leave pageSize null to use the platform's default. A null nextPageToken means there are no more pages.

Find related topics

topics returns related topics without requiring a Bible version. Each SearchTopic contains a text label and a list of subtopics labels.

Code
import com.youversion.platform.core.api.YouVersionApi val results = YouVersionApi.search.topics( query = "faith", languageRanges = listOf("en"), ) results.topics.forEach { topic -> println(topic.text) topic.subtopics.forEach { subtopic -> println(subtopic) } }

Use a topic or subtopic label as the query for a new verse search with userIntent = SearchUserIntent.topical. Topic search is unpaginated — there is no page token and no total count.

Suggested and trending queries

As the user types, request suggestions for the partial query. When the search field is empty, you can show trending queries instead:

Code
import com.youversion.platform.core.api.YouVersionApi val suggestions = YouVersionApi.search.suggestedQueries( query = "lo", languageRanges = listOf("en"), ) val trending = YouVersionApi.search.trendingQueries(languageRanges = listOf("en"))

Debounce input changes and discard responses for outdated input before updating your suggestions.

Both methods return List<SearchQuery>. Each query has text and an optional source string, and the list is empty when the platform has nothing to offer. Only after the user selects a suggested or trending query should you run it through unified or verses to retrieve results.

Parameters

The SDK checks these constraints before sending a request and throws IllegalArgumentException if an argument breaks one.

ParameterConstraint
query1–100 grapheme clusters (characters as the user sees them, so an emoji counts as one) for unified, verses, and topics; non-empty for suggestedQueries
bibleIdGreater than zero
pageSize1 through 99, or null for the platform's default
languageRangesAt least one language range: a language tag or *

Language ranges

Pass languageRanges as a nonempty list, such as listOf("en-US", "en"), for unified search, topic search, suggestions, and trending queries. Use listOf("*") to match all languages. See Language ranges for language selection.

User intent

Unified and verse search accept a SearchUserIntent. The default is SearchUserIntent.unknown.

ValueUse case
SearchUserIntent.unknownLet the platform determine the intent
SearchUserIntent.referenceLook up a scripture reference, such as "John 3:16"
SearchUserIntent.textFind words or phrases in Bible text
SearchUserIntent.topicalFind verses related to a topic

The returned userIntent is nullable and describes the intent the platform inferred. The set of intents is open: the platform may return one this version of the SDK does not name, and it arrives intact in rawValue rather than failing the search. A when over it therefore needs an else branch:

Code
val heading = when (results.userIntent) { SearchUserIntent.reference -> "Passages" SearchUserIntent.topical -> "Topics" else -> "Results" }

Query corrections

Unified, verse, and topic results include correction metadata:

PropertyMeaning
didYouMeanA list of alternative spellings, offered alongside results for the query as written
searchInsteadForThe user's original wording, present only when the platform corrected the query and returned results for the correction

For example, a search for "watr" might return results for a correction along with the original wording:

Code
import com.youversion.platform.core.api.YouVersionApi val results = YouVersionApi.search.unified( query = "watr", bibleId = 3034, languageRanges = listOf("en"), ) results.searchInsteadFor?.let { original -> println("Search instead for $original") } results.didYouMean.forEach { alternative -> println("Did you mean $alternative?") }

Error handling

The error reasons and example in this section require platform-core 3.0 or later. If your app uses 2.x, follow Migrating to 3.0 before using this example.

Search reports failure in three ways:

FailureThrownMeaning
Invalid argumentIllegalArgumentExceptionAn argument broke a parameter constraint; no request was made
Error responseYouVersionNetworkExceptionThe platform answered with an error, or its response couldn't be read. reason says which, as described below
No responsejava.io.IOExceptionThe device is offline, DNS lookup failed, or the connection timed out. The SDK does not wrap these in YouVersionNetworkException

Use reason to decide what to tell the user:

ReasonMeaningWhat your app can do
RATE_LIMITEDToo many requests in a short timeRetry later. If retryAfter is set, wait at least that long
SERVER_ERRORThe platform had a temporary problemRetry later, waiting for retryAfter if it's set
REQUEST_REJECTEDThe platform won't accept this request, such as for a Bible version the app can't accessDon't retry the same request. Check the arguments, or the app's available Bibles
NOT_PERMITTEDThe app key is invalid or lacks accessDon't retry. Check the app key configuration
INVALID_RESPONSEThe response couldn't be readReport that search couldn't complete
REQUEST_FAILEDAny other error responseReport that search couldn't complete

More reasons may be added in later releases, so a when over reason needs an else branch.

Code
import com.youversion.platform.core.api.YouVersionApi import com.youversion.platform.core.api.YouVersionNetworkException import java.io.IOException try { val results = YouVersionApi.search.verses(query = userQuery, bibleId = 3034) showResults(results.references) } catch (e: IllegalArgumentException) { // Validate input against the parameter constraints before searching } catch (e: YouVersionNetworkException) { when (e.reason) { YouVersionNetworkException.Reason.NOT_PERMITTED -> showConfigurationError() YouVersionNetworkException.Reason.RATE_LIMITED, YouVersionNetworkException.Reason.SERVER_ERROR -> showTryAgainLater(e.retryAfter) else -> showSearchUnavailable() } } catch (e: IOException) { // No response arrived, so a retry may succeed showConnectionError() }

To call the same endpoints outside the SDK, see the search API guide.

Last modified on November 13, 2026
ComponentsCopyright & Attribution
On this page
  • Requirements
  • Choose a search method
  • Search for references and topics
  • Page through verse results
  • Find related topics
  • Suggested and trending queries
  • Parameters
    • Language ranges
    • User intent
    • Query corrections
  • Error handling
Kotlin
Kotlin
Kotlin
Kotlin
Kotlin
Kotlin
Kotlin
Kotlin
Kotlin