Overview
Every endpoint is a GET request returning JSON, no auth. The dataset is small, and /api/restaurants returns the whole filtered result in one call.
- Base URL
- https://pawsdine.com
- Auth
- None
- CORS
- Enabled (
*) - Content-Type
- application/json
Endpoints
Response format
Every response is an envelope: on success success: true with data (some also carry meta); on failure success: false with error, plus the matching HTTP status.
{
"success": true,
"data": …,
"meta": …
}Changelog
/api/changesOne entry per date the FEHD list changed, newest first, each listing the restaurants added and removed that day. Call it with no parameters for the last 7 days, or set from / to for any other window (both dates included). Tracking begins on 2026-07-10, so ?from=2026-07-10 gives you everything on record; the list as it stood before that date is the untracked starting point. Every response reports the span it covers in meta, alongside earliest and latest for the whole dataset. A premises can also change without joining or leaving the list. It can be renamed or moved to another district. Those days carry an edits array and have both lists empty, so treat an entry with no additions and no removals as an edit day rather than as a no-op. Each edit names the field that moved (name or district) and carries fromZh / toZh beside the premises' details on that date. Category changes are not logged, because the category comes from Google. Every row records the premises as it stood that day and is never rewritten, so a premises renamed later keeps its old name in older entries. Use licence to join a row to its current details in /api/restaurants. edits is absent on entries recorded before these were tracked, and only the edits switch removes it.
Query parameters
| Param | Type | Default | Description |
|---|---|---|---|
from | string | 6 days before to | Earliest date to include, YYYY-MM-DD. The window counts calendar days, so a day with no change is simply absent from data. |
to | string | today in Hong Kong (UTC+8) | Latest date to include, YYYY-MM-DD. |
added | boolean | true | Set to false to leave the added array out of every entry. The dates still appear. Does not affect edits. |
removed | boolean | true | Set to false to leave the removed array out of every entry. Does not affect edits. |
edits | boolean | true | Set to false to leave the edits array out of every entry. |
Common calls
/api/changesThis week. The last 7 days, which is what you get with no parameters.
/api/changes?from=2026-07-15&to=2026-07-22One specific week, both dates included.
/api/changes?from=2026-07-10Everything on record, by starting from the first tracked date.
/api/changes?removed=falseNew restaurants only, with the removals left out of the payload.
Request
curl "https://pawsdine.com/api/changes?from=2026-07-15&to=2026-07-22"Response
{
"success": true,
"data": [
{
"date": "2026-07-15",
"added": [
{
"licence": 2211084426, "nameZh": "一杯喜", "nameEn": "IPPAIKI SAKAYA",
"district": "灣仔區", "districtEn": "Wan Chai",
"address": "香港銅鑼灣 清風街1A及1B號地下",
"addressEn": "G/F, 1A-1B TSING FUNG STREET, CAUSEWAY BAY, HONG KONG"
}
],
"removed": [
{
"licence": 3163802944, "nameZh": "吳麻辣", "nameEn": "MOTO MALA",
"district": "深水埗區", "districtEn": "Sham Shui Po",
"address": "九龍深水埗深旺道28號 V WALK 2樓L2-127 & 128鋪 …",
"addressEn": "SHOP NOS. L2-127 & 128, LEVEL 2, V WALK, NO. 28 SHAM MONG ROAD, SHAM SHUI PO, KOWLOON"
}
]
},
{
"date": "2026-07-14",
"added": [],
"removed": [],
"edits": [
{
"licence": 2262811512, "nameZh": "SOPHIE'S TREAT", "nameEn": "SOPHIE'S TREAT",
"district": "油尖旺區", "districtEn": "Yau Tsim Mong",
"address": "九龍旺角彌敦道726號彌敦道726 18樓",
"addressEn": "18/F, 726 NATHAN ROAD, NO. 726 NATHAN ROAD, MONG KOK, KOWLOON",
"field": "name",
"fromZh": "烤焰官", "fromEn": "烤焰官",
"toZh": "SOPHIE'S TREAT", "toEn": "SOPHIE'S TREAT"
}
]
}
],
"meta": {
"count": 6,
"from": "2026-07-15",
"to": "2026-07-22",
"earliest": "2026-07-10",
"latest": "2026-07-22"
}
}Restaurants
/api/restaurantsThe full list of dog-friendly restaurants. Call it with no parameters for all of them, or narrow it with any combination of q, region, district and category. There is no pagination: every match comes back in one call, with the total in meta.count. A value that is not a real region, district or category returns 400 rather than an empty list, so typos are easy to spot. See /api/meta for the accepted values.
Query parameters
| Param | Type | Optional | Description |
|---|---|---|---|
q | string | ✓ Yes | Keyword. Matches Chinese/English name, address, and district (case-insensitive). |
region | string | ✓ Yes | Region. Chinese or English (case-insensitive): 香港島 / Hong Kong Island, 九龍 / Kowloon, 新界 / New Territories. |
district | string | ✓ Yes | District. Chinese or English, e.g. 灣仔區 or Wan Chai, 葵青區 or Kwai Tsing. |
category | string | ✓ Yes | Approximate type. Chinese or English, e.g. 咖啡店 or Cafe. |
Request
curl "https://pawsdine.com/api/restaurants?q=wan chai"Response
{
"success": true,
"data": [
{
"licence": 3112808861,
"nameZh": "BLUE BOTTLE CAFE",
"nameEn": "BLUE BOTTLE CAFE",
"district": "灣仔區",
"districtEn": "Wan Chai",
"region": "香港島",
"regionEn": "Hong Kong Island",
"category": "咖啡店",
"categoryEn": "Cafe",
"address": "香港灣仔聖佛蘭士街15號 地下至 2樓",
"addressEn": "G/F - 2/F, 15 ST. FRANCIS STREET, WAN CHAI, HONG KONG",
"lat": 22.27602,
"lng": 114.16913,
"placeId": "ChIJ2XjbroIABDQRy8i7pMPjgm4"
},
{
"licence": 2212802494,
"nameZh": "火車頭越南餐室",
"nameEn": "CAFE LOCOMOTIVE CONTEMPORARY VIETNAMESE",
"district": "灣仔區",
"districtEn": "Wan Chai",
"region": "香港島",
"regionEn": "Hong Kong Island",
"category": "咖啡店",
"categoryEn": "Cafe",
"address": "香港大坑浣紗街11號地下",
"addressEn": "G/F., 11 WUN SHA STREET, TAI HANG, HONG KONG",
"lat": 22.27902,
"lng": 114.19265,
"placeId": null
}
],
"meta": { "count": 7 }
}Restaurant fields
| Field | Type | Description |
|---|---|---|
licence | number | 10-digit FEHD licence number, also the unique id. |
nameZh | string | Chinese name. |
nameEn | string | English name. |
district | string | District (Chinese). |
districtEn | string | District (English). |
region | string | Region (香港島 / 九龍 / 新界). |
regionEn | string | Region in English. |
category | string | Approximate type (Chinese, indicative). Derived from Google place types; see Licence. |
categoryEn | string | Approximate type (English). Derived from Google place types; see Licence. |
address | string | Address (Chinese). |
addressEn | string | Address (English). |
addedOn | string | null | The day this premises joined the list, YYYY-MM-DD. null means it was already listed when tracking began (meta.trackedSince), so the day is unknown. |
lat | number | null | Latitude (WGS84). |
lng | number | null | Longitude (WGS84). |
placeId | string | null | Google Place ID for the premises, or null if we have not matched one. Business details (rating, hours, photos) are not included: Google's terms only allow the ID itself to be stored, so look those up with the Places API using this ID. |
Filter values
/api/metaEvery value the /api/restaurants filters accept: the region → district tree and the category list, each with how many restaurants it holds. Call this to populate dropdowns, or to check a value before filtering on it. It also carries lastUpdated (the newest day the list changed), sourceUpdated (the day FEHD last revised it), checkedOn (the newest day we checked FEHD's list, even when nothing changed) and trackedSince (the day tracking began, before which every premises with a null addedOn was already listed). No parameters.
Request
curl "https://pawsdine.com/api/meta"Response
{
"success": true,
"data": {
"total": 994,
"geocoded": 994,
"lastUpdated": "2026-10-30",
"sourceUpdated": "2026-10-30",
"checkedOn": "2026-10-30",
"trackedSince": "2026-07-10",
"regions": [
{
"name": "香港島",
"nameEn": "Hong Kong Island",
"count": 292,
"districts": [{ "name": "灣仔區", "nameEn": "Wan Chai", "count": 118 }]
}
],
"categories": [{ "name": "餐廳", "nameEn": "Restaurant", "count": 154 }]
}
}Errors
Error responses carry the matching HTTP status and a stable error.code.
| Status | error.code | Description |
|---|---|---|
| 400 | INVALID_REGION | Unknown region value. |
| 400 | INVALID_DISTRICT | Unknown district value. |
| 400 | INVALID_CATEGORY | Unknown category value. |
| 400 | INVALID_DATE | from or to is not a valid YYYY-MM-DD date. |
| 400 | INVALID_RANGE | from is later than to. |
| 404 | NOT_FOUND | Unknown API route. |
| 405 | METHOD_NOT_ALLOWED | Only GET (and HEAD) is supported. |
| 500 | INTERNAL_ERROR | Unexpected server error. |
Examples
{
"success": false,
"error": {
"code": "INVALID_DISTRICT",
"message": "Unknown district \"foo\". See /api/meta for valid values."
}
}Usage
// q is a single case-insensitive keyword — matches EN/ZH name, address, district
const res = await fetch("https://pawsdine.com/api/restaurants?q=wan chai");
const json = await res.json();
if (!json.success) throw new Error(json.error.message);
console.log(json.meta.count, json.data.length);Licence & attribution
Free for anyone to use, for any purpose. The one condition is credit: wherever you show the data, link to pawsdine.com and name FEHD as the source, for example "Source: pawsdine.com, from the FEHD licensed-premises list". pawsdine.com is an independent site, not affiliated with or endorsed by FEHD, and asks nothing beyond that credit. The premises list itself is © the Government of the HKSAR, published by the Food and Environmental Hygiene Department (FEHD) on its own website. Its reuse is governed by FEHD's copyright notice, not the data.gov.hk Terms of Use, and pawsdine.com cannot grant rights over it. Coordinates come from the data.gov.hk Address Lookup Service, used under its terms of use. category and categoryEn are derived from Google place types and provided under the Google Maps Platform Terms of Service.
- Restaurant list © Food and Environmental Hygiene Department (FEHD), "List of premises where dogs are permitted to enter".
- Geocoding uses data.gov.hk's Address Lookup Service (ALS), © The Government of the HKSAR.
- Basemap © OpenFreeMap and OpenStreetMap contributors.
- Business information © Google. Ratings, hours, prices and photos come from Google Maps and are not redistributed by this API; category and categoryEn are derived from Google place types and provided under Google's terms.