# SocialGrid — TikTok Scraper (`fulinlabs/socialgrid-tiktok-scraper`) Actor

Unified-schema TikTok profile and video data via a residential proxy (TikTok mandatory-login-walls datacenter IPs — see PLAN.md). Reduced-surface MVP: profile + single video only; posts-listing/comments/search/trending need TikTok's signed XHR API and are deferred.

- **URL**: https://apify.com/fulinlabs/socialgrid-tiktok-scraper.md
- **Developed by:** [Giovanni](https://apify.com/fulinlabs) (community)
- **Categories:** Social media
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## SocialGrid — TikTok Scraper

> **Unofficial community Actor.** Not affiliated with, endorsed by, or sponsored by TikTok.

Unified-schema TikTok profile and single-video data — flat, agent-ready JSON, never raw SIGI/universal-data blobs. Routed through Apify's residential proxy, which is required to bypass TikTok's mandatory-login-wall on datacenter IPs.

### Why this vs. a raw-blob scraper

TikTok's own embedded JSON (`SIGI_STATE`/`__UNIVERSAL_DATA_FOR_REHYDRATION__`) is a sprawling internal app-state dump — hundreds of fields, most irrelevant, with no stable "here's the profile" shape. This actor extracts just what a creator-analytics workflow or an LLM agent needs — `Author` and `Post` objects shared across SocialGrid's YouTube/TikTok/Instagram scrapers — so the same downstream code works across platforms. Fields TikTok doesn't expose come back as `null`, never `0`, so "no data" and "zero" are never confused.

### What it does — and honestly, what it doesn't (yet)

**Implemented and live-verified:**

| Mode | Description | Key input |
|---|---|---|
| `profile` | Account profile: display name, bio, avatar, follower/following/video counts, verified, external links | `handle` |
| `post` | Single video detail: caption, engagement (views/likes/comments/shares), posted date, hashtags | `videoUrl` |

**Explicitly NOT implemented in this MVP** — `posts` (video listing), `comments`, `search`, and `trending` all throw a clean `notImplemented`-style error, not fake or partial data. These require TikTok's signed XHR API (`X-Bogus`/`msToken` request signing), which is a separate, unsolved reverse-engineering effort, not a quick follow-up. If you need those, this actor isn't ready for them yet — check back or watch for a future version.

We verified there's no simpler fallback: no SSR-embedded video list on the profile page, `/tag/*`, `/discover/*`, `/foryou`, oEmbed, the legacy `node/share` endpoint, sitemap.xml, or Open Graph/JSON-LD meta tags expose a video list without the signed API.

### Example output (`mode: "profile"`)

```json
{
  "success": true,
  "platform": "tiktok",
  "mode": "profile",
  "data": {
    "platform": "tiktok",
    "id": "6614519312189947909",
    "handle": "mrbeast",
    "display_name": "MrBeast",
    "bio": "Watch my latest video! 👇",
    "avatar_url": "https://p16-common-sign.tiktokcdn-eu.com/...",
    "verified": true,
    "followers": 129200000,
    "following": 353,
    "post_count": 462,
    "total_likes": 1300000000,
    "external_links": ["https://youtu.be/iYlODtkyw_I?si=..."],
    "is_private": false
  }
}
````

### Input

- `mode` (required): `profile | post` — only these two are implemented, see above
- `handle`: account handle (`@mrbeast`) or full profile URL — required for `mode=profile`
- `videoUrl`: full TikTok video URL, must include the author's handle in the path (`tiktok.com/@handle/video/123...`) — required for `mode=post`
- `proxyGroup` (default `RESIDENTIAL`): Apify proxy group. TikTok mandatory-login-walls datacenter IPs, so this must stay `RESIDENTIAL` for the actor to work at all — residential IPs are individually inconsistent (some still hit the login wall), so the actor retries with a fresh proxy session automatically

### Usage

#### Apify CLI

```bash
apify actors call fulinlabs/socialgrid-tiktok-scraper \
  --input '{"mode": "profile", "handle": "@mrbeast"}'
```

#### REST API

```bash
curl "https://api.apify.com/v2/acts/fulinlabs~socialgrid-tiktok-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "post", "videoUrl": "https://www.tiktok.com/@mrbeast/video/..."}'
```

### Pricing

Benchmarked against comparable Store TikTok actors (apidojo's TikTok Scraper/Profile Scraper at $0.30/1,000 posts or users, TikTok Shop Scraper at ~$2/1,000 results). Given this actor uses metered residential-proxy bandwidth per call (TikTok's login wall requires it — see Risks below), pricing is set slightly above a plain datacenter-proxy scraper:

- `profile` / `post`: **$1.50 per 1,000 results**

### Reliability & known risks

- Residential proxy bandwidth is metered and billed separately by Apify — every call costs proxy GB, tracked as volume grows.
- Individual residential IPs are inconsistently reliable; the actor retries with a fresh session, but a soak test under real production volume (and non-US regions) hasn't been run yet.
- A 6-hour canary schedule re-runs the live test suite (`getProfile` + `getPost` against known fixtures) and alerts on failure.

# Actor input Schema

## `mode` (type: `string`):

Which operation to run. Only profile and post are implemented in this MVP — see description.

## `handle` (type: `string`):

e.g. '@mrbeast' or a full profile URL. Required for mode=profile.

## `videoUrl` (type: `string`):

Full TikTok video URL (must include the author's handle in the path, e.g. tiktok.com/@handle/video/123...). Required for mode=post.

## `proxyGroup` (type: `string`):

TikTok mandatory-login-walls datacenter IPs — RESIDENTIAL is required for this actor to work at all.

## Actor input object example

```json
{
  "mode": "profile",
  "proxyGroup": "RESIDENTIAL"
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items containing the requested TikTok profile or video result wrapper, including success state, data, or an error.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("fulinlabs/socialgrid-tiktok-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("fulinlabs/socialgrid-tiktok-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call fulinlabs/socialgrid-tiktok-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fulinlabs/socialgrid-tiktok-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "SocialGrid — TikTok Scraper",
        "description": "Unified-schema TikTok profile and video data via a residential proxy (TikTok mandatory-login-walls datacenter IPs — see PLAN.md). Reduced-surface MVP: profile + single video only; posts-listing/comments/search/trending need TikTok's signed XHR API and are deferred.",
        "version": "0.1",
        "x-build-id": "pvihuwZnhTaLBvnRs"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fulinlabs~socialgrid-tiktok-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fulinlabs-socialgrid-tiktok-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/fulinlabs~socialgrid-tiktok-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fulinlabs-socialgrid-tiktok-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/fulinlabs~socialgrid-tiktok-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fulinlabs-socialgrid-tiktok-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "profile",
                            "post"
                        ],
                        "type": "string",
                        "description": "Which operation to run. Only profile and post are implemented in this MVP — see description.",
                        "default": "profile"
                    },
                    "handle": {
                        "title": "Account handle or profile URL",
                        "type": "string",
                        "description": "e.g. '@mrbeast' or a full profile URL. Required for mode=profile."
                    },
                    "videoUrl": {
                        "title": "Video URL",
                        "type": "string",
                        "description": "Full TikTok video URL (must include the author's handle in the path, e.g. tiktok.com/@handle/video/123...). Required for mode=post."
                    },
                    "proxyGroup": {
                        "title": "Apify proxy group",
                        "type": "string",
                        "description": "TikTok mandatory-login-walls datacenter IPs — RESIDENTIAL is required for this actor to work at all.",
                        "default": "RESIDENTIAL"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
