agentsclimarketplace

Hk open data

Skill errchh/hk-open-data/skills/hk-open-data

Use when working with Hong Kong Open Data API (DATA.GOV.HK), fetching datasets, filtering data, querying historical archives, finding nearest facilities, or building applications that consume HK government open dataFrom its SKILL.md

Install
npx -y skills add errchh/hk-open-data --skill hk-open-data

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

10.7 KB, ~2.9k tokens by cl100k_base, as published. Nobody here has run it

Hong Kong Open Data API

Official Documentation: https://data.gov.hk/en/help/api-spec

Overview

DATA.GOV.HK provides multiple APIs for accessing government open data. All APIs use GMT+8 timezone.

API Types:

  1. CKAN API - Dataset discovery and metadata
  2. Data Filtering API - Query and filter dataset resources
  3. Historical Archive API - Access historical versions
  4. Nearest Facilities API - Location-based queries

Language Endpoints

All CKAN APIs have language-specific endpoints:

LanguageEndpoint Pattern
Englishhttps://data.gov.hk/en-data/api/3/action/...
Traditional Chinesehttps://data.gov.hk/tc-data/api/3/action/...
Simplified Chinesehttps://data.gov.hk/sc-data/api/3/action/...

CRITICAL: Always choose the correct language endpoint for your users.

CKAN API (Dataset Discovery)

List All Datasets

import requests

# Get all dataset IDs (English)
response = requests.get("https://data.gov.hk/en-data/api/3/action/package_list")
datasets = response.json()["result"]

Parameters: limit (int, optional), offset (int, optional)

# Get first 10 datasets with pagination
response = requests.get(
    "https://data.gov.hk/en-data/api/3/action/package_list",
    params={"limit": 10, "offset": 0}
)

Get Dataset Metadata

# Get details of a specific dataset
dataset_id = "hk-td-tis_2-traffic-snapshot-images"
response = requests.get(
    "https://data.gov.hk/en-data/api/3/action/package_show",
    params={"id": dataset_id}
)
metadata = response.json()["result"]
resources = metadata["resources"]  # List of data files/URLs

List Data Categories

response = requests.get("https://data.gov.hk/en-data/api/3/action/group_list")
categories = response.json()["result"]
# Returns: ["city-management", "transport", "health", ...]

Get Datasets by Category

category_id = "transport"  # Use category ID from group_list
response = requests.get(
    "https://data.gov.hk/en-data/api/3/action/group_show",
    params={"id": category_id}
)
datasets = response.json()["result"]["packages"]

Category IDs: city-management, climate-and-weather, commerce-and-industry, social-welfare, development, education, legislature, employment-and-labour, environment, finance, food, health, housing, law-and-security, population, recreation-and-culture, information-technology-and-broadcasting, tourism, transport, miscellaneous

Data Filtering API

CRITICAL: Use v2 endpoint, not v1.

Endpoint: https://api.data.gov.hk/v2/filter

Method: GET with URL-encoded JSON query parameter

Query Structure

Columns are 1-indexed (not 0-indexed).

import requests
import urllib.parse
import json

query = {
    "resource": "http://www.cr.gov.hk/datagovhk/psi/ml_licensees.csv",
    "section": 1,  # Required if dataset has sections (default: 1)
    "format": "json",  # Options: csv (default), json, xml
    "filters": [
        [1, "eq", ["3983"]],        # Column 1 equals "3983"
        [2, "nct", ["2021"]],       # Column 2 does not contain "2021"
        [3, "gt", ["100"]]          # Column 3 greater than 100
    ],
    "sorts": [
        [4, "asc"],   # Sort column 4 ascending
        [7, "desc"]   # Then column 7 descending
    ]
}

# URL encode the JSON query
url = f"https://api.data.gov.hk/v2/filter?q={urllib.parse.quote(json.dumps(query))}"
response = requests.get(url)
data = response.json()

Filter Operators

Text Only:

  • eq - equals (1 operand)
  • ne - not equals (1 operand)
  • in - is in (2+ operands)
  • ni - is not in (2+ operands)
  • ct - contains (1 operand)
  • nct - does not contain (1 operand)
  • bw - begins with (1 operand)
  • nbw - does not begin with (1 operand)
  • ew - ends with (1 operand)
  • new - does not end with (1 operand)

Number Only:

  • lt - less than (1 operand)
  • le - less than or equal (1 operand)
  • gt - greater than (1 operand)
  • ge - greater than or equal (1 operand)
  • bt - between (2 operands)

Example - Multiple Values with "in":

query = {
    "resource": "...",
    "filters": [
        [2, "in", ["Kowloon", "Hong Kong Island", "New Territories"]]
    ]
}

Example - Range with "bt":

query = {
    "resource": "...",
    "filters": [
        [5, "bt", ["100", "500"]]  # Column 5 between 100 and 500
    ]
}

CRITICAL: Always include "section": 1 if the dataset has multiple sections. Check the dataset page or metadata to confirm.

Historical Archive API

Endpoint: https://app.data.gov.hk/v1/historical-archive/...

Note: Latest historical data is from yesterday (not today).

List Historical Files

response = requests.get(
    "https://app.data.gov.hk/v1/historical-archive/list-files",
    params={
        "start": "20230101",  # YYYYMMDD
        "end": "20231231",    # YYYYMMDD
        "category": "climate-and-weather",  # Optional
        "provider": "hk-hko",  # Optional
        "format": "csv",  # Optional: file extension
        "search": "temperature",  # Optional: keyword
        "order": "url",  # Optional: dataset-en, dataset-tc, resource-en, etc.
        "skip": 0  # Optional: pagination offset
    }
)
files = response.json()["result"]

List File Versions

response = requests.get(
    "https://app.data.gov.hk/v1/historical-archive/list-file-versions",
    params={
        "url": "http://www.cr.gov.hk/datagovhk/psi/ml_licensees.csv",
        "start": "20230101",
        "end": "20231231"
    }
)
versions = response.json()["result"]
# Note: Maximum 10,000 results returned

Download Historical File

response = requests.get(
    "https://app.data.gov.hk/v1/historical-archive/get-file",
    params={
        "url": "http://www.cr.gov.hk/datagovhk/psi/ml_licensees.csv",
        "time": "202301011230"  # YYYYMMDDHHmm
    }
)
# Response: 302 redirect to file download
# Follow redirect to get file content

Download Schema or Data Dictionary

# Schema
response = requests.get(
    "https://app.data.gov.hk/v1/historical-archive/get-schema",
    params={
        "url": "DATASET_URL",  # Dataset URL, not resource URL
        "date": "20230101"
    }
)

# Data Dictionary
response = requests.get(
    "https://app.data.gov.hk/v1/historical-archive/get-data-dictionary",
    params={
        "url": "DATASET_URL",
        "date": "20230101"
    }
)

Nearest Facilities API

Endpoint: https://api.data.gov.hk/v1/nearest-schools

response = requests.get(
    "https://api.data.gov.hk/v1/nearest-schools",
    params={
        "lat": 22.2812,  # WGS84 latitude
        "long": 114.1659,  # WGS84 longitude
        "max": 5  # Max results (optional, default: all, limit: 100)
    }
)
schools = response.json()["results"]
# Results ordered by distance ascending

Related Dataset: School Location and Information

Common Mistakes

MistakeFix
Using v1 Filtering APIUse https://api.data.gov.hk/v2/filter
0-indexed columnsColumns are 1-indexed
Missing section parameterIf dataset has sections, always include "section": 1
Wrong language endpointUse en-data for English, tc-data for Traditional Chinese, sc-data for Simplified Chinese
Quering today's historical dataHistorical data available starting from yesterday
Not following redirectsHistorical file download returns 302 redirect - follow it
String values for all filter operandsConvert numbers to strings: "100" not 100
Forgetting URL encodingAlways urllib.parse.quote(json.dumps(query))
Exceeding 10,000 result limitHistorical File Version API limits to 10,000 results

Workflow: Getting Started

  1. Discover datasets using CKAN package_list or group_show
  2. Get metadata using package_show to find resource URLs
  3. Query data using v2 Filtering API with proper filters and sections
  4. For historical data use Historical Archive APIs

Error Handling

# Filtering API returns HTTP 200 with JSON
response = requests.get(url)

if response.status_code == 200:
    data = response.json()
else:
    # Error details in JSON
    error = response.json()
    print(error.get("error", {}).get("message", "Unknown error"))

# Historical Archive API
# 200 - Success
# 302 - Redirect (for file downloads)
# 400 - Syntax error (check required parameters)
# 404 - File not available (for historical versions)

Provider IDs (Common)

Provider IDName
hk-dpoDigital Policy Office
hk-hkoHong Kong Observatory
hk-tdTransport Department
hk-fehdFood and Environmental Hygiene Department
mtrMTR Corporation Limited
hospitalHospital Authority

Full provider list: 90+ providers available in API documentation.

Quick Reference

TaskAPIEndpoint
List all datasetsCKAN/api/3/action/package_list
Get dataset metadataCKAN/api/3/action/package_show?id=...
List categoriesCKAN/api/3/action/group_list
Get datasets by categoryCKAN/api/3/action/group_show?id=...
Filter/query dataFilteringhttps://api.data.gov.hk/v2/filter?q=...
List historical filesArchive/v1/historical-archive/list-files?...
Get file versionsArchive/v1/historical-archive/list-file-versions?...
Download historical fileArchive/v1/historical-archive/get-file?...
Find nearest schoolsFacilities/v1/nearest-schools?lat=...&long=...

Real-World Example: Traffic Data

import requests
import urllib.parse
import json

# Step 1: Discover traffic datasets
response = requests.get(
    "https://data.gov.hk/en-data/api/3/action/group_show",
    params={"id": "transport"}
)
datasets = response.json()["result"]["packages"]

# Step 2: Get specific dataset metadata
dataset_id = "hk-td-tis_2-traffic-snapshot-images"
response = requests.get(
    "https://data.gov.hk/en-data/api/3/action/package_show",
    params={"id": dataset_id}
)
resources = response.json()["result"]["resources"]
resource_url = resources[0]["url"]

# Step 3: Filter the data
query = {
    "resource": resource_url,
    "section": 1,
    "format": "json",
    "filters": [
        [1, "eq", ["HIGHWAY"]],
        [5, "gt", ["2024-01-01"]]
    ],
    "sorts": [[3, "desc"]]
}

url = f"https://api.data.gov.hk/v2/filter?q={urllib.parse.quote(json.dumps(query))}"
response = requests.get(url)
traffic_data = response.json()

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,758. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.