API Endpoints Reference
All routes are prefixed with /api/v1/ except health checks. Authentication uses Bearer JWT tokens.
Interactive docs: Swagger UI is available at http://localhost:3001/api/v1/docs when running the API locally.
Auth (/auth)
| Method |
Path |
Auth |
Description |
| POST |
/auth/register |
Public |
Register a new user |
| POST |
/auth/login |
Public |
Login with phone and password |
| POST |
/auth/refresh |
Cookie |
Refresh access token using httpOnly refresh cookie |
| POST |
/auth/logout |
JWT |
Logout and clear auth cookies |
| POST |
/auth/exchange-token |
Public |
Exchange OAuth token pair for httpOnly cookies |
| GET |
/auth/profile |
JWT |
Get current user profile |
| GET |
/auth/profile/agent |
JWT |
Get agent profile for current user |
| PATCH |
/auth/kyc |
Admin |
Verify user KYC status |
OAuth
| Method |
Path |
Auth |
Description |
| GET |
/auth/google |
Public |
Initiate Google OAuth2 login |
| GET |
/auth/google/callback |
Public |
Google OAuth2 callback |
| GET |
/auth/zalo |
Public |
Initiate Zalo OAuth2 login |
| GET |
/auth/zalo/callback |
Public |
Zalo OAuth2 callback |
User Data (GDPR)
| Method |
Path |
Auth |
Description |
| DELETE |
/users/me |
JWT |
Request account deletion (30-day grace period) |
| POST |
/users/me/cancel-deletion |
JWT |
Cancel pending account deletion |
| GET |
/users/me/export |
JWT |
Export user data (GDPR Article 20) |
| DELETE |
/users/:id/force |
Admin |
Force-delete user immediately |
Listings (/listings)
| Method |
Path |
Auth |
Description |
| POST |
/listings |
JWT + Quota |
Create a new property listing |
| GET |
/listings |
Public |
Search and filter property listings |
| GET |
/listings/pending |
Admin |
Get listings pending moderation |
| GET |
/listings/:id |
Public |
Get listing details by ID |
| PATCH |
/listings/:id/status |
JWT |
Update listing status |
| POST |
/listings/:id/media |
JWT |
Upload media (multipart file upload) |
| PATCH |
/listings/:id/moderate |
Admin |
Moderate a listing |
Search (/search)
| Method |
Path |
Auth |
Description |
| GET |
/search |
Public |
Full-text and faceted property search |
| GET |
/search/geo |
Public |
Geographic radius search |
| POST |
/search/reindex |
Admin |
Reindex all properties in Typesense |
Saved Searches (/saved-searches)
| Method |
Path |
Auth |
Description |
| POST |
/saved-searches |
JWT |
Save search filters |
| GET |
/saved-searches |
JWT |
List saved searches |
| GET |
/saved-searches/:id |
JWT |
Get saved search details |
| PATCH |
/saved-searches/:id |
JWT |
Update saved search |
| DELETE |
/saved-searches/:id |
JWT |
Delete saved search |
Payments (/payments)
| Method |
Path |
Auth |
Description |
| POST |
/payments |
JWT |
Create a new payment |
| GET |
/payments |
JWT |
List transactions for authenticated user |
| GET |
/payments/:id |
JWT |
Get payment status by ID |
| POST |
/payments/:id/refund |
Admin |
Refund a payment |
| POST |
/payments/callback/:provider |
Public |
Payment provider webhook (VNPay, MoMo, ZaloPay) |
Subscriptions (/subscriptions)
| Method |
Path |
Auth |
Description |
| GET |
/subscriptions/plans |
Public |
List all subscription plans |
| GET |
/subscriptions/plans/:tier |
Public |
Get subscription plan by tier |
| POST |
/subscriptions |
JWT |
Create a new subscription |
| PUT |
/subscriptions/upgrade |
JWT |
Upgrade existing subscription |
| DELETE |
/subscriptions |
JWT |
Cancel active subscription |
| POST |
/subscriptions/usage |
JWT |
Record metered usage |
| GET |
/subscriptions/quota/:metric |
JWT |
Check remaining quota for a metric |
| GET |
/subscriptions/billing |
JWT |
Get billing history |
Admin (/admin)
User Management
| Method |
Path |
Auth |
Description |
| GET |
/admin/users |
Admin |
List users with optional filters |
| GET |
/admin/users/:id |
Admin |
Get user details by ID |
| PATCH |
/admin/users/status |
Admin |
Update user active status |
| POST |
/admin/users/ban |
Admin |
Ban or unban a user |
| POST |
/admin/subscriptions/adjust |
Admin |
Adjust user subscription plan |
| GET |
/admin/dashboard |
Admin |
Get admin dashboard statistics |
| GET |
/admin/revenue |
Admin |
Get revenue statistics by date range |
| GET |
/admin/audit-logs |
Admin |
Get admin audit logs |
Moderation
| Method |
Path |
Auth |
Description |
| GET |
/admin/moderation |
Admin |
Get listing moderation queue |
| POST |
/admin/moderation/approve |
Admin |
Approve a listing |
| POST |
/admin/moderation/reject |
Admin |
Reject a listing |
| POST |
/admin/moderation/bulk |
Admin |
Bulk approve or reject listings |
| GET |
/admin/kyc |
Admin |
Get KYC verification queue |
| POST |
/admin/kyc/approve |
Admin |
Approve KYC verification |
| POST |
/admin/kyc/reject |
Admin |
Reject KYC verification |
Notifications (/notifications)
| Method |
Path |
Auth |
Description |
| GET |
/notifications/history |
JWT |
Get notification history |
| GET |
/notifications/preferences |
JWT |
Get notification preferences |
| PUT |
/notifications/preferences |
JWT |
Update notification preferences |
| GET |
/notifications/unread |
JWT |
Get unread notifications |
| PATCH |
/notifications/:id/read |
JWT |
Mark notification as read |
| PATCH |
/notifications/read-all |
JWT |
Mark all notifications as read |
| GET |
/notifications/templates |
JWT |
Get available notification templates |
Analytics (/analytics)
All analytics endpoints require JWT and are quota-guarded.
| Method |
Path |
Auth |
Description |
| GET |
/analytics/market-report |
JWT + Quota |
Get market report for a city |
| GET |
/analytics/price-trend |
JWT + Quota |
Get price trend for a district |
| GET |
/analytics/heatmap |
JWT + Quota |
Get price heatmap for a city |
| GET |
/analytics/district-stats |
JWT + Quota |
Get statistics by district |
| GET |
/analytics/valuation |
JWT + Quota |
Get automated property valuation (AVM) |
Agents (/agents)
| Method |
Path |
Auth |
Description |
| GET |
/agents/me/dashboard |
Agent |
Get agent dashboard stats |
| POST |
/agents/:agentId/recalculate-score |
Admin |
Recalculate agent quality score |
Inquiries (/inquiries)
| Method |
Path |
Auth |
Description |
| POST |
/inquiries |
JWT |
Create inquiry for a listing |
| GET |
/inquiries/listing/:listingId |
JWT |
List inquiries by listing |
| GET |
/inquiries/agent/me |
Agent |
List inquiries for current agent |
| PATCH |
/inquiries/:id/read |
Agent |
Mark inquiry as read |
Leads (/leads)
| Method |
Path |
Auth |
Description |
| POST |
/leads |
Agent |
Create lead |
| GET |
/leads |
Agent |
List leads for agent |
| GET |
/leads/stats |
Agent |
Get lead statistics |
| PATCH |
/leads/:id/status |
Agent |
Update lead status |
| DELETE |
/leads/:id |
Agent |
Delete lead |
Reviews (/reviews)
| Method |
Path |
Auth |
Description |
| POST |
/reviews |
JWT |
Create a review |
| GET |
/reviews |
Public |
List reviews by target |
| GET |
/reviews/stats |
Public |
Get aggregate rating stats for a target |
| GET |
/reviews/me |
JWT |
Get reviews by authenticated user |
| DELETE |
/reviews/:id |
JWT |
Delete own review |
Health (/health)
Health endpoints are not prefixed with /api/v1/.
| Method |
Path |
Auth |
Description |
| GET |
/health |
Public |
Liveness probe |
| GET |
/health/ready |
Public |
Readiness probe (DB + Redis) |
| GET |
/health/db |
Public |
Database connectivity check |
| GET |
/health/redis |
Public |
Redis connectivity check |
MCP (/mcp)
| Method |
Path |
Auth |
Description |
| GET |
/mcp/servers |
JWT |
List available MCP servers |
| GET |
/mcp/:serverName/sse |
JWT |
Open SSE connection to MCP server |
| POST |
/mcp/:serverName/messages |
JWT |
Send message to MCP server session |
Metrics
| Method |
Path |
Auth |
Description |
| POST |
/web-vitals |
Public |
Ingest Core Web Vitals metrics |
Authentication Summary
| Auth Type |
Description |
| Public |
No authentication required |
| JWT |
Requires Authorization: Bearer <token> header |
| Admin |
JWT + ADMIN role required |
| Agent |
JWT + AGENT role required |
| Quota |
JWT + subscription quota enforcement |
| Cookie |
Uses httpOnly refresh token cookie |
Rate Limiting
The following endpoints have stricter rate limits:
- Auth endpoints (register, login, refresh):
10 req/60s
- OAuth callbacks:
10 req/60s
- Payment callbacks:
60 req/60s
- MCP endpoints:
30 req/60s
- Default:
60 req/60s