{
  "openapi": "3.0.1",
  "info": {
    "title": "Letterboxd Scraper - Films, Ratings & Reviews",
    "description": "Scrape Letterboxd films and reviews by search phrase, popular or genre lists, or film URL. Extract ratings, directors, runtimes, review text and star ratings. Includes incremental monitoring, resume support and MCP connectors.",
    "version": "0.1",
    "x-build-id": "0MUshTcAFhPauhXPo"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~letterboxd-film-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-letterboxd-film-reviews-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~letterboxd-film-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-letterboxd-film-reviews-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~letterboxd-film-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-letterboxd-film-reviews-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",
        "properties": {
          "mode": {
            "title": "Input mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Search mode looks up films matching the phrases in Search phrases. URL mode reads the pasted Letterboxd URLs (or the Browse path fallback) below.",
            "default": "search"
          },
          "queries": {
            "title": "Search phrases",
            "type": "array",
            "description": "One or more film title phrases to search on Letterboxd. Matching films are returned with full metadata.",
            "default": [
              "dune"
            ],
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "Letterboxd URLs: film pages, browse lists (e.g. https://letterboxd.com/films/popular/), or direct film slugs.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "browsePath": {
            "title": "Browse path (URL mode fallback)",
            "type": "string",
            "description": "Used only in URL mode when Start URLs is empty. Site path to browse, e.g. /films/popular/ or /films/genre/sci-fi/by/rating/.",
            "default": "/films/popular/"
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Maximum films to return across the whole run. 0 is not valid; the cap is always finite.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per source",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum Letterboxd browse/search pages to read per source. Leave empty (0) to walk every result page; max items is the primary output cap.",
            "default": 0
          },
          "fetchReviews": {
            "title": "Fetch reader reviews",
            "type": "boolean",
            "description": "Turn on to also fetch reader reviews for each returned film (charged as a separate per-film enrichment event). Off returns just film metadata.",
            "default": false
          },
          "maxReviewsPerFilm": {
            "title": "Max reviews per film",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Only used when Fetch reader reviews is on. Maximum reviews to collect per film.",
            "default": 25
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID (or dataset ID) from this actor to continue a large job pull without returning or charging for films already collected there (matched by slug). Use this after an interrupted run. For recurring daily monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns all matching films as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED films. Turn on \"Emit unchanged\" or \"Emit expired\" only when you also want those films returned (and billed). State is kept separately for each search/URL and mode setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the mode/queries/URLs/browse path: different searches then never mix state with each other."
          },
          "emitUnchanged": {
            "title": "Emit unchanged films (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return films that have not changed since the last run, marked UNCHANGED. This returns (and bills) extra rows you already have, so leave it off unless you specifically want the full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired films (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return films that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, not when Max items capped it or when Resume was used. This returns (and bills) extra synthetic rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Runs through the Apify proxy by default — direct cloud egress is refused by the site. No special tier needed.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "BUYPROXIES94952"
              ]
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped films into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify > Settings > API & Integrations, then select it here. Notion gets a page-per-film export; other connectors receive a best-effort write or digest. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page",
            "type": "string",
            "description": "URL or id of the Notion page under which film pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max films to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on how many films are written to each selected 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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}