{
  "openapi": "3.0.1",
  "info": {
    "title": "China News Feed with Deletion Watch",
    "description": "China news from 155 Chinese-language sources in one feed: state media, party-gov, commercial, overseas independent, dissident and censorship trackers, each labeled by outlet type and grouped by story. Plus a deletion watch on Weibo, Baidu, Zhihu, Toutiao and Bilibili hot lists, with evidence.",
    "version": "0.2",
    "x-build-id": "0cuRbA7UWJyDbbBP0"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/china.unofficial~china-news-feed/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-china.unofficial-china-news-feed",
        "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/china.unofficial~china-news-feed/runs": {
      "post": {
        "operationId": "runs-sync-china.unofficial-china-news-feed",
        "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/china.unofficial~china-news-feed/run-sync": {
      "post": {
        "operationId": "run-sync-china.unofficial-china-news-feed",
        "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": {
          "hotLists": {
            "title": "Hot lists to snapshot",
            "type": "array",
            "description": "Public trending lists fetched logged-out. The default is every list. A list you leave out is not fetched, and its hot-list rows and deletion flags are not pushed or billed. An empty selection includes none.",
            "items": {
              "type": "string",
              "enum": [
                "weibo",
                "baidu",
                "zhihu",
                "toutiao",
                "bilibili",
                "douyin",
                "kuaishou"
              ],
              "enumTitles": [
                "Weibo hot search",
                "Baidu hot search",
                "Zhihu hot list",
                "Toutiao hot board",
                "Bilibili hot search",
                "Douyin hot list (public mirror)",
                "Kuaishou hot list (public mirror)"
              ]
            },
            "default": [
              "weibo",
              "baidu",
              "zhihu",
              "toutiao",
              "bilibili",
              "douyin",
              "kuaishou"
            ]
          },
          "sourceTypes": {
            "title": "Source types",
            "type": "array",
            "description": "Which news rows to push and bill, by the type each row is credited to after aggregator handling. When a cluster_context record from the last 2 hours is available and this selection is narrower than every type, only sources of the selected types are fetched. If that record is missing, stale, or unusable, or this selection is every type, every approved news source is fetched. Hot lists follow hotLists. Evidence, clusters, and overseas pickup stay the same whatever you select here, using the stored context when the fetch is narrowed. The default is every type, including Commercial platform, and does not drop rows. Leaving the field unset does the same. A Commercial platform news row ships when you select that type and is left out when you select other types only. Douyin mirror rows also require douyin in hotLists; that list is in the default, so a default run still ships them, and leaving douyin out drops them even when Commercial platform is selected. Aggregator items are credited to the original outlet's type or dropped, and a credited row is kept only when that type is selected. A news row of an unselected type is not pushed and is not remembered. An empty list selects no news types.",
            "items": {
              "type": "string",
              "enum": [
                "State media",
                "Party-gov",
                "Commercial platform",
                "Overseas independent",
                "Dissident",
                "Censorship tracker"
              ],
              "enumTitles": [
                "State media",
                "Party-gov",
                "Commercial platform",
                "Overseas independent",
                "Dissident",
                "Censorship tracker"
              ]
            },
            "default": [
              "State media",
              "Party-gov",
              "Commercial platform",
              "Overseas independent",
              "Dissident",
              "Censorship tracker"
            ]
          },
          "newsSources": {
            "title": "News sources",
            "type": "array",
            "description": "\"all\" (default) = every approved outlet that can be read logged-out (about 110). Or list source ids from data/sources/news_notion.json, e.g. mfa, xinhua, bbc.",
            "items": {
              "type": "string"
            },
            "default": [
              "all"
            ]
          },
          "snapshotCount": {
            "title": "Snapshots in this run",
            "minimum": 1,
            "maximum": 24,
            "type": "integer",
            "description": "Use 1 with a schedule (every 5-10 min). Higher values keep one run alive and poll repeatedly.",
            "default": 1
          },
          "emitOnlyNew": {
            "title": "Emit only new rows",
            "type": "boolean",
            "description": "Push only dataset rows that are new since the last run. A deletion flag is pushed again when its status changes (for example likely censored to censored, or to returned). Turn off to push a full snapshot. Apify bills each pushed dataset row.",
            "default": true
          },
          "snapshotIntervalMinutes": {
            "title": "Minutes between in-run snapshots",
            "minimum": 1,
            "type": "integer",
            "description": "Minutes to wait between extra snapshots when snapshotCount is greater than 1.",
            "default": 5
          },
          "maxItems": {
            "title": "Max billed rows",
            "minimum": 1,
            "type": "integer",
            "description": "Optional cap on the total number of billed rows this run. Leave empty for no limit."
          },
          "maxItemsPerSource": {
            "title": "Max items per news source",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Maximum number of news items kept from each source in one run.",
            "default": 30
          },
          "maxHotRank": {
            "title": "Include hot-list items up to rank",
            "minimum": 5,
            "maximum": 50,
            "type": "integer",
            "description": "Hot-list rows ranked worse than this are left out of the feed.",
            "default": 50
          },
          "highRank": {
            "title": "'High rank' threshold for censorship flags",
            "minimum": 3,
            "maximum": 50,
            "type": "integer",
            "description": "A topic that vanishes at or above this rank (or while rising) is flagged.",
            "default": 15
          },
          "recheckUrls": {
            "title": "Re-check URLs of vanished topics",
            "type": "boolean",
            "description": "Kept for compatibility. URL rechecks run on our side, not in this actor. The actor joins the stored result for each flag. A flag with no stored result stays pending.",
            "default": true
          },
          "freeweiboCheck": {
            "title": "Cross-check FreeWeibo (aggregate counts only)",
            "type": "boolean",
            "description": "Kept for compatibility. FreeWeibo lookups run on our side, not in this actor. The actor joins stored aggregate counts. A flag with no stored result leaves freeweibo empty. Post text is not stored.",
            "default": true
          },
          "topN": {
            "title": "Topics in the readable report",
            "type": "integer",
            "description": "How many topics to include in the readable top-stories report.",
            "default": 15
          },
          "clusterBudgetSeconds": {
            "title": "Clustering time budget (seconds)",
            "minimum": 1,
            "type": "integer",
            "description": "Maximum seconds spent clustering items in one run. If this runs out, items not yet assigned are left as their own clusters, a warning is logged, and the run continues. The default is 120 seconds.",
            "default": 120
          },
          "sourceRoutes": {
            "title": "Direct or sidecar route",
            "type": "object",
            "description": "Optional overrides of catalog ingest.route. Each value is direct or sidecar. China Press and Sydney Today default to sidecar: the poller fetches them on the box and this actor reads the store. Set a source to direct to use its actor fetcher instead. An empty object keeps the catalog route.",
            "default": {}
          },
          "includeNfsc": {
            "title": "Include NFSC network rows",
            "type": "boolean",
            "description": "When true (the default), the nine NFSC Dissident rows in the public sidecar record are merged into the dataset. Set false to leave them out without a new build. Telegram and YouTube NFSC rows still follow the channel redaction gate and stay internal until that sign-off.",
            "default": true
          },
          "useApifyProxy": {
            "title": "Use Apify Proxy",
            "type": "boolean",
            "description": "Most sources work without a proxy. Enable if lists start rate-limiting.",
            "default": false
          },
          "proxyGroups": {
            "title": "Proxy groups",
            "type": "array",
            "description": "e.g. RESIDENTIAL. Leave empty for the default datacenter pool.",
            "items": {
              "type": "string"
            }
          },
          "sidecarStoreId": {
            "title": "Sidecar store ID",
            "type": "string",
            "description": "Optional. Overrides the SIDECAR_STORE_ID environment variable. Not shown to buyers."
          },
          "historyStore": {
            "title": "Hot-list history store",
            "type": "string",
            "description": "Internal testing only. Owner runs upload trimmed history here. Buyer runs do not open this store. Leave as default.",
            "default": "china-feed-history"
          },
          "simulateBuyer": {
            "title": "Simulate a buyer run",
            "type": "boolean",
            "description": "Internal testing only. When true, this run skips china-feed-history and uses an in-run temp file, the same as a buyer, even on the owner's account. It cannot turn history on.",
            "default": false
          },
          "apifyRetentionDays": {
            "title": "Apify retention days",
            "minimum": 1,
            "type": "integer",
            "description": "Internal testing only. Days of timestamped rows kept in Apify on each upload. The default is 7. The APIFY_RETENTION_DAYS environment variable overrides this.",
            "default": 7
          },
          "contextKey": {
            "title": "Cluster context record key",
            "type": "string",
            "description": "Internal testing only. Leave as default; changing it disables cross-run clustering.",
            "default": "cluster_context"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}