Connect Your Own Agent

Let your own AI agent or automation work with your Panda IDX account: qualify a lead on WhatsApp, save it in your CRM, find the listings that match what it asked for and send the links back, without opening the dashboard. Everything here is included in your Panda IDX subscription.

MCP or API key?

Chat assistants

MCP + OAuth

Claude, ChatGPT, Cursor and Claude Code connect to https://api.pandaidx.com/mcp and you approve once on a consent screen. Nothing to paste. Use it when you talk to the assistant yourself. See the MCP Server guide.

Bots and automations

Secret API key

A WhatsApp bot (Kapso, Twilio, WhatsApp Cloud API), Zapier, Make, n8n or your own code runs on its own, with nobody to click a consent screen. Give it a secret API key (sk_live_…) and call the REST API below. See API Keys & Scopes.

What your plan unlocks

With an active subscription your agent can use every area below. A secret key only gets the areas you pick when you create it; an MCP connection gets the scopes you approve.

What the agent can doAPI key areaMCP scope
Create, update and find CRM contacts, add and remove tagscontactscontacts
Search MLS listings, with a link to each one on your websitelistingslistings
Save searches for a contact, with email alertssaved_searchessaved_searches
Listing details and price changes, off-market listingsMCP onlylistings
Calendar events, property collectionsMCP onlycalendar, collections
Email a contact a listing, collection or saved searchMCP onlyemail
Website analyticsMCP onlyanalytics
Build and publish your AI Builder websiteMCP onlybuilder

Your website's public data (search, listing pages, areas, condos, forms) is also available with the public key of the Site API. GET /v1/me returns it as account.publicKey.

Example: qualify WhatsApp leads and send them listings

A typical flow: a lead from a Facebook ad writes on WhatsApp, your bot asks what they need (rent or buy, area, budget, bedrooms, pets), and once the lead is qualified it calls Panda IDX four times.

1
Create a key in Workspace settings › API Keys with Contacts & leads Read & write, Listings Read and Saved searchesRead & write. Store it in your bot as PANDA_API_KEY, never in a web page.
2
Save the lead in the CRM.
3
Search the listings that match.
4
Save the search on the lead and get its link.
5
Send the listing links and the search link back on WhatsApp.

1. Save the lead

Create or Update Contact never duplicates: the same email or externalId updates the contact it already made. source shows in the CRM as the lead source. Use type, price and tags for what the lead told your bot.

Request
curl --request POST \
--url "https://api.pandaidx.com/v1/crm/contacts" \
--header "Authorization: Bearer $PANDA_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: whatsapp-17865550142" \
--data '{
"email": "paul@example.com",
"name": "Paul Olivera",
"phone": "+17865550142",
"source": "whatsapp",
"externalId": "17865550142",
"type": "renter",
"price": 7000,
"tags": ["whatsapp", "qualified", "miami-beach"]
}'

2. Search listings

Search Listings with an API Key uses the MLS feeds of your account. Rentals are propertyType=Residential Lease and their price is the monthly rent. Every listing has websiteUrl, its page on your website.

Request
curl --get "https://api.pandaidx.com/v1/listings" \
--header "Authorization: Bearer $PANDA_API_KEY" \
--data-urlencode "propertyType=Residential Lease" \
--data-urlencode "city=Miami Beach" \
--data "maxPrice=7000" \
--data "minBeds=3" \
--data "minBaths=2" \
--data "furnished=false" \
--data "petsAllowed=true" \
--data "sort=price" \
--data "limit=5"
Response 200
{
"total": 4,
"offset": 0,
"limit": 5,
"data": [
{
"ListingId": "B26059333",
"PropertyType": "Residential Lease",
"ListPrice": 5500,
"BedroomsTotal": 3,
"BathroomsTotalInteger": 2,
"City": "Miami Beach",
"photos": ["https://…/1.jpg", "https://…/2.jpg"],
"websiteUrl": "https://yourdomain.com/mls/B26059333"
}
]
}

Give the tools to an LLM

If an LLM drives your bot (an AI agent node, OpenAI or Anthropic tool calling), describe the three calls as tools and run each one as an HTTP request with the key in the Authorization header. Keep the key in your server; the model never needs to see it.

Tools
[
{
"name": "save_lead",
"description": "Create or update the lead in the Panda IDX CRM. Call it once the lead is qualified.",
"method": "POST",
"url": "https://api.pandaidx.com/v1/crm/contacts",
"input_schema": {
"type": "object",
"required": ["email"],
"properties": {
"email": { "type": "string" },
"name": { "type": "string" },
"phone": { "type": "string" },
"type": { "type": "string", "enum": ["buyer", "seller", "renter", "investor"] },
"price": { "type": "number", "description": "Budget, or monthly rent for a renter" },
"tags": { "type": "array", "items": { "type": "string" } }
}
}
},
{
"name": "search_listings",
"description": "Search MLS listings. Rentals: propertyType 'Residential Lease'. Returns listings with websiteUrl.",
"method": "GET",
"url": "https://api.pandaidx.com/v1/listings",
"input_schema": {
"type": "object",
"properties": {
"propertyType": { "type": "string", "enum": ["Residential", "Residential Lease"] },
"city": { "type": "string" },
"minPrice": { "type": "number" },
"maxPrice": { "type": "number" },
"minBeds": { "type": "number" },
"minBaths": { "type": "number" },
"furnished": { "type": "boolean" },
"petsAllowed": { "type": "boolean" },
"sort": { "type": "string", "enum": ["-price", "price", "-listed"] },
"limit": { "type": "number", "maximum": 50 }
}
}
},
{
"name": "save_search_for_lead",
"description": "Save the search on the lead and get its link on the website to send them.",
"method": "POST",
"url": "https://api.pandaidx.com/v1/crm/contacts/{contactId}/saved-searches",
"input_schema": {
"type": "object",
"required": ["contactId", "title", "filters"],
"properties": {
"contactId": { "type": "string" },
"title": { "type": "string" },
"filters": { "type": "object", "description": "Same fields as search_listings, without limit" },
"emailUpdates": { "type": "string", "enum": ["never", "daily", "weekly"] }
}
}
}
]

Limits

  • 120 requests per minute per key. Past that the API answers 429 with Retry-After.
  • Up to 50 listings per search page (limit), paged with offset.
  • Send an Idempotency-Key on Create or Update Contact so a retried webhook returns the first answer.
  • Up to 20 active keys per account. Give each bot its own key so you can revoke one alone.

Errors

Statuserror.codeWhat to do
401unauthorizedThe key is missing, wrong, revoked or expired. Create a new one.
403subscription_inactiveThe account has no active subscription. Renew it in Workspace settings › Subscriptions.
403insufficient_scopeThe key lacks the area named in error.details.required. Create a key with it.
404not_foundNo such contact (or saved search) in this account.
422validation_failedA field or parameter is wrong or unknown. error.details names it.
429rate_limitedWait for the seconds in Retry-After, then retry.

Next Steps