Quickstart

Connect to Listings API, list your locations, create one in a single call, and respond to a review.

1. Set your API key

Get your key from API Keys → New key in the Listings API developer dashboard. The SDK reads it from the LISTINGSAPI_KEY environment variable automatically.

bash
export LISTINGSAPI_KEY="your-api-key"

2. List your locations

quickstart.py
import listingsapi client = listingsapi.ListingsAPI() page = client.locations.list(first=5)for loc in page:  print(loc.name, "--", loc.city, loc.stateIso) print(f"\nShowing {len(page)} locations, has_more={page.has_more}")
bash
python quickstart.py

Expected output:

bash
Acme Dental Downtown -- New York NYAcme Dental Midtown -- New York NYAcme Dental Brooklyn -- Brooklyn NY Showing 3 locations, has_more=False

To walk every page automatically, use client.locations.list(first=100).auto_paging_iter(); it follows cursor pages so you never manage cursors by hand.

3. Create a location in one call

locations.add() takes every mandatory field as a keyword argument and validates them client-side (name length, 200-character description minimum, category, country, city) before any network call, so a bad payload fails fast with a clear ValidationError.

Python
import listingsapi client = listingsapi.ListingsAPI() result = client.locations.add(  name="Acme Dental Uptown",  description=(      "Acme Dental Uptown is a family-owned dental practice on the Upper "      "West Side of New York offering preventive care, cosmetic dentistry, "      "orthodontics, and emergency appointments. Our board-certified team "      "combines modern equipment with a gentle, patient-first approach."  ),  sub_category_id=1432,  country_iso="US",  city="New York",  street="482 Columbus Ave",  state_iso="NY",  postal_code="10024",  phone="6443859313",) print(result.location.id)print(result.location.name)

Publishers use the description as the primary listing copy, which is why the API requires at least 200 characters. Get valid sub_category_id values from client.subcategories().

The new ID comes back as a base64 string like TG9jYXRpb246MTY4MDg=. Numeric and base64 IDs are interchangeable everywhere the SDK takes a location ID, so client.locations.retrieve(16808) and client.locations.retrieve("TG9jYXRpb246MTY4MDg=") fetch the same location.

4. Respond to a review

List reviews for a location, then reply using the review's interactionId:

Python
import listingsapi client = listingsapi.ListingsAPI() reviews = client.reviews.list(16808, first=10, rating_filters=[4, 5])for review in reviews:  print(review.rating, "-", review.get("content")) review = reviews[0]client.reviews.respond(  interaction_id=review.interactionId,  content="Thank you for the kind review! We look forward to seeing you again soon.",)

If the platform rejects the reply, the SDK raises ValidationError even when the HTTP status is 200; you never check success flags yourself.

5. Handle errors

Python
import listingsapi try:  client = listingsapi.ListingsAPI(api_key="bad-key")  client.locations.list()except listingsapi.AuthenticationError as e:  print("Invalid key:", e.code)

Invalid keys come back as HTTP 401 with the platform code SY90005; the SDK raises AuthenticationError. It also defensively handles the same error code if it arrives inside a 200 body. See Error handling for the full exception hierarchy and the error codes reference for the HTTP status matrix.

Next steps