{
  "openapi": "3.0.1",
  "info": {
    "title": "Telegram Channel Scraper - Posts, Views & Exact Subscribers",
    "description": "For OSINT, crypto and market research and channel vetting: posts, views, reactions and forwards from any public Telegram channel, plus the exact subscriber count from the profile page. On one 10.9M channel the rounded preview hid 43,313 people. Median views, ERR and cadence are measured.",
    "version": "0.1",
    "x-build-id": "79ciqDvigWtrhBDHN"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/neverempty~telegram-channel-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-neverempty-telegram-channel-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/neverempty~telegram-channel-scraper/runs": {
      "post": {
        "operationId": "runs-sync-neverempty-telegram-channel-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/neverempty~telegram-channel-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-neverempty-telegram-channel-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": {
          "channels": {
            "title": "Telegram channels",
            "type": "array",
            "description": "Public channels as @durov, durov, https://t.me/durov or https://t.me/s/durov. A link to a single post (t.me/durov/527) works too - the channel is taken from it. Only channels with a public web preview can be read without logging in; invite links (t.me/+..., t.me/joinchat/...) and t.me/c/... are private entrances and are rejected rather than read. A name that has no public preview is reported as its own row that says whether the name exists at all, and is not charged.",
            "default": [
              "@durov",
              "@telegram"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxMessagesPerChannel": {
            "title": "Maximum posts per channel",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "How many of the most recent posts to read from each channel. Telegram serves 20 posts per page, so this is rounded up to whole pages while reading and then cut to this number. You are charged for the rows you actually receive.",
            "default": 40
          },
          "maxMessages": {
            "title": "Maximum posts in total",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "A cap across all channels together, applied after the filters. Use it to keep a run predictable when you pass many channels.",
            "default": 200
          },
          "includeChannelStats": {
            "title": "Add one channel row with the exact subscriber count and measured stats",
            "type": "boolean",
            "description": "On = each channel also gets a single summary row: title, description, verified flag, the exact subscriber count read from the profile page (Telegram's preview page only shows a rounded figure such as 172K, and the exact figure is 171,899), the rounded figure and the difference between them, plus statistics measured from the posts this run read - median, mean, highest and lowest views, the top post, median reactions, views per subscriber, posts per day over the window read, the share of posts with a photo, a video, a link preview or a forward, and the busiest posting hour in UTC. This row costs one channel-summary charge and needs one extra request per channel. In monitoring mode it is only produced for channels that actually posted something new, so a quiet run stays free.",
            "default": true
          },
          "monitoringMode": {
            "title": "Monitoring mode: return only posts you have not been given before",
            "type": "boolean",
            "description": "Off = return the most recent posts of every channel you listed, charged per row. On = remember the newest post id per channel and, on later runs, ask Telegram only for posts published after it, so you are never charged twice for the same post. The id is remembered per channel, not per list, so adding a channel does not re-charge the ones already being watched. A channel that has posted nothing new produces no rows at all on that run, not even its statistics row. **Monitoring adds a flat access fee of $5, charged once per calendar month (UTC)** on the first monitoring run of that month that manages to read at least one channel, no matter how many lists or scheduled tasks you run. That fee is what pays for watching on the days when nothing was posted - those runs return no rows and cost nothing else. Runs with monitoring off never trigger it.",
            "default": false
          },
          "resetMonitoringState": {
            "title": "Forget what was remembered and start over",
            "type": "boolean",
            "description": "Clears the remembered post id for the channels in this run, so the next run returns their recent posts once again and starts a fresh history. **Turn it back off afterwards**: left on in a scheduled task it re-delivers, and re-charges, the same posts on every single run.",
            "default": false
          },
          "postedWithinDays": {
            "title": "Only posts from the last N days",
            "minimum": 0,
            "maximum": 3650,
            "type": "integer",
            "description": "Drop posts older than this many days. 0 = no limit. Posts whose timestamp cannot be read are kept rather than dropped, so a change on Telegram's side never silently empties the result.",
            "default": 0
          },
          "minViews": {
            "title": "Minimum views",
            "minimum": 0,
            "type": "integer",
            "description": "Drop posts below this view count. Telegram publishes views rounded to three significant figures (24.2M, 53.1K), so this is compared against that rounded figure and every row says so in viewsAreRounded. Posts with no view count at all are kept rather than dropped. 0 = no minimum.",
            "default": 0
          },
          "onlyWithMedia": {
            "title": "Only posts with a photo or a video",
            "type": "boolean",
            "description": "Keep only posts whose preview carries a photo or a video. Photos, videos and link previews are the attachment types this Actor has measured on the public preview; other kinds are left unclaimed rather than guessed.",
            "default": false
          },
          "onlyWithLinks": {
            "title": "Only posts that contain a link",
            "type": "boolean",
            "description": "Keep only posts whose text contains at least one outgoing link. Hashtag links and @channel mentions are not counted as links - they come back in their own columns.",
            "default": false
          },
          "excludeForwarded": {
            "title": "Drop forwarded posts",
            "type": "boolean",
            "description": "Keep only posts the channel wrote itself. Forwarded posts carry the source channel and the link to the original post, so leaving them in is useful when you are mapping which channels republish which.",
            "default": false
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Keep only posts whose text, channel title, forwarded source, link preview title or hashtags contain these words. Case is ignored. Leave empty for no keyword filter.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "keywordMatch": {
            "title": "How to match the keywords",
            "enum": [
              "any",
              "all"
            ],
            "type": "string",
            "description": "Any = keep a post that contains at least one of the keywords. All = keep a post only when it contains every keyword.",
            "default": "any"
          },
          "excludeKeywords": {
            "title": "Exclude keywords",
            "type": "array",
            "description": "Drop posts that contain any of these words in the same fields the keyword filter searches. Applied after the keyword filter.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "useProxy": {
            "title": "Use a proxy if Telegram answers with a bot check",
            "type": "boolean",
            "description": "Off by default because t.me answered with the full page on every direct request measured from Apify (three of three, 217-449 ms). Turn it on to have the run retry through a proxy if Telegram ever answers with a bot check - a residential proxy when your account has one, a datacenter proxy otherwise. A proxy makes each run slower and more expensive, so it is not used unless it is needed.",
            "default": false
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}