Social data API · integration guide

Collect comments with bounded pagination

A working Python pattern for Douyin comments: cap the number of paid requests, keep cursors intact, remove duplicate comment IDs and stop when no new data arrives.

Set a spending boundary first

Choose a maximum page count and multiply it by the live catalog price before starting. A successful page is a billable call even when it overlaps a previous page. The example deliberately stops on errors rather than hiding extra retries.

Choose the correct pagination contract

The example below is for Douyin comments with count 20. Comment replies also need a parent comment_id. Other platforms use different cursor or page fields. Threads comments and top search currently support the first page only; nonempty end_cursor is rejected before billing.

Persist checkpoints for deliberate resumptions

Store the video ID, capability, last cursor and seen IDs together. Resume only after deciding whether another paid request is needed. When changing endpoint implementations, start a new cursor chain instead of mixing pagination formats.

Request example

import os
import requests

base = "https://api.chinaapi.ai"
headers = {"Authorization": "Bearer " + os.environ["CHINAAPI_API_KEY"]}
video_id = "YOUR_VIDEO_ID"
seen_ids, seen_cursors = set(), set()
cursor = 0
max_pages = 3  # Budget before starting: max_pages × catalog call price.
for _ in range(max_pages):
    response = requests.get(base + "/v1/social/douyin/comments",
        headers=headers, params={"aweme_id": video_id, "cursor": cursor, "count": 20},
        timeout=45)
    if not response.ok:
        error = response.json().get("error", {})
        if error.get("code") == "social_data_no_result":
            break
        response.raise_for_status()  # Stop; do not retry in a tight loop.
    data = response.json()["data"]
    new_items = []
    for item in data.get("comments", []):
        cid = str(item.get("cid", ""))
        if cid and cid not in seen_ids:
            seen_ids.add(cid)
            new_items.append(item)
    for item in new_items:
        print(item)
    next_cursor = data.get("cursor")
    if not data.get("has_more") or not new_items or next_cursor is None:
        break
    marker = str(next_cursor)
    if marker in seen_cursors or marker == str(cursor):
        break
    seen_cursors.add(str(cursor))
    cursor = next_cursor

Keep the key server-side. Replace resource identifiers with the content you intend to retrieve.

Billing and limits

Beta: paid accounts only. Complete your first top-up before calling this API. Trial credits cannot be used for social-data requests. This beta has no SLA and platform coverage may change.

You must comply with each platform's terms and applicable data rules. Do not use this API to build personal profiles. Login, contact extraction, engagement manipulation, and private or paid-content access are outside this beta.

Calls use your existing ChinaAPI key and balance. Synchronous calls charge only for HTTP 200 with data. Async POST creation reserves the price; failed or empty tasks are refunded, and GET task reads are free. Empty or failed results are not charged. A daily beta budget may return HTTP 429; retry after the UTC day resets. Repeating a successful synchronous request creates another billable call. Retry async creation with the same Idempotency-Key to avoid duplicate submissions.

Every successful page is separately billed. Prices and parameters can change; check the reference before deployment.

Platform guides and working recipes