SDK Quickstart
Installation
Section titled “Installation”npm install @borough/sdkpnpm add @borough/sdkyarn add @borough/sdkQuick start
Section titled “Quick start”import { BoroughClient } from "@borough/sdk";
const borough = new BoroughClient("BOROUGH-...");
// Search rentals in the Upper East Sideconst results = await borough.rentals.search({ areas: "120", minBeds: 1, maxPrice: 4000, noFee: true,});
console.log(`Found ${results.meta.total} listings`);for (const listing of results.data) { console.log( `${listing.address.street}${listing.address.unit ? ` ${listing.address.unit}` : ""} — $${listing.price}/mo`, );}Configuration
Section titled “Configuration”The client accepts a string (API key) or a config object:
// Simple — just the API keyconst borough = new BoroughClient("BOROUGH-...");
// Full configconst borough = new BoroughClient({ apiKey: "BOROUGH-...", baseURL: "https://borough.qwady.app/v1", // default timeout: 30_000, // 30s default maxRetries: 2, // 2 retries on 429/5xx});
// Environment variable fallback// Set BOROUGH_API_KEY in your environment, then:const borough = new BoroughClient();Resources
Section titled “Resources”The client exposes resource modules following a consistent pattern:
// Searchconst rentals = await borough.rentals.search({ areas: "120", minBeds: 2 });const sales = await borough.sales.search({ areas: "200", maxPrice: 1_000_000 });
// Property detailsconst listing = await borough.listings.get("4961849");const history = await borough.listings.history("4961849");const fees = await borough.listings.fees("4961849");const openHouses = await borough.listings.openHouses("4961849");
// Building dataconst building = await borough.buildings.get("12345");const scores = await borough.buildings.scores("12345");const violations = await borough.buildings.violations("12345");const buildingListings = await borough.buildings.listings("12345");
// Areasconst allAreas = await borough.areas.list();const neighborhoods = await borough.areas.list({ level: 2, parentId: 100 });
// Market dataconst snapshot = await borough.market.snapshot({ areaId: 120, bedrooms: 1 });const trends = await borough.market.trends({ areaId: 120 });const comparison = await borough.market.compare({ areas: "120,200,300" });Error handling
Section titled “Error handling”The SDK throws typed errors that you can catch and handle:
import { BoroughClient, NotFoundError, RateLimitError, QuotaExceededError,} from "@borough/sdk";
const borough = new BoroughClient("BOROUGH-...");
try { const listing = await borough.listings.get("nonexistent");} catch (error) { if (error instanceof NotFoundError) { console.log("Listing not found"); } else if (error instanceof RateLimitError) { console.log(`Rate limited. Retry after ${error.retryAfter}s`); } else if (error instanceof QuotaExceededError) { console.log("Monthly quota exceeded"); } else { throw error; }}All error classes extend APIError, which extends BoroughError:
| Error Class | Error Code | When |
|---|---|---|
AuthenticationError | MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY | Bad or missing API key |
RateLimitError | RATE_LIMIT_EXCEEDED | Too many requests per minute |
QuotaExceededError | QUOTA_EXCEEDED | Monthly request quota exceeded |
NotFoundError | NOT_FOUND | Resource doesn’t exist |
ValidationError | INVALID_PARAMS | Bad request parameters |
TierRestrictedError | TIER_RESTRICTED | Endpoint requires higher tier |
UpstreamError | UPSTREAM_ERROR | Data source temporarily unavailable |
ConnectionError | — | Network failure |
Retries
Section titled “Retries”The SDK automatically retries on 429 (rate limit) and 5xx (server error) responses with exponential backoff. Default: 2 retries, starting at 500ms. The Retry-After header is respected when present.
// Disable retriesconst borough = new BoroughClient({ apiKey: "...", maxRetries: 0 });TypeScript
Section titled “TypeScript”The SDK is fully typed. All request parameters and response types are exported:
import type { ListingSummary, ListingDetail, BuildingDetail, BuildingScores, SearchParams, SaleSearchParams,} from "@borough/sdk";Next steps
Section titled “Next steps”- Auto-pagination — Iterate through all pages automatically
- Webhook verification — Verify webhook signatures in Express or Next.js