# SDK quickstart
Install Vyla SDK, resolve a source, and build a safe server-side integration.
## Before you start Vyla SDK is for **server-side Node.js**. It contains provider integrations and makes outbound requests from the process where you install it. Do not import it into a browser bundle or expose provider results, credentials, or internal source keys directly to untrusted clients. You need Node.js 18 or later and, for sources that resolve title metadata, a TMDB API key. ## Install and initialize :::code-group ```bash [npm] npm install @vyla-entertainment/sdk ``` ```bash [pnpm] pnpm install @vyla-entertainment/sdk ``` ```bash [yarn] yarn add @vyla-entertainment/sdk ``` ::: ```javascript import VylaSDK from "@vyla-entertainment/sdk"; const vyla = new VylaSDK({ tmdbApiKey: process.env.TMDB_API_KEY, penguManifest: process.env.PENGU_MANIFEST }); ``` :::callout-warning Keep `TMDB_API_KEY` and any deployment configuration in server-side environment variables. Never commit them or send them to a client. ::: ## Resolve a movie First inspect active providers. Provider availability changes over time, so select a key from the running configuration instead of hard-coding a placeholder. ```javascript const providers = vyla.getSources(true); console.table(providers.map(({ key, label }) => ({ key, label }))); const provider = providers[0]; const result = await vyla.getStream(provider.key, 155); const candidates = result.allUrls ?? [result]; console.log(candidates.map(({ url, type, quality }) => ({ url, type, quality }))); ``` `155` is a TMDB movie ID. For an episode, include season and episode: ```javascript const result = await vyla.getStream(provider.key, 1396, 1, 1); ``` ## Read manga Search manga titles, retrieve chapter listings, and resolve reader-ready page images directly: ```javascript const search = await vyla.searchManga("Steel Ball Run", 1, 5); const firstResult = search.results[0]; const manga = await vyla.getManga(firstResult.id); const firstChapter = manga.chapters[manga.chapters.length - 1]; const chapterData = await vyla.getMangaChapter(manga.id, firstChapter.id); console.log(chapterData.pages.map(p => p.url)); ``` ## Make it resilient Provider results are inherently variable: a source can fail, time out, return more than one candidate, or be temporarily disabled. In production: 1. Probe sources or maintain a recent availability signal before choosing one. 2. Give every provider call a request deadline in your application. 3. Treat `allUrls` as fallback candidates, not a guarantee that every URL will play. 4. Return only the fields your client needs and validate requests at your own API boundary. 5. Cache and rate-limit at your boundary to avoid repeatedly triggering upstream work. ```javascript const health = await vyla.probeAllSources(); const usableKey = Object.entries(health).find(([, result]) => result.ok)?.[0]; if (!usableKey) throw new Error("No providers are currently available"); const stream = await vyla.getStream(usableKey, 155); ``` ## Next steps - Read the complete [SDK reference](/sdk) for methods and return shapes. - Learn provider flags, timeout behavior, and source keys in [Providers](/concepts/providers). - Choose [Stream API](/stream-api/overview) only when an SSE HTTP interface better fits your client architecture.