Skip to content

Providers Reference

In this page

Review the capabilities, rate limits, bridge IDs, and behaviors of the retail providers in the hydration pipeline.

Where this lives in the code

  • config/providers
  • src/MediaEngine.Providers/Adapters
  • src/MediaEngine.Providers/Workers
  • config/pipelines.json

What is this document? A complete reference of every retail provider in the Tuvima Library pipeline - what they accept as search parameters, what they return, and how their output feeds into Stage 4 (Wikidata) resolution. This is the authoritative source for provider capabilities.


How Providers Fit Into the Pipeline

The provider portion of ingestion maps to the numbered stages shown on the Ingestion page:

  1. Stage 3 (Retail Match): Retail providers search for the media item using file metadata. They return primary cover/poster evidence, descriptions, ratings, and - critically - bridge IDs (ISBN, TMDB ID, etc.) that uniquely identify the item on external platforms.

  2. Stage 4 (Wikidata): The Wikidata Reconciliation adapter uses those bridge IDs to resolve the item’s Wikidata QID. Each bridge ID maps to a Wikidata property code (for example, ISBN-13 maps to P212). Stage 4 is strict-gated behind Stage 3: no safe retail match means no automatic Wikidata attempt. A Stage 4 request also needs at least one real bridge ID; title and creator hints are sent as ranking context, not as a broad title-only fallback.

  3. Stage 8 (Artwork): TMDB refreshes ranked movie and TV backgrounds, title logos, poster variants, and season artwork after a TMDB bridge ID is available. It does not replace a user-selected asset.

Retail providers are a rich data source for matching - descriptions, narrator data, ratings, and cover art similarity are all used to rank candidates against file metadata. Wikidata is the authority for final canonical values (title, author, year, genre, series).


Provider Summary

ProviderMedia TypesAuth RequiredRate LimitLanguage StrategyStatus
Apple APIBooks, Audiobooks, MusicNone500ms throttleLocalized (user language)Active
TMDBMovies, TVAPI key query parameter500ms throttle, max 1 concurrentLocalized (user language)Active (requires key)
TheTVDBTVProject or administrator key (an administrator-set key override is used in place of the project key)Configured provider throttleLocalized (user language)First TV identity source when connected
MusicBrainzMusicNone1 request/sec, max 1 concurrentSource (English only)Active music identity
Comic VineComicsAPI key500ms, max 1 concurrentSource (English only)Active (requires key)
LRCLIBMusicNoneConfigured provider throttleSourceText-track provider
SubDLMovies, TVPersonal API keyConfigured provider throttleSourceOptional text-track provider

Query Parameters - What We Send

Provider search is defined in config/providers/*.json, with grouped worker paths for TV and for Apple-led music chains when Apple is configured first. Most providers accept one primary search term; Apple title searches include creator text through query_template when available. The returned candidates are still validated afterward by RetailMatchScoringService.

API credentials are config-file data. Base provider definitions live in config/providers/*.json; optional secret overlays live in config/secrets/{provider}.json and are applied by ConfigurationDirectoryLoader on LoadProvider and LoadAllProviders. A blank http_client.api_key in the base provider file does not mean the effective runtime key is missing if a matching secrets file exists.

Active Retail Lookup Matrix

Media typeProviderSearch or lookup strategyLookup inputsScoring inputs
BooksApple APIISBN lookup, Apple Books ID lookup, ebook searchisbn, apple_books_id, then title plus author in the Apple search term.Title, author, year/date, format, description/publisher/page-count cross-checks, cover similarity.
AudiobooksApple APIApple Books ID lookup, audiobook searchapple_books_id, then title plus author in the Apple search term.Title, author, narrator-in-description, year/date, duration, format, cover similarity.
MusicMusicBrainz, then Apple APIMusicBrainz recording/release search, then Apple track/album enrichmenttitle plus artist/composer/author and album hints for MusicBrainz; Apple uses title/artist/album and Apple collection IDs after identity.Track title, artist/composer/author, album, year/date, track number, duration, format, cover similarity.
MoviesTMDBMovie searchtitle; year when available; api_key; locale.Title, year, local director/writer/author evidence, format, genre/description cross-checks, poster similarity.
TVTheTVDB, then TMDBTheTVDB show/episode lookup with TMDB fallback and artworkshow_name, selected episode order, TheTVDB show/episode IDs where known; TMDB show ID for supported fallback/artwork.Episode title, show/series, provider episode ID, year, format, poster/still similarity.
ComicsComic VineIssue search, volume searchtitle for issue search; series for volume search; api_key.Title, series, issue number or series position, writer/author/illustrator, year, format, cover similarity.

Per-Provider Search Strategies

Apple API

StrategyPriorityRequired FieldsURL PatternMedia Types
ISBN Lookup0 (highest)isbn/lookup?isbn={isbn}Books
Apple ID Lookup1apple_books_id/lookup?id={apple_books_id}&country={country}&lang={lang}_{country}Books, Audiobooks
Ebook Search2title/search?term={title} {author}&entity=ebook&limit={limit}&country={country}&lang={lang}_{country}Books
Audiobook Search2title/search?term={title} {author}&entity=audiobook&limit={limit}&country={country}&lang={lang}_{country}Audiobooks
Music Track Search2title/search?term={title} {artist}&entity=musicTrack&limit={limit}&country={country}&lang={lang}_{country}Music
Music Album Search3title/search?term={artist} {title}&entity=album&limit={limit}&country={country}&lang={lang}_{country}Music
Music Album Lookup4apple_music_collection_id/lookup?id={apple_music_collection_id}&entity=song&country={country}&lang={lang}_{country}Music

Notes: ISBN lookup is exact match (1 result). Book and audiobook search returns up to 25 results and fetches the top 5. For music, Apple runs after the configured MusicBrainz identity step and supplies cover art, retail album metadata, genre/year, and Apple source links. Cover art URL transforms remove Apple’s size constraints for higher resolution.

File languages written as names (English), ISO 639-2 codes (eng) or culture codes (en-US) are normalised to two-letter codes. Apple’s lang must be a real language-country pair; otherwise English is used. Apple results from an ISBN lookup are trusted as the exact edition, while search results are accepted only when the file language matches the storefront language.

TMDB

StrategyPriorityRequired FieldsURL PatternMedia Types
Movie Search1title/search/movie?query={title}&year={year}&include_adult=false&language={lang}-{country}&page=1Movies
TV Search1title/search/tv?query={title}&first_air_date_year={year}&include_adult=false&language={lang}-{country}&page=1TV
TV Season Episodes2tmdb_id, season_number/tv/{tmdb_id}/season/{season_number}?language={lang}-{country}TV

Notes: Year is optional but included when available from file metadata. TV jobs are grouped by show and season: the worker searches the show, fetches show details, then fetches the season episode list and distributes episode-level claims to queued files. Returns poster paths that are expanded to https://image.tmdb.org/t/p/w500{path}.

A Movies-library item with no TMDB movie match is checked against TMDB’s TV catalogue. A strong miniseries or short-season match is never applied automatically; it becomes a Review Queue suggestion, “Found as a TV title”, with Move to TV, Search again, or Keep as unmatched film. Move to TV re-files the item under TV without moving the file: when TMDB lists the show’s parts as one season of at most six episodes numbered from Episode 1, the file covers all of them (for example Season 1, Episodes 1 to 3); otherwise it falls back to Specials (Season 0, Episode 1) and the item’s History records why.

MusicBrainz

StrategyPriorityRequired FieldsURL PatternMedia Types
Recording Album Search1title/recording?query={query}&fmt=json&limit={limit}Music
Release Search2title/release?query={query}&fmt=json&limit={limit}Music

Notes: MusicBrainz is the default first Stage 1 provider for music. It identifies recordings and album/release containers before Apple enrichment runs. Its configured searches combine title with artist/composer/author where available, while album and year remain ranking and scoping signals. Recording IDs stay track-scoped; release and release-group IDs stay album-scoped.

For MusicBrainz and Apple Music matches, a track keeps its tagged album. A release is only applied to the album when its title matches the album tag.

Comic Vine

StrategyPriorityRequired FieldsURL PatternMedia Types
Issue Search1title/search/?query={title}&resources=issue&limit={limit}Comics
Volume Search2series/search/?query={series}&resources=volume&limit={limit}Comics

Notes: Comic Vine supplies comic issue and volume metadata, including cover art and Comic Vine bridge identifiers. Series and issue hints are used for search and post-search ranking. Exact series + issue number + volume context is authoritative for comics; issue title wording is not allowed to reject an otherwise exact run/issue match. Accepted issue matches write issue-scoped fields (issue_title, issue_description, and issue_source_url) so issue detail pages do not reuse the parent series description as an issue synopsis.

When an accepted issue match includes a volume ID, the Engine performs a volume lookup and records volume-scoped sequence facts such as issue count, start year, publisher, and sequence_total_scope = MainSequence. Comic shelves should use the volume/run identity, not an individual issue ID or a same-name title match. When issue lookup fails but a Comic Vine volume strongly matches series and structural context, the Engine may accept the volume/run as the retail identity without inventing an issue ID. Stage 4 can then roll up to a clearly scoped series/run Wikidata QID using wikidata_qid_scope = series and qid_resolution_method = comic_series_rollup.

LRCLIB and SubDL

LRCLIB and SubDL provide lyrics and subtitle/text-track data. They do not decide identity, do not unlock Wikidata resolution, and do not participate in retail candidate scoring. SubDL searches matched movies by TMDB movie ID and owned TV episodes by a verified TheTVDB-to-TMDB episode link; the TMDB season and episode numbers are used when catalog numbering differs. Existing OpenSubtitles tracks remain local and playable after that provider is retired.

Choosing and correcting lyrics. In the player’s lyrics panel, the options menu has Look for lyrics again, Not right? Find another and This one is wrong. Find another asks the switched-on sources live (the list is never stored) and shows each result’s source, whether it is timed to the song, and a short preview; picking one replaces the preferred lyrics and keeps the previous version for This one is wrong, which also stops that result being offered again for the same track. The Engine decides who may use these; the panel only shows what comes back. When no lyrics source is switched on, the panel says so, and administrators get a link to Plugins.

Writing lyrics beside the song. When write-back is on for a library, the preferred lyrics are saved as an .lrc file (timed) or .txt file (plain) next to the song. Original media files are never changed, folders that are read-only or held are skipped, and a lyrics file the Library did not write is never overwritten.

Sequence And Artwork Responsibilities

Media typePreferred sequence sourceArtwork display source
Books/AudiobooksApple retail sequence when available; otherwise Wikidata manifest if the container is sequence-compatible.Managed asset from accepted Apple/provider cover, then placeholder after artwork settles.
MusicMusicBrainz recording/release identity first, then Apple album/artwork enrichment.Managed asset from the accepted Apple source; no direct provider URL after settlement.
MoviesTMDB movie collection for ordered film collections; Wikidata franchise context stays broader discovery context.Managed TMDB posters, backdrops, and title logos.
TVTMDB show/season/episode details.Managed TMDB show and season art; episode stills continue to use the existing TMDB episode retrieval.
ComicsComic Vine volume/run and issue metadata.Managed Comic Vine cover.

Provider descriptions and long-form metadata should carry source attribution when surfaced: provider name, source title, source URL, license name, license URL, retrieval timestamp, and whether the display value was modified or summarized. Wikipedia text is attributed as Wikipedia/CC BY-SA. Comic Vine issue synopses are attributed as Comic Vine issue synopses governed by the Comic Vine API Terms, not as Creative Commons text.


Response Fields - What We Extract

Each provider’s config defines a field_mappings array that maps JSON response paths to claim keys. These become ProviderClaim objects (key, value, confidence) stored in metadata_claims.

Extraction Summary

ProviderActive mediaMain claims extractedBridge claims extracted
Apple APIBooks, Audiobooks, MusicTitle, author/artist, year, cover, description, genre, rating for books, album, track/disc counts, track number, duration. Claim confidence is usually 0.70 to 0.90 depending on field and media type.apple_books_id, apple_music_id, apple_music_collection_id, apple_artist_id.
TMDBMovies, TVTitle, year, cover, description, short description, rating, original language, genre, network. Claim confidence is usually 0.80 to 0.90.tmdb_id.
Comic VineComicsCandidate title for matching, issue_title, issue_description, issue_source_url, series, issue number, creator credits, cover, year, series position, volume sequence facts. Claim confidence is usually 0.70 to 1.00.comic_vine_id, comic_vine_volume_id.
MusicBrainzMusicTitle, artist/author, album, year, track count, MusicBrainz IDs, ISRC.MusicBrainz artist/work/release/recording/release-group IDs when present.

Numbers in provider JSON represent confidence values assigned to extracted claims when the provider is enabled.

Value Transforms

The ValueTransformCatalog applies transformations during extraction:

TransformPurposeUsed By
regex_replaceStrip image size suffixes from cover URLsApple API
strip_htmlClean HTML tags from descriptionsApple API, Comic Vine
to_stringConvert numeric values such as IDs and ratings to stringsApple API, TMDB, Comic Vine
url_templateConstruct full image URLs from partial pathsTMDB, MusicBrainz
first_n_chars(4)Extract 4-digit year from date stringsApple API, TMDB, MusicBrainz, Comic Vine
array_joinJoin array elements into comma-separated stringsApple API, TMDB, MusicBrainz

Bridge IDs - What Feeds Stage 4

Bridge IDs are external platform identifiers that the Wikidata Reconciliation adapter uses to resolve the item’s Wikidata QID after Stage 3 has produced a safe retail match. Each bridge ID maps to a Wikidata property code.

Bridge IDs by Provider

ProviderBridge IDClaim KeyConfidenceWikidata Property
Apple APIApple Books IDapple_books_id0.95P6395
Apple APIApple Music Track IDapple_music_id0.95P10110
Apple APIApple Music Collection IDapple_music_collection_id0.95P2281
Apple APIApple Artist IDapple_artist_id0.90P2850
TMDBTMDB IDtmdb_id1.0P4947 (movies) / P4983 (TV)
Comic VineComic Vine IDcomic_vine_id0.95P5905
Comic VineComic Vine Volume IDcomic_vine_volume_id0.95Provider/run evidence; used for scoped comic series rollup when issue QID is absent
MusicBrainzMusicBrainz IDsmusicbrainz_id, musicbrainz_recording_id, musicbrainz_release_group_idprovider-dependentP434/P435/P436/P5813/P4404 depending on ID type
Embedded book/comic evidenceISBN and retained historical identifiersisbn, isbn_13, isbn_10provider-dependentP212/P957; historical bridge IDs remain evidence only

Stage 4 Resolution Flow Per Bridge ID

The Reconciliation adapter is now a thin orchestrator over Tuvima.Wikidata v3.0’s BridgeResolutionService.

  1. Bridge request build: The adapter converts each WikidataResolveRequest into a BridgeResolutionRequest with bridge IDs, media kind, title/creator/year/series hints, language, custom P-code mappings, and rollup preference.
  2. Direct lookup: The package groups (propertyId, normalizedValue) lookups so duplicate ISBN/TMDB/Apple/MusicBrainz/ComicVine IDs share one Wikidata query.
  3. Edition awareness: The package walks P629 for edition/release-to-work rollups and can return both the resolved entity QID and canonical work QID plus the relationship path.
  4. Media-specific bridge mapping: TMDB, Apple, TVDB, MusicBrainz, and ComicVine keys are mapped to official Wikidata properties inside the package; retained historical keys are evidence only and do not activate a provider.
  5. Strict bridge gate: If a request has no real bridge IDs, the adapter does not build a Stage 4 bridge request. Title-only automatic requests are skipped.
  6. Claim and diagnostics follow-up: After every successful resolution, the adapter calls ExtendAsync over the known bridge P-codes to populate WikidataResolveResult.Claims and CollectedBridgeIds, and it also carries BridgeDiagnostics, ranked candidates, and rollup details from the package result.

Manual Wikidata searches from the editor and automated bridge resolution both flow through ReconciliationAdapter before calling Tuvima.Wikidata, but manual user searches are not the same as automatic Stage 4 fallback. Exact QID searches such as Q155653 are passed through as identity lookups, so the package fetches the entity directly and still applies configured media type constraints.

Wikidata Lookup Matrix

The bridge worker sends these fields to Wikidata after Stage 3 has produced a retail match and at least one bridge ID.

Media typeBridge IDsHintsMedia kind / filter
Booksisbn, isbn_13, isbn_10, asin, apple_books_id, goodreads_idTitle, author, year, languageBook/literary work, edition-aware
Audiobooksapple_books_id, isbn, asin, MusicBrainz IDsTitle, author, year, languageAudiobook, edition-aware, prefers edition
MusicMusicBrainz recording/release/release-group IDs first; Apple Music IDs as secondary hintsAlbum, artist, composer/author fallback, track title, year, languageRecording/track when safely bridgeable; album when only release-group identity is known
Moviestmdb_id, imdb_id, Apple TV movie IDsTitle, creator if canonicalized, year, languageMovie/film
TVtmdb_id, imdb_id, tvdb_id, Apple TV show/episode IDsShow name or series, creator if canonicalized, year, languageTV series
Comicscomic_vine_id, comic_vine_volume_id, gcd_id, isbnSeries plus title, series title, writer/author/illustrator, year, languageComic issue when available; scoped comic series/run when issue QID is absent

Retail Match Scoring

After a provider returns results, the RetailMatchScoringService scores each candidate against file metadata:

Scoring Weights

FieldWeightHow Scored
Title0.45Fuzzy string similarity (Levenshtein distance)
Author/Creator0.35Fuzzy string similarity
Year0.10Exact = 1.0, off-by-1 = 0.8, off-by-2+ = 0.3
Format0.10Exact media type match

Boosters

BoosterConditionBoost
Cross-fieldNarrator found in description, genre overlapVariable
Cover art (strong)pHash similarity > 0.8+0.10
Cover art (moderate)pHash similarity > 0.6+0.05

Cover similarity can boost an already plausible candidate, but it cannot rescue weak title or creator evidence on its own.

Thresholds

ThresholdValueResult
Auto-accept>= 0.90Match accepted automatically and allowed to proceed to Wikidata
Ambiguous0.65 - <0.90Review queue (RetailMatchAmbiguous)
Failed< 0.65 or no resultsUnmatched: the file stays where it is, plays with its file name and tags, and is looked up again later; no Needs Review item

Additional contradiction gates apply before auto-accept. Weak creator agreement can cap a candidate to review, grouped TV auto-accept requires exact show/season/episode agreement, and grouped music auto-accept requires track-number or duration corroboration.

Cover Art Matching

Embedded cover art from the file is perceptually hashed (aHash - 64-bit fingerprint via 8x8 grayscale resize). When retail provider cover art is downloaded, it’s hashed and compared. The Hamming distance produces a similarity score (0.0-1.0) that feeds into the scoring composite as a confidence boost.


Provider Configuration

All provider configs live in config/providers/ as individual JSON files. Each is self-contained with connection details, search strategies, response mappings, and bridge ID preferences. Adding a new REST+JSON provider is a zero-code operation: create a config file, restart the Engine.

Declarative blocks

Beyond search_strategies and field_mappings, a provider file may carry the blocks below. They are how the shipped providers work; none of them is tied to a provider name in code.

BlockWhat it declaresShipped use
auth, apiSign-in request, token lifetime and delivery; named endpoints with argument checks, paging and caching; allowed hoststvdb.json
flowsfetch and search as step programs over the named endpointstvdb.json
follow_upsExtra lookups after a match and the rules that turn them into claimstmdb.json (detail, collection), comicvine.json (volume details, issue manifest)
candidate_rankingFacts, matching, scoring terms, preferred-run search and ordering for near-identical resultscomicvine.json
result_rulesClaim rules run on the matched resultcomicvine.json (creator credits)
search_strategies[].claim_rules, .role, .extra_field_aliasesDrop, derive and language-guard claims; what a strategy returnscomicvine.json
sequence_manifestThe paged request a paged_sequence rule readscomicvine.json
text_track (with adapter_type: "text_track")Subtitle and lyrics search, download, archive limits, error mappingsubdl.json, lrclib.json
registration_orderA positive number registers the provider after the ordinary file-based providers and the built-in reconciliation provider, lowest number first; registration order decides which provider answers first. Default 0 registers with the ordinary providers.tvdb.json

All blocks are validated when the file loads (unknown properties and bad shapes name their path) and are documented in config/schemas/providers/provider.schema.json. See How to add a metadata provider.

Config File Structure

{
"id": "UUID",
"name": "provider_name",
"display_name": "Human Name",
"enabled": true,
"version": "1.0",
"domain": "media_domain",
"media_types": ["Type1", "Type2"],
"entity_types": ["Work", "MediaAsset"],
"base_url": "https://api.example.com",
"weight": 0.8,
"language_strategy": "localized|source|both",
"auth": { ... },
"rate_limit": { "throttle_ms": 500, "max_concurrent": 2 },
"search_strategies": [ ... ],
"field_mappings": [ ... ],
"preferred_bridge_ids": { "MediaType": ["id1", "id2"] }
}

See config/providers/ for complete examples of each provider.

Sources From Plugins

A switched-on JSON plugin can supply metadata sources (the metadata_sources part of its declarative section, written in the same format as a file in config/providers/). When the plugin is switched on, the Library writes each source into config/providers/ as plugin_<plugin id>_<source name>.json; when the plugin is switched off or removed, the file is removed. The plugin only suggests: the Library sets the name, the identity, the weight (0.5, below every source that ships with the Library), the order (after the shipped sources), and removes any key, icon or onboarding. Only config_driven and text_track sources are accepted, every address must be one the plugin declared under network, and the plugin must hold the network.http permission; anything else is left out and logged. A source that asks for its own key is not supported. Sources are read when the Engine starts, so the Plugins page shows “Restart the Engine” after one is switched on or off. Existing matches are never changed by adding or removing a source, and nothing is matched again unless the person asks.

The Plugins page lists every source (built in or from a plugin) with what it supplies, and a comparison of any two. The Metadata providers page asks for confirmation before a source is switched off and says what would have no source. First-run setup lists what the chosen media needs and which sources supply it. All of these read GET /plugin-sources and the wording comes from one shared list of phrases (ProviderCapabilityPhrases).