# Zalo Official Account Scraper — OA Profiles & QR Pages (`crawloop/zalo-scraper`) Actor

Scrape public Zalo Official Account pages: OA ID, name, avatar, verified flag, category, address, working hours, and QR image. No login, no QR session. Export JSON via Python, Node.js, or MCP.

- **URL**: https://apify.com/crawloop/zalo-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 zalo oa results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

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

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Zalo Official Account Scraper — OA Profiles & QR Pages

> **Disclaimer:** Independent tool for **publicly accessible** Zalo Official Account landing pages on zalo.me. **Zalo** and related marks are trademarks of VNG Corporation. Not affiliated with, sponsored by, or endorsed by Zalo or VNG. Does not log into Zalo, does not scan a QR session, and does not read private chats, contacts, or group members. For research, lead enrichment, and brand-monitoring of **public OA pages** only. Respect applicable terms of use and law.

**Zalo scraper** for **public Official Accounts (OA)** — a practical **Zalo API alternative** that needs **no login** and **no QR code**. Look up `zalo.me/{oaId}` or a custom OA slug and export **OA ID**, **name**, **avatar**, **verified flag**, **category**, **address**, **working hours**, and **QR image URL** as **JSON**, **CSV**, or **Excel**. Scrape Zalo OA pages with **Python**, **Node.js**, **cURL**, or **Apify MCP** / AI assistants.

This Actor reads the same public landing payload a logged-out browser sees. It is a **Zalo OA scraper** and a **Zalo Official Account profile extractor**, not a personal-chat exporter.

### When to use this Actor

- You need a **Zalo scraper** / **Zalo API alternative** for **Official Account** profile fields
- You have `zalo.me` OA URLs, numeric **OA IDs**, or custom **OA slugs**
- You want **verified** status, **category**, **address**, **hours**, **avatar**, and **QR** in a dataset
- You scrape Zalo with **Python**, **Node.js**, or **MCP** and export JSON

### When not to use this Actor

- **Private chats, contacts, group members, or message history** — those are not on public OA pages (and require a logged-in Zalo account)
- **Personal `zalo.me/{phone}` profiles** — Zalo redirects those to login
- **Group invite links** (`zalo.me/g/…`) — not public on the web
- **OA posts, articles, shop SKUs, or follower lists** — not exposed on the logged-out landing page

### Key features

- **Public OA landing pages** — numeric IDs and custom slugs
- **Stable OA ID** plus name, description, avatar, QR image
- **Verified flag**, category (vi/en), tier, address, working hours
- **Clear statuses** — `public`, `login_required`, `not_found`, `invalid`, `error` (a login redirect is not treated as a profile)
- **HTTP only** — Chrome TLS via curl\_cffi, 256–512 MB, no Playwright, no QR login
- **MCP / AI ready** — call from assistants via Apify MCP

### Use cases

| Use case | What you get |
| :--- | :--- |
| **Brand / OA directory** | Canonical OA ID, name, verified flag, category |
| **Store / branch cards** | Public address + working hours when the OA publishes them |
| **QR / deep-link ops** | QR image URL + message argv for the public OA |
| **CRM enrichment** | Structured OA rows from a list of zalo.me links |

### Input

| Field | Type | Description |
| :--- | :--- | :--- |
| `startUrls` | array | Public `zalo.me/…` OA URLs |
| `oaIds` | array | Numeric Official Account IDs |
| `slugs` | array | Custom OA URL slugs |
| `oaText` | string | Paste mixed IDs / slugs / URLs |
| `maxItems` | integer | Dataset cap (default 100) |
| `concurrency` | integer | Parallel fetches (default 5) |
| `proxyConfiguration` | object | Optional Apify Proxy |

```json
{
  "startUrls": [{ "url": "https://zalo.me/officialaccount" }],
  "oaIds": ["4462152339089565647"],
  "maxItems": 20,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

| Field | Description |
| :--- | :--- |
| `status` | `public` / `login_required` / `not_found` / `invalid` / `error` |
| `oaId` | Numeric Official Account ID |
| `slug` | Custom URL slug when present |
| `name` | Public OA name |
| `description` | Public bio |
| `avatarUrl` | Avatar image |
| `qrCodeUrl` | Public QR image |
| `isVerified` | Verification flag |
| `category` / `categoryEn` | OA category |
| `address` / `workingHours` | Public location card |
| `canonicalUrl` | `https://zalo.me/{oaId}` |

```json
{
  "type": "oa",
  "status": "public",
  "oaId": "4462152339089565647",
  "slug": "officialaccount",
  "name": "Zalo Official Account",
  "isVerified": true,
  "category": "VNG",
  "address": "Z06 Duong so 13, Phuong Tan Thuan, Thanh pho Ho Chi Minh",
  "workingHours": "08:00 - 18:00",
  "canonicalUrl": "https://zalo.me/4462152339089565647"
}
```

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/zalo-scraper').call({
  startUrls: [{ url: 'https://zalo.me/officialaccount' }],
  maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("crawloop/zalo-scraper").call(
    run_input={
        "startUrls": [{"url": "https://zalo.me/officialaccount"}],
        "maxItems": 10,
    }
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~zalo-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://zalo.me/officialaccount"}],"maxItems":10}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp).
Connect your Apify account, then call this Actor by its Store ID / name.

Example prompts:

- "Run Zalo Official Account Scraper for https://zalo.me/officialaccount and return the OA ID, verified flag, and address as JSON"
- "Scrape these Zalo OA IDs with Zalo Official Account Scraper and summarize name, category, and working hours"
- "Look up custom Zalo OA slugs and list which ones are public vs login\_required"

### FAQ

**Is this a Zalo chat exporter?**\
No. It only reads **public Official Account landing pages**. Chats, contacts, and group rosters need a logged-in Zalo account and are out of scope.

**Why did I get `login_required`?**\
That URL is not a public OA page (personal profile, group invite, or unknown slug). Zalo sent the browser to the login wall.

**Do I need a Zalo developer token?**\
No. This is a page scraper, not the official OA Open API.

**Does it scrape OA posts?**\
Not in v1. The logged-out landing page exposes profile + QR fields, not the post feed.

# Actor input Schema

## `startUrls` (type: `array`):

Public Official Account pages on zalo.me — numeric OA IDs (https://zalo.me/4462152339089565647) or custom slugs (https://zalo.me/officialaccount). Group invite links (zalo.me/g/…) are not public on the web.

## `oaIds` (type: `array`):

Numeric Zalo Official Account IDs (10–24 digits). Equivalent to https://zalo.me/{oaId}.

## `slugs` (type: `array`):

Custom Official Account URL slugs registered on Zalo (the path after zalo.me/). Unknown slugs often redirect to login — those rows come back as login\_required, not as a private profile dump.

## `oaText` (type: `string`):

Optional. Paste many OA IDs, slugs, or zalo.me URLs at once (one per line, or comma/semicolon separated). Merged with the fields above and de-duplicated.

## `maxItems` (type: `integer`):

Hard cap on dataset rows for the whole run.

## `concurrency` (type: `integer`):

Parallel page fetches (1–20). Lower it if you see rate limits.

## `proxyConfiguration` (type: `object`):

Public OA landing pages usually work without a proxy. Enable Apify Proxy for larger batches.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://zalo.me/officialaccount"
    }
  ],
  "oaIds": [
    "4462152339089565647"
  ],
  "slugs": [
    "officialaccount"
  ],
  "maxItems": 100,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Default dataset items.

# 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 = {
    "startUrls": [
        {
            "url": "https://zalo.me/officialaccount"
        }
    ],
    "oaIds": [
        "4462152339089565647"
    ],
    "slugs": [
        "officialaccount"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/zalo-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 = {
    "startUrls": [{ "url": "https://zalo.me/officialaccount" }],
    "oaIds": ["4462152339089565647"],
    "slugs": ["officialaccount"],
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/zalo-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 '{
  "startUrls": [
    {
      "url": "https://zalo.me/officialaccount"
    }
  ],
  "oaIds": [
    "4462152339089565647"
  ],
  "slugs": [
    "officialaccount"
  ]
}' |
apify call crawloop/zalo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/zalo-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/prF4pTYZQ5zTdsUNp/builds/xFSgf1571AdJ8GHIy/openapi.json
