> ## 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.

# Test a Source

> Debug a single provider in isolation — get the raw URL, proxy URL, elapsed time, and error details.

Tests one specific provider for a given TMDB ID without running the full parallel fanout. Useful for debugging why a source isn't appearing in movie or TV responses, or for checking a provider's availability before building.

<Note>
  This endpoint runs the **same two-step verification pipeline** as `/movie` and `/tv` — a HEAD check on the raw URL, followed by a proxied HLS playability check. The `ok` field reflects whether a verified, playable URL was found. HTTP status is always `200` regardless of source success or failure — always check `ok` in the body.
</Note>

<Warning>
  This endpoint requires a `standard` or `partner` API key, or a session token from `POST /api/auth`. The `public` key will receive a `403` response.
</Warning>

***

## Path Parameters

<ParamField path="id" type="string" required>
  TMDB ID. For movies, use the movie ID. For TV, use the series ID.
</ParamField>

***

## Query Parameters

<ParamField query="source" type="string" required>
  Provider key to test. Must exactly match one of the configured source keys.

  Available keys are listed in the `sources` field of [`/api/health`](https://1c34-y.hf.space/api/health) or via [`GET /api?sources_meta=1`](https://1c34-y.hf.space/api?sources_meta=1).
</ParamField>

<ParamField query="season" type="number">
  Season number. Required for TV episodes; omit for movies.
</ParamField>

<ParamField query="episode" type="number">
  Episode number. Required for TV episodes; omit for movies.
</ParamField>

***

## Request

<CodeGroup>
  ```bash Movie (API key) theme={null}
  curl "https://1c34-y.hf.space/api/test/550?source=<provider-key>" \
    --header "Authorization: Bearer YOUR_API_KEY"
  ```

  ```bash Movie (session token) theme={null}
  TOKEN=$(curl -s -X POST https://1c34-y.hf.space/api/auth | jq -r .token)

  curl "https://1c34-y.hf.space/api/test/550?source=<provider-key>" \
    -H "X-Session-Token: $TOKEN"
  ```

  ```bash TV Episode (API key) theme={null}
  curl "https://1c34-y.hf.space/api/test/1396?season=1&episode=1&source=<provider-key>" \
    --header "Authorization: Bearer YOUR_API_KEY"
  ```

  ```bash TV Episode (session token) theme={null}
  TOKEN=$(curl -s -X POST https://1c34-y.hf.space/api/auth | jq -r .token)

  curl "https://1c34-y.hf.space/api/test/1396?season=1&episode=1&source=<provider-key>" \
    -H "X-Session-Token: $TOKEN"
  ```

  ```javascript JavaScript (session token) theme={null}
  const { token } = await fetch(
    'https://1c34-y.hf.space/api/auth',
    { method: 'POST' }
  ).then(r => r.json());

  const res = await fetch(
    'https://1c34-y.hf.space/api/test/550?source=<provider-key>',
    { headers: { 'X-Session-Token': token } }
  );
  const data = await res.json();

  if (data.ok) {
    console.log(`✓ ${data.source} (${data.elapsed_ms}ms): ${data.url}`);
  } else {
    console.error(`✗ ${data.source}: ${data.error}`);
  }
  ```

  ```typescript TypeScript (session token) theme={null}
  interface TestResponse {
    source: string;
    id: string;
    s: number | null;
    e: number | null;
    ok: boolean;
    url: string | null;
    raw_url: string | null;
    elapsed_ms: number;
    error: string | null;
  }

  const { token } = await fetch(
    'https://1c34-y.hf.space/api/auth',
    { method: 'POST' }
  ).then(r => r.json());

  const data: TestResponse = await fetch(
    'https://1c34-y.hf.space/api/test/550?source=<provider-key>',
    { headers: { 'X-Session-Token': token } }
  ).then(r => r.json());
  ```

  ```python Python (server-side key) theme={null}
  import requests

  res = requests.get(
    'https://1c34-y.hf.space/api/test/550',
    params={'source': '<provider-key>'},
    headers={
      'Authorization': 'Bearer your_standard_api_key'
    }
  ).json()

  print(f"ok={res['ok']} elapsed={res['elapsed_ms']}ms")
  if res['error']:
      print(f"error: {res['error']}")
  ```
</CodeGroup>

***

## Response

<ResponseField name="source" type="string" required>
  The provider key that was tested.
</ResponseField>

<ResponseField name="id" type="string" required>
  The TMDB ID that was tested.
</ResponseField>

<ResponseField name="s" type="number | null" required>
  Season number. `null` for movies.
</ResponseField>

<ResponseField name="e" type="number | null" required>
  Episode number. `null` for movies.
</ResponseField>

<ResponseField name="ok" type="boolean" required>
  `true` if the provider returned a URL that passed stream verification.
</ResponseField>

<ResponseField name="url" type="string | null">
  Fully-qualified, proxied stream URL if the provider returned a valid stream. `null` on failure. Always an absolute URL — no base URL prepending needed.
</ResponseField>

<ResponseField name="raw_url" type="string | null">
  The original, unproxied stream URL from the provider. Useful for debugging. `null` on failure.
</ResponseField>

<ResponseField name="elapsed_ms" type="number" required>
  Time in milliseconds from the start of the test to receiving a result.
</ResponseField>

<ResponseField name="error" type="string | null" required>
  Error message if the provider threw an exception or returned nothing. `null` on success.
</ResponseField>

***

## Responses

<Tabs>
  <Tab title="200 — Source Working">
    ```json theme={null}
    {
      "source": "provider-a",
      "id": "550",
      "s": null,
      "e": null,
      "ok": true,
      "url": "https://1c34-y.hf.space/api?url=https%3A%2F%2F...&pa=1",
      "raw_url": "https://...",
      "elapsed_ms": 1204,
      "error": null
    }
    ```
  </Tab>

  <Tab title="200 — TV Episode">
    ```json theme={null}
    {
      "source": "provider-b",
      "id": "1396",
      "s": 1,
      "e": 1,
      "ok": true,
      "url": "https://1c34-y.hf.space/api?url=https%3A%2F%2F...&pb=1",
      "raw_url": "https://...",
      "elapsed_ms": 980,
      "error": null
    }
    ```
  </Tab>

  <Tab title="200 — Source Failed">
    HTTP status is still `200` even when the source fails.

    ```json theme={null}
    {
      "source": "provider-c",
      "id": "550",
      "s": null,
      "e": null,
      "ok": false,
      "url": null,
      "raw_url": null,
      "elapsed_ms": 435,
      "error": "no stream returned"
    }
    ```
  </Tab>

  <Tab title="401 — Unauthorized">
    ```json theme={null}
    { "error": "Missing API key. Provide via Authorization header or X-API-Key header." }
    ```
  </Tab>

  <Tab title="403 — Forbidden">
    ```json theme={null}
    { "error": "Public keys cannot access test endpoints" }
    ```
  </Tab>

  <Tab title="400 — Invalid Source">
    ```json theme={null}
    { "error": "invalid or missing source" }
    ```
  </Tab>
</Tabs>

***

## Testing All Sources

To test all providers in one go and see which are working for a given title:

```javascript theme={null}
const BASE = 'https://1c34-y.hf.space';

async function testAll(tmdbId, season, episode) {
  const { token } = await fetch(`${BASE}/api/auth`, { method: 'POST' }).then(r => r.json());

  const meta = await fetch(`${BASE}/api?sources_meta=1`).then(r => r.json());
  const sourceKeys = meta.sources.map(s => s.key);

  const params = new URLSearchParams({ source: '' });
  if (season && episode) { params.set('season', season); params.set('episode', episode); }

  const results = await Promise.all(
    sourceKeys.map(source =>
      fetch(`${BASE}/api/test/${tmdbId}?${params.toString()}&source=${source}`, {
        headers: { 'X-Session-Token': token }
      })
        .then(r => r.json())
        .catch(err => ({ source, ok: false, error: err.message, elapsed_ms: null }))
    )
  );

  results.forEach(r => {
    const status = r.ok ? '✓' : '✗';
    const time   = r.elapsed_ms != null ? `${r.elapsed_ms}ms` : 'N/A';
    console.log(`${status} ${r.source.padEnd(12)} ${time.padStart(7)}  ${r.error || ''}`);
  });
}

testAll(550);
```

<Tip>
  For a quick overview without per-provider isolation, use [`/api/health`](https://1c34-y.hf.space/api/health) — it probes all providers simultaneously and is optimised for monitoring. Health accepts `public_api_key`.
</Tip>
