Developer Documentation

BDS Chat API Reference

A standardized API layer for Vietnamese real estate, built for developers, brokerages, and AI platforms: HCMC listings, NQ 87/2025 state land-price references, data-trust grades, risk signals, and scoped listing chat.

OpenAPI 3.1
14 endpoints
4-tier auth
Scalar interactive docs

Get started in 60 seconds

1Register POST /auth/register
2Get key (from response)
3First call GET /listings

Getting Started

Start using the BDS Chat API in three steps. Endpoints return JSON over HTTPS and expose rate-limit headers for integration testing.

1

Register for an API Key

Create a free account to get your API key. Free tier includes 100 requests/day.

2

Make Your First Request

Add your key as a Bearer token and search listings: GET /listings?district=Binh+Tan&limit=5

3

Enrich with Reference Data

Use /meta/gov-land-price, /meta/zoning, and /meta/risk/check to add risk and reference context.

Base URL: All API requests go to https://api.bds.chat. All responses are JSON with Content-Type: application/json. Every response includes an X-Request-ID header for traceability.

Authentication

The BDS Chat API uses Bearer token authentication. Include your API key in the Authorization header of every request.

Access Tiers

TierDaily LimitEndpointsFeatures
Anonymous10 req/day/health, /openapi.yamlRead-only public
Free100 req/day+ /listings, /listings/{id}Search + detail
Pro10,000 req/day+ /meta/*, /listings/{id}/chatFull API + chat
PartnerCustomAll + /admin/*Sync, enrichment

Auth Header Format

Authorization: Bearer bds_live_abc123def456...
Keep your key secure. The raw API key is returned only once during registration. Never expose it in client-side code, public repositories, or URL parameters.

Rate Limiting

Every API response includes rate limit headers so you can track usage in real time.

Response Headers

HeaderDescription
X-RateLimit-LimitYour daily request quota
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUTC epoch when the window resets
Retry-AfterSeconds to wait (only on 429)
X-Request-IDUnique request identifier (UUID v7)

Handling 429 Too Many Requests

When you exceed your rate limit, the API returns 429 with a Retry-After header. Implement exponential backoff.

GET/listings

Search and filter real estate listings across Ho Chi Minh City. Supports district, price, area, legal status, and seller type filters with configurable sorting and pagination.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
districtstringOptionalDistrict name (diacritic-insensitive)
wardstringOptionalWard name within district
min_priceintegerOptionalMinimum price in VND
max_priceintegerOptionalMaximum price in VND
min_areanumberOptionalMinimum area in m²
max_areanumberOptionalMaximum area in m²
legal_statusstringOptionalso_do_so_hong, so_hong, so_hong_rieng, dang_cho_so, giay_tay
seller_typestringOptionalchinh_chu (direct owner) or moi_gioi (broker)
sortstringOptionalprice_asc, price_desc, area_asc, area_desc, newest (default)
limitintegerOptionalResults per page (default: 20, max: 100)
offsetintegerOptionalPagination offset (default: 0)
Diacritic-insensitive search: The API uses immutable_unaccent() so "Binh Tan" matches "Bình Tân" automatically.
GET/listings/{id}

Retrieve complete details for a single listing including trust_grade, quality_score, risk_score, risk_band, gov_price_per_m2, market_gov_ratio, images, and provenance data.

Try it in Scalar →

Path Parameters

NameTypeRequiredDescription
idstring (UUID)RequiredListing UUID. E.g. 985fafb9-8503-4e86-9056-d385851708ac
POST/listings

Create a new listing. Requires Partner tier. Automatic deduplication on source + source_listing_id returns 409 Conflict if duplicate.

Try it in Scalar →

Request Body

FieldTypeRequiredDescription
titlestringRequiredListing title (Vietnamese)
price_vndintegerRequiredPrice in VND
area_m2numberRequiredArea in square meters
districtstringRequiredDistrict name
wardstringOptionalWard name
legal_statusstringOptionalLegal document status code
seller_typestringOptionalchinh_chu or moi_gioi
sourcestringOptionalSource platform identifier
source_listing_idstringOptionalExternal listing ID (for dedup)
GET/meta/gov-land-price

Look up state land prices from NQ 87/2025. Covers 30,775 street-level records across HCMC with price per m² by street, position, and road width.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
streetstringOptionalStreet name (diacritic-insensitive)
districtstringOptionalDistrict name to narrow results
limitintegerOptionalMax results (default: 20)
GET/meta/gov-land-price/compare

Compare a listing's asking price against the state land-price benchmark. Returns ratio, differential, and assessment.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
listing_idstring (UUID)RequiredListing to compare
GET/meta/zoning

Query zoning and urban planning data for a geographic coordinate. Returns zone code, LBCS classification, DGT road risk, and development constraints.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
latnumberRequiredLatitude (EPSG:4326)
lonnumberRequiredLongitude (EPSG:4326)
GET/meta/zoning/check-listing

Check zoning for a specific listing. Combines listing coordinates with zoning data to assess land use compatibility and planning constraints.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
listing_idstring (UUID)RequiredListing to check
GET/meta/risk/check

Full risk assessment with 9 subscores and 5 blocking risk flags. Returns a final risk band from low to critical. Checks price reasonableness, location quality, listing completeness, source reputation, gov price alignment, and more.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
listing_idstring (UUID)RequiredListing to assess
POST/listings/{id}/chat

Ask a natural-language question about a specific listing. Returns a streaming SSE response with AI-generated analysis grounded in listing data, government benchmarks, and zoning info.

Try it in Scalar →

Path Parameters

NameTypeRequiredDescription
idstring (UUID)RequiredListing UUID

Request Body

FieldTypeRequiredDescription
questionstringRequiredNatural language question about this listing
Streaming response: This endpoint returns Server-Sent Events (SSE). See the Streaming section for event format details.
GET/health

Health check endpoint. Returns service status and version. No authentication required.

Try it in Scalar →
GET/openapi.yaml

Returns the full OpenAPI 3.1.0 specification. Useful for code generation, client SDKs, and API exploration. No authentication required.

GET/meta/resolve-ward

Normalize ward names with 2025 ward reform awareness. Maps old ward names to current administrative units.

Try it in Scalar →

Query Parameters

NameTypeRequiredDescription
wardstringRequiredWard name to resolve
districtstringRequiredDistrict context

Streaming (SSE)

POST /listings/{id}/chat uses Server-Sent Events to stream listing-scoped responses. The answer should stay within returned listing data, citations, and visible gaps.

Event Types

TypeDescriptionPayload
textText chunk{"type":"text","content":"..."}
doneStream complete{"type":"done","tokens_used":87}
errorStream error{"type":"error","message":"..."}

Handling SSE in JavaScript

const res = await fetch(url, {
  method: "POST",
  headers: { "Authorization": `Bearer ${key}`, "Content-Type": "application/json" },
  body: JSON.stringify({ "question": "Pháp lý listing này thế nào?" })
});

const reader = res.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value);
  // Parse SSE lines: event: type\ndata: {...}
}

Error Handling

The API uses standard HTTP status codes. Error responses include JSON fields your integration can log and show without exposing internal details.

Status Codes

CodeMeaningWhen
200OKSuccessful request
201CreatedResource created (POST /listings)
400Bad RequestInvalid parameters or malformed JSON
401UnauthorizedMissing or invalid API key
403ForbiddenInsufficient tier for this endpoint
404Not FoundResource does not exist
409ConflictDuplicate listing (dedup match)
429Too Many RequestsRate limit exceeded
500Internal ErrorServer error (report via X-Request-ID)

Error Response Format

{
  "error": "forbidden",
  "message": "Pro tier required for /meta/* endpoints",
  "request_id": "019726a3-4b5c-7d8e-9f0a-1b2c3d4e5f6a"
}

Code Examples

curl "https://api.bds.chat/listings?district=Binh+Tan&max_price=5000000000&limit=10" \
  -H "Authorization: Bearer bds_live_abc123"

Resources

Standards

  • RESO Data Dictionary -- Property field naming conventions
  • ISO 4217 -- VND currency code
  • ISO 3166-2:VN -- VN-SG (Ho Chi Minh City)
  • ISO 8601 -- Date/time formatting
  • GeoJSON RFC 7946 -- Geographic data (EPSG:4326)
  • APA LBCS -- Land-based classification codes
  • W3C PROV -- Data provenance tracking