Panda IDX API: Getting Started

Panda IDX gives your own website the real data of a Panda IDX account: profile and brand, team, MLS listings and search, areas, condos, new developments, blog, forms and visitor accounts. The same data is available to AI assistants through MCP servers. Machine-readable spec: /openapi.json. Developer hub: /developers.

Ways to connect

Site API

Public key

REST endpoints under /v1 for websites built with the Panda AI Builder or your own code. One public key in the key query parameter picks the account. No OAuth, no secret to protect.

MCP servers

OAuth 2.1

Let Claude, ChatGPT or Cursor search listings, work your CRM and calendar, or build and publish your website with the Builder tools. The owner approves once on a consent screen.

CRM API

Secret API key

Send leads from your own systems (lead vendors, WhatsApp bots, landing pages, Zapier, scripts) into your CRM with POST /v1/crm/contacts (an upsert, so the same person never duplicates), search MLS listings with GET /v1/listings and save searches for your leads. Create the key in the dashboard under Workspace settings › API Keys and send it as Authorization: Bearer sk_live_…. Keys are for servers only. Read the reference and API keys & scopes, or follow Connect Your Own Agent.

Base URLs

authorize, token, revoke

Public key

Every Site API request carries the site's public key as ?key=pk_…. The key selects the account, is safe to ship to the browser, and only unlocks public, read-only data (plus the visitor and form endpoints a public website needs). AI Builder sites receive it as the NEXT_PUBLIC_PANDA_PUBLIC_KEY environment variable. With a secret API key, GET /v1/me returns it as account.publicKey.

  • Prefer calling the API on the server (React Server Components, route handlers). Browsers are only allowed from the account's own domain and its configured widget origins.
  • An account without an active subscription answers 403 with code: "TENANT_INACTIVE": render an offline page. Check Site Status from your root layout.
  • Listing endpoints only return listings from the MLS feeds the account is licensed for.

First request

Read the account's profile, brand and navigation:

Request
curl --request GET \
--url "https://api.pandaidx.com/v1/site?key=YOUR_PUBLIC_KEY"

Then search listings with Search Listings.

Try it in the docs

Every endpoint page has a Try it button. Open the variables menu (the gear icon), save your key as public_key, and send real requests to production. Requests go through a Panda IDX relay, so browser CORS rules do not block you. Anything you send with a write endpoint (for example a form or a sign-up) creates real data in the account that owns the key, so use a test account.

Endpoint groups

OAuth and MCP

The MCP servers use OAuth 2.1 with PKCE and the scopes profile, listings, contacts, analytics, calendar, collections, saved_searches, email and builder. Clients register through Dynamic Client Registration or publish a Client ID Metadata Document; the user approves on the consent screen and can disconnect any time in Dashboard → Apps. OAuth tokens are accepted by the MCP servers only, not by the Site API.

Start with the MCP server guide, or read the OAuth endpoints starting at Authorize User.

Caching and limits

  • Responses are CDN cacheable. Content the owner edits (site, team, testimonials, popups) refreshes within seconds of an edit; listing data is cached for minutes. Each endpoint page shows its edge cache.
  • There is no global per-key quota on the Site API today. Specific endpoints are rate limited and answer 429 with a Retry-After header, for example AI search (12 requests per minute per IP and account) and the password reset helpers.
  • Optional text fields are null when empty and lists are [], never an empty string.
  • Paginated responses share total, page, pageSize and totalPages.

Error handling

Site API errors are { "message": string } with the HTTP status. The CRM Contacts API answers { "error": { code, message, details } }. OAuth and MCP endpoints answer the standard error and error_description fields.

400 Bad Request

The request is invalid: a parameter is malformed, a required field is missing, or an OAuth code is expired.

Site API: the message says what is wrong

{
"message": "Request failed"
}

OAuth: expired code

{
"error": "invalid_grant",
"error_description": "Authorization code is invalid or expired"
}

Versioning

The version lives in the path (/v1/). New optional fields can appear in /v1 responses at any time, so ignore fields you do not know. A breaking change ships as /v2/ and is announced before /v1 is retired.

Next Steps