> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vyla.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Reference

> Scrape video streams, fetch subtitles, retrieve download links, and monitor provider health directly from your Node.js application.

The **Vyla SDK** (`@vyla-entertainment/sdk`) is a server-side JavaScript/TypeScript framework that provides direct access to Vyla's stream scrapers, health probes, download resolvers, and subtitle providers.

By embedding the SDK directly into your backend application, you execute scrapers locally within your own environment. This is an alternative to self-hosting the full Vyla API server — the SDK gives you the same streaming capabilities but embedded directly in your Node.js application, eliminating REST API rate limits, reducing network latency, and giving you total control over execution timeouts, IP forwarding, and headers.

<Note>
  The SDK repository is public and can be used independently of the self-hosted API server. If you prefer to embed streaming functionality directly into your existing Node.js application rather than running a separate API server, the SDK is the recommended approach.
</Note>

***

## Features

* **Direct-to-Client Playback**: Scraped streams link directly to source CDNs. No proxy server overhead required unless specified by provider headers.
* **Built-In Health Probing**: Monitor latency and uptime per provider with built-in health check utilities.
* **Automated Anime Sub/Dub Routing**: Automatically configures audio track requirements (`sub` vs `dub`) based on provider naming conventions.
* **Multi-Source Subtitle Aggregation**: Merges subtitle tracks from multiple redundant subtitle mirrors into a unified VTT/SRT format.
* **Metadata Fallbacks**: Automatically maps TMDB IDs to external IDs (such as IMDB and AniList) for smooth stream lookups.
* **Self-Contained**: No need to deploy a separate API server — all streaming functionality runs within your existing Node.js application.

***

## Installation

Install the package into your Node.js backend using your package manager of choice:

<CodeGroup>
  ```bash npm theme={null}
  npm install @vyla-entertainment/sdk
  ```

  ```bash pnpm theme={null}
  pnpm install @vyla-entertainment/sdk
  ```

  ```bash yarn theme={null}
  yarn add @vyla-entertainment/sdk
  ```
</CodeGroup>

> **Note**: Node.js **v18+** is required due to modern standard `fetch` and `AbortSignal.timeout` usage.

***

## Initialization

Initialize the `VylaSDK` client by supplying your **TMDB API Key**. The key resolves media metadata, validates movie/TV show IDs, and translates TMDB IDs into AniList IDs for anime sources.

You may optionally provide a pengu.uk manifest URL to enable the Pengu source.

```javascript theme={null}
import VylaSDK from "@vyla-entertainment/sdk";

const sdk = new VylaSDK({
  tmdbApiKey: process.env.TMDB_API_KEY, // Required for metadata resolution

  penguManifest: "" // Optional, get from pengu.uk
});
```

***

## Core Methods

### `getStream(key, id, s?, e?, clientIP?)`

Scrapes video stream URLs and playability headers for a specified provider key.

```javascript theme={null}
// Fetch a movie stream (TMDB ID: 155 - The Dark Knight)
const movieStream = await sdk.getStream("sourcename", "155");

// Fetch a TV show episode (TMDB ID: 1399, Season 1, Episode 1)
const tvStream = await sdk.getStream("sourcename", "1399", 1, 1);

// Pass client IP for providers that use geo-verification
const geoStream = await sdk.getStream("sourcename", "155", null, null, "203.0.113.195");
```

#### Parameters

| Parameter  | Type               | Required | Default | Description                                                                                   |
| :--------- | :----------------- | :------- | :------ | :-------------------------------------------------------------------------------------------- |
| `key`      | `string`           | **Yes**  | —       | Unique key identifier for the provider (e.g. `"sourcename"`, `"sourcename"`, `"sourcename"`). |
| `id`       | `string`           | **Yes**  | —       | TMDB media ID (e.g., `"155"`).                                                                |
| `s`        | `string \| number` | **No**   | `null`  | Season number (required for TV shows).                                                        |
| `e`        | `string \| number` | **No**   | `null`  | Episode number (required for TV shows).                                                       |
| `clientIP` | `string`           | **No**   | `null`  | End-user IP address forwarded for geo-restricted scrapers.                                    |

#### Example Response Format

```json theme={null}
{
  "url": "https://example-cdn.com/hls/manifest.m3u8",
  "quality": "auto",
  "isM3U8": true,
  "headers": {
    "Referer": "https://example.com/",
    "Origin": "https://example.com"
  },
  "allUrls": [
    {
      "url": "https://example-cdn.com/hls/manifest.m3u8",
      "quality": "1080p",
      "isM3U8": true
    }
  ]
}
```

***

### `getSubtitles(id, s?, e?)`

Fetches subtitle files aggregated across multiple subtitle backend mirrors (`v1`, `v2`, `febbox`). Returns clean VTT and SRT tracks.

```javascript theme={null}
// Fetch movie subtitles
const movieSubs = await sdk.getSubtitles("155");

// Fetch TV show episode subtitles
const tvSubs = await sdk.getSubtitles("1399", 1, 1);
```

#### Parameters

| Parameter | Type               | Required | Default | Description                             |
| :-------- | :----------------- | :------- | :------ | :-------------------------------------- |
| `id`      | `string`           | **Yes**  | —       | TMDB media ID.                          |
| `s`       | `string \| number` | **No**   | `null`  | Season number (required for TV shows).  |
| `e`       | `string \| number` | **No**   | `null`  | Episode number (required for TV shows). |

#### Example Response Format

```json theme={null}
[
  {
    "label": "English",
    "file": "https://sub.vdrk.site/v1/vtt/movie/155/English.vtt",
    "type": "vtt",
    "source": "v1"
  },
  {
    "label": "Spanish",
    "file": "https://fed-subs.pstream.mov/subtitles/spanish.srt",
    "type": "srt",
    "source": "febbox"
  }
]
```

***

### `getDownloads(id, s?, e?)`

Fetches direct downloadable media files (MP4/MKV) paired with resolution and file size descriptors.

```javascript theme={null}
// Movie downloads
const downloads = await sdk.getDownloads("155");

// TV Episode downloads
const tvDownloads = await sdk.getDownloads("1399", 1, 1);
```

#### Example Response Format

```json theme={null}
[
  {
    "url": "https://download-node.com/file/the-dark-knight-1080p.mp4",
    "quality": "1080p",
    "size": "2.14 GB",
    "format": "MP4"
  }
]
```

***

## Provider & Health Management

### `getSources(excludeDisabled?)`

Retrieves provider configurations registered in the SDK.

```javascript theme={null}
// Get all sources including temporarily disabled ones
const allSources = sdk.getSources(false);

// Get only active/enabled sources
const activeSources = sdk.getSources(true);
```

#### Parameters

| Parameter         | Type      | Required | Default | Description                                                               |
| :---------------- | :-------- | :------- | :------ | :------------------------------------------------------------------------ |
| `excludeDisabled` | `boolean` | **No**   | `false` | When `true`, filters out providers marked as disabled (`disabled: true`). |

***

### `probeSource(key)`

Executes a health ping test against a single provider to determine current availability and latency using a probe payload (`TMDB ID: 155`).

```javascript theme={null}
const health = await sdk.probeSource("vidrock");
console.log(health);
// Output: { ok: true, ms: 840 }
```

***

### `probeAllSources()`

Executes health tests in parallel across all non-disabled provider modules.

```javascript theme={null}
const results = await sdk.probeAllSources();
console.log(results);
```

#### Example Response Format

```json theme={null}
{
  "sourcename1": { "ok": true, "ms": 420 },
  "sourcename2": { "ok": true, "ms": 1150 },
  "sourcename3": { "ok": false, "ms": null }
}
```

***

## Provider Metadata Properties

When calling `getSources()`, each provider entry returns metadata describing its features and streaming behavior:

```javascript theme={null}
{
  key: 'example',
  label: 'Example',
  sourceFile: 'example',
  proxyParam: 'ex',
  timeout: 20000,
  jitter: 800,
  retries: 3,
  multiUrl: true,
  skipProxy: false,
  cdnHeaders: [{
    pattern: /./,
    headers: {
      Referer: 'https://example.com/',
      Origin: 'https://example.com'
    }
  }]
}
```

### Property Reference

| Field        | Type      | Description                                                                                                                                              |
| :----------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`        | `string`  | Unique identifier used in `getStream()` and `probeSource()`.                                                                                             |
| `label`      | `string`  | Human-readable name for UI display.                                                                                                                      |
| `skipProxy`  | `boolean` | When `true`, stream URLs can be fed directly to web video players (e.g., HLS.js, Video.js) without needing an intermediate backend proxy.                |
| `multiUrl`   | `boolean` | Indicates whether the source returns multiple stream resolution choices.                                                                                 |
| `timeout`    | `number`  | Internal request timeout threshold in milliseconds.                                                                                                      |
| `retries`    | `number`  | Max automatic retry attempts executed by health/stream scrapers.                                                                                         |
| `cdnHeaders` | `Array`   | Regex pattern matching rules detailing required request headers (`Referer`, `Origin`) needed to playback stream segments without `403 Forbidden` errors. |
| `disabled`   | `boolean` | Set to `true` if a source is down or undergoing maintenance.                                                                                             |

***

## Practical Express.js Backend Example

Here is an example showing how to serve stream links to your client web application while handling custom CDN playback headers and subtitle merging:

```javascript theme={null}
import express from "express";
import VylaSDK from "@vyla-entertainment/sdk";

const app = express();
const sdk = new VylaSDK({ tmdbApiKey: process.env.TMDB_API_KEY });

// Scrape stream route
app.get("/api/stream", async (req, res) => {
  const { provider, tmdbId, season, episode } = req.query;
  const clientIP = req.headers["x-forwarded-for"] || req.socket.remoteAddress;

  try {
    const streamData = await sdk.getStream(
      provider,
      tmdbId,
      season || null,
      episode || null,
      clientIP
    );

    if (!streamData || !streamData.url) {
      return res.status(404).json({ error: "No stream found for this provider" });
    }

    return res.json({
      success: true,
      provider,
      stream: streamData,
    });
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
});

// Fetch subtitles route
app.get("/api/subtitles", async (req, res) => {
  const { tmdbId, season, episode } = req.query;

  try {
    const subtitles = await sdk.getSubtitles(
      tmdbId,
      season || null,
      episode || null
    );

    return res.json({ subtitles });
  } catch (error) {
    return res.status(500).json({ subtitles: [] });
  }
});

app.listen(3000, () => console.log("Vyla SDK Server running on port 3000"));
```

## SDK vs Self-Hosted API

The SDK and the self-hosted API server provide the same streaming functionality but in different deployment models:

| Aspect            | SDK                          | Self-Hosted API              |
| ----------------- | ---------------------------- | ---------------------------- |
| **Deployment**    | Embedded in your Node.js app | Separate server process      |
| **Network**       | Direct source CDN access     | Built-in proxy for CORS      |
| **Rate Limiting** | None (you control it)        | Per-API-key limits           |
| **Setup**         | npm install + init           | Clone repo + configure       |
| **Use Case**      | Existing Node.js apps        | Standalone streaming service |

Choose the SDK if you want to integrate streaming directly into an existing Node.js application. Choose the self-hosted API if you want a standalone streaming service that can be used by multiple clients.
