# HKEX Company Announcements Scraper (`automation-lab/hkex-company-announcements-scraper`) Actor

Collect official HKEX company announcement metadata by publication date, stock code and title keyword. Export announcement IDs, issuer names, timestamps, categories and document links without downloading PDFs.

- **URL**: https://apify.com/automation-lab/hkex-company-announcements-scraper.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $27.42 / 1,000 item processeds

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?

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

## HKEX Company Announcements Scraper

Collect official **HKEX company announcements** as structured filing metadata for investment research, compliance review, and recurring regulatory monitoring. Choose a Hong Kong publication-date window and receive announcement IDs, issuer identifiers, timestamps, titles, categories, and direct official document links.

This Actor reads public HKEXnews JSON. It does not download PDFs, extract filing text, summarize documents, retrieve paid quotes, or make investment recommendations.

### Why use this Actor?

Turn a disclosure search into consistent rows that can be joined to a watchlist or stored in a research database. Stable announcement IDs support downstream deduplication; zero-padded stock-code arrays preserve identifiers; publication timestamps carry the Hong Kong UTC+08:00 offset. Filtering and limits apply before result billing.

No HKEX account, proxy, paid data subscription, or external API key is needed for the supported public endpoint. The Actor has no automatic paid proxy fallback.

### Who is it for?

- Analysts compiling daily filing watchlists and links for source review.
- Compliance teams retaining metadata trails of public company disclosures.
- Data engineers loading regulatory headlines into spreadsheets and warehouses.
- Automation builders scheduling recurring collection with their own alert rules.

The Actor returns a snapshot. Scheduling, cross-run change detection, and notifications belong to your downstream workflow, not an internal alerting service.

### Get started

1. Set `fromDate` to a publication date in `YYYY-MM-DD` format.
2. Optionally set `toDate`, stock codes, or a title keyword.
3. Choose a result cap and run the Actor.
4. Inspect the Announcements dataset tab and the collection summary.
5. Export JSON, CSV, Excel, or another format supported by Apify datasets.

Try a known populated date:

```json
{
  "fromDate": "2026-10-23",
  "toDate": "2026-10-23",
  "language": "en",
  "maxItems": 20
}
```

### Input reference

| Input | Default | Behavior |
|---|---|---|
| `fromDate` | Today in Hong Kong | Inclusive first publication date; no future dates. |
| `toDate` | `fromDate` | Inclusive last publication date. Maximum window: 31 days. |
| `stockCodes` | All | Up to 100 numeric strings. `700` becomes `00700`. ANY supplied code may match ANY code on a filing. |
| `keyword` | No filter | Case-insensitive contiguous substring in the decoded title only. Input-edge whitespace is trimmed; internal spaces are literal. |
| `language` | `en` | Official English (`en`) or Traditional Chinese (`zh`) section; not machine translation. |
| `maxItems` | 100 | Global accepted unique row cap, 1–10000. No zero/unlimited mode. |

Stock codes and keyword combine with AND. Both filters run locally against official results, so highly selective searches can take longer than unfiltered ones. A stock code is not an HKEX internal stock ID.

Empty input searches today in Hong Kong. This can legitimately return no announcements on quiet dates. For recurring monitoring, explicitly supply your desired date window or update the input in your scheduler. The Actor does not infer yesterday or persist an incremental cursor.

### HKEX company announcements output

One dataset row represents one official announcement ID in the selected language section. Rows are deduplicated within a run. Later dates are processed first, with official newest-first ordering within a day.

| Field | Meaning |
|---|---|
| `announcementId` | Official HKEXnews ID, kept as a string. |
| `stockCodes` | Array of zero-padded stock codes; empty if the source supplies no issuer code. |
| `stockName` | Official stock short name, or empty when absent. |
| `publishedAt` | ISO timestamp with Hong Kong `+08:00` offset. |
| `title` | Official title with HTML entities decoded. |
| `category` | Official category and headline classification text. |
| `documentUrl` | Direct official document URL. The file is not downloaded. |
| `fileType` | Source format label, such as PDF or HTM. |
| `fileSize` | Source file-size label, not a measured download size. |
| `language` | Requested `en` or `zh` section. |
| `scrapedAt` | UTC collection timestamp. |

Actual source record from the 2026-10-23 window (collection time varies):

```json
{
  "announcementId": "12382302",
  "stockCodes": ["01236"],
  "stockName": "LDROBOT",
  "publishedAt": "2026-10-23T22:59:00+08:00",
  "title": "H Share Award Scheme",
  "category": "Documents on Display",
  "documentUrl": "https://www1.hkexnews.hk/listedco/listconews/sehk/2026/1023/2026102301723.pdf",
  "fileType": "PDF",
  "fileSize": "585KB",
  "language": "en",
  "scrapedAt": "2026-10-25T07:15:00.000Z"
}
```

The `SUMMARY` key-value-store record reports requests, retries, response bytes, unique scanned rows, delivered `saved` rows, dates visited, and `limitReached` for the requested result cap. `billingLimitReached` identifies an SDK billing stop; `completionReason` is `billing_limit`, `max_items`, or `source_exhausted`. A billing-limited result is partial, not full date-window coverage. Platform termination or timeout may prevent a final summary from being written.

### How much does it cost to collect HKEX announcements?

Pay-per-event pricing has a **$0.015 start fee** and an `item` event for each delivered announcement row. BRONZE pricing is **$0.0457 per announcement**. Per-announcement rates are $0.052555 on FREE, $0.035646 on SILVER, and $0.02742 on GOLD, PLATINUM, and DIAMOND. No separate charge applies to document links, filters, scanned-but-rejected rows, duplicates, or retries. A zero-result run still incurs the start fee after valid input is accepted.

At the listed BRONZE rate, estimated Actor-event totals are $0.0607 for one result, $0.472 for 10 results, and $4.585 for 100 results, including the start fee. Tier eligibility depends on aggregate monthly Apify Store spend, not this Actor's individual result count. Apify invoices and any separately applicable platform charges remain authoritative.

### Coverage and limits

- The route queries the official SEHK listed-company title-search corpus. No separate GEM-only selector or claim of a complete cross-board archive is provided.
- Date inputs are accepted from 1999-04-01 to today, but historical availability depends on the live index. No full-archive coverage guarantee is made.
- Date windows are at most 31 days; split longer research periods into separate runs.
- Each day has a 10000-row upstream scan safety cap. If unseen rows remain, the run fails with a clear message rather than silently claiming completeness.
- A capped run is a bounded subset, not the entire date window. Billing limits and timeout can also stop collection.
- English and Chinese sections can differ; this Actor does not pair translations.
- It returns all indexed filing categories available on this route, including records without an issuer code. A stock-code filter excludes such records.

### Reliability and troubleshooting

Transient network, 429, and server errors receive up to three total attempts per request, with a 30-second request timeout and bounded backoff. Permanent HTTP errors and changed JSON shapes fail rather than masquerading as an empty feed. No browser or proxy recovery is enabled.

**Why are there no results?** Check the date, language, exact stock codes, and literal title substring. Compare with the official HKEXnews search. A weekend or selective filter may naturally be empty.

**Why did the run fail after producing rows?** An upstream error, timeout, malformed record, or safety cap can occur after partial output. Treat rows from a failed run as partial, investigate the log, and narrow the window. Do not treat a nonempty dataset as proof of a complete successful export.

**Does a keyword search document text?** No. Only the decoded title is tested; category and PDF text are not searched.

### Integrations

Use Apify schedules for recurring collection, then an integration or webhook to send successful-run rows to Google Sheets, Make, n8n, or your own database. Use `announcementId` plus `language` as a downstream deduplication key across overlapping daily pulls. Separate document-review systems can follow the links; this Actor does not read the files.

For compliance trails, retain the timestamp, ID, category, and official URL alongside your own ingestion date. Build alert rules downstream, and keep human review for legally or financially significant decisions.

### API usage

Start one run using your Apify token:

```bash
curl -X POST \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  'https://api.apify.com/v2/acts/automation-lab~hkex-company-announcements-scraper/runs' \
  -d '{"fromDate":"2026-10-23","maxItems":100}'
```

Keep the returned run ID. Check that same run to terminal success, then fetch its `defaultDatasetId` with bounded dataset pagination. Starting a run returns run metadata, not the announcement rows.

JavaScript with `apify-client`:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/hkex-company-announcements-scraper')
  .call({ fromDate: '2026-10-23', maxItems: 100 });
if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 100 });
console.log(items);
```

Python with `apify-client`:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/hkex-company-announcements-scraper').call(
    run_input={'fromDate': '2026-10-23', 'maxItems': 100})
if run['status'] != 'SUCCEEDED':
    raise RuntimeError(run['status'])
print(client.dataset(run['defaultDatasetId']).list_items(limit=100).items)
```

### MCP setup

Use the Actor-specific hosted endpoint; private Actors may not be discoverable until publication and appropriate authorization.

#### Claude Code

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/hkex-company-announcements-scraper"
```

#### Claude Desktop, Cursor, and VS Code

Use the equivalent HTTP server configuration supported by your client's version, with Apify authorization configured securely:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/hkex-company-announcements-scraper"
    }
  }
}
```

Example prompt: “Collect 20 English HKEX announcements for 2026-10-23 and show titles, stock codes, publication times, and official document links.”

Example prompt: “Collect announcements for stock code 00700 on 2026-10-23, then return only rows whose title contains results.”

Discover actual tool names and argument schemas with `tools/list`. Actor selection also exposes run/data helpers, not exactly one tool. For an authorized invocation, start once and retain the run ID. Follow that same run with bounded backoff (2, 4, 8 seconds, capped at 10) and a 120-second consumer deadline; configure client timeout above the chosen server wait plus transport margin. If the deadline passes, report pending with the run ID rather than restarting.

After success, read untransformed dataset pages of 20 rows with explicit offsets and fields. A suggested model-context budget is 100 source rows or 64 KiB of serialized UTF-8 content, whichever comes first. Enforce byte limits host-side before model injection; if the client cannot intercept oversized responses, do not claim a hard byte guarantee. Report continuation offsets and partial/truncated status honestly. Full exports remain in storage outside model context. No numeric token-saving claim is made.

### Legality and data handling

This is an independent automation-lab tool, not affiliated with or endorsed by HKEX. Source names identify the public corpus only; the icon is an original generated document/data illustration, not an official exchange logo. Use Apify's standard terms and comply with source rights and applicable law. Public filings can contain regulated information; verify the official document before relying on a headline.

The runtime uses no AI service and sends no announcement data to a model provider. Apify hosts inputs, logs, and per-run datasets under your account's retention settings; you control deletion through Apify storage/run controls. There is no persistent cross-run cache or copied document archive. Do not place credentials or private information in title filters.

Failed operations send sanitized diagnostic input, exceptions, and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; reports are retained for 30 days. General logs contain counters and safe date/status information, not document bodies or request credentials.

### FAQ

**Can I obtain PDF text or AI summaries?** No. This product exports metadata and filing URLs only.

**Can I get every filing in a month?** Use windows of at most 31 days and a sufficient result cap; confirm successful completion and source coverage. Split busy windows into smaller runs when needed.

**Can I use it as a real-time alert service?** You can schedule recurring snapshots and compare IDs downstream. No real-time delivery guarantee, webhook alert generation, or internal incremental state is included.

### Support

For technical help, use the Actor's Apify Issues tab with a safe input sample, run link, expected result, and observed behavior. Never post tokens or private data.

### Related workflows

This Actor is intentionally standalone for HKEX metadata. Separate jurisdictions require their own source-specific collectors and validation; it does not combine regional feeds or imply equivalent coverage. Connect this dataset to your existing spreadsheet, warehouse, or filing-review pipeline.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/hkex-company-announcements-scraper/changelog.md

# Actor input Schema

## `fromDate` (type: `string`):

Inclusive first publication date, YYYY-MM-DD. Defaults to today in Hong Kong. Earliest supported date is 1999-04-01; source coverage can vary. The total window must contain at most 31 days.

## `toDate` (type: `string`):

Inclusive last publication date, YYYY-MM-DD. Defaults to fromDate. Must be on or after fromDate and not later than today in Hong Kong.

## `stockCodes` (type: `array`):

Optional exact stock-code filter. Enter 1–5 digit strings; leading zeros are added (700 matches 00700). A filing is accepted if ANY of its codes matches ANY supplied code. Empty array means all companies. Applied locally after retrieval; selective filters may scan many rows.

## `keyword` (type: `string`):

Optional case-insensitive contiguous substring of the decoded announcement TITLE only, not PDF/body text or category. Surrounding input whitespace is trimmed; internal whitespace is literal. Combined with stockCodes using AND. Empty means no title filter.

## `language` (type: `string`):

Choose the official English or Traditional Chinese results section. No translation or cross-language deduplication is performed.

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

Global maximum accepted unique announcement rows for the entire run, after all filters and ID deduplication. Newest dates first. Must be 1–10000; zero/unlimited is unsupported. Collection stops at this limit or billing limit, so a capped run is not a full archive. The source scan safety cap is 10000 rows per day; unresolved overflow fails rather than silently truncating.

## Actor input object example

```json
{
  "fromDate": "2026-10-23",
  "toDate": "2026-10-23",
  "language": "en",
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Unique announcement IDs, stock codes, titles, categories, timestamps and filing URLs.

## `summary` (type: `string`):

Request, retry, byte, scanned and saved counters for this run.

# 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 = {
    "fromDate": "2026-10-23",
    "toDate": "2026-10-23",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/hkex-company-announcements-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 = {
    "fromDate": "2026-10-23",
    "toDate": "2026-10-23",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/hkex-company-announcements-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 '{
  "fromDate": "2026-10-23",
  "toDate": "2026-10-23",
  "maxItems": 20
}' |
apify call automation-lab/hkex-company-announcements-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/hkex-company-announcements-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/ghrqlLvMXy8FBj87x/builds/ncDSHa6L0IUi9Z2K9/openapi.json
