# Likee Scraper — Profiles, Videos, Share Links & Discovery (`teodor_banea/likee-scraper`) Actor

Scrape Likee creator profiles by username or ID, their videos with exact plays, likes, comments and shares, share links with a direct mp4, and Likee's recommended creators per country. 3$/1000, cheaper than the competition :P

- **URL**: https://apify.com/teodor_banea/likee-scraper.md
- **Developed by:** [Banea Teodor](https://apify.com/teodor_banea) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Likee Scraper — Profiles, Videos, Share Links & Discovery

Scrape **Likee** creators and videos through Likee's own web JSON API. Paste usernames,
user IDs, share links or country codes and get clean rows: follower counts, exact plays,
likes, comments and shares per video, captions, hashtags, mentions, music, cover images and
— for share links — the direct mp4. No Likee account, no API key, no browser, no proxy setup.

### What does Likee Scraper do?

- **Creator profiles by username** — `@Likee_USA`, `Likee_USA` or `https://likee.video/@Likee_USA`.
  Followers, following, total likes, level, bio, verification badge, linked Instagram /
  YouTube / Facebook / Twitter / VK, external link, private flag. Numeric user IDs work too.
- **Video history per creator** — newest first, with exact `plays`, `likes`, `comments`,
  `shares`, caption, hashtags, mentions, publish date, music / original sound, cover image,
  dimensions and country. Cap it per creator, by date window, or by minimum plays / likes.
- **Individual videos** — share links (`https://likee.video/v/sepkYQ`, the link the app
  copies) return the video **plus its direct mp4 URL, duration and download count**. Video
  page links (`https://likee.video/@user/video/7575905643698432274`) return the stats.
- **Creator discovery by country** — Likee's recommended-creator list (up to 100 per country)
  as profile rows, optionally with each creator's newest videos.

Every row carries a `type` (`video` or `profile`) and the same key set, so CSV and
Google Sheets exports stay aligned.

### Why use this Actor?

- **Usernames work.** Likee's web pages no longer render profiles, which is why other
  scrapers ask for numeric user IDs or share links only. This Actor resolves `@username` to
  the full profile and video history directly.
- **Exact numbers, not rounded.** Plays, likes, comments and shares come from the API as
  integers (`899054`), not from the share page's `899K`.
- **Cheap and fast.** Plain HTTP against a JSON API: a 100-video profile is two requests.
  No browser, no residential proxies, no login that can get banned.
- **Honest reporting.** Unknown usernames, private accounts, deleted videos and dead share
  links are reported per target under `ERRORS` and in the run's status message instead of
  failing silently. Filtered-out videos are never billed.
- **Restart-safe.** State is saved after every page; a migrated or resurrected run resumes
  its cursors and never bills a page twice.

### How much does it cost?

**$3.00 per 1,000 results** (one result = one video row or one profile row). No per-run fee,
compute and proxies included.

| Run | Results | Cost |
|---|---|---|
| Default input (2 profiles × 30 videos + 2 profile rows) | 62 | $0.19 |
| Creator vetting: 20 usernames, profile rows only (`maxVideosPerProfile: 0`) | 20 | $0.06 |
| Daily monitor: 10 creators, `publishedAfter: "1 day"` (~3 videos/day each) | ~40 | ~$0.12/day |
| Discovery: 5 countries × 100 creators, profile rows | 500 | $1.50 |
| Full export: 1 creator, 5,000 videos | 5,001 | $15.00 |

Error records are free.

### Input

| Field | Type | Description |
|---|---|---|
| `profiles` | array | Creators as `@name`, `name`, `https://likee.video/@name`, a numeric uid (`30007`) or `uid:30007`. Up to 200 per run. |
| `maxVideosPerProfile` | integer | Newest videos per creator in `profiles`. Default 100, max 10,000. `0` = profile row only. |
| `videoUrls` | array | Share links (`https://likee.video/v/sepkYQ`, `https://l.likee.video/v/sepkYQ`), video page links (`https://likee.video/@user/video/123…`) or `user/123…`. Up to 500. |
| `discoverCountries` | array | Two-letter country codes (`US`, `RU`, `ID`, `PK`, `BR`…). Returns Likee's recommended creators per country. |
| `maxCreatorsPerCountry` | integer | Cap per country. Likee's list holds at most 100. Default 100. |
| `videosPerDiscoveredCreator` | integer | Newest videos per discovered creator. Default `0` (profile rows only). |
| `publishedAfter` | string | Only videos on or after this date: `YYYY-MM-DD` or relative (`3 days`, `2 weeks`). Paging stops at the boundary. |
| `publishedBefore` | string | Only videos on or before this date (`YYYY-MM-DD`). |
| `minPlays` / `minLikes` | integer | Skip videos below these thresholds. Not billed. |
| `includeProfileRows` | boolean | Add one profile row per creator scraped or discovered. Default `true`. |
| `maxTotalResults` | integer | Run-wide cap on rows. `0` (default) = no cap. |

At least one of `profiles`, `videoUrls` or `discoverCountries` is required.

Example input:

```json
{
    "profiles": ["Likee_USA", "@baby.miaa"],
    "maxVideosPerProfile": 30,
    "videoUrls": ["https://likee.video/v/sepkYQ"],
    "publishedAfter": "30 days"
}
```

### Output

One row per video or profile in the default dataset. A video row:

```json
{
    "type": "video",
    "uid": "1216719122",
    "likeeId": "baby.miaa",
    "nickname": "BABY MIA💫",
    "url": "https://likee.video/@baby.miaa/video/7575905643698432274",
    "profileUrl": "https://likee.video/@baby.miaa",
    "avatarUrl": "https://img.like.video/eu_live/9uz/1x7fpV00m2IH3Aw0qIyL9_4.jpg?type=20&auth-token=…",
    "isVerified": true,
    "badgeType": "7",
    "verifiedLabel": null,
    "isPrivate": false,
    "followers": 2311407,
    "following": 61,
    "totalLikes": 150371229,
    "level": 25,
    "bio": "💌 реклама: @kris_pr_mia",
    "externalLink": null,
    "instagram": null,
    "youtube": null,
    "facebook": null,
    "twitter": null,
    "vk": null,
    "country": "RU",
    "postId": "7575905643698432274",
    "shareUrl": "https://likee.video/v/sepkYQ",
    "caption": "Справилась ? 👇🏻😂",
    "hashtags": [],
    "mentions": [],
    "mentionUids": [],
    "plays": 1590770,
    "likes": 84847,
    "comments": 4718,
    "shares": 662,
    "downloads": 43,
    "publishedAt": "2025-11-23T13:03:07.000Z",
    "durationSeconds": 37,
    "videoUrl": "https://video.like.video/eu_live/9uF/01vN9jgg01IZ_4.mp4?crc=1487566046&type=5",
    "coverUrl": "https://videosnap.like.video/eu_live/9uy/1vN9kB00m2EfDMg1MUCTx_4.jpg?wmk_sdk=1&type=8",
    "width": 1080,
    "height": 1920,
    "musicName": "BABY MIA💫",
    "musicId": null,
    "soundId": "3280938347698432274",
    "soundOwner": "BABY MIA💫",
    "postType": 0,
    "source": "shareLink",
    "scrapedAt": "2026-10-15T18:40:12.345Z"
}
```

A profile row has `type: "profile"`, `url` = the profile URL, the creator metrics filled
(`followers`, `following`, `totalLikes`, `level`, `bio`, social links) and every video
field `null` (arrays empty). Video rows scraped from a creator in `profiles` or
`discoverCountries` also carry that creator's `followers`, `following`, `totalLikes`,
`verifiedLabel` and `bio`; rows from share links and video links fetch the creator's profile too.

Field notes:

- `videoUrl` (mp4), `durationSeconds` and `downloads` are only available through **share
  links** — Likee's API does not expose them for profile video lists. `downloads` is Likee's
  rounded figure (`1.79K` → `1790`); every other count is exact.
- `isVerified` is derived from Likee's badge object; `badgeType` keeps the raw code (`"2"` on official
  accounts, other codes for creator programmes) so you can apply your own definition.
- `avatarUrl` and `coverUrl` are signed URLs that expire after some days — download what you need.
- `source` tells where a row came from: `profile:<input>`, `discovery:<country>`, `shareLink`
  or `videoLink`.

Two dataset views are provided in the Console: **Videos** and **Profiles**.

#### Errors

Targets that could not be scraped are listed under the `ERRORS` key of the run's key-value
store with a reason (`notFound`, `private`, `invalid`, `noVideos`, `requestFailed`) and a
plain-language message. The run's status message repeats the count. A run whose targets all
fail exits with an error; a run with partial failures exits normally with the rows it got.

### Tips and tricks

- **Creator vetting at scale:** list usernames in `profiles` with `maxVideosPerProfile: 0`
  for one cheap profile row each; add `maxVideosPerProfile: 20` to get per-video engagement.
- **Daily monitoring:** schedule the Actor with `publishedAfter: "1 day"` on creators that post
  regularly. Videos are walked newest-first and paging stops at the boundary, so you pay only for
  new videos (the official `Likee_*` accounts post rarely — pick real creators).
- **Hashtag and search data are not available.** Likee retired its web search, hashtag and
  trending endpoints; they answer "system busy" for every client. Discovery by country is
  the remaining way to find creators you do not know yet.
- **Numeric user IDs** are resolved to usernames through the creator's newest video. A
  private account or an account with no public videos cannot be resolved that way — use the
  username.
- **Likee hides some posts** (deleted, under review, region-locked): official accounts most of all
  (`Likee_India` serves 2 of its newest 30), but regular creators lose a few per page too. A short
  page is not the end of the history; the Actor keeps paging until Likee returns nothing.
- **Hashtags:** Likee's API intermittently omits the hashtag list on long pages, so the Actor falls
  back to the `#tags` written in the caption. Casing then follows the caption (`#haul`) rather than
  Likee's canonical form (`Haul`).
- **Discovery lists are editorial, not geographic.** Countries without their own recommended list
  (most of them) return Likee's global list, and the creators on a country's list often post from
  elsewhere. A creator on several requested lists appears once, under the first country in your
  input. Some recommended creators are private: they yield a profile row only.
- `postType` is Likee's raw code (0, 1 and 5 observed); `verifiedLabel` comes in the creator's
  language; `level` can be 0; `twitter` and `vk` are rarely filled.
- **Speed:** Likee answers in 4–6 s per request and a creator's pages load one after another, so
  expect roughly 1,000 videos per minute per creator. Several creators run in parallel.

### Integrations

Export the dataset as JSON, CSV or Excel from the run's **Dataset** tab, pull it through the
[Apify API](https://docs.apify.com/api/v2#/reference/datasets/item-collection/get-items)
(`/v2/datasets/{datasetId}/items?format=csv`), or connect it to Google Sheets, Zapier, Make,
Airtable or a webhook with [Apify integrations](https://apify.com/integrations). Schedule the
Actor in the Console for monitoring runs.

# Changelog

This Actor's version history is a separate document: https://apify.com/teodor_banea/likee-scraper/changelog.md

# Actor input Schema

## `profiles` (type: `array`):

Enter one creator per line as a username (Likee ID) — @Likee_USA, Likee_USA or https://likee.video/@Likee_USA — or as a numeric user ID (30007 or uid:30007). Each profile yields one profile row plus its newest videos, up to the per-profile maximum.

## `maxVideosPerProfile` (type: `integer`):

Newest videos to return for each profile in the Creator profiles list. Set to 0 to return only the profile row.

## `videoUrls` (type: `array`):

Enter one video per line. Share links (https://likee.video/v/sepkYQ or https://l.likee.video/v/sepkYQ — in the app: Share → Copy link) also return the direct mp4 URL. Video page links (https://likee.video/@username/video/7575905643698432274) and the short form username/postId return the stats without an mp4.

## `discoverCountries` (type: `array`):

Two-letter country codes (US, RU, ID, PK, BR…). For each country the Actor returns Likee's recommended-creator list (up to 100 creators) as profile rows. Countries without a dedicated list return Likee's global list.

## `maxCreatorsPerCountry` (type: `integer`):

Cap on discovered creators per country. Likee's list holds at most 100 per country.

## `videosPerDiscoveredCreator` (type: `integer`):

Also return this many newest videos for every discovered creator. 0 (default) returns profile rows only — each extra video is a billed result, so 100 creators × 20 videos = 2,000 results.

## `publishedAfter` (type: `string`):

Only include videos published on or after this date. Use an absolute date (YYYY-MM-DD, UTC start of day) or a relative one such as "7 days" (= 7 days ago). Videos are walked newest-first, so paging stops at this boundary — ideal for scheduled runs.

## `publishedBefore` (type: `string`):

Only include videos published on or before this date (YYYY-MM-DD, UTC end of day). Newer videos are skipped page by page.

## `minPlays` (type: `integer`):

Skip videos with fewer plays than this.

## `minLikes` (type: `integer`):

Skip videos with fewer likes than this.

## `includeProfileRows` (type: `boolean`):

Add one profile row (followers, following, total likes, bio, verification, social links) for every creator scraped or discovered. Each profile row is one billed result. Turn off to receive video rows only.

## `maxTotalResults` (type: `integer`):

Optional cap on rows (profiles + videos) across the whole run. Leave at 0 for no run-wide cap.

## Actor input object example

```json
{
  "profiles": [
    "Likee_USA",
    "@Likee_Russia"
  ],
  "maxVideosPerProfile": 30,
  "maxCreatorsPerCountry": 20,
  "videosPerDiscoveredCreator": 0,
  "minPlays": 0,
  "minLikes": 0,
  "includeProfileRows": true,
  "maxTotalResults": 0
}
```

# Actor output Schema

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

Rows with type "video" (plays, likes, comments, shares, caption, hashtags, mentions, music, cover, mp4 for share links) and type "profile" (followers, following, total likes, bio, verification, social links).

## `resultsCsv` (type: `string`):

The same rows as a CSV download for spreadsheets.

## `errors` (type: `string`):

Profiles, videos or countries that could not be scraped (not found, private, invalid link, requests failed). Only present when something failed; the run's status message reports each shortfall.

# 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 = {
    "profiles": [
        "Likee_USA",
        "@Likee_Russia"
    ],
    "maxVideosPerProfile": 30,
    "maxCreatorsPerCountry": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("teodor_banea/likee-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 = {
    "profiles": [
        "Likee_USA",
        "@Likee_Russia",
    ],
    "maxVideosPerProfile": 30,
    "maxCreatorsPerCountry": 20,
}

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

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

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

```

## CLI example

```bash
echo '{
  "profiles": [
    "Likee_USA",
    "@Likee_Russia"
  ],
  "maxVideosPerProfile": 30,
  "maxCreatorsPerCountry": 20
}' |
apify call teodor_banea/likee-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,teodor_banea/likee-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bRkvYFPPhyXcbHtdV/builds/IthXprqeIv2ortGrx/openapi.json
