{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "Creator Scraper API",
    "version": "2026-11-11",
    "summary": "TikTok profiles, videos, search, followers and audience, plus bulk jobs.",
    "description": "The TikTok routes answer the same requests as ScrapeCreators, with the same\npaths, parameters and response bodies: a client switches by changing the base\nURL and the key.\n\n**Envelope.** Every TikTok route answer carries `success`, `credits_charged`\nand `credits_remaining`. Credits are exact decimals in JSON (`1`, `0.002`),\nnever rounded floats. You are charged only for an answer you receive; every\n4xx and 5xx is free (`credits_charged: 0`).\n\n**Errors.** TikTok routes answer errors as\n`{\"success\": false, \"error\": <code>, \"errorStatus\": <HTTP status>, \"message\", \"credits_charged\": 0}`.\nBranch on `error` (RouteErrorCode); `message` may be reworded. The job and\ncorpus routes use `{\"error\": {\"code\": <code>, \"message\"}}` (JobErrorCode).\n\n**Time limit.** A TikTok route holds the connection open until it answers,\nup to **180 seconds** (audience: 300). Past that you get `504 timeout`, free.\nSet your client timeout above 180 s (audience: above 300 s; we use 360).\n\n**Capacity.** No per-key rate limit and no concurrency cap on the TikTok\nroutes: requests are served first in, first out across all keys. When we\ncannot answer within the time limit you get `429 over_capacity` at once, with\n`Retry-After` and the same number in `retry_after_s`.\n\n**Free-answer limit.** Answers that are free although they are answers (an\naccount that does not exist on profile videos, followers or following, a\nhidden following list, an unindexed or moved `user_id`) are limited to 100\nper API key per 10 minutes, sliding. Past that such an answer becomes\n`429 rate_limited` with `Retry-After`, free. Charged answers are never limited.\n\n**Idempotency.** Send `Idempotency-Key` (up to 255 characters) to make a\nretry safe. Same key and same parameters within 24 hours: the stored answer\ncomes back uncharged, with `Idempotent-Replay: true`. While the first\nrequest still runs, a retry gets `409 idempotency_conflict` with\n`Retry-After: 1`. Only charged answers are stored. Keys are per API key.\n",
    "contact": {
      "name": "Creator Scraper API"
    }
  },
  "servers": [
    {
      "url": "https://scraper.riken.me",
      "description": "Riken Scraper"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "TikTok",
      "description": "ScrapeCreators-compatible TikTok routes. Held open until answered; priced per call."
    },
    {
      "name": "Jobs",
      "description": "Bulk work (thousands of keywords or handles), billed per unit attempted, read back with paging or an export."
    },
    {
      "name": "System",
      "description": "Liveness."
    }
  ],
  "paths": {
    "/v1/tiktok/profile": {
      "get": {
        "operationId": "tiktokProfile",
        "tags": [
          "TikTok"
        ],
        "summary": "Profile",
        "description": "One TikTok account: its user record and its counts. `stats` holds TikTok's\nrounded counts and `statsV2` the exact counts as strings. `itemList` is\nalways empty, as on ScrapeCreators.\n\nAn account that does not exist is a **200, charged** answer with\n`account_deactivated: true`, as ScrapeCreators answers it. A private\naccount is the normal body with `user.privateAccount: true`, charged.\n\nWhen TikTok's profile page fails and we fall back to the embed, some\n`user` settings and counts can be `null`.\n\nLatency (our load test, 31 Oct 2026, 40 requests/s on one box): p50 1.14 s, p95 4.51 s.\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 1,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Handle"
          },
          {
            "$ref": "#/components/parameters/UserID"
          },
          {
            "$ref": "#/components/parameters/CacheMaxAge"
          },
          {
            "$ref": "#/components/parameters/Trim"
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Accepted and ignored. Not validated on this route (any value passes).",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The profile, or the not-found answer. Charged either way.",
            "x-charged": true,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ProfileResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ProfileNotFound"
                    }
                  ]
                },
                "examples": {
                  "profile": {
                    "summary": "A profile (our shaper on our fixture)",
                    "value": {
                      "credits_charged": 1,
                      "credits_remaining": 999,
                      "itemList": [],
                      "stats": {
                        "diggCount": 0,
                        "followerCount": 8740,
                        "followingCount": 125,
                        "friendCount": 41,
                        "heart": 275500,
                        "heartCount": 275500,
                        "videoCount": 48
                      },
                      "statsV2": {
                        "diggCount": "0",
                        "followerCount": "8740",
                        "followingCount": "125",
                        "friendCount": "41",
                        "heart": "275546",
                        "heartCount": "275546",
                        "videoCount": "48"
                      },
                      "success": true,
                      "user": {
                        "UserStoryStatus": 0,
                        "avatarLarger": "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/23acee9247d9576ff8a4626add13fbfd~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=7231d9a6&x-expires=1793563200&x-signature=c41FazTETsYo8P%2BTmuPfZjEZAFI%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8",
                        "avatarMedium": "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/23acee9247d9576ff8a4626add13fbfd~tplv-tiktokx-cropcenter:720:720.jpeg?dr=9640&refresh_token=69603e15&x-expires=1793563200&x-signature=scJlakKQv0P9I46Wo9%2FV5pfatIw%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8",
                        "avatarThumb": "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/23acee9247d9576ff8a4626add13fbfd~tplv-tiktokx-cropcenter:100:100.jpeg?dr=9640&refresh_token=95abdb08&x-expires=1793563200&x-signature=8OwnKAnW8MdgUe9z%2FBger1%2FN%2FZQ%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8",
                        "bioLink": {
                          "link": "Dagestantrainingcamp.com",
                          "risk": 3
                        },
                        "canExpPlaylist": true,
                        "commentSetting": 0,
                        "commerceUserInfo": {
                          "commerceUser": false
                        },
                        "createTime": 1610747711,
                        "downloadSetting": 0,
                        "duetSetting": 0,
                        "eventList": [],
                        "followingVisibility": 1,
                        "ftc": false,
                        "id": "6918108151024829445",
                        "isADVirtual": false,
                        "isEmbedBanned": false,
                        "isOrganization": 0,
                        "language": "fr",
                        "nickNameModifyTime": 1777223133,
                        "nickname": "Dagestan Training Camp",
                        "nowInvitationCardUrl": "",
                        "openFavorite": false,
                        "privateAccount": false,
                        "profileEmbedPermission": 1,
                        "profileTab": {
                          "showMusicTab": false,
                          "showPlayListTab": false,
                          "showQuestionTab": false
                        },
                        "recommendReason": "",
                        "relation": 0,
                        "roomId": "",
                        "secUid": "MS4wLjABAAAAynBXrV7vRUXrvgYYr-msCZbjkFi9Xh-AiK6DkKzopQIeqh7Ppoqv81VHPZfD5xf6",
                        "secret": false,
                        "shortDramaCreator": {},
                        "shortId": "",
                        "signature": "🥊 MMA & Wrestling Training Camp in Dagestan\n⛰️For all level (beginner to professional)\n\nCheck our website ⬇️",
                        "stitchSetting": 0,
                        "suggestAccountBind": false,
                        "ttSeller": false,
                        "uniqueId": "dagestantrainingcamp",
                        "uniqueIdModifyTime": 0,
                        "verified": false
                      }
                    }
                  },
                  "not_found": {
                    "summary": "The account does not exist (charged)",
                    "value": {
                      "success": true,
                      "credits_remaining": 48175,
                      "credits_charged": 1,
                      "account_deactivated": true,
                      "handle": "zq_nosuchuser_scdiff_7731",
                      "message": "Account doesn't exist"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamFailed"
          },
          "503": {
            "$ref": "#/components/responses/NotPriced"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v3/tiktok/profile/videos": {
      "get": {
        "operationId": "tiktokProfileVideos",
        "tags": [
          "TikTok"
        ],
        "summary": "Profile videos",
        "description": "An account's newest videos.\n\n**Beta: page 1 only.** `has_more` is always `0`. Asking for a later page\nwith `max_cursor` returns `501 not_yet_available`, free. On page 1\n`statistics` has `play_count` only; like, comment, share and save counts\nare `null`. The count per page is what TikTok's embed gives (12 and 13 in\nour fixtures) and is not fixed.\n\nAn account that does not exist is a **404, free** (counts toward the\nfree-answer limit). A private account is a 200, **charged**,\n`{\"handle\", \"account_private\": true}`.\n",
        "x-status": "beta",
        "x-beta": true,
        "x-credits": {
          "amount": 1,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Handle"
          },
          {
            "$ref": "#/components/parameters/UserID"
          },
          {
            "name": "max_cursor",
            "in": "query",
            "required": false,
            "description": "Absent, empty or `0` means page 1. Any other value is `501 not_yet_available` in beta.",
            "schema": {
              "type": "string",
              "default": "0"
            },
            "example": "0"
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "`latest` or absent. `popular` is `400 unsupported_parameter`; any other value is `400 bad_request`.",
            "schema": {
              "type": "string",
              "enum": [
                "latest",
                "popular"
              ],
              "default": "latest"
            }
          },
          {
            "name": "include_pinned",
            "in": "query",
            "required": false,
            "description": "`true` or absent. `false` is `400 unsupported_parameter`: pinned posts are always included.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "$ref": "#/components/parameters/RegionIgnored"
          },
          {
            "$ref": "#/components/parameters/TrimUnchecked"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Page 1 of the videos, or the private-account answer. Charged.",
            "x-charged": true,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ProfileVideosResponse"
                    },
                    {
                      "$ref": "#/components/schemas/PrivateAccount"
                    }
                  ]
                },
                "examples": {
                  "videos": {
                    "summary": "Page 1 (our shaper on our fixture, list cut to one item)",
                    "value": {
                      "aweme_list": [
                        {
                          "added_sound_music_info": null,
                          "aigc_info": null,
                          "anchors": null,
                          "anchors_extras": null,
                          "animated_image_info": null,
                          "author": {
                            "avatar_168x168": null,
                            "avatar_300x300": null,
                            "avatar_larger": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/23acee9247d9576ff8a4626add13fbfd~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=7231d9a6&x-expires=1793563200&x-signature=c41FazTETsYo8P%2BTmuPfZjEZAFI%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "avatar_medium": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/23acee9247d9576ff8a4626add13fbfd~tplv-tiktokx-cropcenter:720:720.jpeg?dr=9640&refresh_token=69603e15&x-expires=1793563200&x-signature=scJlakKQv0P9I46Wo9%2FV5pfatIw%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "avatar_thumb": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/23acee9247d9576ff8a4626add13fbfd~tplv-tiktokx-cropcenter:100:100.jpeg?dr=9640&refresh_token=95abdb08&x-expires=1793563200&x-signature=8OwnKAnW8MdgUe9z%2FBger1%2FN%2FZQ%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "aweme_count": 48,
                            "commerce_user_level": null,
                            "custom_verify": null,
                            "enterprise_verify_reason": null,
                            "favoriting_count": 0,
                            "follower_count": 8740,
                            "following_count": 125,
                            "hide_search": null,
                            "ins_id": null,
                            "is_star": null,
                            "language": "fr",
                            "nickname": "Dagestan Training Camp",
                            "sec_uid": "MS4wLjABAAAAynBXrV7vRUXrvgYYr-msCZbjkFi9Xh-AiK6DkKzopQIeqh7Ppoqv81VHPZfD5xf6",
                            "secret": 0,
                            "short_id": "",
                            "signature": "🥊 MMA & Wrestling Training Camp in Dagestan\n⛰️For all level (beginner to professional)\n\nCheck our website ⬇️",
                            "total_favorited": 275500,
                            "twitter_id": null,
                            "uid": "6918108151024829445",
                            "unique_id": "dagestantrainingcamp",
                            "verification_type": 0,
                            "with_commerce_entry": null,
                            "youtube_channel_id": null
                          },
                          "author_user_id": 6918108151024829000,
                          "aweme_acl": null,
                          "aweme_id": "7574554126068075798",
                          "aweme_type": null,
                          "banners": null,
                          "behind_the_song_music_ids": null,
                          "behind_the_song_video_music_ids": null,
                          "bodydance_score": null,
                          "branded_content_accounts": null,
                          "c2pa_info": null,
                          "cc_template_info": null,
                          "cha_list": null,
                          "challenge_position": null,
                          "cmt_swt": null,
                          "collect_stat": null,
                          "comment_config": null,
                          "comment_topbar_info": null,
                          "commerce_config_data": null,
                          "commerce_info": null,
                          "content_desc": null,
                          "content_desc_extra": null,
                          "content_model": null,
                          "content_original_type": null,
                          "content_size_type": null,
                          "content_type": null,
                          "cover_labels": null,
                          "create_time": 1763588312,
                          "create_time_utc": "2025-11-19T21:38:32.000Z",
                          "creation_info": null,
                          "desc": "Visite de la salle à Khabib, c’est ici que vous allez passer vos camps d’entraînement avec nous 🏔️ #mma #islammakhachev #khabib_nurmagomedov #dagestan #trainingcamp ",
                          "desc_language": null,
                          "disable_search_trending_bar": null,
                          "distance": null,
                          "distribute_type": null,
                          "follow_up_item_id_groups": null,
                          "follow_up_publish_from_id": null,
                          "geofencing": null,
                          "geofencing_regions": null,
                          "green_screen_materials": null,
                          "group_id": "7574554126068075798",
                          "group_id_list": null,
                          "has_danmaku": null,
                          "has_promote_entry": null,
                          "has_vs_entry": null,
                          "have_dashboard": null,
                          "hybrid_label": null,
                          "image_infos": null,
                          "interact_permission": null,
                          "interaction_stickers": null,
                          "is_ad": null,
                          "is_ads": null,
                          "is_description_translatable": null,
                          "is_eligible_for_commission": null,
                          "is_hash_tag": null,
                          "is_nff_or_nr": null,
                          "is_on_this_day": null,
                          "is_paid_partnership": null,
                          "is_pgcshow": null,
                          "is_preview": null,
                          "is_relieve": null,
                          "is_text_sticker_translatable": null,
                          "is_title_translatable": null,
                          "is_top": null,
                          "is_vr": null,
                          "item_comment_settings": null,
                          "item_duet": null,
                          "item_react": null,
                          "item_stitch": null,
                          "label_top": null,
                          "label_top_text": null,
                          "long_video": null,
                          "main_arch_common": null,
                          "mask_infos": null,
                          "meme_reg_info": null,
                          "misc_info": null,
                          "muf_comment_info_v2": null,
                          "music": {
                            "author": null,
                            "duration": null,
                            "id_str": null,
                            "is_original_sound": null,
                            "owner_handle": null,
                            "title": null
                          },
                          "music_begin_time_in_ms": null,
                          "music_end_time_in_ms": null,
                          "music_selected_from": null,
                          "music_title_style": null,
                          "music_volume": null,
                          "need_trim_step": null,
                          "need_vs_entry": null,
                          "nickname_position": null,
                          "no_selected_music": null,
                          "operator_boost_info": null,
                          "origin_comment_ids": null,
                          "origin_volume": null,
                          "original_client_text": null,
                          "picked_users": null,
                          "playlist_blocked": null,
                          "poi_re_tag_signal": null,
                          "position": null,
                          "prevent_download": null,
                          "products_info": null,
                          "promote_capcut_toggle": null,
                          "promote_icon_text": null,
                          "promote_toast": null,
                          "promote_toast_key": null,
                          "question_list": null,
                          "quick_reply_emojis": null,
                          "rate": null,
                          "reference_tts_voice_ids": null,
                          "reference_voice_filter_ids": null,
                          "region": null,
                          "risk_infos": null,
                          "search_highlight": null,
                          "share_info": null,
                          "share_url": "https://www.tiktok.com/@dagestantrainingcamp/video/7574554126068075798",
                          "shoot_tab_name": null,
                          "shop_product_url": null,
                          "social_interaction_blob": null,
                          "solaria_profile": null,
                          "sort_label": null,
                          "standard_component_info": null,
                          "statistics": {
                            "aweme_id": "7574554126068075798",
                            "collect_count": null,
                            "comment_count": null,
                            "digg_count": null,
                            "download_count": null,
                            "forward_count": null,
                            "lose_comment_count": null,
                            "lose_count": null,
                            "play_count": 42300,
                            "repost_count": null,
                            "share_count": null,
                            "whatsapp_share_count": null
                          },
                          "status": {
                            "allow_comment": null,
                            "allow_share": null,
                            "aweme_id": "7574554126068075798",
                            "is_delete": null,
                            "is_prohibited": null,
                            "private_status": 0,
                            "self_see": null
                          },
                          "support_danmaku": null,
                          "text_extra": null,
                          "text_sticker_major_lang": null,
                          "title_language": null,
                          "ttec_suggest_words": null,
                          "tts_voice_ids": null,
                          "uniqid_position": null,
                          "upvote_info": null,
                          "upvote_preload": null,
                          "url": "https://www.tiktok.com/@dagestantrainingcamp/video/7574554126068075798",
                          "used_full_song": null,
                          "user_digged": null,
                          "video": {
                            "CoverTsp": null,
                            "ai_dynamic_cover": null,
                            "ai_dynamic_cover_bak": null,
                            "animated_cover": null,
                            "big_thumbs": null,
                            "bit_rate": null,
                            "bit_rate_audio": null,
                            "cdn_url_expired": null,
                            "cover": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://p16-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/oMOEFHNkmQAjGzJuRaOgefGGAgEqzBDApQORqF~tplv-tiktokx-origin.image?dr=9636&x-expires=1793563200&x-signature=v5fG%2BDuW6t9y66Go9nYmPf%2BnXvM%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast8"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "duration": null,
                            "dynamic_cover": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://p16-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/oURBgFFEEuNfAqHzOpC3AAkewKQEQhRODjOGEg~tplv-tiktokx-origin.image?dr=9636&x-expires=1793563200&x-signature=SF0ary6TU0RymVZVVO5%2FuRdbF0M%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast8"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "has_watermark": null,
                            "height": 1024,
                            "is_bytevc1": null,
                            "is_callback": null,
                            "meta": null,
                            "misc_download_addrs": null,
                            "need_set_token": null,
                            "origin_cover": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://p19-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/owkOOjHzDQwOAeqgARFCk0RNGBf4pdFQEjguEH~tplv-tiktokx-origin.image?dr=9636&x-expires=1793563200&x-signature=yU0DtuLP405xCZlGLmGW7I02GQM%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast8"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "play_addr": {
                              "height": null,
                              "uri": null,
                              "url_list": [
                                "https://v45.tiktokcdn-us.com/951e1b268a588f6919ae0e92d73dae0b/6ae7a75b/video/tos/useast2a/tos-useast2a-ve-68c810-euttp/ooIjRIDeHeMgcEIjb4PSnALAAkhGcBALAiVf4D/?a=1233&bti=ODszNWYuMDE6&&bt=1113&ft=aEKfuqT0mIoPD12pyq9I3wUBI0AbMeF~O5&mime_type=video_mp4&rc=ZjQ8ODc3aWdoODozZ2U3PEBpMzZ2d285cjY2NzMzbzczNUBjNWNjM19gNTExXy5iLzE0YSMtZWxgMmRjZGNhLS1kMTFzcw%3D%3D&vvpl=1&l=20261030205450AE8867C13A6CC8260364&btag=e00095000"
                              ],
                              "url_prefix": null,
                              "width": null
                            },
                            "ratio": "540p",
                            "source_HDR_type": null,
                            "tags": null,
                            "width": 576
                          },
                          "video_control": null,
                          "video_labels": null,
                          "video_text": null,
                          "visual_search_info": null,
                          "voice_filter_ids": null,
                          "with_promotional_music": null,
                          "without_watermark": null
                        }
                      ],
                      "credits_charged": 1,
                      "credits_remaining": 999,
                      "has_more": 0,
                      "max_cursor": 1763503506000,
                      "status_code": 0,
                      "success": true
                    }
                  },
                  "private": {
                    "summary": "A private account (charged; ScrapeCreators' recorded body, ours has the same keys)",
                    "value": {
                      "success": true,
                      "credits_remaining": 48177,
                      "credits_charged": 1,
                      "handle": "yukaaa_s",
                      "account_private": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "501": {
            "description": "`max_cursor` asks for page 2 or later, not available in beta. Free.",
            "x-charged": false,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteError"
                },
                "examples": {
                  "not_yet_available": {
                    "value": {
                      "success": false,
                      "error": "not_yet_available",
                      "errorStatus": 501,
                      "message": "pages after the first are not available yet; call without max_cursor for page 1",
                      "credits_charged": 0
                    }
                  }
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/UpstreamFailed"
          },
          "503": {
            "$ref": "#/components/responses/NotPriced"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/tiktok/search/keyword": {
      "get": {
        "operationId": "tiktokSearchKeyword",
        "tags": [
          "TikTok"
        ],
        "summary": "Keyword search",
        "description": "TikTok's Top results for a keyword, one page per call. Send back `cursor`\nfor the next page; on the last page `has_more` is `0` and there is no\n`cursor`.\n\n**Cursors** are bound to your API key, the query and the region page 1\ncame from, and expire after 24 hours. Another key or query:\n`400 invalid_cursor`. Older than 24 h (or TikTok expired the session):\n`400 cursor_expired`. Page 1's IP session gone: `409 cursor_exit_gone`.\nA later page only available from another country: `409 cursor_region_changed`.\nIn every case, start again from page 1 without a cursor. A cursor is an\ninteger of at most 2^53 - 1.\n\n**Region.** We search from the US, and from Canada when US capacity is\nshort. `X-Search-Region` says which (`US` or `CA`); all pages of one\nsearch come from the same region. `region=CA` searches from Canada only.\n\nPage size is what TikTok's Top tab returns (median 23 on page 1 on 31 Oct 2026).\nLatency (31 Oct 2026, 90 pages, pages 1 to 3): p50 3.9 s, p95 8.9 s.\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 1,
          "unit": "page",
          "status": "set"
        },
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "The keyword. Trimmed. At most 200 bytes, valid UTF-8.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "example": "protein"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `cursor` of the previous page. Absent, empty or `0` means page 1.",
            "schema": {
              "type": "string"
            },
            "example": "4503599627370495"
          },
          {
            "name": "date_posted",
            "in": "query",
            "required": false,
            "description": "`all-time` or absent. `yesterday`, `this-week`, `this-month`, `last-3-months` and `last-6-months` are `400 unsupported_parameter`; anything else `400 bad_request`.",
            "schema": {
              "type": "string",
              "enum": [
                "all-time",
                "yesterday",
                "this-week",
                "this-month",
                "last-3-months",
                "last-6-months"
              ],
              "default": "all-time"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "`relevance` or absent. `most-liked` and `date-posted` are `400 unsupported_parameter`; anything else `400 bad_request`.",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "most-liked",
                "date-posted"
              ],
              "default": "relevance"
            }
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Two letters, or absent. `CA` (any case) searches from Canada only; any other two letters use the default order (US, then Canada). Not two letters is `400 bad_request`.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$"
            },
            "example": "CA"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "One page of results. Charged.",
            "x-charged": true,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-Search-Region": {
                "$ref": "#/components/headers/XSearchRegion"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchKeywordResponse"
                },
                "examples": {
                  "page1": {
                    "summary": "Page 1 (our shaper on our fixture, list cut to one item; the cursor is a stand-in)",
                    "value": {
                      "credits_charged": 1,
                      "credits_remaining": 999,
                      "cursor": 4503599627370495,
                      "has_more": 1,
                      "search_item_list": [
                        {
                          "aweme_info": {
                            "added_sound_music_info": null,
                            "aigc_info": null,
                            "anchors": null,
                            "anchors_extras": null,
                            "animated_image_info": null,
                            "author": {
                              "avatar_168x168": null,
                              "avatar_300x300": null,
                              "avatar_larger": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/al.jpg"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "avatar_medium": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/am.jpg"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "avatar_thumb": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/at.jpg"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "aweme_count": 2017,
                              "commerce_user_level": null,
                              "custom_verify": null,
                              "enterprise_verify_reason": null,
                              "follower_count": 4100000,
                              "following_count": 74,
                              "hide_search": null,
                              "ins_id": null,
                              "is_star": null,
                              "nickname": "Dave Portnoy",
                              "sec_uid": "MS4wLjABAAAAINC_ElRR",
                              "secret": 0,
                              "short_id": null,
                              "total_favorited": 190400000,
                              "uid": "6659752019493208069",
                              "unique_id": "stoolpresidente",
                              "verification_type": 1,
                              "with_commerce_entry": null
                            },
                            "author_user_id": 6659752019493208000,
                            "aweme_acl": null,
                            "aweme_id": "7334621391758642478",
                            "aweme_type": null,
                            "banners": null,
                            "behind_the_song_music_ids": null,
                            "behind_the_song_video_music_ids": null,
                            "bodydance_score": null,
                            "branded_content_accounts": null,
                            "c2pa_info": null,
                            "cc_template_info": null,
                            "cha_list": [
                              {
                                "cha_name": "gym",
                                "cid": "1",
                                "desc": ""
                              }
                            ],
                            "challenge_position": null,
                            "cmt_swt": null,
                            "collect_stat": null,
                            "comment_config": null,
                            "comment_topbar_info": null,
                            "commerce_config_data": null,
                            "commerce_info": null,
                            "content_desc": null,
                            "content_desc_extra": null,
                            "content_model": null,
                            "content_original_type": null,
                            "content_size_type": null,
                            "content_type": null,
                            "cover_labels": null,
                            "create_time": 1707840000,
                            "create_time_utc": "2024-02-13T16:00:00.000Z",
                            "creation_info": null,
                            "desc": "leg day #gym",
                            "desc_language": null,
                            "disable_search_trending_bar": null,
                            "distance": null,
                            "distribute_type": null,
                            "follow_up_item_id_groups": null,
                            "follow_up_publish_from_id": null,
                            "geofencing": null,
                            "geofencing_regions": null,
                            "green_screen_materials": null,
                            "group_id": "7334621391758642478",
                            "group_id_list": null,
                            "has_danmaku": null,
                            "has_promote_entry": null,
                            "has_vs_entry": null,
                            "have_dashboard": null,
                            "hybrid_label": null,
                            "image_infos": null,
                            "interact_permission": null,
                            "interaction_stickers": null,
                            "is_ad": false,
                            "is_ads": false,
                            "is_description_translatable": null,
                            "is_eligible_for_commission": null,
                            "is_hash_tag": null,
                            "is_nff_or_nr": null,
                            "is_on_this_day": null,
                            "is_paid_partnership": null,
                            "is_pgcshow": null,
                            "is_preview": null,
                            "is_relieve": null,
                            "is_text_sticker_translatable": null,
                            "is_title_translatable": null,
                            "is_top": null,
                            "is_vr": null,
                            "item_comment_settings": null,
                            "item_duet": null,
                            "item_react": null,
                            "item_stitch": null,
                            "label_top": null,
                            "label_top_text": null,
                            "long_video": null,
                            "main_arch_common": null,
                            "mask_infos": null,
                            "meme_reg_info": null,
                            "misc_info": null,
                            "muf_comment_info_v2": null,
                            "music": {
                              "author": "Dave Portnoy",
                              "duration": 89,
                              "id_str": "7470969632736709422",
                              "is_original_sound": true,
                              "owner_handle": null,
                              "title": "original sound - stoolpresidente"
                            },
                            "music_begin_time_in_ms": null,
                            "music_end_time_in_ms": null,
                            "music_selected_from": null,
                            "music_title_style": null,
                            "music_volume": null,
                            "need_trim_step": null,
                            "need_vs_entry": null,
                            "nickname_position": null,
                            "no_selected_music": null,
                            "operator_boost_info": null,
                            "origin_comment_ids": null,
                            "origin_volume": null,
                            "original_client_text": null,
                            "picked_users": null,
                            "playlist_blocked": null,
                            "poi_re_tag_signal": null,
                            "position": null,
                            "prevent_download": null,
                            "products_info": null,
                            "promote_capcut_toggle": null,
                            "promote_icon_text": null,
                            "promote_toast": null,
                            "promote_toast_key": null,
                            "question_list": null,
                            "quick_reply_emojis": null,
                            "rate": null,
                            "reference_tts_voice_ids": null,
                            "reference_voice_filter_ids": null,
                            "region": "US",
                            "risk_infos": null,
                            "search_desc": null,
                            "search_highlight": null,
                            "share_info": null,
                            "share_url": "https://www.tiktok.com/@stoolpresidente/video/7334621391758642478",
                            "shoot_tab_name": null,
                            "shop_product_url": null,
                            "social_interaction_blob": null,
                            "solaria_profile": null,
                            "sort_label": null,
                            "standard_component_info": null,
                            "statistics": {
                              "aweme_id": "7334621391758642478",
                              "collect_count": 274,
                              "comment_count": 152,
                              "digg_count": 18651,
                              "download_count": null,
                              "forward_count": null,
                              "lose_comment_count": null,
                              "lose_count": null,
                              "play_count": 141567,
                              "repost_count": null,
                              "share_count": 237,
                              "whatsapp_share_count": null
                            },
                            "status": {
                              "allow_comment": null,
                              "allow_share": null,
                              "aweme_id": "7334621391758642478",
                              "is_delete": null,
                              "is_prohibited": null,
                              "private_status": 0,
                              "self_see": null
                            },
                            "suggest_words": null,
                            "support_danmaku": null,
                            "text_extra": [
                              {
                                "end": 12,
                                "hashtag_id": "1",
                                "hashtag_name": "gym",
                                "sec_uid": "",
                                "start": 8,
                                "type": 1,
                                "user_id": ""
                              }
                            ],
                            "text_sticker_major_lang": null,
                            "title_language": null,
                            "ttec_suggest_words": null,
                            "tts_voice_ids": null,
                            "uniqid_position": null,
                            "upvote_info": null,
                            "upvote_preload": null,
                            "url": "https://www.tiktok.com/@stoolpresidente/video/7334621391758642478",
                            "used_full_song": null,
                            "user_digged": null,
                            "video": {
                              "CoverTsp": null,
                              "ai_dynamic_cover": null,
                              "ai_dynamic_cover_bak": null,
                              "animated_cover": null,
                              "big_thumbs": null,
                              "bit_rate": null,
                              "bit_rate_audio": null,
                              "cdn_url_expired": null,
                              "cover": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/1.jpg"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "download_addr": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/d.mp4"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "duration": 89000,
                              "dynamic_cover": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/3.jpg"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "has_watermark": null,
                              "height": 1024,
                              "is_bytevc1": null,
                              "is_callback": null,
                              "meta": null,
                              "need_set_token": null,
                              "origin_cover": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/2.jpg"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "play_addr": {
                                "height": null,
                                "uri": null,
                                "url_list": [
                                  "https://c/p.mp4"
                                ],
                                "url_prefix": null,
                                "width": null
                              },
                              "play_addr_bytevc1": null,
                              "play_addr_h264": null,
                              "ratio": "540p",
                              "source_HDR_type": null,
                              "tags": null,
                              "width": 576
                            },
                            "video_control": null,
                            "video_labels": null,
                            "video_text": null,
                            "visual_search_info": null,
                            "voice_filter_ids": null,
                            "with_promotional_music": null,
                            "without_watermark": null
                          }
                        }
                      ],
                      "success": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A bad parameter, or a cursor that cannot be used. Free.",
            "x-charged": false,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteError"
                },
                "examples": {
                  "bad_request": {
                    "value": {
                      "success": false,
                      "error": "bad_request",
                      "errorStatus": 400,
                      "message": "query is required",
                      "credits_charged": 0
                    }
                  },
                  "unsupported_parameter": {
                    "value": {
                      "success": false,
                      "error": "unsupported_parameter",
                      "errorStatus": 400,
                      "message": "sort_by \"most-liked\" is not supported yet; use relevance or leave it out",
                      "credits_charged": 0
                    }
                  },
                  "invalid_cursor": {
                    "value": {
                      "success": false,
                      "error": "invalid_cursor",
                      "errorStatus": 400,
                      "message": "this cursor is not valid for this query; pass a cursor from a previous response to the same query, or none for page 1",
                      "credits_charged": 0
                    }
                  },
                  "cursor_expired": {
                    "value": {
                      "success": false,
                      "error": "cursor_expired",
                      "errorStatus": 400,
                      "message": "this cursor has expired; start again from page 1 without a cursor; not charged",
                      "credits_charged": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "409": {
            "description": "An idempotency conflict, or a cursor whose search session cannot continue. Free.",
            "x-charged": false,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteError"
                },
                "examples": {
                  "idempotency_conflict": {
                    "value": {
                      "success": false,
                      "error": "idempotency_conflict",
                      "errorStatus": 409,
                      "message": "a request with this Idempotency-Key is still in progress; retry after it finishes",
                      "credits_charged": 0,
                      "retry_after_s": 1
                    }
                  },
                  "cursor_region_changed": {
                    "value": {
                      "success": false,
                      "error": "cursor_region_changed",
                      "errorStatus": 409,
                      "message": "this page could only be searched from another region than page 1; start again from page 1 without a cursor; not charged",
                      "credits_charged": 0
                    }
                  },
                  "cursor_exit_gone": {
                    "value": {
                      "success": false,
                      "error": "cursor_exit_gone",
                      "errorStatus": 409,
                      "message": "the search session behind this cursor is gone; start again from page 1 without a cursor; not charged",
                      "credits_charged": 0
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "No capacity to answer within the time limit, or the server is restarting. Free. Wait `Retry-After` seconds.",
            "x-charged": false,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteError"
                },
                "examples": {
                  "over_capacity": {
                    "$ref": "#/components/examples/OverCapacity"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamFailed"
          },
          "503": {
            "description": "No search IP can serve now (`search_unavailable`, `Retry-After: 60`), or the route is not priced. Free.",
            "x-charged": false,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteError"
                },
                "examples": {
                  "search_unavailable": {
                    "value": {
                      "success": false,
                      "error": "search_unavailable",
                      "errorStatus": 503,
                      "message": "no search capacity right now; retry later; not charged",
                      "credits_charged": 0,
                      "retry_after_s": 60
                    }
                  },
                  "route_not_priced": {
                    "$ref": "#/components/examples/NotPriced"
                  }
                }
              }
            }
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/tiktok/user/followers": {
      "get": {
        "operationId": "tiktokUserFollowers",
        "tags": [
          "TikTok"
        ],
        "summary": "Followers",
        "description": "One page of an account's followers, newest first, usually 50. Send back\n`min_time` for the next page; stop when `has_more` is `false`.\n\nEach follower carries every key of ScrapeCreators' item; `region`,\n`create_time` and app-only flags are `null` (TikTok's web list does not\nsend them). Rarely the second half of a page fails: you then get 30,\ncharged, with a `min_time` that resumes right after them.\n\nAn account that does not exist is a 404, free. A private account is a\n200, **charged**, `{\"handle\", \"account_private\": true}`.\n\n**Coming in beta.** Built but not priced for customers: answers\n`503 route_not_priced` until a price row exists.\n",
        "x-status": "coming",
        "x-beta": true,
        "x-credits": {
          "amount": 1,
          "unit": "page",
          "status": "placeholder"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Handle"
          },
          {
            "$ref": "#/components/parameters/UserID"
          },
          {
            "$ref": "#/components/parameters/MinTime"
          },
          {
            "$ref": "#/components/parameters/Trim"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "One page of followers, or the private-account answer. Charged.",
            "x-charged": true,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/FollowersResponse"
                    },
                    {
                      "$ref": "#/components/schemas/PrivateAccount"
                    }
                  ]
                },
                "examples": {
                  "page": {
                    "summary": "A page (our shaper on our hand-written fixture, list cut to one item)",
                    "value": {
                      "credits_charged": 1,
                      "credits_remaining": 999,
                      "extra": {
                        "fatal_item_ids": [],
                        "logid": "20261030171146081F76B937404FB3139A",
                        "now": 1793380307000
                      },
                      "followers": [
                        {
                          "accept_private_policy": null,
                          "account_labels": null,
                          "account_region": null,
                          "ad_cover_url": null,
                          "advance_feature_item_order": null,
                          "advanced_feature_info": null,
                          "authority_status": null,
                          "avatar_168x168": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:100:100.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_300x300": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:720:720.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_larger": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:1080:1080.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_medium": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:720:720.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_thumb": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:100:100.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                          "aweme_count": 5,
                          "bind_phone": null,
                          "bold_fields": null,
                          "can_message_follow_status_list": null,
                          "can_set_geofencing": null,
                          "cha_list": null,
                          "comment_filter_status": null,
                          "comment_setting": 0,
                          "commerce_user_level": null,
                          "cover_url": null,
                          "create_time": null,
                          "custom_verify": null,
                          "cv_level": null,
                          "download_prompt_ts": null,
                          "download_setting": 3,
                          "duet_setting": 3,
                          "enabled_filter_all_comments": null,
                          "enterprise_verify_reason": null,
                          "events": null,
                          "fake_data_info": null,
                          "favoriting_count": 28191,
                          "follow_status": null,
                          "follower_count": 12,
                          "follower_status": null,
                          "followers_detail": null,
                          "following_count": 2359,
                          "friends_status": null,
                          "geofencing": null,
                          "has_email": null,
                          "has_insights": null,
                          "has_orders": null,
                          "hide_search": null,
                          "homepage_bottom_toast": null,
                          "is_ad_fake": false,
                          "is_block": null,
                          "is_discipline_member": null,
                          "is_mute": null,
                          "is_mute_lives": null,
                          "is_mute_non_story_post": null,
                          "is_mute_story": null,
                          "is_mute_thought": null,
                          "is_phone_binded": null,
                          "is_star": null,
                          "item_list": null,
                          "language": null,
                          "live_agreement": null,
                          "live_commerce": null,
                          "live_verify": null,
                          "mention_status": null,
                          "mutual_relation_avatars": null,
                          "need_points": null,
                          "need_recommend": null,
                          "nickname": "grams",
                          "original_musician": null,
                          "platform_sync_info": null,
                          "prevent_download": null,
                          "react_setting": null,
                          "region": null,
                          "relative_users": null,
                          "reply_with_video_flag": null,
                          "search_highlight": null,
                          "sec_uid": "MS4wLjABAAAAexampleexampleexampleexampleexampleexample1",
                          "secret": 0,
                          "share_info": null,
                          "share_qrcode_uri": null,
                          "shield_comment_notice": null,
                          "shield_digg_notice": null,
                          "shield_edit_field_info": null,
                          "shield_follow_notice": null,
                          "short_id": null,
                          "show_image_bubble": null,
                          "signature": "hi",
                          "special_account": null,
                          "special_lock": null,
                          "status": null,
                          "stitch_setting": 3,
                          "total_favorited": 4,
                          "type_label": null,
                          "uid": "6761309637569709061",
                          "unique_id": "gramsworld",
                          "unique_id_modify_time": null,
                          "user_canceled": null,
                          "user_mode": null,
                          "user_period": null,
                          "user_profile_guide": null,
                          "user_rate": null,
                          "user_spark_info": null,
                          "user_tags": null,
                          "verification_type": null,
                          "verify_info": null,
                          "video_icon": null,
                          "white_cover_url": null,
                          "with_commerce_entry": null,
                          "with_shop_entry": null
                        }
                      ],
                      "has_more": true,
                      "log_pb": {
                        "impr_id": "20261030171146081F76B937404FB3139A"
                      },
                      "max_time": 1793380036,
                      "min_time": 1792981730,
                      "myself_user_id": "0",
                      "next_page_token": "eyJtYXhfY3Vyc29yIjoxNzkzMzgwMDM2LCJtaW5fY3Vyc29yIjoxNzkyOTgxNzMwfQ==",
                      "offset": 0,
                      "status_code": 0,
                      "status_msg": "",
                      "success": true,
                      "total": 221779
                    }
                  },
                  "private": {
                    "summary": "A private account (charged)",
                    "value": {
                      "success": true,
                      "credits_charged": 1,
                      "credits_remaining": 998,
                      "handle": "example.private",
                      "account_private": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamFailed"
          },
          "503": {
            "$ref": "#/components/responses/NotPriced"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/tiktok/user/following": {
      "get": {
        "operationId": "tiktokUserFollowing",
        "tags": [
          "TikTok"
        ],
        "summary": "Following",
        "description": "One page of the accounts an account follows, newest follow first, usually\n50. Send back `min_time` for the next page; stop when `has_more` is `false`.\n`rec_has_more` always equals `has_more`.\n\n**A hidden list is free:** 200, `credits_charged: 0`, the page shape with\nno accounts, `following_hidden: true` and `total: null`. It counts toward\nthe free-answer limit.\n\nAn account that does not exist is a 404, free. A private account is a\n200, **charged**, `{\"handle\", \"account_private\": true}`.\n\n**Coming.** Built but not priced: answers `503 route_not_priced` until a\nprice row exists.\n",
        "x-status": "coming",
        "x-beta": true,
        "x-credits": {
          "amount": 1,
          "unit": "page",
          "status": "placeholder"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Handle"
          },
          {
            "$ref": "#/components/parameters/UserID"
          },
          {
            "$ref": "#/components/parameters/MinTime"
          },
          {
            "$ref": "#/components/parameters/Trim"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "A page (charged), a hidden list (free, `credits_charged` 0), or the private-account answer (charged).",
            "x-charged": "conditional",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/FollowingResponse"
                    },
                    {
                      "$ref": "#/components/schemas/PrivateAccount"
                    }
                  ]
                },
                "examples": {
                  "page": {
                    "summary": "A page (our shaper on our hand-written fixture, list cut to one item)",
                    "value": {
                      "credits_charged": 1,
                      "credits_remaining": 999,
                      "extra": {
                        "fatal_item_ids": [],
                        "logid": "20261030171146081F76B937404FB3139A",
                        "now": 1793380307000
                      },
                      "followings": [
                        {
                          "accept_private_policy": null,
                          "account_labels": null,
                          "account_region": null,
                          "ad_cover_url": null,
                          "advance_feature_item_order": null,
                          "advanced_feature_info": null,
                          "authority_status": null,
                          "avatar_168x168": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:100:100.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_300x300": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:720:720.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_larger": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:1080:1080.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_medium": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:720:720.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_thumb": {
                            "data_size": 0,
                            "height": 720,
                            "uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                            "url_list": [
                              "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2~tplv-tiktokx-cropcenter:100:100.jpeg?x-expires=1793466000"
                            ],
                            "url_prefix": null,
                            "width": 720
                          },
                          "avatar_uri": "tos-maliva-avt-0068/d6a1705a030406c01fb474ce6cc6f0c2",
                          "aweme_count": 5,
                          "bind_phone": null,
                          "bold_fields": null,
                          "can_message_follow_status_list": null,
                          "can_set_geofencing": null,
                          "cha_list": null,
                          "comment_filter_status": null,
                          "comment_setting": 0,
                          "commerce_user_level": null,
                          "cover_url": null,
                          "create_time": null,
                          "custom_verify": null,
                          "cv_level": null,
                          "download_prompt_ts": null,
                          "download_setting": 3,
                          "duet_setting": 3,
                          "enabled_filter_all_comments": null,
                          "enterprise_verify_reason": null,
                          "events": null,
                          "fake_data_info": null,
                          "favoriting_count": 28191,
                          "follow_status": null,
                          "follower_count": 12,
                          "follower_status": null,
                          "followers_detail": null,
                          "following_count": 2359,
                          "friends_status": null,
                          "geofencing": null,
                          "has_email": null,
                          "has_insights": null,
                          "has_orders": null,
                          "hide_search": null,
                          "homepage_bottom_toast": null,
                          "is_ad_fake": false,
                          "is_block": null,
                          "is_discipline_member": null,
                          "is_mute": null,
                          "is_mute_lives": null,
                          "is_mute_non_story_post": null,
                          "is_mute_story": null,
                          "is_mute_thought": null,
                          "is_phone_binded": null,
                          "is_star": null,
                          "item_list": null,
                          "language": null,
                          "live_agreement": null,
                          "live_commerce": null,
                          "live_verify": null,
                          "mention_status": null,
                          "mutual_relation_avatars": null,
                          "need_points": null,
                          "need_recommend": null,
                          "nickname": "grams",
                          "original_musician": null,
                          "platform_sync_info": null,
                          "prevent_download": null,
                          "react_setting": null,
                          "region": null,
                          "relative_users": null,
                          "reply_with_video_flag": null,
                          "search_highlight": null,
                          "sec_uid": "MS4wLjABAAAAexampleexampleexampleexampleexampleexample1",
                          "secret": 0,
                          "share_info": null,
                          "share_qrcode_uri": null,
                          "shield_comment_notice": null,
                          "shield_digg_notice": null,
                          "shield_edit_field_info": null,
                          "shield_follow_notice": null,
                          "short_id": null,
                          "show_image_bubble": null,
                          "signature": "hi",
                          "special_account": null,
                          "special_lock": null,
                          "status": null,
                          "stitch_setting": 3,
                          "total_favorited": 4,
                          "type_label": null,
                          "uid": "6761309637569709061",
                          "unique_id": "gramsworld",
                          "unique_id_modify_time": null,
                          "user_canceled": null,
                          "user_mode": null,
                          "user_period": null,
                          "user_profile_guide": null,
                          "user_rate": null,
                          "user_spark_info": null,
                          "user_tags": null,
                          "verification_type": null,
                          "verify_info": null,
                          "video_icon": null,
                          "white_cover_url": null,
                          "with_commerce_entry": null,
                          "with_shop_entry": null
                        }
                      ],
                      "has_more": true,
                      "log_pb": {
                        "impr_id": "20261030171146081F76B937404FB3139A"
                      },
                      "max_time": 1793380036,
                      "min_time": 1792981730,
                      "myself_user_id": "0",
                      "next_page_token": "eyJtYXhfY3Vyc29yIjoxNzkzMzgwMDM2LCJtaW5fY3Vyc29yIjoxNzkyOTgxNzMwfQ==",
                      "offset": 0,
                      "rec_has_more": true,
                      "status_code": 0,
                      "status_msg": "",
                      "success": true,
                      "total": 221779
                    }
                  },
                  "hidden": {
                    "summary": "A hidden following list (free)",
                    "value": {
                      "success": true,
                      "credits_charged": 0,
                      "credits_remaining": 1000,
                      "extra": {
                        "fatal_item_ids": [],
                        "logid": "",
                        "now": null
                      },
                      "followings": [],
                      "following_hidden": true,
                      "handle": "example.hidden",
                      "has_more": false,
                      "log_pb": {
                        "impr_id": ""
                      },
                      "max_time": 0,
                      "min_time": 0,
                      "myself_user_id": "0",
                      "next_page_token": "eyJtYXhfY3Vyc29yIjowLCJtaW5fY3Vyc29yIjowfQ==",
                      "offset": 0,
                      "rec_has_more": false,
                      "status_code": 0,
                      "status_msg": "",
                      "total": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamFailed"
          },
          "503": {
            "$ref": "#/components/responses/NotPriced"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/tiktok/user/audience": {
      "get": {
        "operationId": "tiktokUserAudience",
        "tags": [
          "TikTok"
        ],
        "summary": "Audience",
        "description": "The countries of an account's followers, estimated from a sample: we read\nthe newest 720 followers and place up to 150 by the country their latest\nvideo was posted from. **Estimates, subject to change.**\n\nUsually 35 to 40 seconds; up to **5 minutes**. Set your client timeout to\nat least 6 minutes.\n\n**Charged only when 30 or more followers are placed.** 1 to 29 placed:\n200, free, `X-Audience-Confidence: low`. None placed: 200,\n`audienceLocations: []`, free. Private account: 200, free,\n`{\"account_private\": true, \"handle\"}`. Some free answers are kept per\naccount (24 h; private 6 h) and served again with `X-Audience-Cached`.\n\nLimits: 2 audience requests in flight per key (a third is\n`429 rate_limited`, `Retry-After: 30`); past 100 free answers in 10\nminutes, audience requests from the key are refused **before** they run.\n\n**Coming in beta.** Answers `503 route_not_priced` until priced.\n",
        "x-status": "coming",
        "x-beta": true,
        "x-credits": {
          "amount": 20,
          "unit": "call",
          "status": "placeholder"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/HandleOnly"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The country breakdown (charged at 30+ placed, else free), or the private answer (free).",
            "x-charged": "conditional",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              },
              "X-Audience-Sample-Size": {
                "description": "How many followers the breakdown counts (the sum of `count`).",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Audience-Confidence": {
                "description": "`normal` at 100 or more placed, `low` under 100, `none` when no follower could be placed.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "normal",
                    "low",
                    "none"
                  ]
                }
              },
              "X-Audience-Notice": {
                "description": "A fixed notice that the figures are estimates.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Audience-Cached": {
                "description": "Only on a stored free answer. When it was made, RFC 3339 UTC.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/AudienceResponse"
                    },
                    {
                      "$ref": "#/components/schemas/PrivateAccount"
                    }
                  ]
                },
                "examples": {
                  "breakdown": {
                    "summary": "Our own live answer for karlaakat (smoke, 31 Oct 2026), cut to 3 of 22 countries",
                    "description": "The example file is rendered with the generic 1-credit envelope; a charged audience answer carries `credits_charged` 20.",
                    "value": {
                      "audienceLocations": [
                        {
                          "count": 115,
                          "country": "United States",
                          "countryCode": "US",
                          "percentage": "70.55%"
                        },
                        {
                          "count": 19,
                          "country": "Mexico",
                          "countryCode": "MX",
                          "percentage": "11.66%"
                        },
                        {
                          "count": 3,
                          "country": "Chile",
                          "countryCode": "CL",
                          "percentage": "1.84%"
                        }
                      ],
                      "credits_charged": 1,
                      "credits_remaining": 999,
                      "success": true
                    }
                  },
                  "private": {
                    "summary": "A private account (free)",
                    "value": {
                      "success": true,
                      "credits_charged": 0,
                      "credits_remaining": 1000,
                      "account_private": true,
                      "handle": "example.private"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "description": "Over capacity (`over_capacity`), or the key's audience limits (`rate_limited`). Free.",
            "x-charged": false,
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteError"
                },
                "examples": {
                  "over_capacity": {
                    "$ref": "#/components/examples/OverCapacity"
                  },
                  "rate_limited": {
                    "value": {
                      "success": false,
                      "error": "rate_limited",
                      "errorStatus": 429,
                      "message": "this key already has 2 audience requests in progress; retry after retry_after_s seconds; not charged",
                      "credits_charged": 0,
                      "retry_after_s": 30
                    }
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Internal"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamFailed"
          },
          "503": {
            "$ref": "#/components/responses/NotPriced"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        }
      }
    },
    "/v1/jobs": {
      "post": {
        "operationId": "submitJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Submit a job",
        "description": "Queue a bulk job and hold its credits. Answers `202` at once; poll\n`poll_url`. Handles lose a leading `@`; units are trimmed and deduplicated\ncase-insensitively; at most 50,000 units per job.\n\n**Billing is per unit attempted, not per result found**, at the job kind's\nprice pinned at submit. The whole hold is taken now; unused credit comes\nback when the job finishes or is cancelled.\n\n`Idempotency-Key`: the same key with the same request returns the same job\n(`Idempotency-Replayed: true`, `idempotent_replay: true`), no second hold.\nThe same key with a different request is `409 idempotency_conflict`.\n\nUnknown body fields are a 400. Per-key rate limit and a per-key cap on\nqueued plus running jobs apply (`429 rate_limited`, `429 concurrency_limit`).\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 1,
          "unit": "unit attempted (keyword or handle)",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitRequest"
              },
              "examples": {
                "walk": {
                  "summary": "A TikTok walk with an early-stop rule",
                  "value": {
                    "kind": "tiktok.walk",
                    "handles": [
                      "lucymfit",
                      "@dishes.easyrecieps"
                    ],
                    "options": {
                      "max_videos": 120,
                      "early_stop": {
                        "min_reels_per_week": 3,
                        "full_weeks": 4,
                        "ignore_current_week": true,
                        "reel_kinds": [
                          "video"
                        ],
                        "views": {
                          "min_views_per_video": 40000,
                          "min_share_clearing": 0.8,
                          "band_min_age_days": 10,
                          "band_max_age_days": 40,
                          "min_band_videos": 5,
                          "exclude_pinned": true
                        }
                      }
                    }
                  }
                },
                "search": {
                  "summary": "TikTok keyword search from Canada only",
                  "value": {
                    "kind": "tiktok.search",
                    "keywords": [
                      "protein",
                      "meal prep"
                    ],
                    "options": {
                      "region": "CA"
                    }
                  }
                },
                "instagram": {
                  "summary": "Instagram profile and feed fetch",
                  "value": {
                    "kind": "instagram.fetch",
                    "handles": [
                      "example.creator"
                    ]
                  }
                },
                "audience": {
                  "summary": "TikTok audience share with a 45% US+CA cutoff",
                  "value": {
                    "kind": "tiktok.audience",
                    "handles": [
                      "karlaakat"
                    ],
                    "options": {
                      "us_ca_share_min": 0.45
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted (or replayed for the same Idempotency-Key). Credits are held, not yet spent.",
            "x-charged": "conditional",
            "headers": {
              "Idempotency-Replayed": {
                "description": "`true` when an earlier job with this Idempotency-Key and the same request was returned.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                },
                "examples": {
                  "accepted": {
                    "summary": "Illustrative (shape from cmd/apiserver/jobs.go writeAccepted)",
                    "value": {
                      "job_id": 685,
                      "job": {
                        "id": 685,
                        "kind": "tiktok.walk",
                        "state": "queued",
                        "priority": 120,
                        "progress": {
                          "units_done": 0,
                          "units_total": 2
                        },
                        "credits": {
                          "held_micro": 2000000,
                          "spent_micro": 0,
                          "held": "2.000000",
                          "spent": "0.000000"
                        },
                        "created_at": "2026-11-05T10:00:00Z"
                      },
                      "poll_url": "/v1/jobs/685"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/JobInsufficientCredits"
          },
          "409": {
            "$ref": "#/components/responses/JobIdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/JobTooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          }
        }
      },
      "get": {
        "operationId": "listJobs",
        "tags": [
          "Jobs"
        ],
        "summary": "List jobs",
        "description": "This key's jobs, newest first, without chunks or results. Free.",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 0,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Comma-separated or repeated filter.",
            "schema": {
              "type": "string"
            },
            "example": "running,queued"
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "Comma-separated or repeated filter, one of the job kinds.",
            "schema": {
              "type": "string"
            },
            "example": "tiktok.walk"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PageCursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of jobs. Free.",
            "x-charged": false,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobList"
                },
                "examples": {
                  "jobs": {
                    "summary": "The real final state of job 533 (docs/results/2026-10-31-search-inpage-deployed/job533.json)",
                    "value": {
                      "jobs": [
                        {
                          "id": 533,
                          "kind": "tiktok.search",
                          "state": "failed",
                          "priority": 30,
                          "progress": {
                            "units_done": 0,
                            "units_total": 20
                          },
                          "credits": {
                            "held_micro": 20000000,
                            "spent_micro": 0,
                            "held": "20.000000",
                            "spent": "0.000000"
                          },
                          "error": "ttsearch: exit status 1: ***  IN-HOUSE SEARCH RETURNED NOTHING  ***",
                          "created_at": "2026-10-31T02:37:56.843367Z",
                          "started_at": "2026-10-31T02:37:56.860944Z",
                          "finished_at": "2026-10-31T02:38:55.516451Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "429": {
            "$ref": "#/components/responses/JobRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          }
        }
      }
    },
    "/v1/search": {
      "post": {
        "operationId": "searchSync",
        "tags": [
          "Jobs"
        ],
        "summary": "Submit a job and wait for it",
        "description": "The same body as `POST /v1/jobs`, run ahead of queued work and held open\nuntil it finishes or the server's synchronous cap (`CS_SEARCH_TIMEOUT`,\ndefault 30 s) passes. Finished: `200` with the job and the first page of\nresults. Still running: `202` with `poll_url`; the job is queued and paid\nfor, so poll rather than resubmit. At most `CS_SEARCH_MAX_UNITS` units\n(default 200). `priority` is not settable here (400).\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 1,
          "unit": "unit attempted (keyword or handle)",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows per list in the finished answer.",
            "schema": {
              "type": "integer",
              "default": 100,
              "minimum": 1,
              "maximum": 500
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitRequest"
              },
              "examples": {
                "search": {
                  "value": {
                    "kind": "tiktok.search",
                    "keywords": [
                      "protein"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The finished job with the first page of each list. Units already billed at submit.",
            "x-charged": true,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobDetail"
                },
                "examples": {
                  "finished": {
                    "summary": "Illustrative (shape from cmd/apiserver/search.go)",
                    "value": {
                      "id": 701,
                      "kind": "tiktok.search",
                      "state": "done",
                      "priority": 10,
                      "progress": {
                        "units_done": 1,
                        "units_total": 1,
                        "chunks": {
                          "queued": 0,
                          "running": 0,
                          "done": 1,
                          "failed": 0
                        },
                        "units_fetched": 1,
                        "last_progress_at": "2026-11-06T09:00:12Z"
                      },
                      "credits": {
                        "held_micro": 0,
                        "spent_micro": 1000000,
                        "held": "0.000000",
                        "spent": "1.000000"
                      },
                      "created_at": "2026-11-06T09:00:00Z",
                      "started_at": "2026-11-06T09:00:01Z",
                      "finished_at": "2026-11-06T09:00:12Z",
                      "results": {
                        "creators": [
                          {
                            "id": 42,
                            "platform": "tiktok",
                            "handle": "example.creator",
                            "followers": 120000,
                            "first_seen": "2026-09-18T10:00:00Z",
                            "last_seen": "2026-11-06T09:00:12Z"
                          }
                        ],
                        "media": [
                          {
                            "external_id": "7334621391758642478",
                            "creator_handle": "example.creator",
                            "caption": "leg day #gym",
                            "plays": 141567,
                            "posted_at": "2024-02-13T16:00:00Z",
                            "keyword": "protein",
                            "region": "US"
                          }
                        ],
                        "units": [
                          {
                            "unit": "protein",
                            "outcome": "answered",
                            "region": "US",
                            "tries": 1,
                            "billed": true
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Still running past the synchronous cap. Poll `poll_url`; do not resubmit.",
            "x-charged": "conditional",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchAccepted"
                },
                "examples": {
                  "running": {
                    "value": {
                      "job_id": 702,
                      "job": {
                        "id": 702,
                        "kind": "tiktok.search",
                        "state": "running",
                        "priority": 10,
                        "progress": {
                          "units_done": 0,
                          "units_total": 150
                        },
                        "credits": {
                          "held_micro": 150000000,
                          "spent_micro": 0,
                          "held": "150.000000",
                          "spent": "0.000000"
                        },
                        "created_at": "2026-11-06T09:00:00Z",
                        "started_at": "2026-11-06T09:00:01Z"
                      },
                      "poll_url": "/v1/jobs/702",
                      "message": "still running after 30s; the job is queued and paid for -- poll poll_url rather than resubmitting"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/JobInsufficientCredits"
          },
          "409": {
            "$ref": "#/components/responses/JobIdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/JobTooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Get a job and page its results",
        "description": "The job, its first chunks, and (unless `results=false`) one page of each\nof its result lists. Free: every row was paid for when the job ran.\n\n**Lists by kind:** every kind has `creators` and `media`;\n`tiktok.search` media are its search hits and it adds `units`;\n`tiktok.walk` and `instagram.fetch` add `walks`; `tiktok.audience` adds\n`audience`. Page each list on its own with its cursor until the\n`next_*_cursor` key is absent.\n\n**Cursors (v2).** `creators` and `media` come in ascending id order since\n2026-11-09 and their cursors are version 2. A version-1 cursor from the\nold plays/followers order is `400 cursor_expired`: restart without a\ncursor. A cursor that does not parse, or is from another list, is\n`400 bad_request`.\n\n**`sections=`** reads only the named lists. Lists left out keep the\nkind's shape (`creators: []`, `media: []`, other lists absent) with no\nnext cursor. Without it every request reads the first page of every list.\n\nPage a job only after it is done: while it runs, a newly linked row can\nland behind your cursor. For a whole job, use the export.\n\nAnother key's job is `404`, the same as a job that does not exist.\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 0,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/JobID"
          },
          {
            "name": "results",
            "in": "query",
            "required": false,
            "description": "`false` leaves out `results`. An unparseable value counts as the default.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "chunks",
            "in": "query",
            "required": false,
            "description": "How many chunk rows to include.",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 0
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "sections",
            "in": "query",
            "required": false,
            "description": "Comma list of the lists to read.",
            "schema": {
              "type": "string",
              "pattern": "^(creators|media|walks|audience|units)(,(creators|media|walks|audience|units))*$"
            },
            "example": "walks"
          },
          {
            "name": "units",
            "in": "query",
            "required": false,
            "description": "`failed` narrows `units` (tiktok.search) to the failures.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "failed"
              ],
              "default": "all"
            }
          },
          {
            "name": "creator_cursor",
            "in": "query",
            "required": false,
            "description": "`next_creator_cursor` of the previous page (v2).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "media_cursor",
            "in": "query",
            "required": false,
            "description": "`next_media_cursor` of the previous page (v2).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "walk_cursor",
            "in": "query",
            "required": false,
            "description": "`next_walk_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "audience_cursor",
            "in": "query",
            "required": false,
            "description": "`next_audience_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unit_cursor",
            "in": "query",
            "required": false,
            "description": "`next_unit_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job. Free.",
            "x-charged": false,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobDetail"
                },
                "examples": {
                  "failed_search": {
                    "summary": "The real final state of job 533 (docs/results/2026-10-31-search-inpage-deployed/job533.json), results=false",
                    "value": {
                      "id": 533,
                      "kind": "tiktok.search",
                      "state": "failed",
                      "priority": 30,
                      "progress": {
                        "units_done": 0,
                        "units_total": 20,
                        "chunks": {
                          "queued": 0,
                          "running": 0,
                          "done": 0,
                          "failed": 1
                        },
                        "units_fetched": 0,
                        "last_progress_at": "2026-10-31T02:38:55.516451Z"
                      },
                      "credits": {
                        "held_micro": 20000000,
                        "spent_micro": 0,
                        "held": "20.000000",
                        "spent": "0.000000"
                      },
                      "error": "ttsearch: exit status 1: ***  IN-HOUSE SEARCH RETURNED NOTHING  ***",
                      "created_at": "2026-10-31T02:37:56.843367Z",
                      "started_at": "2026-10-31T02:37:56.860944Z",
                      "finished_at": "2026-10-31T02:38:55.516451Z",
                      "chunks": [
                        {
                          "seq": 0,
                          "state": "failed",
                          "attempts": 1,
                          "units_done": 0,
                          "units_total": 20,
                          "requests": 60,
                          "bytes_webshare": 0,
                          "bytes_dataimpulse": 0,
                          "error": "ttsearch: exit status 1: ***  IN-HOUSE SEARCH RETURNED NOTHING  ***",
                          "claimed_at": "2026-10-31T02:37:56.860944Z",
                          "finished_at": "2026-10-31T02:38:55.516451Z"
                        }
                      ]
                    }
                  },
                  "walk_sections": {
                    "summary": "Illustrative walk job read with sections=walks (field values from docs/API_SERVICE_DESIGN.md 8.1)",
                    "value": {
                      "id": 123,
                      "kind": "tiktok.walk",
                      "state": "done",
                      "priority": 120,
                      "progress": {
                        "units_done": 20,
                        "units_total": 20,
                        "chunks": {
                          "queued": 0,
                          "running": 0,
                          "done": 1,
                          "failed": 0
                        },
                        "units_fetched": 20,
                        "last_progress_at": "2026-09-29T12:10:00Z"
                      },
                      "credits": {
                        "held_micro": 0,
                        "spent_micro": 20000000,
                        "held": "0.000000",
                        "spent": "20.000000"
                      },
                      "created_at": "2026-09-29T12:00:00Z",
                      "started_at": "2026-09-29T12:00:05Z",
                      "finished_at": "2026-09-29T12:10:00Z",
                      "results": {
                        "creators": [],
                        "media": [],
                        "walks": [
                          {
                            "handle": "lucymfit",
                            "platform": "tiktok",
                            "creator_id": 42,
                            "outcome": "ok",
                            "items": 24,
                            "videos": 23,
                            "photos": 1,
                            "pinned": 2,
                            "oldest_days": 19.4,
                            "has_more": true,
                            "short": false,
                            "stopped_early": true,
                            "stop_reason": "early_stop",
                            "stop_detail": "week of 2026-09-21 has 2 reels, needs 3",
                            "weeks_covered": 1,
                            "band_videos": 3,
                            "secs": 38.5,
                            "walked_at": "2026-09-29T12:03:00Z"
                          }
                        ],
                        "next_walk_cursor": "eyJ2IjoxLCJpIjo5OTl9"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequestOrCursorExpired"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "429": {
            "$ref": "#/components/responses/JobRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          }
        }
      }
    },
    "/v1/jobs/{id}/cancel": {
      "post": {
        "operationId": "cancelJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Cancel a job",
        "description": "Stop a `queued` or `running` job and refund what it has not spent. Work\nalready under way finishes and is billed; nothing is deleted. A job in\nany other state is `400 bad_request`. Free.\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 0,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/JobID"
          }
        ],
        "responses": {
          "200": {
            "description": "The job after the cancel and refund.",
            "x-charged": false,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "examples": {
                  "canceled": {
                    "summary": "Illustrative",
                    "value": {
                      "id": 686,
                      "kind": "instagram.fetch",
                      "state": "canceled",
                      "priority": 100,
                      "progress": {
                        "units_done": 50,
                        "units_total": 200
                      },
                      "credits": {
                        "held_micro": 0,
                        "spent_micro": 50000000,
                        "held": "0.000000",
                        "spent": "50.000000"
                      },
                      "created_at": "2026-11-05T10:00:00Z",
                      "started_at": "2026-11-05T10:00:02Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "429": {
            "$ref": "#/components/responses/JobRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          }
        }
      }
    },
    "/v1/jobs/{id}/export": {
      "post": {
        "operationId": "requestJobExport",
        "tags": [
          "Jobs"
        ],
        "summary": "Start an export",
        "description": "Write all of a finished job's results as gzipped NDJSON files, read in one\ndatabase snapshot. Free; owner key only. The job must be `done`,\n`failed` or `canceled` with `finished_at` set, else `409 job_not_finished`.\n\nIdempotent: POST again and you get the same export, not rebuilt. It is\nrebuilt only when the last export failed or the job finished again after\nit was built. `202` while it builds, with `Location` and `Retry-After: 5`.\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 0,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/JobID"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/ExportDone"
          },
          "202": {
            "$ref": "#/components/responses/ExportPending"
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "409": {
            "$ref": "#/components/responses/JobNotFinished"
          },
          "429": {
            "$ref": "#/components/responses/JobRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          },
          "503": {
            "$ref": "#/components/responses/ExportUnavailable"
          }
        }
      },
      "get": {
        "operationId": "getJobExport",
        "tags": [
          "Jobs"
        ],
        "summary": "Poll and download an export",
        "description": "The export's state; once `done`, one presigned URL per part. Download each\nwith a plain GET and no API key: the URL is the credential. Every GET\nsigns fresh URLs; `urls_expire_at` is when these stop working (24 h at\nmost, sooner when the signing session ends).\n\nSections by job kind: `tiktok.walk` and `instagram.fetch`: creators,\nmedia, walks. `tiktok.search`: creators, media (the hits), units.\n`tiktok.audience`: creators, media, audience. Up to 50,000 rows per file;\neach line is byte-for-byte the object `GET /v1/jobs/{id}` returns in that list.\n\n`stale`: the job finished again after this export was built; no URLs,\nPOST to rebuild.\n",
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 0,
          "unit": "call",
          "status": "set"
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/JobID"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/ExportDone"
          },
          "202": {
            "$ref": "#/components/responses/ExportPending"
          },
          "400": {
            "$ref": "#/components/responses/JobBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/JobUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "409": {
            "$ref": "#/components/responses/JobNotFinished"
          },
          "429": {
            "$ref": "#/components/responses/JobRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/JobInternal"
          },
          "503": {
            "$ref": "#/components/responses/ExportUnavailable"
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "operationId": "healthz",
        "tags": [
          "System"
        ],
        "summary": "Liveness",
        "description": "No auth. `503` with `status: degraded` when the database is unreachable.",
        "security": [],
        "x-status": "live",
        "x-beta": false,
        "x-credits": {
          "amount": 0,
          "unit": "call",
          "status": "set"
        },
        "responses": {
          "200": {
            "description": "Up.",
            "x-charged": false,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "examples": {
                  "ok": {
                    "value": {
                      "status": "ok",
                      "version": "6bced82",
                      "schema_version": 28,
                      "uptime_seconds": 3600.5
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The process is up and the database is not.",
            "x-charged": false,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "examples": {
                  "degraded": {
                    "value": {
                      "status": "degraded",
                      "schema_version": 0,
                      "uptime_seconds": 12.1,
                      "db_error": "database unreachable"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Your API key. If both headers are sent, `x-api-key` wins."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer <key>`, the same key."
      }
    },
    "parameters": {
      "Handle": {
        "name": "handle",
        "in": "query",
        "required": false,
        "description": "The TikTok handle. Required unless `user_id` is given. A leading `@` is\nremoved; case does not matter. Letters, digits, `_` and `.` only, at most\n64 characters. With both `handle` and `user_id`, `user_id` is ignored.\n",
        "schema": {
          "type": "string",
          "maxLength": 65,
          "pattern": "^@?[A-Za-z0-9_.]{1,64}$"
        },
        "example": "dagestantrainingcamp"
      },
      "HandleOnly": {
        "name": "handle",
        "in": "query",
        "required": true,
        "description": "The TikTok handle; a leading `@` is removed. The only parameter, as on ScrapeCreators.",
        "schema": {
          "type": "string",
          "maxLength": 65,
          "pattern": "^@?[A-Za-z0-9_.]{1,64}$"
        },
        "example": "karlaakat"
      },
      "UserID": {
        "name": "user_id",
        "in": "query",
        "required": false,
        "description": "TikTok's numeric user id, at most 20 digits, used only when `handle` is\nabsent. Works only for accounts in our index: an unknown id is\n`400 unsupported_parameter` (\"pass handle\"), and an id whose handle has\nchanged is `400 unsupported_parameter` too. Both free, both count toward\nthe free-answer limit.\n",
        "schema": {
          "type": "string",
          "pattern": "^[0-9]{1,20}$"
        },
        "example": "6918108151024829445"
      },
      "CacheMaxAge": {
        "name": "cache_max_age",
        "in": "query",
        "required": false,
        "description": "Accepted and ignored; we always fetch live. Any other value is `400 bad_request`.",
        "schema": {
          "type": "string",
          "enum": [
            "1d",
            "3d",
            "7d",
            "14d",
            "30d"
          ]
        }
      },
      "Trim": {
        "name": "trim",
        "in": "query",
        "required": false,
        "description": "Accepted and ignored. Must be `true` or `false` (else `400 bad_request`).",
        "schema": {
          "type": "boolean"
        }
      },
      "TrimUnchecked": {
        "name": "trim",
        "in": "query",
        "required": false,
        "description": "Accepted and ignored. Not validated on this route.",
        "schema": {
          "type": "string"
        }
      },
      "RegionIgnored": {
        "name": "region",
        "in": "query",
        "required": false,
        "description": "Two letters, accepted and ignored. Not two letters is `400 bad_request`.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z]{2}$"
        }
      },
      "MinTime": {
        "name": "min_time",
        "in": "query",
        "required": false,
        "description": "The `min_time` of the previous page (TikTok's own cursor, unix seconds). Absent, empty or `0` means page 1.",
        "schema": {
          "type": "integer",
          "format": "int64",
          "minimum": 0,
          "maximum": 253402300799,
          "default": 0
        },
        "example": 1792981730
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Any string up to 255 characters. Makes a retry safe for 24 hours; bound to this API key and the request's parameters.",
        "schema": {
          "type": "string",
          "maxLength": 255
        },
        "example": "profile-dagestantrainingcamp-2026-11-01"
      },
      "JobID": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "The job id. Another key's job answers as if it did not exist.",
        "schema": {
          "type": "integer",
          "format": "int64",
          "minimum": 1
        },
        "example": 685
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Rows per page (per list). 0 or less means the default; above 500 is capped at 500.",
        "schema": {
          "type": "integer",
          "default": 50,
          "maximum": 500
        },
        "example": 500
      },
      "PageCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "The `next_cursor` of the previous page.",
        "schema": {
          "type": "string"
        }
      },
      "Platform": {
        "name": "platform",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "tiktok",
            "instagram"
          ]
        }
      }
    },
    "headers": {
      "XRequestId": {
        "description": "Our id for this request; quote it when you report a problem. Not sent on a 401.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying; the same number as `retry_after_s`.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "IdempotentReplay": {
        "description": "`true` when this is a stored answer replayed for an `Idempotency-Key`. Not charged again.",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        }
      },
      "XSearchRegion": {
        "description": "The country the page was searched from.",
        "schema": {
          "type": "string",
          "enum": [
            "US",
            "CA"
          ]
        }
      }
    },
    "examples": {
      "OverCapacity": {
        "summary": "Over capacity (Retry-After 12)",
        "value": {
          "success": false,
          "error": "over_capacity",
          "errorStatus": 429,
          "message": "no capacity to answer within the time limit; retry after retry_after_s seconds",
          "credits_charged": 0,
          "retry_after_s": 12
        }
      },
      "NotPriced": {
        "summary": "The route has no price yet",
        "value": {
          "success": false,
          "error": "route_not_priced",
          "errorStatus": 503,
          "message": "this route is not available yet",
          "credits_charged": 0
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "A parameter is missing, malformed, or one we cannot honour yet. Free.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "bad_request": {
                "value": {
                  "success": false,
                  "error": "bad_request",
                  "errorStatus": 400,
                  "message": "handle is required",
                  "credits_charged": 0
                }
              },
              "unsupported_parameter": {
                "value": {
                  "success": false,
                  "error": "unsupported_parameter",
                  "errorStatus": 400,
                  "message": "user_id 6918108151024829445 is not in our index yet; pass handle",
                  "credits_charged": 0
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, unknown or revoked key. Free.",
        "x-charged": false,
        "headers": {
          "WWW-Authenticate": {
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "unauthorized": {
                "value": {
                  "success": false,
                  "error": "unauthorized",
                  "errorStatus": 401,
                  "message": "missing or invalid API key: send x-api-key or Authorization: Bearer",
                  "credits_charged": 0
                }
              }
            }
          }
        }
      },
      "InsufficientCredits": {
        "description": "The key cannot cover this request. `needed_credits` is the price. Free.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "insufficient_credits": {
                "value": {
                  "success": false,
                  "error": "insufficient_credits",
                  "errorStatus": 402,
                  "message": "this key does not have enough credits for this request",
                  "credits_charged": 0,
                  "credits_remaining": 0,
                  "needed_credits": 1
                }
              }
            }
          }
        }
      },
      "AccountNotFound": {
        "description": "The account does not exist. Free; counts toward the free-answer limit.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountNotFound"
            },
            "examples": {
              "not_found": {
                "summary": "ScrapeCreators' recorded body; ours has the same keys",
                "value": {
                  "success": false,
                  "credits_remaining": 48176,
                  "credits_charged": 0,
                  "account_deactivated": true,
                  "handle": "zq_nosuchuser_scdiff_7731",
                  "message": "Account deactivated",
                  "error": "not_found",
                  "errorStatus": 404
                }
              }
            }
          }
        }
      },
      "IdempotencyConflict": {
        "description": "A request with this Idempotency-Key and parameters is still running. Free; retry after `Retry-After` (1 s).",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "idempotency_conflict": {
                "value": {
                  "success": false,
                  "error": "idempotency_conflict",
                  "errorStatus": 409,
                  "message": "a request with this Idempotency-Key is still in progress; retry after it finishes",
                  "credits_charged": 0,
                  "retry_after_s": 1
                }
              }
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "`over_capacity`: no capacity within the time limit, or the server is\nrestarting (30 s). `rate_limited`: the free-answer limit (this answer\nwould have been free). Free; wait `Retry-After` seconds.\n",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "over_capacity": {
                "$ref": "#/components/examples/OverCapacity"
              },
              "rate_limited": {
                "value": {
                  "success": false,
                  "error": "rate_limited",
                  "errorStatus": 429,
                  "message": "this answer would be free (unknown user_id, moved handle or missing account), and this key has had 100 free answers in 10m0s; retry after retry_after_s seconds; not charged. Answers that are charged are never limited",
                  "credits_charged": 0,
                  "retry_after_s": 42
                }
              }
            }
          }
        }
      },
      "Internal": {
        "description": "Our fault. Free; retry and quote `X-Request-Id`.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "internal": {
                "value": {
                  "success": false,
                  "error": "internal",
                  "errorStatus": 500,
                  "message": "internal error",
                  "credits_charged": 0
                }
              }
            }
          }
        }
      },
      "UpstreamFailed": {
        "description": "TikTok's answer failed or could not be read (including accounts TikTok withholds from logged-out views). Free.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "upstream_failed": {
                "value": {
                  "success": false,
                  "error": "upstream_failed",
                  "errorStatus": 502,
                  "message": "the upstream request failed; not charged",
                  "credits_charged": 0
                }
              }
            }
          }
        }
      },
      "NotPriced": {
        "description": "The route has no price yet, so it does not serve. Free.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "route_not_priced": {
                "$ref": "#/components/examples/NotPriced"
              }
            }
          }
        }
      },
      "Timeout": {
        "description": "No answer within the time limit (180 s; audience 300 s). Free.",
        "x-charged": false,
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RouteError"
            },
            "examples": {
              "timeout": {
                "value": {
                  "success": false,
                  "error": "timeout",
                  "errorStatus": 504,
                  "message": "no answer within the time limit; not charged",
                  "credits_charged": 0
                }
              }
            }
          }
        }
      },
      "JobBadRequest": {
        "description": "A malformed body, parameter or cursor. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "bad_request": {
                "value": {
                  "error": {
                    "code": "bad_request",
                    "message": "kind must be one of instagram.fetch, instagram.search, tiktok.audience, tiktok.screen, tiktok.search, tiktok.walk, got \"tiktok.profile\""
                  }
                }
              },
              "invalid_unit": {
                "value": {
                  "error": {
                    "code": "invalid_unit",
                    "message": "unit \"#gym\" starts with \"#\"; drop the \"#\" to search the word",
                    "field": "keywords"
                  }
                }
              }
            }
          }
        }
      },
      "JobBadRequestOrCursorExpired": {
        "description": "A bad parameter or cursor (`bad_request`), or a version-1 cursor from the old order (`cursor_expired`). Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "bad_request": {
                "value": {
                  "error": {
                    "code": "bad_request",
                    "message": "sections: unknown list \"hits\" (want creators, media, walks, audience or units)"
                  }
                }
              },
              "cursor_expired": {
                "value": {
                  "error": {
                    "code": "cursor_expired",
                    "message": "store: malformed cursor: cursor expired: a job's creators and media are paged by id since 2026-11-05; this cursor is from the old order -- restart paging without a cursor"
                  }
                }
              }
            }
          }
        }
      },
      "JobUnauthorized": {
        "description": "Missing, unknown or revoked key. Free.",
        "x-charged": false,
        "headers": {
          "WWW-Authenticate": {
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "unauthorized": {
                "value": {
                  "error": {
                    "code": "unauthorized",
                    "message": "invalid API key"
                  }
                }
              }
            }
          }
        }
      },
      "JobInsufficientCredits": {
        "description": "The key cannot cover the job's hold. Micro fields are the exact integers; the credit strings are the same amounts for people. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "insufficient_credits": {
                "value": {
                  "error": {
                    "code": "insufficient_credits",
                    "message": "this job needs 20.000000 credits for 20 units of tiktok.walk; the key has 3.000000. Billing is per unit attempted, not per result found.",
                    "needed_micro": 20000000,
                    "available_micro": 3000000,
                    "needed_credits": "20.000000",
                    "available_credits": "3.000000"
                  }
                }
              }
            }
          }
        }
      },
      "JobIdempotencyConflict": {
        "description": "This Idempotency-Key was already used for a different request. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "idempotency_conflict": {
                "value": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "Idempotency-Key \"batch-7\" was already used for a different request (job 685, kind \"tiktok.walk\"). Use a new key, or resend the original request.",
                    "job_id": 685
                  }
                }
              }
            }
          }
        }
      },
      "JobTooManyRequests": {
        "description": "The key's request rate (`rate_limited`) or its cap on queued plus running jobs (`concurrency_limit`, Retry-After 10). Free.",
        "x-charged": false,
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "rate_limited": {
                "value": {
                  "error": {
                    "code": "rate_limited",
                    "message": "rate limit exceeded for this key",
                    "retry_after_seconds": 1
                  }
                }
              },
              "concurrency_limit": {
                "value": {
                  "error": {
                    "code": "concurrency_limit",
                    "message": "this key already has 4 jobs queued or running; its limit is 4. Wait for one to finish, or cancel one.",
                    "retry_after_seconds": 10
                  }
                }
              }
            }
          }
        }
      },
      "JobRateLimited": {
        "description": "The key's request rate. Free.",
        "x-charged": false,
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "rate_limited": {
                "value": {
                  "error": {
                    "code": "rate_limited",
                    "message": "rate limit exceeded for this key",
                    "retry_after_seconds": 1
                  }
                }
              }
            }
          }
        }
      },
      "JobNotFound": {
        "description": "No such job, another key's job, or (GET export only) no export requested yet. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "not_found": {
                "value": {
                  "error": {
                    "code": "not_found",
                    "message": "no job 685"
                  }
                }
              },
              "no_export": {
                "value": {
                  "error": {
                    "code": "not_found",
                    "message": "no export of job 685; POST /v1/jobs/685/export to start one"
                  }
                }
              }
            }
          }
        }
      },
      "JobNotFinished": {
        "description": "The job is still queued or running, or canceled/failed with results still being saved (no `finished_at` yet). Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "job_not_finished": {
                "value": {
                  "error": {
                    "code": "job_not_finished",
                    "message": "job 685 is running; export it once it is done"
                  }
                }
              }
            }
          }
        }
      },
      "ExportUnavailable": {
        "description": "Export is switched off on this server. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "export_unavailable": {
                "value": {
                  "error": {
                    "code": "export_unavailable",
                    "message": "bulk export is not configured on this server"
                  }
                }
              }
            }
          }
        }
      },
      "JobInternal": {
        "description": "Our fault. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobError"
            },
            "examples": {
              "internal": {
                "value": {
                  "error": {
                    "code": "internal",
                    "message": "internal error"
                  }
                }
              }
            }
          }
        }
      },
      "ExportDone": {
        "description": "The export is `done` (with URLs), `failed`, or `stale`. Free.",
        "x-charged": false,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Export"
            },
            "examples": {
              "done": {
                "summary": "Job 685's real row counts; byte sizes and times illustrative (docs/customer/routes/job-export.md)",
                "value": {
                  "job_id": 685,
                  "state": "done",
                  "format": "ndjson.gz",
                  "poll_url": "/v1/jobs/685/export",
                  "sections": {
                    "creators": 9720,
                    "media": 299818,
                    "walks": 9731
                  },
                  "parts": [
                    {
                      "section": "creators",
                      "part": 0,
                      "rows": 9720,
                      "bytes": 1350211,
                      "url": "https://cs-niche-video.s3.us-west-2.amazonaws.com/scraper/exports/key-7/job-685/attempt-1/creators-0000.ndjson.gz?X-Amz-..."
                    },
                    {
                      "section": "media",
                      "part": 0,
                      "rows": 50000,
                      "bytes": 6012345,
                      "url": "https://..."
                    },
                    {
                      "section": "media",
                      "part": 1,
                      "rows": 50000,
                      "bytes": 5998812,
                      "url": "https://..."
                    }
                  ],
                  "rows_total": 319269,
                  "bytes_total": 41234567,
                  "urls_expire_at": "2026-11-05T23:41:00Z",
                  "credits_charged": "0",
                  "attempts": 1,
                  "requested_at": "2026-11-05T18:02:11Z",
                  "started_at": "2026-11-05T18:02:11Z",
                  "finished_at": "2026-11-05T18:04:40Z"
                }
              },
              "failed": {
                "summary": "Illustrative",
                "value": {
                  "job_id": 685,
                  "state": "failed",
                  "format": "ndjson.gz",
                  "poll_url": "/v1/jobs/685/export",
                  "parts": [],
                  "rows_total": 0,
                  "bytes_total": 0,
                  "credits_charged": "0",
                  "failure_reason": "storage unavailable",
                  "attempts": 3,
                  "requested_at": "2026-11-05T18:02:11Z",
                  "started_at": "2026-11-05T18:03:20Z",
                  "finished_at": "2026-11-05T18:03:25Z"
                }
              }
            }
          }
        }
      },
      "ExportPending": {
        "description": "The export is `pending` or `running`. Poll `poll_url` after `Retry-After` (5 s). Free.",
        "x-charged": false,
        "headers": {
          "Location": {
            "description": "The poll URL.",
            "schema": {
              "type": "string"
            }
          },
          "Retry-After": {
            "description": "Always 5.",
            "schema": {
              "type": "integer",
              "const": 5
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Export"
            },
            "examples": {
              "pending": {
                "summary": "docs/customer/routes/job-export.md",
                "value": {
                  "job_id": 685,
                  "state": "pending",
                  "format": "ndjson.gz",
                  "poll_url": "/v1/jobs/685/export",
                  "parts": [],
                  "rows_total": 0,
                  "bytes_total": 0,
                  "credits_charged": "0",
                  "attempts": 0,
                  "requested_at": "2026-11-05T18:02:11Z"
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Credits": {
        "description": "An amount in credits, as an exact JSON decimal (1, 0.002), never a rounded float.",
        "type": "number",
        "minimum": 0
      },
      "CreditsRemaining": {
        "description": "What the key can still spend after this request.",
        "type": "number"
      },
      "RouteErrorCode": {
        "description": "Stable error codes of the TikTok routes (`error`). Branch on these, not\non `message`. Kept equal to the codes the server can emit by\ndocs/openapi/spec_test.go.\n",
        "type": "string",
        "enum": [
          "bad_request",
          "unsupported_parameter",
          "invalid_cursor",
          "cursor_expired",
          "unauthorized",
          "insufficient_credits",
          "not_found",
          "idempotency_conflict",
          "cursor_region_changed",
          "cursor_exit_gone",
          "over_capacity",
          "rate_limited",
          "internal",
          "not_yet_available",
          "upstream_failed",
          "route_not_priced",
          "search_unavailable",
          "timeout"
        ]
      },
      "RouteError": {
        "description": "The error body of every TikTok route. `errorStatus` equals the HTTP status.",
        "type": "object",
        "required": [
          "success",
          "error",
          "errorStatus",
          "message",
          "credits_charged"
        ],
        "properties": {
          "success": {
            "const": false
          },
          "error": {
            "$ref": "#/components/schemas/RouteErrorCode"
          },
          "errorStatus": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "message": {
            "type": "string",
            "description": "For people; may be reworded."
          },
          "credits_charged": {
            "$ref": "#/components/schemas/Credits"
          },
          "credits_remaining": {
            "$ref": "#/components/schemas/CreditsRemaining"
          },
          "retry_after_s": {
            "type": "integer",
            "minimum": 1,
            "description": "The same number as the Retry-After header."
          },
          "needed_credits": {
            "$ref": "#/components/schemas/Credits"
          }
        }
      },
      "AccountNotFound": {
        "description": "The 404 of profile videos, followers, following and audience, as ScrapeCreators sends it.",
        "type": "object",
        "required": [
          "success",
          "error",
          "errorStatus",
          "message",
          "credits_charged",
          "account_deactivated",
          "handle"
        ],
        "properties": {
          "success": {
            "const": false
          },
          "error": {
            "const": "not_found"
          },
          "errorStatus": {
            "const": 404
          },
          "message": {
            "type": "string"
          },
          "credits_charged": {
            "const": 0
          },
          "credits_remaining": {
            "$ref": "#/components/schemas/CreditsRemaining"
          },
          "account_deactivated": {
            "const": true
          },
          "handle": {
            "type": "string"
          }
        }
      },
      "JobErrorCode": {
        "description": "Stable error codes of the job and corpus routes (`error.code`). Kept\nequal to the codes the server can emit by docs/openapi/spec_test.go.\n",
        "type": "string",
        "enum": [
          "bad_request",
          "invalid_unit",
          "cursor_expired",
          "unauthorized",
          "insufficient_credits",
          "not_found",
          "idempotency_conflict",
          "job_not_finished",
          "rate_limited",
          "concurrency_limit",
          "internal",
          "export_unavailable"
        ]
      },
      "JobError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "$ref": "#/components/schemas/JobErrorCode"
              },
              "message": {
                "type": "string"
              },
              "needed_micro": {
                "type": "integer",
                "format": "int64",
                "description": "402 only: micro-credits the job needs (1 credit = 1,000,000)."
              },
              "available_micro": {
                "type": "integer",
                "format": "int64",
                "description": "402 only: micro-credits the key can spend."
              },
              "needed_credits": {
                "type": "string",
                "description": "402 only: needed_micro as a decimal string."
              },
              "available_credits": {
                "type": "string",
                "description": "402 only: available_micro as a decimal string."
              },
              "job_id": {
                "type": "integer",
                "format": "int64",
                "description": "409 only: the job the Idempotency-Key belongs to."
              },
              "retry_after_seconds": {
                "type": "integer",
                "minimum": 1,
                "description": "The same number as the Retry-After header."
              },
              "field": {
                "type": "string",
                "description": "`invalid_unit` only: keywords or handles."
              }
            }
          }
        }
      },
      "Envelope": {
        "type": "object",
        "required": [
          "success",
          "credits_charged",
          "credits_remaining"
        ],
        "properties": {
          "success": {
            "const": true
          },
          "credits_charged": {
            "$ref": "#/components/schemas/Credits"
          },
          "credits_remaining": {
            "$ref": "#/components/schemas/CreditsRemaining"
          }
        }
      },
      "PrivateAccount": {
        "description": "A private account, as ScrapeCreators answers it. Charged on profile videos, followers and following; free on audience.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "required": [
              "handle",
              "account_private"
            ],
            "properties": {
              "handle": {
                "type": "string"
              },
              "account_private": {
                "const": true
              }
            }
          }
        ]
      },
      "ProfileResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "required": [
              "user",
              "stats",
              "statsV2",
              "itemList"
            ],
            "properties": {
              "user": {
                "$ref": "#/components/schemas/TikTokUser"
              },
              "stats": {
                "$ref": "#/components/schemas/TikTokStats"
              },
              "statsV2": {
                "$ref": "#/components/schemas/TikTokStatsV2"
              },
              "itemList": {
                "description": "Always empty, as on ScrapeCreators.",
                "type": "array",
                "maxItems": 0
              }
            }
          }
        ]
      },
      "ProfileNotFound": {
        "description": "The profile of an account that does not exist. 200, charged, as ScrapeCreators.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "required": [
              "account_deactivated",
              "handle",
              "message"
            ],
            "properties": {
              "account_deactivated": {
                "const": true
              },
              "handle": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        ]
      },
      "TikTokUser": {
        "description": "The account record, ScrapeCreators' keys (internal/sccontract/profile.go). Settings and counts can be null when we fall back to the embed.",
        "type": "object",
        "required": [
          "id",
          "uniqueId",
          "nickname",
          "secUid"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "TikTok's numeric user id",
            "as a string.": null
          },
          "uniqueId": {
            "type": "string",
            "description": "The handle."
          },
          "nickname": {
            "type": "string"
          },
          "secUid": {
            "type": "string"
          },
          "signature": {
            "type": [
              "string",
              "null"
            ],
            "description": "The bio."
          },
          "verified": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "privateAccount": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "secret": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "createTime": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unix seconds."
          },
          "language": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatarLarger": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatarMedium": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatarThumb": {
            "type": [
              "string",
              "null"
            ]
          },
          "bioLink": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "link": {
                "type": "string"
              },
              "risk": {
                "type": "integer"
              }
            }
          },
          "followingVisibility": {
            "type": [
              "integer",
              "null"
            ]
          },
          "commerceUserInfo": {
            "type": [
              "object",
              "null"
            ]
          },
          "ttSeller": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "isOrganization": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "TikTokStats": {
        "description": "TikTok's rounded counts.",
        "type": "object",
        "properties": {
          "followerCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "followingCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "heart": {
            "type": [
              "integer",
              "null"
            ]
          },
          "heartCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "videoCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "diggCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "friendCount": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "TikTokStatsV2": {
        "description": "The exact counts, as strings.",
        "type": "object",
        "properties": {
          "followerCount": {
            "type": [
              "string",
              "null"
            ]
          },
          "followingCount": {
            "type": [
              "string",
              "null"
            ]
          },
          "heart": {
            "type": [
              "string",
              "null"
            ]
          },
          "heartCount": {
            "type": [
              "string",
              "null"
            ]
          },
          "videoCount": {
            "type": [
              "string",
              "null"
            ]
          },
          "diggCount": {
            "type": [
              "string",
              "null"
            ]
          },
          "friendCount": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Aweme": {
        "description": "One video, ScrapeCreators' item keys (144 in the example;\ninternal/sccontract/aweme.go). Keys we cannot fill are null, never absent.\n",
        "type": "object",
        "required": [
          "aweme_id",
          "desc",
          "create_time",
          "author",
          "statistics"
        ],
        "properties": {
          "aweme_id": {
            "type": "string"
          },
          "desc": {
            "type": [
              "string",
              "null"
            ],
            "description": "The caption."
          },
          "create_time": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Unix seconds."
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "share_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "region": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_top": {
            "type": [
              "integer",
              "boolean",
              "null"
            ],
            "description": "Pinned."
          },
          "author": {
            "$ref": "#/components/schemas/AwemeAuthor"
          },
          "statistics": {
            "$ref": "#/components/schemas/AwemeStatistics"
          },
          "video": {
            "type": [
              "object",
              "null"
            ]
          },
          "music": {
            "type": [
              "object",
              "null"
            ]
          }
        }
      },
      "AwemeAuthor": {
        "type": "object",
        "required": [
          "uid",
          "unique_id"
        ],
        "properties": {
          "uid": {
            "type": "string"
          },
          "unique_id": {
            "type": "string"
          },
          "nickname": {
            "type": [
              "string",
              "null"
            ]
          },
          "sec_uid": {
            "type": [
              "string",
              "null"
            ]
          },
          "follower_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "region": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "AwemeStatistics": {
        "description": "On profile videos page 1 only `play_count` is filled; the rest are null.",
        "type": "object",
        "required": [
          "play_count"
        ],
        "properties": {
          "aweme_id": {
            "type": "string"
          },
          "play_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "digg_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "comment_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "share_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "collect_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "download_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "forward_count": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "ProfileVideosResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "required": [
              "aweme_list",
              "has_more",
              "max_cursor",
              "status_code"
            ],
            "properties": {
              "aweme_list": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Aweme"
                }
              },
              "has_more": {
                "type": "integer",
                "enum": [
                  0,
                  1
                ],
                "description": "Always 0 in beta."
              },
              "max_cursor": {
                "type": "integer",
                "description": "Filled",
                "but not usable in beta.": null
              },
              "status_code": {
                "type": "integer"
              }
            }
          }
        ]
      },
      "SearchKeywordResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "required": [
              "search_item_list",
              "has_more"
            ],
            "properties": {
              "search_item_list": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "aweme_info"
                  ],
                  "properties": {
                    "aweme_info": {
                      "$ref": "#/components/schemas/Aweme"
                    }
                  }
                }
              },
              "has_more": {
                "type": "integer",
                "enum": [
                  0,
                  1
                ]
              },
              "cursor": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "The next page's cursor; absent on the last page. Bound to your key, the query and the region; 24 hours."
              }
            }
          }
        ]
      },
      "TikTokListUser": {
        "description": "One account of a followers or following page, every key of\nScrapeCreators' item (107 in the example; internal/sccontract/followers.go).\nOnly account basics, stats and settings are filled; `region`,\n`create_time` and app-only flags are null.\n",
        "type": "object",
        "required": [
          "uid",
          "unique_id",
          "nickname",
          "sec_uid"
        ],
        "properties": {
          "uid": {
            "type": "string"
          },
          "unique_id": {
            "type": "string"
          },
          "nickname": {
            "type": "string"
          },
          "sec_uid": {
            "type": "string"
          },
          "signature": {
            "type": [
              "string",
              "null"
            ]
          },
          "follower_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "following_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "aweme_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "total_favorited": {
            "type": [
              "integer",
              "null"
            ]
          },
          "secret": {
            "type": [
              "integer",
              "null"
            ],
            "description": "1 for a private account."
          },
          "region": {
            "type": "null"
          },
          "create_time": {
            "type": "null"
          }
        }
      },
      "UserListPage": {
        "type": "object",
        "required": [
          "has_more",
          "min_time",
          "max_time",
          "total",
          "status_code"
        ],
        "properties": {
          "has_more": {
            "type": "boolean"
          },
          "min_time": {
            "type": "integer",
            "format": "int64",
            "description": "Send back as `min_time` for the next page."
          },
          "max_time": {
            "type": "integer",
            "format": "int64"
          },
          "next_page_token": {
            "type": "string"
          },
          "total": {
            "type": [
              "integer",
              "null"
            ],
            "description": "TikTok's own count; null on a hidden following list."
          },
          "offset": {
            "type": "integer"
          },
          "myself_user_id": {
            "type": "string"
          },
          "status_code": {
            "type": "integer"
          },
          "status_msg": {
            "type": "string"
          },
          "extra": {
            "type": "object"
          },
          "log_pb": {
            "type": "object"
          }
        }
      },
      "FollowersResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "$ref": "#/components/schemas/UserListPage"
          },
          {
            "type": "object",
            "required": [
              "followers"
            ],
            "properties": {
              "followers": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TikTokListUser"
                }
              }
            }
          }
        ]
      },
      "FollowingResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "$ref": "#/components/schemas/UserListPage"
          },
          {
            "type": "object",
            "required": [
              "followings",
              "rec_has_more"
            ],
            "properties": {
              "followings": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TikTokListUser"
                }
              },
              "rec_has_more": {
                "type": "boolean",
                "description": "Always equals has_more."
              },
              "following_hidden": {
                "const": true,
                "description": "Only on a hidden list (free): no accounts, total null."
              },
              "handle": {
                "type": "string",
                "description": "Only on a hidden list."
              }
            }
          }
        ]
      },
      "AudienceResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "required": [
              "audienceLocations"
            ],
            "properties": {
              "audienceLocations": {
                "description": "The whole country breakdown, count descending (ties by country code). Empty when no follower could be placed.",
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "countryCode",
                    "count",
                    "percentage"
                  ],
                  "properties": {
                    "country": {
                      "type": "string",
                      "description": "Left out for a code without a name."
                    },
                    "countryCode": {
                      "type": "string",
                      "pattern": "^[A-Z]{2}$"
                    },
                    "count": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "percentage": {
                      "type": "string",
                      "pattern": "^[0-9]{1,3}\\.[0-9]{2}%$"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "JobKind": {
        "type": "string",
        "enum": [
          "tiktok.search",
          "tiktok.screen",
          "tiktok.walk",
          "tiktok.audience",
          "instagram.search",
          "instagram.fetch"
        ],
        "description": "`tiktok.search` keywords; `tiktok.screen` handles (profile and first\nvideos); `tiktok.walk` handles (newest posts, about 24 per creator);\n`tiktok.audience` handles (US+CA audience share); `instagram.search`\nkeywords; `instagram.fetch` handles (profile and feed).\n"
      },
      "SubmitRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "kind"
        ],
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/JobKind"
          },
          "keywords": {
            "description": "For tiktok.search and instagram.search. Trimmed, deduplicated; no control characters, no leading `#`.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 50000
          },
          "handles": {
            "description": "For the other kinds. A leading `@` is removed.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 50000
          },
          "options": {
            "$ref": "#/components/schemas/JobOptions"
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "description": "Lower runs first. 0 or absent takes the kind's default band. Not settable on POST /v1/search."
          },
          "chunk_size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "description": "Operator tuning; leave it out."
          }
        }
      },
      "JobOptions": {
        "description": "Passed to the scraper. Validated at submit for tiktok.walk\n(`max_videos`, `walk_timeout_s`, `min_days`, `early_stop`),\ntiktok.search (`region`) and tiktok.audience (`us_ca_share_min`); other\nkeys are passed through.\n",
        "type": "object",
        "properties": {
          "max_videos": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500,
            "default": 120,
            "description": "tiktok.walk. Caps one creator's walk."
          },
          "walk_timeout_s": {
            "type": "integer",
            "minimum": 60,
            "maximum": 900,
            "default": 600,
            "description": "tiktok.walk. One attempt at one creator."
          },
          "min_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 60,
            "default": 10,
            "description": "tiktok.walk. A shallower walk while TikTok has more is retried."
          },
          "early_stop": {
            "$ref": "#/components/schemas/EarlyStop"
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^([A-Za-z]{2})?$",
            "description": "tiktok.search. CA searches from Canada only."
          },
          "us_ca_share_min": {
            "type": "number",
            "exclusiveMinimum": 0,
            "exclusiveMaximum": 1,
            "description": "tiktok.audience. The cutoff as a fraction (0.45 for 45%); 45 when absent."
          }
        }
      },
      "EarlyStop": {
        "description": "tiktok.walk. Stop walking a creator the rule already rejects (docs/API_SERVICE_DESIGN.md 8.2). Unknown keys are a 400.",
        "type": [
          "object",
          "null"
        ],
        "additionalProperties": false,
        "properties": {
          "min_reels_per_week": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50
          },
          "full_weeks": {
            "type": "integer",
            "minimum": 1,
            "maximum": 8
          },
          "ignore_current_week": {
            "type": "boolean",
            "default": true
          },
          "reel_kinds": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "video",
                "photo"
              ]
            },
            "default": [
              "video"
            ]
          },
          "views": {
            "type": "object",
            "required": [
              "min_views_per_video"
            ],
            "properties": {
              "min_views_per_video": {
                "type": "number",
                "minimum": 0
              },
              "min_share_clearing": {
                "type": "number",
                "exclusiveMinimum": 0,
                "maximum": 1,
                "default": 0.8
              },
              "band_min_age_days": {
                "type": "number",
                "minimum": 0,
                "default": 10
              },
              "band_max_age_days": {
                "type": "number",
                "maximum": 365,
                "default": 40
              },
              "min_band_videos": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              },
              "exclude_pinned": {
                "type": "boolean",
                "default": true
              }
            }
          }
        }
      },
      "JobState": {
        "type": "string",
        "enum": [
          "queued",
          "running",
          "done",
          "failed",
          "canceled"
        ]
      },
      "Job": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "state",
          "priority",
          "progress",
          "credits",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "$ref": "#/components/schemas/JobKind"
          },
          "state": {
            "$ref": "#/components/schemas/JobState"
          },
          "priority": {
            "type": "integer"
          },
          "idempotency_key": {
            "type": "string"
          },
          "progress": {
            "type": "object",
            "required": [
              "units_done",
              "units_total"
            ],
            "properties": {
              "units_done": {
                "type": "integer",
                "description": "Billed units of finished chunks."
              },
              "units_total": {
                "type": "integer"
              },
              "chunks": {
                "type": "object",
                "properties": {
                  "queued": {
                    "type": "integer"
                  },
                  "running": {
                    "type": "integer"
                  },
                  "done": {
                    "type": "integer"
                  },
                  "failed": {
                    "type": "integer"
                  }
                }
              },
              "units_fetched": {
                "type": "integer",
                "description": "Units with an answer so far; moves per creator. Watch this",
                "not units_done": null,
                "to tell a slow job from a hung one.": null
              },
              "last_progress_at": {
                "type": "string",
                "format": "date-time"
              },
              "lane_parked_until": {
                "type": "string",
                "format": "date-time",
                "description": "The kind is paused fleet-wide until then; the job is waiting",
                "not hung.": null
              }
            }
          },
          "credits": {
            "description": "Money as exact micro-credit integers and as decimal strings. Never a JSON number of credits.",
            "type": "object",
            "required": [
              "held_micro",
              "spent_micro",
              "held",
              "spent"
            ],
            "properties": {
              "held_micro": {
                "type": "integer",
                "format": "int64"
              },
              "spent_micro": {
                "type": "integer",
                "format": "int64"
              },
              "held": {
                "type": "string",
                "pattern": "^-?[0-9]+\\.[0-9]{6}$"
              },
              "spent": {
                "type": "string",
                "pattern": "^-?[0-9]+\\.[0-9]{6}$"
              }
            }
          },
          "error": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "description": "Set once nothing is still writing to the job; export needs it."
          }
        }
      },
      "JobAccepted": {
        "type": "object",
        "required": [
          "job_id",
          "job",
          "poll_url"
        ],
        "properties": {
          "job_id": {
            "type": "integer",
            "format": "int64"
          },
          "job": {
            "$ref": "#/components/schemas/Job"
          },
          "idempotent_replay": {
            "type": "boolean"
          },
          "poll_url": {
            "type": "string"
          }
        }
      },
      "SearchAccepted": {
        "type": "object",
        "required": [
          "job_id",
          "job",
          "poll_url",
          "message"
        ],
        "properties": {
          "job_id": {
            "type": "integer",
            "format": "int64"
          },
          "job": {
            "$ref": "#/components/schemas/Job"
          },
          "poll_url": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "JobList": {
        "type": "object",
        "required": [
          "jobs"
        ],
        "properties": {
          "jobs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Job"
            }
          },
          "next_cursor": {
            "type": "string"
          }
        }
      },
      "JobDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Job"
          },
          {
            "type": "object",
            "properties": {
              "chunks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Chunk"
                }
              },
              "results": {
                "$ref": "#/components/schemas/JobResults"
              }
            }
          }
        ]
      },
      "Chunk": {
        "type": "object",
        "required": [
          "seq",
          "state",
          "attempts",
          "units_done",
          "units_total",
          "requests",
          "bytes_webshare",
          "bytes_dataimpulse"
        ],
        "properties": {
          "seq": {
            "type": "integer"
          },
          "state": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "done",
              "failed"
            ]
          },
          "attempts": {
            "type": "integer"
          },
          "units_done": {
            "type": "integer"
          },
          "units_total": {
            "type": "integer"
          },
          "requests": {
            "type": "integer"
          },
          "bytes_webshare": {
            "type": "integer",
            "format": "int64"
          },
          "bytes_dataimpulse": {
            "type": "integer",
            "format": "int64"
          },
          "error": {
            "type": "string"
          },
          "claimed_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "JobResults": {
        "type": "object",
        "required": [
          "creators",
          "media"
        ],
        "properties": {
          "creators": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Creator"
            }
          },
          "media": {
            "description": "Media rows; for tiktok.search, the search hits.",
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/Media"
                },
                {
                  "$ref": "#/components/schemas/SearchHit"
                }
              ]
            }
          },
          "next_creator_cursor": {
            "type": "string"
          },
          "next_media_cursor": {
            "type": "string"
          },
          "walks": {
            "description": "tiktok.walk and instagram.fetch only. One row per handle attempted.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Walk"
            }
          },
          "next_walk_cursor": {
            "type": "string"
          },
          "audience": {
            "description": "tiktok.audience only.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceRow"
            }
          },
          "next_audience_cursor": {
            "type": "string"
          },
          "units": {
            "description": "tiktok.search only. Each keyword's final outcome.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Unit"
            }
          },
          "next_unit_cursor": {
            "type": "string"
          }
        }
      },
      "Creator": {
        "type": "object",
        "required": [
          "id",
          "platform",
          "handle",
          "followers",
          "first_seen",
          "last_seen"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "platform": {
            "type": "string",
            "enum": [
              "tiktok",
              "instagram"
            ]
          },
          "handle": {
            "type": "string"
          },
          "external_id": {
            "type": "string"
          },
          "sec_uid": {
            "type": "string"
          },
          "nickname": {
            "type": "string"
          },
          "bio": {
            "type": "string"
          },
          "followers": {
            "type": [
              "integer",
              "null"
            ]
          },
          "following": {
            "type": "integer"
          },
          "hearts": {
            "type": "integer"
          },
          "verified": {
            "type": "boolean"
          },
          "private": {
            "type": "boolean"
          },
          "first_seen": {
            "type": "string",
            "format": "date-time"
          },
          "last_seen": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Media": {
        "type": "object",
        "required": [
          "id",
          "platform",
          "external_id",
          "plays",
          "pinned",
          "first_seen",
          "last_seen"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "platform": {
            "type": "string",
            "enum": [
              "tiktok",
              "instagram"
            ]
          },
          "external_id": {
            "type": "string"
          },
          "creator_id": {
            "type": "integer",
            "format": "int64"
          },
          "creator_handle": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "description": "`video` or `photo`."
          },
          "code": {
            "type": "string",
            "description": "Instagram shortcode."
          },
          "caption": {
            "type": "string"
          },
          "plays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "likes": {
            "type": "integer"
          },
          "comments": {
            "type": "integer"
          },
          "posted_at": {
            "type": "string",
            "format": "date-time"
          },
          "pinned": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "null when the route does not say."
          },
          "sound_id": {
            "type": "string"
          },
          "sound_title": {
            "type": "string"
          },
          "sound_author": {
            "type": "string"
          },
          "sound_original": {
            "type": "boolean"
          },
          "duration_s": {
            "type": "integer"
          },
          "first_seen": {
            "type": "string",
            "format": "date-time"
          },
          "last_seen": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SearchHit": {
        "description": "One video a tiktok.search job matched. `plays` is the count at search time.",
        "type": "object",
        "required": [
          "external_id",
          "creator_handle",
          "plays",
          "keyword"
        ],
        "properties": {
          "external_id": {
            "type": "string"
          },
          "creator_handle": {
            "type": "string"
          },
          "caption": {
            "type": "string"
          },
          "plays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "posted_at": {
            "type": "string",
            "format": "date-time"
          },
          "keyword": {
            "type": "string"
          },
          "region": {
            "type": "string",
            "enum": [
              "US",
              "CA"
            ]
          }
        }
      },
      "Walk": {
        "type": "object",
        "required": [
          "handle",
          "platform",
          "creator_id",
          "outcome",
          "items",
          "videos",
          "photos",
          "pinned",
          "oldest_days",
          "has_more",
          "short",
          "stopped_early",
          "weeks_covered",
          "band_videos",
          "secs",
          "walked_at"
        ],
        "properties": {
          "handle": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "tiktok",
              "instagram"
            ]
          },
          "creator_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "outcome": {
            "type": "string",
            "enum": [
              "ok",
              "failed"
            ]
          },
          "items": {
            "type": "integer"
          },
          "videos": {
            "type": "integer"
          },
          "photos": {
            "type": "integer"
          },
          "pinned": {
            "type": "integer"
          },
          "oldest_days": {
            "type": [
              "number",
              "null"
            ]
          },
          "has_more": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "short": {
            "type": "boolean"
          },
          "stopped_early": {
            "type": "boolean"
          },
          "stop_reason": {
            "type": "string"
          },
          "stop_detail": {
            "type": "string"
          },
          "weeks_covered": {
            "type": "integer"
          },
          "band_videos": {
            "type": "integer"
          },
          "secs": {
            "type": [
              "number",
              "null"
            ]
          },
          "err": {
            "type": "string"
          },
          "walked_at": {
            "type": "string",
            "format": "date-time"
          },
          "related_profiles": {
            "description": "instagram.fetch only; absent means not read.",
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "username",
                "is_verified"
              ],
              "properties": {
                "username": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "full_name": {
                  "type": "string"
                },
                "is_verified": {
                  "type": "boolean"
                },
                "is_private": {
                  "type": "boolean"
                }
              }
            }
          },
          "ai_label": {
            "description": "instagram.fetch only; facts, no verdict.",
            "type": "object",
            "properties": {
              "profile_labels": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              },
              "posts_read": {
                "type": "integer"
              },
              "posts_disclosed": {
                "type": "integer"
              },
              "methods": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              }
            }
          },
          "post_owners": {
            "description": "instagram.fetch only.",
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "pk"
              ],
              "properties": {
                "pk": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "owner": {
                  "type": "string"
                },
                "coauthors": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "ai_disclosure": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "AudienceRow": {
        "type": "object",
        "required": [
          "handle",
          "platform",
          "creator_id",
          "verdict",
          "us_ca_pct",
          "us_ca_raw",
          "margin",
          "followers_total",
          "followers_sampled",
          "looked_up",
          "with_country",
          "capped",
          "measured_at"
        ],
        "properties": {
          "handle": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "creator_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "verdict": {
            "type": "string",
            "description": "e.g. PASS",
            "FAIL": null,
            "NO_DATA.": null
          },
          "us_ca_pct": {
            "type": [
              "number",
              "null"
            ]
          },
          "us_ca_raw": {
            "type": [
              "number",
              "null"
            ]
          },
          "margin": {
            "type": [
              "number",
              "null"
            ]
          },
          "followers_total": {
            "type": [
              "integer",
              "null"
            ]
          },
          "followers_sampled": {
            "type": [
              "integer",
              "null"
            ]
          },
          "looked_up": {
            "type": [
              "integer",
              "null"
            ]
          },
          "with_country": {
            "type": [
              "integer",
              "null"
            ]
          },
          "capped": {
            "type": "boolean"
          },
          "countries": {},
          "err": {
            "type": "string"
          },
          "measured_at": {
            "type": "string",
            "format": "date-time"
          },
          "cutoff": {
            "type": "number"
          },
          "split": {
            "type": "object"
          }
        }
      },
      "Unit": {
        "type": "object",
        "required": [
          "unit",
          "outcome",
          "tries",
          "billed"
        ],
        "properties": {
          "unit": {
            "type": "string"
          },
          "outcome": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "region": {
            "type": [
              "string",
              "null"
            ]
          },
          "tries": {
            "type": "integer"
          },
          "billed": {
            "type": "boolean"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "Export": {
        "type": "object",
        "required": [
          "job_id",
          "state",
          "format",
          "poll_url",
          "parts",
          "rows_total",
          "bytes_total",
          "credits_charged",
          "attempts",
          "requested_at"
        ],
        "properties": {
          "job_id": {
            "type": "integer",
            "format": "int64"
          },
          "state": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "done",
              "failed",
              "stale"
            ]
          },
          "format": {
            "const": "ndjson.gz"
          },
          "poll_url": {
            "type": "string"
          },
          "sections": {
            "description": "Every list this kind exports with its row count, 0 included. Present once done.",
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "parts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "section",
                "part",
                "rows",
                "bytes",
                "url"
              ],
              "properties": {
                "section": {
                  "type": "string"
                },
                "part": {
                  "type": "integer",
                  "minimum": 0
                },
                "rows": {
                  "type": "integer"
                },
                "bytes": {
                  "type": "integer",
                  "description": "Gzipped."
                },
                "url": {
                  "type": "string",
                  "description": "Presigned; send no API key."
                }
              }
            }
          },
          "rows_total": {
            "type": "integer"
          },
          "bytes_total": {
            "type": "integer"
          },
          "urls_expire_at": {
            "type": "string",
            "format": "date-time"
          },
          "credits_charged": {
            "const": "0"
          },
          "failure_reason": {
            "type": "string"
          },
          "retry_at": {
            "type": "string",
            "format": "date-time"
          },
          "attempts": {
            "type": "integer"
          },
          "requested_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreatorPage": {
        "type": "object",
        "required": [
          "creators"
        ],
        "properties": {
          "creators": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Creator"
            }
          },
          "next_cursor": {
            "type": "string"
          }
        }
      },
      "MediaPage": {
        "type": "object",
        "required": [
          "media"
        ],
        "properties": {
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            }
          },
          "next_cursor": {
            "type": "string"
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status",
          "schema_version",
          "uptime_seconds"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "version": {
            "type": "string"
          },
          "schema_version": {
            "type": "integer"
          },
          "uptime_seconds": {
            "type": "number"
          },
          "db_error": {
            "type": "string"
          }
        }
      }
    }
  }
}