{
  "openapi": "3.0.1",
  "info": {
    "title": "PineDrama Scraper - Short-Drama Series, Episodes & Views",
    "description": "Scrape the PineDrama short-drama catalogue: series with watch counts, episode counts, categories, theme tags, covers, language, hot/new/free labels, creator ids and full episode lists. Filter by keyword or category in 17 languages, or paste links. Incremental runs and MCP export.",
    "version": "0.1",
    "x-build-id": "rk2yEXAsVN7Nf2vCJ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~pinedrama-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-pinedrama-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/abotapi~pinedrama-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-pinedrama-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/abotapi~pinedrama-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-pinedrama-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Search walks the whole short-drama catalogue, optionally narrowed by keywords and category filters. URL mode scrapes the links you paste in the URL section.",
            "default": "search"
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Only keep series whose title, categories or theme tags contain one of these words (case-insensitive). The catalogue is walked and narrowed as it is read, so a rare keyword can take many pages. Leave empty for every series.",
            "items": {
              "type": "string"
            }
          },
          "categoryFilters": {
            "title": "Category filters",
            "type": "array",
            "description": "Only keep series tagged with one of these categories or theme tags, for example Revenge, Zero to hero or Werewolf. Names are matched in the language chosen below. Leave empty for every category.",
            "items": {
              "type": "string"
            }
          },
          "language": {
            "title": "Language",
            "enum": [
              "en",
              "id",
              "pt",
              "es",
              "de",
              "fr",
              "it",
              "ja",
              "ko",
              "th",
              "vi",
              "tr",
              "ru",
              "ar",
              "nl",
              "pl",
              "zh"
            ],
            "type": "string",
            "description": "Language of the category and tag names. The series titles themselves stay in each series' own language (see language_code).",
            "default": "en"
          },
          "urls": {
            "title": "Links",
            "type": "array",
            "description": "Multi-URL, search fields ignored. Accepts the short-drama landing page (also a country page or the sitemap) and series links. A series link returns that series with its episode list.",
            "default": [
              {
                "url": "https://shortdrama.tiktok.com/"
              },
              {
                "url": "https://shortdrama.tiktok.com/gb"
              },
              {
                "url": "https://shortdrama.tiktok.com/sitemap.xml"
              }
            ],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "fetchDetails": {
            "title": "Fetch episode lists",
            "type": "boolean",
            "description": "Fetch each series' episode list: creator id, shortcut count, first-episode video id and every episode with its number, free or paid status and intro flag. Adds the detail-enrichment charge per series. Without it you still get the catalogue card: title, cover, counts, categories, tags and labels.",
            "default": true
          },
          "fetchVideoStats": {
            "title": "Fetch first-episode video stats",
            "type": "boolean",
            "description": "Also read the public page of each series' first episode video (needs Fetch episode lists): series synopsis, caption, play, like, comment, share and save counts, duration, publish time, and the creator's handle, name, bio, followers and profile link. Heavier per series; counted in the same detail-enrichment charge. Off by default.",
            "default": false
          },
          "maxPages": {
            "title": "Max pages",
            "type": "integer",
            "description": "Optional limit on catalogue pages walked per link or search. This does NOT cap results and has no default (blank or 0 = unlimited); it defers to Max items, which is the single cap on a run."
          },
          "maxItems": {
            "title": "Max items",
            "type": "integer",
            "description": "The one cap on a run (default 20): stop after this many series records. Episodes nested inside a series do not count as items. Set 0 for no limit. Max pages does not cap results and defers to this field.",
            "default": 20
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Residential is the default and recommended. Datacenter is cheaper but the data source often answers it with empty pages, so choose it only for light use. If the selected connection is refused the run continues on a backup connection; on a free Apify plan (no proxy access) some pages may be unavailable.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "resumeFromRunId": {
            "title": "Resume from run ID",
            "type": "string",
            "description": "ID of an interrupted run to continue. The run skips series already saved. Leave empty for a fresh run."
          },
          "incrementalMode": {
            "title": "Incremental mode",
            "type": "boolean",
            "description": "Compare series against the previous run for the same scope (state key) and only emit NEW or UPDATED rows (plus optional EXPIRED tombstones). Compared: title, episode count, categories, theme tags, labels, free window, creator id, shortcut count and the episode list (number, id, paid flag, intro flag). Ignored: watch count, signed cover URL, scrape time. Unchanged series are skipped and not charged.",
            "default": false
          },
          "stateKey": {
            "title": "State key",
            "type": "string",
            "description": "Name of the remembered baseline for incremental mode. Defaults to a hash of the current scope, so two runs with the same settings compare against each other automatically."
          },
          "emitUnchanged": {
            "title": "Emit unchanged records",
            "type": "boolean",
            "description": "In incremental mode, also emit rows classified UNCHANGED (handy for full snapshots or debugging).",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired tombstones",
            "type": "boolean",
            "description": "In incremental mode, emit an EXPIRED row for series present in the baseline but missing from this run. Only a scan that walked the whole scope expires anything: a run stopped by Max items, Max pages, an error, or started mid-catalogue never does. Tombstones respect Max items.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Extra dataset fields that must NOT mark a record UPDATED when they change (watch count, cover URL and scrape time are ignored by default).",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per series, not the full JSON, the complete record stays in the dataset. Leave empty to skip.",
            "items": {
              "type": "string"
            }
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}