> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sideshift.app/llms.txt
> Use this file to discover all available pages before exploring further.

# TikTok — creator reposts

> Posts a creator reposted. Platform field names are preserved inside `data`. Standard billing: 1 SideShift credit per completed lookup; the Scraper dashboard shows the exact rate for an account with negotiated pricing.



## OpenAPI

````yaml /openapi/scraper.yaml post /scrape/tiktok/reposts
openapi: 3.0.4
info:
  title: SideShift Scraper API
  version: 1.3.0
  description: >
    One scraper API with canonical /scrape/{platform}/{resource} paths.
    Normalized

    profile, posts, post, and TikTok audience resources remain stable; focused
    TikTok

    and Instagram operations preserve platform fields when their schemas are
    genuinely

    different. Standard completed lookups cost one credit except TikTok
    audience,

    which costs 25. The authenticated Scraper dashboard shows any
    account-specific rates.


    ## Quickstart


    Every endpoint is a POST with a JSON body and your key in the `x-api-key`
    header.


    ```bash

    curl -X POST https://app.sideshift.app/api/v1/scrape/tiktok/posts \
      -H "x-api-key: scrape_live_YOUR_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "username": "mrbeast" }'
    ```


    ```jsonc

    {
      "data": {
        "posts": [
          {
            "id": "7670566355153833246",
            "title": "The last one was hard 😴",
            "views": 25081146,
            "likes": 2543164,
            "comments": 85606,
            "shares": 47126,
            "bookmarks": 126013,
            "uploadedAt": 1785942939,          // unix seconds
            "postPage": "https://www.tiktok.com/@mrbeast/video/7670566355153833246",
            "creator": "mrbeast",
            "videoUrl": "https://…",           // direct media URL, short-lived
            "thumbnail": "https://…",
            "platform": "tiktok",
            "hashtags": []
          }
          // … the rest of the page
        ],
        "profile_pictures": { "mrbeast": "https://…" },
        "next_cursor": "1768430796798"       // pass back as "cursor" for page 2
      },
      "request_id": "req_k4XjoVoiYdzZ1ibg",
      "upstream_calls": 1,
      "meta": { "credits_charged": 1, "credits_remaining": 104987 }
    }

    ```


    ## 1. Authentication


    Create a key in the [Scraper dashboard](https://app.sideshift.app/scraper)
    under **Keys**.

    The full key is shown once. Send it in the `x-api-key` header on every
    request, and revoke

    it from the dashboard whenever you need to.


    Scraper keys start with `scrape_live_`. Integration API keys (`sk_live_*`,
    `sk_test_*`) are

    rejected with `401` on scraper routes, and scraper keys are rejected on
    integration routes.


    > **Call from your backend only.** Never embed a scraper key in client-side
    code.


    ## 2. Credits and billing


    Standard lookups cost one credit. You buy a credit balance up front; there
    is no subscription.

    The authenticated Scraper dashboard shows the exact `post`, `posts`,
    `profile`, and `advanced`

    rates for your account; TikTok audience is always 25. You are charged when
    we complete the

    work, and refunded when we can't.


    | Outcome | Charged |

    |---|---|

    | Successful scrape (each page of a listing counts as one) | The account's
    resource rate; standard 1 credit |

    | Confirmed not-found: the platform answered, the account or post isn't
    there (`404`) | Full rate for the resource: 1 credit, or 25 for audience |

    | TikTok audience demographics (`/scrape/tiktok/audience`) | 25 credits |

    | Rejected before we start work: bad input, bad key, empty balance,
    oversized body, over your rate limit (`400` `401` `402` `413` `429`) | Free
    |

    | Our problem or the platform's: errors and timeouts (`500` `502` `504`) |
    Free, auto-refunded |


    A full catalog costs `ceil(total_posts / page_size)` credits, one per page.
    A 300-video

    TikTok account is about 10.


    `meta.credits_charged` and `meta.credits_remaining` come back on every
    success. Error bodies

    have no `meta` block, so read the `X-Scraper-Credits-Charged` header to see
    what a billed

    error cost you. Refunds are automatic; you never have to claim one. Top up
    in the

    [Scraper dashboard](https://app.sideshift.app/scraper).


    ## 3. Resources


    | Resource | Path | Returns |

    |---|---|---|

    | **Profile** | `POST /scrape/{platform}/profile` | Display name, bio,
    follower/following counts, avatar, post count. |

    | **Posts** | `POST /scrape/{platform}/posts` | One page of the creator's
    recent posts, plus a `next_cursor` where the platform supports one. |

    | **Single Post** | `POST /scrape/{platform}/post` | One post, by URL. |

    | **Audience** | `POST /scrape/tiktok/audience` | TikTok audience
    distribution by country. 25 credits. |


    Platforms: `tiktok`, `instagram`, `youtube`, `facebook`, `snapchat`,
    `twitter` (X), `linkedin`.


    Normalized profile, posts, post, and audience endpoints read their
    documented fields and

    ignore the rest. Focused TikTok and Instagram operations reject unknown or
    misspelled

    fields with the JSON error envelope before billing. Bodies over 32 KB return

    `413 PAYLOAD_TOO_LARGE`. Unknown TikTok or Instagram operations return a
    JSON

    `ENDPOINT_NOT_FOUND` response; paths outside the documented platform
    namespaces may return

    the framework's standard HTTP `404`.


    ## 4. Pagination, page size, and speed


    Same request, same response shape everywhere. What differs is how much each
    platform gives

    you per call:


    | Platform | Posts per page | More pages? | `videoUrl` in listings | Speed |

    |---|---|---|---|---|

    | TikTok | 30 | Yes, cursor | Yes | 2–4 s |

    | Instagram | 12 | Yes, cursor | Yes | 8–15 s |

    | YouTube | 30 | Yes, cursor | No; fetch the single post | 15–45 s |

    | Facebook | Up to 30 | Yes, cursor | Yes | 10–30 s |

    | Snapchat | Up to 30 | No; single page | Yes | 4–10 s |

    | X | 20 | Yes, cursor | Videos only | 3–8 s |

    | LinkedIn | 1–11 | No; single page | Videos only | 4–10 s |


    Listings return video-style content: reels on Instagram and Facebook, Shorts
    by default on

    YouTube (`contentType: video` switches to longform), Spotlights on Snapchat.


    Set your client timeout to 60 seconds, and 90 for YouTube and Facebook. Run
    scrapes from a

    background job, not inside a user request.


    ### Walking a full catalog


    Pass each response's `next_cursor` back as `cursor`. Stop on the cursor, not
    the page size:

    the first page can overshoot, and short pages turn up mid-walk.


    ```js

    const posts = [];

    let cursor;

    do {
      const res = await fetch("https://app.sideshift.app/api/v1/scrape/tiktok/posts", {
        method: "POST",
        headers: { "x-api-key": KEY, "Content-Type": "application/json" },
        body: JSON.stringify(cursor ? { username: "mrbeast", cursor } : { username: "mrbeast" }),
      });
      const { data } = await res.json();
      posts.push(...data.posts);
      cursor = data.next_cursor;
    } while (cursor);

    ```


    Cursors are opaque: pass one back verbatim, and never construct or derive
    one. A stale or

    unrecognised cursor is not an error, so you get a billed page that is not
    where you meant to

    be, and a loop that trusts it may never terminate.


    Snapchat and LinkedIn return a single page and never issue a cursor, so
    their listings are

    only what the platform exposes, not the account's full history. A creator
    with no retrievable

    posts returns `200` with an empty `posts` array, not a `404`, and is billed.


    New posts arrive at the front of page one. After the first backfill, poll
    page one on your

    schedule and keep what you haven't seen; re-fetch known posts only when you
    want updated

    metrics.


    ## 5. Reading the response


    Metrics are cumulative totals as of the moment you called. `uploadedAt` is
    unix seconds.

    `id` is the platform's own post id and is stable, which makes it the right
    key for storing

    and de-duplicating posts. On TikTok, Instagram, and Facebook, `videoUrl` and
    `thumbnail` are

    signed URLs that expire within hours: download the media when you receive
    it, and never

    store the URL. On TikTok photo posts, `videoUrl` points at the post's audio
    track rather

    than a video and nothing in the response flags it, so check the response
    `Content-Type`

    before treating the bytes as video.


    Two fields need care if you work across platforms:


    - `creator` is a lowercase handle on TikTok, Instagram, and LinkedIn,
    canonical case on X,
      and the account's **display name** on YouTube and Facebook (`Coca-Cola`, not `cocacola`).
      Join accounts on the identifier you requested, never on `creator`.
    - `postPage` on a single-post lookup echoes the URL you sent, so the same
    post can produce
      several different `postPage` values. Deduplicate on `id` plus `platform`, never on
      `postPage`.

    Single-post responses carry two keys that listings omit entirely,
    `transcript` and

    `topComments`, so read them defensively. Both are filled only when you ask
    for them with

    `include_transcript` or `include_comments`, and only on **TikTok, YouTube,
    and Facebook**;

    Instagram, Snapchat, X, and LinkedIn accept the flags and return `null`.
    Neither flag costs

    extra credits.


    Profile responses return `username`, `display_name`, and `follower_count` on
    all seven

    platforms. Everything else depends on what the source exposes, and
    unavailable fields are

    usually omitted rather than returned as `null`, so test for a usable value
    rather than for

    key presence.


    Field-level types, per-platform gaps, and the metrics that are structurally
    always `0` are

    in the `UnifiedPost` and `ScrapeProfileResponse` schemas below.


    ## 6. Errors and refunds


    Every error is JSON with an `error` code, a human-readable `message`, and a
    `request_id` to

    quote at support.


    | Code | What happened | What to do |

    |---|---|---|

    | `PROFILE_NOT_FOUND`<br>`POST_NOT_FOUND` | The platform confirmed it
    doesn't exist. Billed, because it was a real lookup. | Remove the identifier
    from your schedule. Retrying it costs a credit every time. |

    | `UPSTREAM_ERROR`<br>`UPSTREAM_TIMEOUT` | The platform failed or timed out.
    Refunded. | Retry with backoff: 30 s, then a few minutes. YouTube and
    Facebook throw these the most. |

    | `SCRAPER_RATE_LIMITED` | One of *your* limits is exhausted. The
    `X-Scraper-RateLimit-*` headers report the one that denied you. | Wait for
    `Retry-After`. If you hit this steadily, ask us to raise your limit. |

    | `SCRAPER_SYSTEM_BUSY` | *Our* capacity, nothing about your account.
    Refunded, and it does not consume your rate limit. | Wait for `Retry-After`
    and retry. |

    | `INSUFFICIENT_SCRAPER_CREDITS` | Balance is empty. Nothing charged. | Top
    up in the dashboard. `meta.credits_remaining` is on every success for
    alerting. |

    | `INVALID_INPUT` | The body failed validation. The `message` names the
    field and why. | Fix and resend. |


    The retry rule in one line: **retry refunded errors, never retry billed ones
    on a loop, and

    always honour `Retry-After`.**


    Not every `5xx` body is JSON. A request that outruns the roughly 120-second
    server ceiling

    is terminated by the gateway and returns a bare `504` with a `text/plain`
    body; its

    reservation is reclaimed within about ten minutes rather than at the moment
    it fails.


    ### A retry wrapper you can copy


    The wrapper below is the retry rule as code: it honours `Retry-After` on a
    `429`, backs

    off with jitter on refunded `5xx` errors, and gives up immediately on
    everything else.

    Route every call through it and both kinds of transient failure stop
    reaching your code.


    ```js

    async function scrape(url, body, attempts = 5) {
      for (let attempt = 1; ; attempt++) {
        const res = await fetch(url, {
          method: "POST",
          headers: { "x-api-key": KEY, "Content-Type": "application/json" },
          body: JSON.stringify(body),
        });
        if (res.ok) return (await res.json()).data;

        // 4xx other than 429 is deterministic (bad input, bad key, billed not-found):
        // retrying repeats the same answer, and on a 404 it repeats the same charge.
        const retriable = res.status === 429 || res.status >= 500;
        if (!retriable || attempt === attempts) throw new Error(await res.text());

        // A 429 says exactly when to come back. Refunded 5xx errors don't, so back off:
        // 30 s, 60 s, 2 min, 4 min. Jitter keeps parallel workers from retrying in step.
        const retryAfter = Number(res.headers.get("Retry-After"));
        const waitMs = retryAfter > 0
          ? retryAfter * 1000
          : Math.min(30_000 * 2 ** (attempt - 1), 300_000);
        await new Promise((resolve) => setTimeout(resolve, waitMs + Math.random() * 1000));
      }
    }


    const profile = await scrape(
      "https://app.sideshift.app/api/v1/scrape/tiktok/profile",
      { username: "mrbeast" },
    );

    ```


    It slots straight into the catalog walk in section 4: swap the raw `fetch`
    for

    `scrape(...)` and the loop rides out rate limits and platform hiccups
    unattended.


    ## 7. Rate limits


    New accounts start at 120 requests per minute across all endpoints. You may
    additionally have a

    per-endpoint limit. The account total is shared, so a request can be denied
    by the total

    while its own endpoint still has allowance. Both are token buckets: you can
    spend a minute's

    allowance in one burst, and it refills continuously rather than at a window
    edge.


    `X-Scraper-RateLimit-Limit`, `-Remaining`, and `-Reset` come back on every
    `200` and every

    `429`, reporting whichever limit is closest to being reached. Prefer
    `Retry-After` on a

    `429`: `-Reset` is computed when your request is admitted, so on a slow
    platform it can

    already be in the past by the time you read it.


    In almost all cases your limit is exactly what you get: stay under your rpm
    and your

    requests are admitted. The exception is the moment the scraping system as a
    whole is

    saturated across all customers, when a request can be turned away with

    `SCRAPER_SYSTEM_BUSY` even though your own buckets still have tokens. That
    answer is

    free, refunded, and carries a `Retry-After`; the wrapper in section 6
    absorbs it without

    any extra code. Treat it as something your client retries automatically, not
    an outage.


    For production volume, contact support to raise your limits.
servers:
  - url: https://app.sideshift.app/api/v1
    description: Production
security: []
tags:
  - name: Profile
    description: >-
      Profile-level info for a creator (display name, bio, follower/following
      counts, avatar, post count).
  - name: Posts
    description: One page of a creator's recent posts.
  - name: Single Post
    description: One post, looked up by its URL.
  - name: Audience
    description: Audience location data for a creator.
  - name: TikTok · Creator
    description: TikTok · Creator focused platform operations.
  - name: TikTok · Sound
    description: TikTok · Sound focused platform operations.
  - name: TikTok · Hashtag
    description: TikTok · Hashtag focused platform operations.
  - name: TikTok · Playlist
    description: TikTok · Playlist focused platform operations.
  - name: TikTok · Collection
    description: TikTok · Collection focused platform operations.
  - name: TikTok · Discovery
    description: TikTok · Discovery focused platform operations.
  - name: TikTok · Comments
    description: TikTok · Comments focused platform operations.
  - name: TikTok · Media
    description: TikTok · Media focused platform operations.
  - name: TikTok · Ads
    description: TikTok · Ads focused platform operations.
  - name: Instagram · Profile
    description: Instagram · Profile focused platform operations.
  - name: Instagram · Posts
    description: Instagram · Posts focused platform operations.
  - name: Instagram · Comments
    description: Instagram · Comments focused platform operations.
  - name: Instagram · Discovery
    description: Instagram · Discovery focused platform operations.
  - name: Instagram · Audio
    description: Instagram · Audio focused platform operations.
  - name: Instagram · Stories
    description: Instagram · Stories focused platform operations.
  - name: Instagram · Transcript
    description: Instagram · Transcript focused platform operations.
paths:
  /scrape/tiktok/reposts:
    post:
      tags:
        - TikTok · Creator
      summary: TikTok — creator reposts
      description: >-
        Posts a creator reposted. Platform field names are preserved inside
        `data`. Standard billing: 1 SideShift credit per completed lookup; the
        Scraper dashboard shows the exact rate for an account with negotiated
        pricing.
      operationId: scrapeTiktokReposts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlatformTiktokRepostsRequest'
            example:
              handle: tiktok
              cursor: '0'
      responses:
        '200':
          description: >-
            Completed lookup. Standard cost: 1 SideShift credit;
            account-specific pricing, when present, is shown in the Scraper
            dashboard and returned in the billing headers.
          headers:
            X-Scraper-Credits-Charged:
              description: Credits debited for this completed lookup (normally 1).
              schema:
                type: integer
                example: 1
            X-Scraper-Credits-Remaining:
              $ref: '#/components/headers/CreditsRemaining'
            X-Scraper-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-Scraper-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-Scraper-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformTiktokRepostsResponse'
              examples:
                live:
                  summary: Live data captured 2026-08-08
                  description: >-
                    The data object comes from a successful live request using
                    the documented input. Arrays are shortened to representative
                    items, long strings are trimmed, contact fields are
                    redacted, and transient URL query strings are removed. The
                    SideShift envelope values are representative.
                  value:
                    data:
                      unique_id: tiktok
                      cursor: '30'
                      has_more: true
                      aweme_list:
                        - aweme_id: '7634552248974052630'
                          desc: >-
                            send this one to all your college besties and get
                            the first campus group chat going ASAP‼️
                            #TikTokCampusHub — a new TikTok experience that
                            builds on the brand's Campus Verification feature —
                            is live, and I have the exclusive details on all the
                            cool perks that come along with t…
                          url: >-
                            https://www.tiktok.com/@hercampus/video/7634552248974052630
                          create_time: 1777557723
                          music:
                            author: hercampus
                            id: '7634552271187708694'
                            title: original sound - hercampus
                            id_str: '7634552271187708694'
                            mid: '7634552271187708694'
                            owner_nickname: hercampus
                            duration: 85
                            is_original: true
                            is_original_sound: true
                            cover_large:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:1080:1080.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:1080:1080.jpeg
                            cover_medium:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:1080:1080.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:1080:1080.jpeg
                            cover_thumb:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:1080:1080.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:1080:1080.jpeg
                            play_url:
                              uri: >-
                                https://v16-ies-music.tiktokcdn-us.com/7ed1b188798315e84662f6ddab0a64b1/6a80ca84/video/tos/no1a/tos-no1a-v-2370-no/oQczJ2zspEkAUAFjYB8FYDDEEJDAL3CedgfjNz/
                              url_list:
                                - >-
                                  https://v16-ies-music.tiktokcdn-us.com/7ed1b188798315e84662f6ddab0a64b1/6a80ca84/video/tos/no1a/tos-no1a-v-2370-no/oQczJ2zspEkAUAFjYB8FYDDEEJDAL3CedgfjNz/
                          video:
                            data_size: 10889747
                            duration: 85
                            watermark_data_size: 11361054
                            cover:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/oQZgIy7PtBANYI27GNi7CI0DXClwXAUfIRvxzi~tplv-tiktokx-cropcenter-q:300:400:q70.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/oQZgIy7PtBANYI27GNi7CI0DXClwXAUfIRvxzi~tplv-tiktokx-cropcenter-q:300:400:q70.jpeg
                            download_addr:
                              uri: >-
                                https://v45.tiktokcdn-us.com/d3ef9c994962959d6840c37f1e972314/6a77e3e8/video/tos/useast2a/tos-useast2a-ve-68c811-euttp/oMvRzQtACQAi1lwP7HBXy0EtfIKgNYI7Ni7CbI/
                              url_list:
                                - >-
                                  https://v45.tiktokcdn-us.com/d3ef9c994962959d6840c37f1e972314/6a77e3e8/video/tos/useast2a/tos-useast2a-ve-68c811-euttp/oMvRzQtACQAi1lwP7HBXy0EtfIKgNYI7Ni7CbI/
                            dynamic_cover:
                              uri: >-
                                https://p16-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/owAjCCQ0yitBOIxIg7zvAiYfLBXDPNI7XhlRIw~tplv-tiktokx-origin.image
                              url_list:
                                - >-
                                  https://p16-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/owAjCCQ0yitBOIxIg7zvAiYfLBXDPNI7XhlRIw~tplv-tiktokx-origin.image
                            origin_cover:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/o8A8qQsMTL9fgftZAMDDvHO5XDFgIg8jfIC5Ns~tplv-tiktokx-shrink-aq:360:360:q75.webp
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/o8A8qQsMTL9fgftZAMDDvHO5XDFgIg8jfIC5Ns~tplv-tiktokx-shrink-aq:360:360:q75.webp
                            play_addr:
                              uri: >-
                                https://v45.tiktokcdn-us.com/87405bf8812ca7f59907618beb368b39/6a77e3e8/video/tos/useast2a/tos-useast2a-ve-68c810-euttp/owBIYi7QgEYftiJCXyVvrR7SGlK7AIwPz0INAC/
                              url_list:
                                - >-
                                  https://v45.tiktokcdn-us.com/87405bf8812ca7f59907618beb368b39/6a77e3e8/video/tos/useast2a/tos-useast2a-ve-68c810-euttp/owBIYi7QgEYftiJCXyVvrR7SGlK7AIwPz0INAC/
                          author:
                            nickname: hercampus
                            unique_id: hercampus
                            region: US
                            uid: '167450281859964928'
                            avatar_larger:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:300:300.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:300:300.jpeg
                            avatar_medium:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:300:300.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:300:300.jpeg
                            avatar_thumb:
                              uri: >-
                                https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:300:300.jpeg
                              url_list:
                                - >-
                                  https://p19-common-sign.tiktokcdn-us.com/tos-useast2a-avt-0068-euttp/8a57f9686e1f52263841295ec656b60c~tplv-tiktokx-cropcenter:300:300.jpeg
                          statistics:
                            aweme_id: '7634552248974052630'
                            collect_count: 16
                            comment_count: 9
                            play_count: 17410
                            share_count: 11
                            digg_count: 180
                            download_count: 2
                          author_user_id: '167450281859964928'
                          create_time_utc: '2026-04-30T14:02:03.000Z'
                          media_id: v24044gl0000d7pm1dnog65r7i26antg
                          region: US
                          aweme_type: 0
                          is_ad: true
                          is_nff_or_nr: false
                          is_top: 0
                          item_comment_settings: 0
                          anchors:
                            - id: '263840'
                              component_key: anchor_effect
                              description: Effects
                              extra: >-
                                {"effect_post_publish_count":1063811572,"effect_source":0,"is_commerce":0,"resource_id":6711137499550323208}
                              keyword: Green Screen
                              log_extra: >-
                                {"anchor_id":"263840","anchor_name":"Green
                                Screen","anchor_type":"prop","has_friends_info":"0"}
                              type: 28
                              actions:
                                - schema: shoot
                                  action_type: 1
                                  icon:
                                    uri: >-
                                      tiktok-obj/28px_primary_create_onDark3x.png
                                    height: 720
                                    width: 720
                                    url_list:
                                      - >-
                                        https://p16-common.tiktokcdn-us.com/tiktok-obj/28px_primary_create_onDark3x.png~tplv-tiktokx-origin.image
                                      - >-
                                        https://p19-common.tiktokcdn-us.com/tiktok-obj/28px_primary_create_onDark3x.png~tplv-tiktokx-origin.image
                                      - >-
                                        https://p16-common.tiktokcdn-us.com/tiktok-obj/28px_primary_create_onDark3x.png~tplv-tiktokx-origin.jpeg
                              icon:
                                uri: tiktok-obj/20px_anchor_effect3x.png
                                height: 720
                                width: 720
                                url_list:
                                  - >-
                                    https://p16-common.tiktokcdn-us.com/tiktok-obj/20px_anchor_effect3x.png~tplv-tiktokx-origin.image
                                  - >-
                                    https://p19-common.tiktokcdn-us.com/tiktok-obj/20px_anchor_effect3x.png~tplv-tiktokx-origin.image
                                  - >-
                                    https://p16-common.tiktokcdn-us.com/tiktok-obj/20px_anchor_effect3x.png~tplv-tiktokx-origin.jpeg
                              thumbnail:
                                uri: cfaa5ce4a49351ceb195197df28a788b
                                height: 64
                                width: 64
                                url_list:
                                  - >-
                                    https://lf16-effectcdn-us.tiktokcdn-us.com/obj/tiktok-loki-effect-oracle-tx/cfaa5ce4a49351ceb195197df28a788b
                                  - >-
                                    https://lf19-effectcdn-us.tiktokcdn-us.com/obj/tiktok-loki-effect-oracle-tx/cfaa5ce4a49351ceb195197df28a788b
                          commerce_info:
                            ad_source: 1
                            adv_promotable: true
                            auction_ad_invited: false
                            branded_content_type: 0
                            is_diversion_ad: 0
                            with_comment_filter_words: false
                      user_id: null
                    request_id: req_8f3c9a2b1d4e6f70
                    upstream_calls: 1
                    meta:
                      credits_charged: 1
                      credits_remaining: 9998
        '400':
          $ref: '#/components/responses/PlatformOperationBadRequest'
        '401':
          $ref: '#/components/responses/PlatformOperationUnauthorized'
        '402':
          $ref: '#/components/responses/PlatformOperationInsufficientCredits'
        '404':
          $ref: '#/components/responses/PlatformOperationNotFound'
        '413':
          $ref: '#/components/responses/PlatformOperationPayloadTooLarge'
        '429':
          $ref: '#/components/responses/PlatformOperationRateLimited'
        '500':
          $ref: '#/components/responses/PlatformOperationServerError'
        '502':
          $ref: '#/components/responses/PlatformOperationDataSourceError'
        '504':
          $ref: '#/components/responses/PlatformOperationDataSourceTimeout'
components:
  schemas:
    PlatformTiktokRepostsRequest:
      type: object
      additionalProperties: false
      properties:
        handle:
          type: string
          description: >-
            Creator handle. Accepted names: `handle` or `unique_id`. Send only
            one.
          default: null
          nullable: true
        unique_id:
          type: string
          description: >-
            Creator handle. Accepted names: `handle` or `unique_id`. Send only
            one.
          default: null
          nullable: true
        user_id:
          type: string
          description: Numeric creator id.
          default: null
          nullable: true
        cursor:
          type: string
          description: Opaque pagination token.
          default: '0'
          maxLength: 32768
      allOf:
        - description: Use a handle (or unique_id) or a numeric creator id, not both.
          oneOf:
            - required:
                - handle
              not:
                anyOf:
                  - required:
                      - unique_id
                  - required:
                      - user_id
            - required:
                - unique_id
              not:
                anyOf:
                  - required:
                      - handle
                  - required:
                      - user_id
            - required:
                - user_id
              not:
                anyOf:
                  - required:
                      - handle
                  - required:
                      - unique_id
    PlatformTiktokRepostsResponse:
      type: object
      required:
        - data
        - request_id
        - upstream_calls
        - meta
      properties:
        data:
          $ref: '#/components/schemas/PlatformTiktokRepostsData'
        request_id:
          type: string
          description: SideShift request id. Include it in support requests.
        upstream_calls:
          type: integer
          enum:
            - 1
          description: Number of data-source lookups performed.
        meta:
          $ref: '#/components/schemas/CreditsMeta'
    PlatformTiktokRepostsData:
      type: object
      description: TikTok platform data payload. Field names and nesting are preserved.
      additionalProperties: true
      properties:
        aweme_list:
          type: array
          items:
            $ref: '#/components/schemas/PlatformTiktokPost'
        cursor:
          type: string
          nullable: true
          description: Pass back on the next call. null once the list is exhausted.
        has_more:
          type: boolean
          description: Whether another page exists.
        unique_id:
          type: string
          description: Echo of what you queried.
        user_id:
          type: string
          nullable: true
          description: Echo of what you queried.
    CreditsMeta:
      type: object
      description: >-
        Per-request credit accounting (also surfaced in the X-Scraper-Credits-*
        response headers).
      properties:
        credits_charged:
          type: integer
        credits_remaining:
          type: integer
    ScrapeError:
      type: object
      required:
        - error
        - message
        - request_id
      properties:
        error:
          type: string
          enum:
            - INVALID_JSON
            - INVALID_INPUT
            - PAYLOAD_TOO_LARGE
            - UNAUTHORIZED
            - INSUFFICIENT_SCRAPER_CREDITS
            - PROFILE_NOT_FOUND
            - POST_NOT_FOUND
            - RESOURCE_NOT_FOUND
            - SCRAPER_RATE_LIMITED
            - SCRAPER_SYSTEM_BUSY
            - UPSTREAM_ERROR
            - UPSTREAM_TIMEOUT
            - SCRAPER_USAGE_FINALIZE_FAILED
            - INTERNAL_ERROR
        message:
          type: string
          description: Human-readable, SideShift-owned message.
        platform:
          type: string
          enum:
            - tiktok
            - instagram
            - youtube
            - facebook
            - snapchat
            - twitter
            - linkedin
        identifier:
          type: string
          description: The username or URL that was requested, when known.
        field:
          type: string
          description: Offending field on a validation error.
        reason:
          type: string
          description: Validation reason.
        request_id:
          type: string
    PlatformTiktokPost:
      type: object
      additionalProperties: true
      properties:
        aweme_id:
          type: string
        desc:
          type: string
          nullable: true
        desc_language:
          type: string
          nullable: true
        region:
          type: string
        create_time:
          oneOf:
            - type: number
            - type: string
              format: date-time
        create_time_utc:
          type: string
        is_ad:
          type: boolean
        is_top:
          type: number
          nullable: true
        is_eligible_for_commission:
          type: boolean
          nullable: true
        is_paid_partnership:
          type: boolean
          nullable: true
        aweme_type:
          type: number
        statistics:
          type: object
          description: >-
            Nested — aweme_id, play_count, digg_count, comment_count,
            share_count, download_count, …
          additionalProperties: true
          properties:
            aweme_id:
              type: string
            collect_count:
              type: number
              nullable: true
            comment_count:
              type: number
            digg_count:
              type: number
            download_count:
              type: number
            forward_count:
              nullable: true
            lose_comment_count:
              nullable: true
            lose_count:
              nullable: true
            play_count:
              type: number
            repost_count:
              nullable: true
            share_count:
              type: number
            whatsapp_share_count:
              nullable: true
        video:
          type: object
          description: >-
            Nested — play_addr, download_addr, cover, origin_cover,
            dynamic_cover, duration, …
          additionalProperties: true
          properties:
            cover:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            data_size:
              type: number
              nullable: true
            download_addr:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            duration:
              type: number
              nullable: true
            dynamic_cover:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            height:
              nullable: true
            origin_cover:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            play_addr:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            watermark_data_size:
              type: number
              nullable: true
            width:
              nullable: true
        image_post_info:
          type: object
          nullable: true
          additionalProperties: true
          properties:
            image_post_cover:
              type: object
              additionalProperties: true
              properties:
                display_image:
                  type: object
                  additionalProperties: true
                owner_watermark_image:
                  type: object
                  additionalProperties: true
            images:
              type: array
              items:
                type: object
                additionalProperties: true
        author:
          type: object
          description: >-
            Nested — uid, short_id, unique_id, nickname, signature,
            avatar_thumb, …
          additionalProperties: true
          properties:
            avatar_larger:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            avatar_medium:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            avatar_thumb:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            events:
              nullable: true
            language:
              nullable: true
            nickname:
              type: string
            region:
              type: string
            sec_uid:
              nullable: true
            short_id:
              nullable: true
            signature:
              nullable: true
            social_info:
              nullable: true
            uid:
              type: string
            unique_id:
              type: string
        author_user_id:
          type: string
        music:
          type: object
          nullable: true
          description: Nested — id, id_str, mid, title, author, owner_nickname, …
          additionalProperties: true
          properties:
            album:
              type: string
              nullable: true
            author:
              type: string
            cover_large:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            cover_medium:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            cover_thumb:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            duration:
              type: number
            id:
              type: string
            id_str:
              type: string
            is_original:
              type: boolean
            is_original_sound:
              type: boolean
            mid:
              type: string
            owner_nickname:
              type: string
            play_url:
              type: object
              additionalProperties: true
              properties:
                height:
                  nullable: true
                uri:
                  type: string
                url_list:
                  type: array
                  items: {}
                url_prefix:
                  nullable: true
                width:
                  nullable: true
            title:
              type: string
            user_count:
              nullable: true
        item_comment_settings:
          type: number
        is_nff_or_nr:
          type: boolean
          nullable: true
        commerce_info:
          type: object
          nullable: true
          description: >-
            Nested — adv_promotable, auction_ad_invited, branded_content_type,
            is_diversion_ad, with_comment_filter_words
          additionalProperties: true
          properties:
            adv_promotable:
              type: boolean
            auction_ad_invited:
              type: boolean
            branded_content_type:
              type: number
            is_diversion_ad:
              type: number
            organic_log_extra:
              type: string
            with_comment_filter_words:
              type: boolean
        anchors:
          type: array
          nullable: true
          items:
            type: object
            additionalProperties: true
            properties:
              actions:
                type: array
                items: {}
              anchor_strong:
                nullable: true
              component_key:
                type: string
              description:
                type: string
              extra:
                type: string
              general_type:
                type: number
              icon:
                type: object
                additionalProperties: true
              id:
                type: string
              keyword:
                type: string
              log_extra:
                type: string
              thumbnail:
                type: object
                additionalProperties: true
              type:
                type: number
        url:
          type: string
        shop_product_url:
          type: string
          nullable: true
        media_id:
          type: string
          nullable: true
        content_type:
          type: string
        id:
          type: string
        images:
          nullable: true
  headers:
    CreditsRemaining:
      schema:
        type: integer
      description: Account credit balance after this request.
    RateLimitLimit:
      schema:
        type: integer
      description: >-
        Requests allowed per minute by the limit closest to being reached — your
        account total, or the per-endpoint limit for this endpoint if you have
        one.
    RateLimitRemaining:
      schema:
        type: integer
      description: >-
        Requests you can still make right now against that same limit. It is a
        token bucket, so this refills continuously at the per-minute rate rather
        than jumping back to the full limit at a window edge.
    RateLimitReset:
      schema:
        type: integer
      description: >-
        Unix seconds. Computed when the request is admitted, not when the
        response is written, so on a success it reads about a minute out MINUS
        the call's latency — on a slow platform it can already be in the past by
        the time you read it. On a 429, when the denied limit will have refilled
        enough to serve the request; prefer the `Retry-After` header, which says
        the same thing in seconds from now.
    CreditsCharged:
      schema:
        type: integer
      description: Credits debited for this request.
  responses:
    PlatformOperationBadRequest:
      description: Invalid JSON or request fields. No credits are charged.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: INVALID_INPUT
            message: Invalid request body.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationUnauthorized:
      description: Missing or invalid SideShift scraper key. No credits are charged.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: UNAUTHORIZED
            message: Invalid scraper API key.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationInsufficientCredits:
      description: Insufficient scraper credits. No credits are charged.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: INSUFFICIENT_SCRAPER_CREDITS
            message: Insufficient scraper credits.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationNotFound:
      description: >-
        The requested public resource was not found or is unavailable. A
        completed lookup is billed at the endpoint rate.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: RESOURCE_NOT_FOUND
            message: Requested resource not found or unavailable.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationPayloadTooLarge:
      description: Request body exceeds 32 KB. No credits are charged.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: PAYLOAD_TOO_LARGE
            message: Request body must be 32KB or smaller.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationRateLimited:
      description: >-
        Rate limit or system-capacity limit. No credits are charged; honor
        Retry-After.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            minimum: 1
        X-Scraper-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-Scraper-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-Scraper-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: SCRAPER_RATE_LIMITED
            message: Scraper API rate limit exceeded.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationServerError:
      description: Unexpected SideShift error. Credits are refunded.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: INTERNAL_ERROR
            message: Request failed. Your credits were refunded.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationDataSourceError:
      description: The data source failed. Credits are refunded.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: UPSTREAM_ERROR
            message: Data source failed. Your credits were refunded.
            request_id: req_8f3c9a2b1d4e6f70
    PlatformOperationDataSourceTimeout:
      description: The data source timed out. Credits are refunded.
      headers:
        X-Scraper-Credits-Charged:
          $ref: '#/components/headers/CreditsCharged'
        X-Scraper-Credits-Remaining:
          $ref: '#/components/headers/CreditsRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScrapeError'
          example:
            error: UPSTREAM_TIMEOUT
            message: Data source timed out. Your credits were refunded.
            request_id: req_8f3c9a2b1d4e6f70

````