快速入门
使用 TypeScript 连接 Listings API、列出您的地点、创建地点并回复评价。
1. 设置您的 API 密钥
在 Listings API 开发者控制台中,通过 API 密钥 → 新建密钥获取您的密钥。
export LISTINGSAPI_KEY="your-api-key"new ListingsAPI() 会自动从环境中读取 LISTINGSAPI_KEY,您也可以显式传入 apiKey。
2. 列出您的地点
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); const result = await client.fetchAllLocations({ first: 5 });if (!Array.isArray(result)) {for (const location of result.locations) { console.log(location.name, '--', location.city, location.stateIso);}console.log('\nhasNextPage:', result.pageInfo.hasNextPage);}npx tsx quickstart.ts预期输出:
Acme Dental Midtown -- New York NYAcme Dental Brooklyn -- Brooklyn NYAcme Dental Jersey City -- Jersey City NJ hasNextPage: falsefetchAllLocations 默认返回包含 locations 和 pageInfo 的对象。传入 fetchAll: true 后,SDK 会自动按游标获取各页,并改为返回扁平的 Location[]。
const all = await client.fetchAllLocations({ fetchAll: true, pageSize: 100 });if (Array.isArray(all)) {console.log('Total: ' + all.length + ' locations');}3. 创建地点
API 要求提供 name、city、countryIso、subCategoryId,以及至少包含 200 个字符的 description。从 client.fetchSubcategories() 获取有效的 subCategoryId 值,并使用每个条目的 databaseId。
const created = await client.createLocation({name: 'Acme Dental',storeId: 'ACME-NYC-001',street: '123 Jump Street',city: 'New York',stateIso: 'NY',postalCode: '10013',countryIso: 'US',phone: '6443859313',subCategoryId: 1432,description: 'Acme Dental is a family-owned dental practice serving downtown New York since 2009. ' + 'Our team provides preventive checkups, cosmetic dentistry, orthodontics, and emergency care, ' + 'with same-day appointments, transparent pricing, and a patient-first approach on every visit.',});console.log(created);如果载荷无效,即使 API 返回 HTTP 200,SDK 也会抛出包含平台错误条目的 ValidationError。没有可供检查的 success 标志。
4. 回复评价
获取某个地点的评价,然后通过互动 ID 回复。所有接受地点 ID 的地方都支持数字形式的地点 ID:SDK 会自动对其进行 base64 编码。
const reviews = await client.fetchInteractions(16808, {startDate: '2026-01-01',endDate: '2026-06-30',first: 10,}); if (!Array.isArray(reviews)) {const unanswered = reviews.interactions.find( (review) => (review.responses ?? []).length === 0,);if (unanswered) { console.log(unanswered.rating, unanswered.content?.slice(0, 80)); await client.respondToReview( unanswered.id, 'Thank you for the kind words! We look forward to seeing you at your next visit.', );}}5. 处理错误
import { ListingsAPI, APIError, AuthenticationError } from 'listingsapi-js'; const client = new ListingsAPI({ apiKey: 'bad-key' }); try {await client.fetchAllLocations();} catch (error) {if (error instanceof AuthenticationError) { console.log('Invalid API key. Check LISTINGSAPI_KEY.');} else if (error instanceof APIError) { console.log('Status:', error.statusCode); // can be 200 for payload-level errors console.log('Code:', error.code); // first platform code, e.g. 'SY10005' console.log('Errors:', error.errors); // [{ code, message, context }, ...]}}对于非 2xx 响应、平台随 HTTP 200 返回的错误载荷,以及报告 success: false 的写入操作,SDK 都会抛出具有特定类型的错误。SDK 还会自动重试返回 429 和 5xx 响应的请求。有关重试模式和状态码的说明,请参阅错误处理。