Pagination
Every list endpoint uses one contract: pass cursor and count, get back cursor and has_more at the top level.
The contract
Paginated endpoints take cursor (omit it for the first page) and count. Every response has cursor (string | null) and has_more (boolean) at the top level, whatever the upstream used: max_cursor, min_cursor, offset, next_page_token or a 0/1 flag. The raw upstream fields are still in the body.
{
"cursor": "1794158512000",
"has_more": true,
"items": [
"…"
]
}Walk every page
Pass the cursor back until has_more is false. Each page is one billed call.
1import os, requests
2
3def pages(path, **params):
4 cursor = None
5 while True:
6 if cursor:
7 params["cursor"] = cursor
8 r = requests.get(f"https://api.tikultra.com{path}", params=params,
9 headers={"x-api-key": os.environ["TIKULTRA_KEY"]})
10 r.raise_for_status()
11 page = r.json()
12 yield page
13 if not page["has_more"]:
14 return
15 cursor = page["cursor"]
16
17for page in pages("/v1/video/comments", aweme_id=7705852133855161377, count=50):
18 print(page["cursor"], page["has_more"])
Which endpoints paginate
39 endpoints: /v1/video/comments, /v1/video/comments/replies, /v1/video/duets, /v1/video/upvotes, /v1/user/posts, /v1/user/stories, /v1/user/reposts, /v1/user/favorites, /v1/user/playlists, /v1/user/followers, /v1/user/followings, /v1/user/collections, /v1/user/collections/videos, /v1/feed/persona-fyp and more. The catalog can filter to them.