DuLieu.dev API

Vietnamese Economic Data — REST API Documentation

Authentication

All API requests require an API key. Sign in with Google at /settings to create one.

Plans

Free(Free)— Basic access to Vietnamese economic data
Pro($9/mo)— Full access including grocery price data
Unlimited(Contact us)— No limits — for internal use and partners
FeatureFreeProUnlimited
Economic data (exchange, gold, fuel, coffee...)
Interest rates (40+ banks)
CPI, inflation, economic indicators
Oil & coffee international futures
AI agent daily summary
Grocery prices (40K+ products)
COICOP classification & unit pricing
CSV export
Daily API calls10010,000Unlimited

API Key (Header)

Authorization: Bearer dl_your_api_key_here

API Key (Query)

GET /api/exchange?api_key=dl_your_api_key_here

Rate Limit Headers

X-RateLimit-Plan: free | pro | unlimited
X-RateLimit-Limit: 100 (or "unlimited")
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1714003200

Base URL

https://dulieu.dev

Response Format

{
  "data": [...],
  "meta": {
    "source": "domain.com",
    "count": 42,
    "updated_at": "2026-04-23T14:00:00.000Z"
  }
}

Endpoints

59 endpoints
GET/api/exchange

Currency exchange rates (VND). Sources: Vietcombank, CafeF.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-04-23", "currency": "USD", "buy": 25000, "sell": 25500, "transfer": 25200, "source": "vietcombank.com.vn", "bank": "VCB" }], "meta": { "source": "vietcombank.com.vn", "count": 9, "updated_at": "..." } }
GET/api/gold

Gold prices by type (SJC, rings, jewelry). Sources: DOJI, CafeF.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-04-23", "type": "SJC 1L-10L", "buy_price": 92000000, "sell_price": 94000000, "unit": "tael", "source": "giavang.doji.vn" }], "meta": { "source": "giavang.doji.vn", "count": 8 } }
GET/api/silver

Silver prices (11 types). Source: CafeF.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-04-23", "type": "Bạc miếng SJC", "buy_price": 1200000, "sell_price": 1400000, "unit": "tael" }], "meta": { "source": "cafef.vn" } }
GET/api/weather

Weather data for 70+ Vietnamese cities (all province capitals + tourist destinations).

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)
citystringFilter by city name (partial match)

Response

{ "data": [{ "date": "2026-05-21", "city": "Hà Nội", "temperature": 28.5, "humidity": 65, "conditions": "mây thưa", "geo_location_id": 71 }] }
GET/api/weather/forecast

5-day weather forecast for 70+ Vietnamese cities. Source: OpenWeatherMap.

Query Parameters

datestringFilter by target_date (YYYY-MM-DD)
fromstringStart target_date (YYYY-MM-DD)
tostringEnd target_date (YYYY-MM-DD)
citystringFilter by city name (partial match)

Response

{ "data": [{ "forecast_date": "2026-05-21", "target_date": "2026-05-22", "city": "Đà Nẵng", "temp_min": 26.0, "temp_max": 33.0, "humidity": 70, "conditions": "mây thưa" }] }
GET/api/weather/summary

Today's weather summary for all cities.

Response

{ "data": [{ "city": "Hà Nội", "temperature": 28.5, "temp_unit": "°C", "humidity": 65, "humidity_unit": "%", "conditions": "mây thưa" }] }
GET/api/fuel

Fuel prices (6 types, zone 1 & 2). Source: webgia.com.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-04-23", "fuel_type": "RON 95-V", "zone": 1, "price": 23800 }] }
GET/api/coffee

Coffee prices by region. Source: webgia.com.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-04-23", "region": "Đắk Lắk", "price": 125000, "unit": "VND/kg" }] }
GET/api/interest

Bank deposit & lending rates (28+ banks, 8 terms). Sources: webgia, VCB, BIDV, CafeF.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-04-23", "bank": "Vietcombank", "term_months": 12, "deposit_rate": 4.7, "lending_rate": null }] }
GET/api/indicators

Economic indicators (CPI, inflation, IIP). Source: nso.gov.vn.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "indicator": "CPI", "value": 103.2, "period": "2026-03", "yoy_change": 3.2 }] }
GET/api/lottery

Vietnam lottery results (north/central/south, 41 provinces). Sources: CafeF + Minh Ngọc.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)
sourcestringFilter by source (cafef.vn or minhngoc.net.vn)

Response

{ "data": [{ "date": "2026-04-23", "region": "south", "province": "TP.HCM", "prize": "Giải Đặc biệt", "numbers": "123456" }] }
GET/api/pepper

Pepper prices — domestic (5 regions) + international (India Kochi). Source: giatieu.com.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)

Response

{ "data": [{ "date": "2026-05-20", "region": "Đắk Lắk", "price": 148000, "unit": "VND/kg" }] }
GET/api/commodities

All commodity prices — crude oil (WTI, Brent), international coffee futures.

Query Parameters

datestringSingle date (YYYY-MM-DD)
fromstringStart date (YYYY-MM-DD)
tostringEnd date (YYYY-MM-DD)
symbolstringFilter by symbol (e.g. WTI, BRENT, ROBUSTA)

Response

{ "data": [{ "date": "2026-05-20", "symbol": "WTI", "name": "WTI Crude Oil", "price": 72.50, "unit": "USD/barrel" }] }
GET/api/groceries

Grocery prices (56K+ products, COICOP classified, unit pricing). Pro plan required.

Query Parameters

storestringFilter by store (e.g. lottemart, cooponline)
categorystringFilter by category
limitnumberMax results (default: 500)

Response

{ "data": [{ "store": "lottemart", "name": "Sữa TH True Milk 1L", "price": 32000, "coicop": "01.1.4", "unit_price_per_l": 32000 }] }
GET/api/groceries/summary

Grocery category averages with COICOP codes. Pro plan required.

Response

{ "data": [{ "category": "Sữa", "coicop": "01.1.4", "products": 450, "avg_price": 85000, "stores": 4 }] }
GET/api/groceries/stores

Store product counts and latest crawl dates.

Response

{ "data": [{ "store": "lottemart", "products": 26610, "latest_date": "2026-05-20" }] }
GET/api/groceries/catalog

Full deduplicated grocery catalog — the latest price per product (source_id) across ALL crawl dates, not just the latest crawl slice. For sync consumers that need every product at its current price (the plain /groceries with date=latest only returns the newest crawl run). Pro plan required.

Query Parameters

storestringFilter by store (e.g. kingfoodmart, lottemart)
categorystringFilter by category
limitnumberMax results (default: 200000)

Response

{ "data": [{ "store": "kingfoodmart", "source_id": "kingfoodmart:8938512909042", "name": "Sữa TH True Milk 1L", "price": 32000, "date": "2026-06-14" }] }
GET/api/groceries/search

Live product-name search (suggestions / autocomplete). Case-insensitive ILIKE on name, deduplicated to the latest price per product, `_raw` stripped — query live instead of syncing the whole catalog into a stale local cache. Pro plan required.

Query Parameters

qstringSearch text (matched against product name; required)
storestringFilter by store
categorystringFilter by category
limitnumberMax results (default: 50)

Response

{ "data": [{ "store": "lottemart", "source_id": "lottemart:8938512909042", "name": "Sữa TH True Milk 1L", "price": 32000, "date": "2026-06-14" }] }
GET/api/groceries/freshness

Per-store crawl freshness — catalog_size, latest_date, days_stale, and a stale flag (≥2 days). Lets sync consumers detect when a store silently stopped updating.

Response

{ "data": [{ "store": "kingfoodmart", "latest_date": "2026-06-14", "catalog_size": 11609, "crawl_days": 18, "days_stale": 0, "stale": false }] }
GET/api/drugs

Drug & pharmacy prices (12K+ products, COICOP 06 classified). Pharmacity, Long Chau.

Query Parameters

storestringFilter by store (pharmacity, longchau)
limitnumberMax results (default: 500)

Response

{ "data": [{ "store": "pharmacity", "name": "Panadol Extra", "price": 52000, "is_drug": 1, "is_prescription": 0, "coicop": "06.1.1" }] }
GET/api/drugs/summary

Drug category averages with COICOP 06 codes and drug/Rx counts.

Response

{ "data": [{ "category": "Thuốc", "coicop": "06.1.1", "products": 5431, "drugs": 5431, "prescription": 4309 }] }
GET/api/drugs/stores

Pharmacy product counts and latest crawl dates.

Response

{ "data": [{ "store": "pharmacity", "products": 7610, "latest_date": "2026-05-20" }] }
GET/api/drugs/catalog

Full deduplicated drug catalog — latest price per product across all crawl dates (see /groceries/catalog). Pro plan required.

Query Parameters

storestringFilter by store (pharmacity, longchau)
limitnumberMax results (default: 200000)

Response

{ "data": [{ "store": "longchau", "source_id": "longchau:00000450", "name": "Panadol Extra", "price": 52000, "date": "2026-06-14" }] }
GET/api/drugs/search

Live drug-name search (suggestions / autocomplete). ILIKE on name, deduplicated to latest price per product, `_raw` stripped (see /groceries/search). Pro plan required.

Query Parameters

qstringSearch text (matched against product name; required)
storestringFilter by store (pharmacity, longchau)
limitnumberMax results (default: 50)

Response

{ "data": [{ "store": "pharmacity", "source_id": "pharmacity:P03029", "name": "Panadol Cold & Flu", "price": 14400, "date": "2026-06-14" }] }
GET/api/geo

Vietnamese administrative geography (provinces, districts, wards).

Query Parameters

provincestringProvince code or name (partial match)

Response

{ "data": [{ "province_code": "79", "province_name": "TP. Hồ Chí Minh", "district_code": null }] }
GET/api/summary

Daily summary of all data domains. Ideal for AI agent daily briefing. Includes exchange, gold, silver, weather, fuel, coffee, pepper, interest, indicators, MST company-registry KPI, and real-estate top provinces. Supports ?at=T (record-time as-of): each source resolves to its latest crawl date ≤ T with carry-forward fallback (lagged/gappy sources never return empty); response echoes as_of + a resolved{} map of the date each series fell back to.

Query Parameters

atstringRecord-time as-of date (YYYY-MM-DD) or 'now' (default). Carry-forward: returns the latest data ≤ this date.

Response

{ "date": "2026-05-20", "as_of": "2026-05-20", "resolved": { "gold": "2026-05-19", "exchange": "2026-05-20" }, "last_crawl": "...", "exchange": [...], "gold": [...], "weather": [...], "fuel": [...], "coffee": [...], "interest": [...], "indicators": [...], "mst": { "total": 54059, "active": 36000, "ceased": 1200, "added_7d": 36 }, "realestate": [{ "province": "ho-chi-minh", "listings": 1234, "median_price_per_m2_sale": 95000000 }] }
GET/api/snapshot

Record-time cross-source metric snapshot. Returns the nearest stored snapshot with taken_at ≤ T (the as-of record time); falls back to a live summary computation when no stored snapshot exists yet. The `cached` flag indicates which path served the response. Single-source-of-truth for reproducible point-in-time metric reads.

Query Parameters

atstringRecord-time as-of (ISO timestamp/date) or 'now' (default). Returns the most recent snapshot at or before this time.

Response

{ "cached": true, "taken_at": "2026-05-20T07:00:00Z", "as_of_date": "2026-05-20", "kind": "summary", "data": { "exchange": [...], "gold": [...], ... } }
GET/api/stats

API usage statistics — by key, by user, by endpoint, by day. Admin only.

Query Parameters

daysnumberLookback period (default: 7)

Response

{ "overview": { "total": 1234, "unique_keys": 5 }, "by_key": [...], "by_user": [...], "by_endpoint": [...] }
GET/api/crawl-logs

Crawler execution history.

Query Parameters

limitnumberMax results (default: 20)

Response

{ "data": [{ "crawler": "exchange-vietcombank", "status": "success", "records_inserted": 9, "duration_ms": 1200 }] }
GET/api/crawl/progress

Realtime progress of in-flight streaming crawls (BullMQ workers publish live counts to Redis).

Response

{ "count": 1, "data": [{ "crawler": "electronics-cellphones", "status": "running", "phase": "products", "done": 12340, "total": 58853, "ok": 12100, "fail": 240, "inserted": 12100, "pct": 21, "updated_at": "..." }] }
GET/api/electronics

Electronics prices from major Vietnamese retailers — phones, laptops, appliances and PC/components (TGDD, CellphoneS, FPT Shop, Hoang Ha Mobile, Di Dong Viet, Nguyen Kim, Dien May Xanh, GearVN, Tan Doanh, …). 500K+ products with ratings, reviews, variants. Filter by store.

Query Parameters

storestringFilter by store (thegioididong, cellphones, fptshop, hoanghamobile, didongviet)
brandstringFilter by brand
categorystringFilter by category (partial match)
limitnumberMax results (default: 500)

Response

{ "data": [{ "store": "thegioididong", "name": "iPhone 15 Pro Max", "price": 29990000, "brand": "Apple", "rating": 4.5, "in_stock": 1 }] }
GET/api/electronics/summary

Electronics store-level summary — product counts, avg prices, brand/category diversity, ratings.

Response

{ "data": [{ "store": "thegioididong", "products": 9000, "avg_price": 8500000, "categories": 15, "brands": 120, "avg_rating": 4.2 }] }
GET/api/electronics/stores

Electronics store product counts and latest crawl dates.

Response

{ "data": [{ "store": "cellphones", "products": 58000, "crawl_days": 15, "latest_date": "2026-05-20" }] }
GET/api/electronics/catalog

Full deduplicated electronics catalog — latest price per product across all crawl dates (see /groceries/catalog).

Query Parameters

storestringFilter by store (thegioididong, cellphones, fptshop, …)
brandstringFilter by brand
categorystringFilter by category (partial match)
limitnumberMax results (default: 200000)

Response

{ "data": [{ "store": "fptshop", "source_id": "fptshop:0000056", "name": "iPhone 15 Pro Max", "price": 29990000, "date": "2026-06-14" }] }
GET/api/electronics/search

Live product-name search (suggestions / autocomplete). ILIKE on name, deduplicated to latest price per product, `_raw` stripped (see /groceries/search).

Query Parameters

qstringSearch text (matched against product name; required)
storestringFilter by store
brandstringFilter by brand
categorystringFilter by category (partial match)
limitnumberMax results (default: 50)

Response

{ "data": [{ "store": "fptshop", "source_id": "fptshop:00677914", "name": "iPhone 15 Pro Max", "price": 29990000, "date": "2026-06-14" }] }
GET/api/realestate

Real-estate listings from batdongsan.com.vn + guland.vn + nhatot.com — sale & rent, all property types (apartment, house, villa, street-front, land, project land, warehouse, office, …). First geo focus: Hồ Chí Minh, Lâm Đồng, Đà Nẵng, Hà Nội, Quảng Ngãi. Daily newest-first snapshot. price_unit ∈ {total, per_month, per_m2, per_m2_month, negotiable}.

Query Parameters

transactionstringban (sale) | cho-thue (rent)
typestringProperty type slug (e.g. can-ho-chung-cu, nha-rieng, nha-mat-pho, dat, van-phong)
provincestringProvince key (ho-chi-minh, lam-dong, da-nang, ha-noi, quang-ngai)
districtstringFilter by district (partial match)
sourcestringSource filter (guland.vn | batdongsan.com.vn)
date / from / tostringDate range filter (YYYY-MM-DD)
limitnumberMax results (default: 500)

Response

{ "data": [{ "listing_id": "45785289", "transaction": "ban", "property_type": "nha-rieng", "province": "ho-chi-minh", "district": "Quận 7", "title": "...", "price_value": 9900000000, "price_unit": "total", "area": 75, "price_per_m2": 132000000, "url": "https://batdongsan.com.vn/..." }] }
GET/api/realestate/facets

Distinct filter values with counts for real-estate listings. Returns provinces, property_types, sources, and transactions. Supports cross-filtering — pass any combination of filters to get counts scoped to the selection (e.g. province=da-nang&transaction=ban returns only matching facets).

Query Parameters

transactionstringban (sale) | cho-thue (rent)
typestringProperty type slug
provincestringProvince key (e.g. ha-noi, ho-chi-minh)
sourcestringSource filter (guland.vn | batdongsan.com.vn | nhatot.com)
date / from / tostringDate range filter (YYYY-MM-DD)

Response

{ "data": { "provinces": [{ "province": "ha-noi", "count": 533603 }], "property_types": [{ "property_type": "nha-o", "type_name": "Nhà ở", "count": 211060 }], "sources": [{ "source": "guland.vn", "count": 737081 }], "transactions": [{ "transaction": "ban", "count": 1044712 }] } }
GET/api/realestate/sources/stats

Per-source organic-activity stats for ranking BĐS sources: all-time distinct listings (total), freshness (last_crawled), NEW-listing counts by first-seen window (added_24h/7d/<days>d — the 'new posts per N days' analog) + per_day rate, and sale/rent + property-type skew on the latest crawl-date snapshot. Read-only aggregate.

Query Parameters

daysnumberFirst-seen window in days for added_<days>d + per_day (default 30, max 365)

Response

{ "data": [{ "source": "guland.vn", "total": 230472, "rows": 942816, "last_crawled": "2026-06-13", "last_fetched_at": "2026-06-13T03:34:01Z", "added_24h": 114, "added_7d": 215705, "added_30d": 230472, "per_day": 7682.4, "by_transaction": { "ban": 30000, "cho-thue": 1200 }, "by_property_type": [{ "property_type": "nha-rieng", "type_name": "Nhà ở", "count": 12000 }] }], "meta": { "window_days": 30 } }
GET/api/realestate/summary

Real-estate market snapshot grouped by province × transaction × property type. Median price & price/m² are the headline (robust to outlier/garbage rows); avg_* are trimmed to a sane band. Covers all 63 provinces.

Query Parameters

provincestringFilter by province key

Response

{ "data": [{ "province": "ho-chi-minh", "transaction": "ban", "property_type": "can-ho-chung-cu", "listings": 100, "median_price": 4200000000, "median_price_per_m2": 95000000, "avg_price": 4500000000, "avg_price_per_m2": 65000000, "avg_area": 72 }] }
GET/api/realestate/stores

Real-estate listing counts & latest crawl date by province × transaction.

Response

{ "data": [{ "province": "da-nang", "transaction": "cho-thue", "listings": 200, "crawl_days": 5, "latest_date": "2026-06-04" }] }
GET/api/realestate/trends

Daily real-estate market trend — listings count, avg & median price/m², avg price & area over time. Filter by province/transaction/type.

Query Parameters

daysnumberLookback window (default: 30)
provincestringProvince key filter
transactionstringban | cho-thue
typestringProperty type slug

Response

{ "data": [{ "date": "2026-06-04", "listings": 78, "avg_price": 1741372077, "avg_price_per_m2": 13745484, "median_price_per_m2": 11110000, "avg_area": 456 }] }
GET/api/realestate/movers

Listings whose price changed between their two most recent crawl snapshots — sorted by absolute change. Populates once ≥2 crawl days exist.

Query Parameters

provincestringProvince key filter
limitnumberMax results (default: 50)

Response

{ "data": [{ "listing_id": "...", "prev_price": 4500000000, "curr_price": 4200000000, "pct_change": -6.7, "prev_date": "2026-06-04", "curr_date": "2026-06-05", "url": "..." }] }
GET/api/realestate/planning

Guland planning/zoning map (quy hoạch) tile layers per province — land-use planning 2021-2030 (land-2030), general planning (qh-chung) & base land layer. Each layer carries an {z}/{x}/{y} XYZ tile URL template (renderable in Leaflet/Mapbox), max zoom, source year & GSO admin codes.

Query Parameters

provincestringProvince key filter (ho-chi-minh, lam-dong, da-nang, ha-noi, quang-ngai)

Response

{ "data": [{ "province": "ho-chi-minh", "province_code": "79", "layer_key": "land-2030", "layer_name": "Quy hoạch sử dụng đất 2021-2030", "layer_type": "xyz", "tile_url_template": "https://l5cfglaebpobj.vcdn.cloud/tp-ho-chi-minh-2030/{z}/{x}/{y}.png", "max_zoom": 18, "source_year": 2030 }] }
GET/api/realestate/benchmarks

Area-level price benchmarks — median & avg price-per-m², avg price & area aggregated from crawled listings per source × province × district × transaction × property type, per crawl date.

Query Parameters

provincestringProvince key filter
transactionstringban | cho-thue
sourcestringSource filter (guland.vn | batdongsan.com.vn)
limitnumberMax results (default: 200)

Response

{ "data": [{ "source": "guland.vn", "province": "ho-chi-minh", "district": null, "transaction": "ban", "listings": 44, "median_price_per_m2": 11575000, "avg_price_per_m2": 25963707, "avg_area": 120 }] }
GET/api/realestate/estimate

Comps-based price estimate for a specific property. Finds the most specific tier of comparable crawled listings (project → street → ward → district → province) that has enough samples, takes the median price/m², and scales by area. Returns the estimate, a low–high band (p25–p75), the tier used, sample size, the comps & a confidence level. Descriptive only — floor, alley width & lot depth are NOT modeled.

Query Parameters

provincestringProvince key (default ho-chi-minh)
districtstringe.g. "quan 7" / "Quận 7" / "bình thạnh"
wardstringWard name (partial match)
streetstringStreet, e.g. "Nguyễn Thị Thập"
projectstringProject, e.g. "Cosmo City"
typestringapt | house | land | raw property_type slug
transactionstringban (default) | cho-thue
areanumberArea in m² (required for a total price)
refreshstring1 → also fetch a targeted realtime source query (nhatot keyword) + upsert before estimating, so project/street tiers reflect the freshest listings

Response

{ "data": [{ "used_tier": { "tier": "street", "label": "Street “Nguyễn Thị Thập”", "n": 8, "median_ppm2": 68000000 }, "median_ppm2": 68000000, "estimate_vnd": 4760000000, "confidence": "medium", "comps": [], "notes": [], "live": { "queries": ["Cosmo City"], "fetched": 102, "upserted": 100 } }] }
GET/api/realestate/fetch

On-demand realtime fetch + upsert (no estimate). Searches the nhatot Chợ Tốt gateway by keyword (project → street → district) and upserts arriving listings/agents into the DB so they're available to subsequent cached reads & estimates. Explicit opt-in action (like the MST live lookup); 60s per-query throttle, bounded pages.

Query Parameters

provincestringProvince key (default ho-chi-minh)
districtstringe.g. "Quận 7"
streetstringe.g. "Nguyễn Thị Thập"
projectstringe.g. "Cosmo City"
max_pagesnumberPages per keyword (50 ads/page, default 2)

Response

{ "data": [{ "queries": ["Cosmo City", "Nguyễn Thị Thập"], "fetched": 102, "upserted": 100, "agents_upserted": 67, "skipped_throttled": [] }] }
GET/api/realestate/land-prices

Official government land-price schedule (Bảng giá đất 2026) from guland.vn — per street/segment × land type (Đất ở, Đất thương mại dịch vụ, …), priced by 4 position tiers (Vị trí 1-4) in VNĐ/m². Latest snapshot per street. Covers every ward & street (HCMC ≈ 35K rows).

Query Parameters

provincestringProvince key filter (ho-chi-minh, lam-dong, da-nang, ha-noi, quang-ngai)
wardstringWard filter (partial match)
land_typestringLand type filter (partial match, e.g. 'Đất ở')
qstringStreet name search (partial match)
limitnumberMax results (default: 200)

Response

{ "data": [{ "province": "ho-chi-minh", "ward": "Phường Bến Thành", "street": "LÊ LỢI", "segment": "TRỌN ĐƯỜNG", "land_type": "Đất ở", "price_vt1": 687200000, "price_vt2": 343600000, "price_vt3": 274880000, "price_vt4": 219904000 }] }
GET/api/realestate/agents

Real-estate sellers — agencies, brokers & individual sellers (nhatot.com + guland.vn) with their active-listing counts (live_ads), ratings, verified/company flags, shop name & address. Ordered by activity.

Query Parameters

sourcestringSource filter (nhatot.com)
provincestringProvince key filter (ho-chi-minh, lam-dong, da-nang, ha-noi, quang-ngai)
qstringName / shop search (partial match)
companiesstring'1' → only agencies/companies
limitnumberMax results (default: 100)

Response

{ "data": [{ "source": "nhatot.com", "agent_id": "314697", "name": "HUỲNH LONG SƠN", "shop_name": "HUỲNH LONG SƠN", "address": "Thảo Điền Quận 2", "is_company": true, "is_verified": false, "live_ads": 145, "rating": 4.5 }] }
GET/api/geo/resolve

Resolve a Vietnamese location — a name (e.g. 'Q7, Nguyễn Thị Thập', 'HCM Tân Thuận') or a Google Maps URL/short-url — to structured admin units (province/district/ward), coordinates, and a batdongsan.com.vn geo mapping. geocode.maps.co primary + goong.io enrichment, cached.

Query Parameters

qstringLocation name or Google Maps URL (required)

Response

{ "data": [{ "query": "Q7, Nguyễn Thị Thập, HCM", "province": "Hồ Chí Minh", "district": "Quận 7", "ward": "Phường Tân Thuận", "lat": 10.738, "lng": 106.723, "province_key": "ho-chi-minh", "batdongsan": { "sale_url": "https://batdongsan.com.vn/nha-dat-ban-tp-hcm", "district_slug": "quan-7" }, "confidence": "high", "cached": false }] }
GET/api/realestate/geo

Resolve a location (name or Google Maps URL) AND return matching real-estate listings in that province/district. Combines /api/geo/resolve with a listings query.

Query Parameters

qstringLocation name or Google Maps URL (required)
transactionstringban (sale) | cho-thue (rent)
limitnumberMax listings (default: 50)

Response

{ "geo": { "province": "Hồ Chí Minh", "district": "Quận 7", "province_key": "ho-chi-minh" }, "data": [{ "listing_id": "...", "price_value": 4500000000, "area": 72 }] }
GET/api/provinces/summary

Vietnam 2025 province/ward merge summary. 63 → 34 provinces, 3,321 wards. Before/after metrics: Population, Area, Density, GRDP, Budget.

Response

{ "slug": "vn-2025-province-merge", "total_before": 63, "total_after": 34, "metrics": [...], "before": {...}, "after": {...} }
GET/api/geo/vnsdi-provinces

Official VNSDI 34-province boundaries (Resolution 202/2025/QH15, post-merger, WGS84) as a simplified GeoJSON FeatureCollection. The VN-territorial-compliant boundary set powering the dashboard maps.

Response

{ "type": "FeatureCollection", "meta": { "source": "VNSDI", "basis": "Resolution 202/2025/QH15" }, "features": [{ "properties": { "code": "0001", "name": "Thủ đô Hà Nội" }, "geometry": {...} }] }
GET/api/provinces/map

Province GeoJSON with merge metadata. Returns Leaflet-ready official VNSDI boundary GeoJSON + per-province metrics for choropleth coloring.

Response

{ "data": [{ "id": "An Giang", "name": "An Giang", "merged_from": "...", "metrics": {...} }], "geoJSON": {...}, "metricExtents": {...}, "boundary_source": "VNSDI (NQ 202/2025/QH15)" }
GET/api/provinces/wards

Search merged wards (3,321 total). Supports search, province filter, pagination.

Query Parameters

qstringSearch by ward name (new or old)
provincestringFilter by province name (exact)
per_pagenumberResults per page (default: 50, max: 5000)

Response

{ "data": [{ "new_name": "Phường 1", "province": "TP HCM", "old_names": "Phường 1, Phường 2" }], "meta": { "total_wards": 3321 } }
GET/api/blog

Data-driven blog posts — original cross-source analysis generated from our own crawled metrics (AI-generated posts flagged via ai_generated). Newest first.

Query Parameters

categorystringFilter by category slug (e.g. diem-tin-ngay, vang-ty-gia)
limitnumberMax results (default: 50, max: 200)

Response

{ "data": [{ "slug": "...", "title": "...", "summary": "...", "ai_generated": true, "cadence": "daily", "category": "diem-tin-ngay", "published_at": "..." }], "meta": { "count": 12, "updated_at": "..." } }
GET/api/blog/categories

Blog categories (metric domains: daily brief, gold & FX, energy, agriculture, real estate, retail, macro) and post counts.

Response

{ "data": [{ "slug": "diem-tin-ngay", "name_vi": "Điểm Tin Ngày", "cadence": "daily", "post_count": 12 }] }
GET/api/blog/:slug

Single blog post including markdown body and the cross-source metric snapshot it was built from (for client-side charts).

Response

{ "data": { "slug": "...", "title": "...", "body_md": "...", "ai_generated": true, "ai_model": "...", "cadence": "daily" } }
GET/api/mst/:code

Vietnamese company lookup by tax ID (mã số thuế). Cached company_info; ?refresh=true forces a live enrich.

Query Parameters

refreshbooleanForce a live re-fetch instead of cached (default false)

Response

{ "data": { "tax_code": "0312866443", "company_name": "...", "status": "NNT đang hoạt động", "address": "...", "representative": "...", "founded_date": "...", "tax_office": "..." }, "meta": { "cached": true, "fetched_at": "..." } }
GET/api/mst/stats

Aggregate analytics over the company corpus (54k+ businesses): counts by status (business health), entity type, province, HCMC tax area, formation year, daily enrichment velocity, and field coverage. Filterable; unfiltered result cached (5 min).

Query Parameters

provincestringFilter by province slug: hcm|hanoi|danang|binhduong|dongnai|haiphong|cantho
orgstringFilter by entity type: dn (doanh nghiệp) | ho (hộ kinh doanh)
founded_fromdateEarliest founding date, YYYY-MM-DD (e.g. 2015-01-01)
founded_todateLatest founding date, YYYY-MM-DD (e.g. 2015-12-31)

Response

{ "data": { "kpi": { "total": 54023, "active": 14337, "ceased": 20645, "added_7d": 54023 }, "by_status": [{ "label": "Không ở địa chỉ ĐK", "n": 17183 }], "by_org_type": [...], "by_province": [...], "by_hcm_area": [...], "formation_by_year": [...], "velocity": [...], "coverage": {...}, "recent": [...] }, "meta": { "updated_at": "..." } }

API Key Management

GET/api/keys

List your API keys. Requires authentication (session cookie).

Response

{ "data": [{ "id": "uuid", "name": "my-agent", "key_prefix": "dl_a1b2c3d4", "created_at": "..." }] }
POST/api/keys

Create a new API key. The raw key is only shown once.

Query Parameters

namestringLabel for this key (required)

Response

{ "data": { "id": "uuid", "name": "my-agent", "key_prefix": "dl_a1b2c3d4", "key": "dl_a1b2c3d4e5f6..." } }
POST/api/keys/:id/rotate

Rotate an API key — generates a new secret while keeping the same ID. All usage stats are preserved.

Response

{ "data": { "id": "uuid", "name": "my-agent", "key_prefix": "dl_e7f8g9h0", "key": "dl_e7f8g9h0i1j2..." } }
GET/api/keys/stats

Your API usage stats — overview, per-key breakdown, top endpoints (30d).

Query Parameters

daysnumberLookback period (default: 30)

Response

{ "data": { "overview": { "total_calls": 450, "avg_ms": 12, "keys_count": 2 }, "by_key": [...], "by_endpoint": [...] } }
DELETE/api/keys/:id

Revoke an API key. Cannot be undone.

Response

{ "data": { "revoked": true } }

Admin Endpoints

Require session cookie from a user with role=admin.

GET/api/admin/users

List all users with their roles and plans.

Response

{ "data": [{ "user_id": "...", "role": "admin", "plan": "unlimited", "email": "...", "name": "..." }] }
PUT/api/admin/users/:id/plan

Set a user's plan. Only admins can change plans.

Query Parameters

planstringOne of: free, pro, unlimited (in JSON body)

Response

{ "data": { "user_id": "...", "plan": "pro" } }

Quick Start (for LLMs / Agents)

# 1. Sign in at /settings and create an API key
# 2. Use the key in all requests:

# Get today's summary (best for daily briefing)
curl -H "Authorization: Bearer dl_YOUR_KEY" https://dulieu.dev/api/summary

# Get exchange rates for a date range
curl -H "Authorization: Bearer dl_YOUR_KEY" "https://dulieu.dev/api/exchange?from=2026-05-01&to=2026-05-20"

# Or use query parameter
curl "https://dulieu.dev/api/gold?date=2026-05-20&api_key=dl_YOUR_KEY"

# Free plan: 100 calls/day. Upgrade to Pro for grocery data + higher limits.