Quickstart

Connect to listingsAPI, list your locations, create a location, and reply to a review in TypeScript.

1. Set your API key

Get your key from API Keys → New key in the listingsAPI developer dashboard.

bash
export LISTINGSAPI_KEY="your-api-key"

new ListingsAPI() reads LISTINGSAPI_KEY from the environment automatically, or pass apiKey explicitly.

2. List your locations

quickstart.ts
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);
}
bash
npx tsx quickstart.ts

Expected output:

bash
Acme Dental Midtown -- New York NY
Acme Dental Brooklyn -- Brooklyn NY
Acme Dental Jersey City -- Jersey City NJ
 
hasNextPage: false

fetchAllLocations returns an object with locations and pageInfo by default. Pass fetchAll: true and the SDK follows cursor pages automatically, returning a flat Location[] instead.

TypeScript
const all = await client.fetchAllLocations({ fetchAll: true, pageSize: 100 });
if (Array.isArray(all)) {
console.log('Total: ' + all.length + ' locations');
}

3. Create a location

The API requires name, city, countryIso, subCategoryId, and a description of at least 200 characters. Get valid subCategoryId values from client.fetchSubcategories() and use each entry's databaseId.

TypeScript
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);

If the payload is invalid, the SDK throws a ValidationError carrying the platform error entries, even when the API responds with HTTP 200. There is no success flag to check.

4. Respond to a review

Fetch reviews for a location, then reply by interaction ID. Numeric location IDs are accepted everywhere: the SDK base64-encodes them automatically.

TypeScript
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. Handle errors

TypeScript
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 }, ...]
}
}

The SDK throws typed errors for non-2xx responses, for error payloads the platform returns with HTTP 200, and for mutations reporting success: false. It also retries 429 and 5xx responses automatically. See Error handling for retry patterns and status-code guidance.

Next steps