# DramaBox API (`ezvidnet/dramabox-api`) Actor

DramaBox-only Apify Actor wrapping the Ezvid Movies API Gateway. Pull catalog, search, detail, episode lists and per-language feeds from DramaBox with a single, cursor-paginated interface. Built for streaming sites, content aggregators and SEO pipelines.

- **URL**: https://apify.com/ezvidnet/dramabox-api.md
- **Developed by:** [Ezvid.Net](https://apify.com/ezvidnet) (community)
- **Categories:** Videos, Social media, Other
- **Features:** Limited permissions
- **Stats:** 45 total users, 2 monthly users, 4.9% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## DramaBox API — Free Actor, Your Ezvid API Key

Run Ezvid DramaBox content requests as an Apify Actor and export results to a
dataset. Version **1.0.0** uses a bundled OpenAPI snapshot from **2026-10-10**
covering **1 provider (DramaBox) and 10 GET endpoints**.

**Register with Ezvid and use your own API key.** The intended Store model is a
free Actor with no developer fee, configured as **pay per usage** in Apify Console.
Apify compute/storage/network usage and Ezvid API access/quota are separate and
depend on your accounts. The code contains no custom charging calls. Deploying
it does not change an existing Actor's pricing; follow [DEPLOY.md](DEPLOY.md).

### Get started

1. Register with Ezvid and obtain your own API key. Start with the
   [Ezvid API documentation](https://api.ezvid.net/docs) for API access information.
   If key issuance is not available there, request access from Ezvid's operator.
   This Actor does not create Ezvid accounts or issue keys.
2. Enter that key in the required **Your registered Ezvid API key** input field.
3. Choose an action/resource, then run the Actor.

Start with a small languages request to verify your key:

```json
{
  "apiKey": "YOUR_REGISTERED_EZVID_KEY",
  "provider": "dramabox",
  "action": "languages"
}
```

Replace the placeholder with your key in the Apify input form. Open the run's
**Results** output for dataset records and **Run summary** for the `OUTPUT` record.
Use `browse`, `search`, or another discovery resource to obtain IDs before
requesting content details or episodes.

The `apiKey` field uses Apify's encrypted secret input. Every API request sends
it only in `X-API-Key`. Missing/blank keys fail before any HTTP request; Ezvid
validates the supplied key and its permissions. There is no embedded key and no
`EZVID_API_KEY` environment fallback. Authentication errors do not include
upstream bodies or keys in logs. Local INPUT files contain plaintext secrets:
keep them in the ignored `storage/` directory.

### Supported resources

See [RESOURCES.md](RESOURCES.md) for the complete generated reference, including
all required query parameters.

Provider: `dramabox` (10 resources).

Coverage includes languages, lists, discovery, search, categories, details,
episodes, playback sources, subtitles and other resources actually exposed by
DramaBox. The service routes `/`, `/health`, `/openapi.json` are not content
resources.

Use `provider: "dramabox"` with `resource` to address any endpoint. Supply the
exact relative path template, such as `allepisode` (the DramaBox `episodes`
alias), or a full `/api/dramabox/...` template. Arbitrary URLs are not accepted.

For convenience, `action` supports exact resource names and these familiar
aliases:

- `home`: resolves to DramaBox `foryou`.
- `detail` / `episodes`: DramaBox uses `bookId` query endpoints (`detail` →
  `detail?bookId=...`, `episodes` → `allepisode?bookId=...`).
- `languages` / `langs`: resolves to `languages`.
- `source`: resolves to a unique episode source endpoint when available.
- DramaBox `vip`/`categories` are no longer advertised: those paths are absent
  from the current Ezvid contract.

Unsupported or ambiguous actions fail with a request to select an exact resource.

### Input

| Field | Purpose |
| --- | --- |
| `apiKey` | **Required**, your own registered Ezvid key; no default/shared key. |
| `provider` | **Required**, fixed to `dramabox`. |
| `action` | Convenience action; defaults to `home`. |
| `resource` | Exact resource template; overrides `action`. |
| `pathParams` | Object containing native path arguments; overrides `id`/`ep`. |
| `queryParams` | Object containing native query arguments; overrides shortcuts. Unknown keys fail validation. |
| `id` | Shortcut for the first path parameter, or DramaBox `bookId`. |
| `ep` | Shortcut for the episode/chapter parameter. May be an opaque ID, not a sequence number. |
| `query` | Search text, mapped to `query`. |
| `language` | Mapped to `lang`; omit for upstream default. |
| `category` | Sent when the endpoint documents `category`. |
| `limit` | 1–100, default 20; sent only if documented and may be capped upstream. |
| `page` | Starting numeric page, used by `browse`/`dubbed`. |
| `cursor` | Starting opaque cursor for supported endpoints. |
| `maxPages` | 1–50, default 1; maximum page fetches for a paginated resource. Retries are additional HTTP attempts. |
| `pagination` | `auto` (default), `none`, `cursor`, or `page`. |
| `outputMode` | `records` (default) or `response`. |

Optional shortcuts are sent only where supported. Use `queryParams` for strict
parameter checking and provider-specific options such as `classify`.

#### Search DramaBox

```json
{
  "apiKey": "YOUR_REGISTERED_EZVID_KEY",
  "provider": "dramabox",
  "action": "search",
  "query": "love",
  "language": "en"
}
```

#### Fetch DramaBox episodes

```json
{
  "apiKey": "YOUR_REGISTERED_EZVID_KEY",
  "provider": "dramabox",
  "action": "episodes",
  "id": "YOUR_DRAMA_ID"
}
```

#### Browse dubbed DramaBox content starting at page 5

```json
{
  "apiKey": "YOUR_REGISTERED_EZVID_KEY",
  "provider": "dramabox",
  "resource": "dubbed",
  "language": "en",
  "queryParams": { "classify": "terbaru" },
  "page": 5,
  "maxPages": 3
}
```

### Pagination and output

Auto pagination uses an explicitly supplied cursor, otherwise the endpoint's
`page`/`p`, otherwise its `cursor`. Endpoints without these parameters run once.
The Actor stops on empty results, end markers, repeated pages/tokens, missing
next cursor, or `maxPages`. It does not invent cursor values or silently switch
to another resource.

The default dataset contains records with `_meta` (`provider`, `resource`, `page`,
`url`, `fetchedAt`). Records mode unwraps common `data`/`result`/`payload` envelopes
and list arrays. Entity/detail objects retain nested episodes; primitive values
are wrapped in `{ "value": ... }`.

Provider fields are preserved rather than normalized to a universal movie schema.
Ezvid's OpenAPI does not describe response field schemas. For an unfamiliar
resource or to preserve all envelope metadata, use `outputMode: "response"`,
which stores `{ "response": <complete JSON>, "_meta": ... }` for each nonempty page.

The `OUTPUT` key-value record contains `provider`, `resource`, `pagination`,
`outputMode`, `pagesFetched`, `recordsPushed`, `maxPages`, `stopReason`, timestamps,
and continuation values (`nextCursor`/`nextPage` when `maxPages` is reached).
`pagesFetched` counts parsed responses, including a final empty or repeated page;
it does not count retry attempts. A numeric next page is a candidate if the
upstream did not supply an explicit next-page marker. Pass `nextCursor` as input
`cursor`, or `nextPage` as input `page`, to continue with the same resource and
filters. A later failure fails the run; previously written dataset records remain,
but a success summary is not written.

Requests time out after 60 seconds. Network errors, HTTP 429 and 5xx get up to
three retries, with backoff and `Retry-After` handling capped at 60 seconds.
401/403 and other client errors fail immediately. The Actor returns metadata and
playback URLs; it does not download or stream video. Playback URLs may expire.

### Verification and provider availability

Automated tests cover request construction for all 10 DramaBox endpoints,
authentication requirements, parsing, pagination, retries and the Apify SDK
lifecycle with mocked HTTP responses. See the test suite in `tests/`.

Live checks using a registered key have covered DramaBox `languages`, `search`,
`browse`, `detail`, `episodes`, plus a home request. Some home responses were
empty or returned upstream failures; detail, search, browse and episodes worked
even when home failed. These counts describe a specific test run, not a permanent
availability guarantee.

See [LIVE_CHECKS.md](LIVE_CHECKS.md) for findings. An unavailable home resource
does not necessarily mean every resource is down. Ezvid can wrap provider errors
as HTTP 400; the Actor reports those separately from ordinary request validation
errors.

### Development

Use Node.js 22+ and, for `apify run`/deployment, the Apify CLI.

```bash
npm ci
npm test
npm run validate:input
```

Create the local input directory:

```bash
mkdir -p storage/key_value_stores/default
```

Save one of the input examples above as
`storage/key_value_stores/default/INPUT.json`, replacing the key placeholder
locally. Then run `npm start` (Apify SDK storage) or `npm run start:local`
(Apify CLI). The `storage/` directory is ignored by Git.

Local results are written to `storage/datasets/default/`; the summary is at
`storage/key_value_stores/default/OUTPUT.json`. These paths assume the default
local storage configuration. Back up results before starting another local run,
because the SDK purges default storage on startup while preserving input.

| Command | Purpose |
| --- | --- |
| `npm start` | Run `src/main.js` through the Apify SDK. |
| `npm run start:local` | Run through the installed Apify CLI. |
| `npm test` | Run automated tests; no real Ezvid key or API requests required. |
| `npm run validate:input` | Validate the input schema using the installed CLI. |
| `npm run generate` | Regenerate the resource reference from the bundled snapshot. |
| `npm run sync:resources` | Download the public OpenAPI snapshot and regenerate the reference. Note: the sync tool keeps the upstream catalog untouched; this repo is filtered to DramaBox only, so a fresh sync must be filtered again before being checked in. |
| `npm run deploy` | Deploy with `apify push`; requires Apify login. |

```bash
npm test
npm run validate:input
```

Resource changes are reviewed at build time; each Actor run uses the checked-in
snapshot. Updating the snapshot does not prove every endpoint is available:
end-to-end verification requires a valid key with access to those resources.

See [DEPLOY.md](DEPLOY.md) to publish a free/pay-per-usage Actor.

### License

MIT.

# Actor input Schema

## `apiKey` (type: `string`):

Required: obtain your own key from Ezvid (https://api.ezvid.net). Sent only as the X-API-Key header. No shared key is provided.

## `provider` (type: `string`):

Choose the Ezvid content provider.

## `action` (type: `string`):

Common action such as home, search, detail, episodes, languages, source, or an exact resource template. Ignored when Resource is supplied.

## `resource` (type: `string`):

Exact resource template from RESOURCES.md or Ezvid docs, e.g. channels/{channelId}/subchannels. A full /api/provider/... template is also accepted. Overrides Action; keep placeholders and supply pathParams.

## `query` (type: `string`):

Mapped to the documented q, query or keyword parameter.

## `id` (type: `string`):

Shortcut for the first path parameter or DramaBox bookId. Use pathParams for named parameters.

## `ep` (type: `string`):

Shortcut for ep, episode, episodeId, episodeOrder, episodeNum or chapterId. Some providers require an opaque ID rather than an episode number.

## `language` (type: `string`):

Mapped to language, lang or locale when the resource supports it. Omit to use the upstream default.

## `category` (type: `string`):

Sent only when the resource documents the category query parameter.

## `pathParams` (type: `object`):

Exact path parameter names, e.g. {"channelId":"123"}. These override ID/episode shortcuts.

## `queryParams` (type: `object`):

Exact documented query parameters, e.g. {"lang":"en","classify":"terbaru"}. These override shortcuts. Unknown keys are rejected.

## `limit` (type: `integer`):

Sent only to resources supporting limit; upstream may cap it.

## `page` (type: `integer`):

Starting page for resources supporting page or p.

## `cursor` (type: `string`):

Opaque continuation token from a prior response, for resources supporting cursor.

## `maxPages` (type: `integer`):

Maximum pages per run. Stops earlier at an empty page, repeated page/token, or end marker. Resources without pagination run once.

## `pagination` (type: `string`):

Auto prefers an explicit cursor, then page/p, then cursor. Select none to fetch only one response.

## `outputMode` (type: `string`):

Records unwraps common list/data envelopes and adds \_meta. Response preserves each complete JSON response under response. Provider fields are preserved, not normalized.

## Actor input object example

```json
{
  "provider": "dramabox",
  "action": "home",
  "limit": 20,
  "maxPages": 1,
  "pagination": "auto",
  "outputMode": "records"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "provider": "dramabox"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ezvidnet/dramabox-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "provider": "dramabox" }

# Run the Actor and wait for it to finish
run = client.actor("ezvidnet/dramabox-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "provider": "dramabox"
}' |
apify call ezvidnet/dramabox-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ezvidnet/dramabox-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/FTABFgWkrvUSgxepW/builds/mqeBRrFVNBqnH0pMe/openapi.json
