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 + OAuthClaude, 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 keyA 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 do | API key area | MCP scope |
|---|---|---|
| Create, update and find CRM contacts, add and remove tags | contacts | contacts |
| Search MLS listings, with a link to each one on your website | listings | listings |
| Save searches for a contact, with email alerts | saved_searches | saved_searches |
| Listing details and price changes, off-market listings | MCP only | listings |
| Calendar events, property collections | MCP only | calendar, collections |
| Email a contact a listing, collection or saved search | MCP only | email |
| Website analytics | MCP only | analytics |
| Build and publish your AI Builder website | MCP only | builder |
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.
PANDA_API_KEY, never in a web page.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.
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.
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"
{"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"}]}
3. Save the search
Save a Search for a Contact keeps the search on the lead in your CRM and returns url, the search on your website. With emailUpdates the lead also gets new matches by email.
curl --request POST \--url "https://api.pandaidx.com/v1/crm/contacts/CONTACT_ID/saved-searches" \--header "Authorization: Bearer $PANDA_API_KEY" \--header "Content-Type: application/json" \--data '{"title": "Miami Beach rentals","emailUpdates": "weekly","filters": {"propertyType": "Residential Lease","city": "Miami Beach","maxPrice": 7000,"minBeds": 3,"minBaths": 2,"petsAllowed": true,"sort": "price"}}'
4. Send the links
Build the message in your bot from the two answers and send it with your WhatsApp provider.
# Compose the WhatsApp message in your bot from the two answers above.
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.
[{"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
429withRetry-After. - Up to 50 listings per search page (
limit), paged withoffset. - Send an
Idempotency-Keyon 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
| Status | error.code | What to do |
|---|---|---|
| 401 | unauthorized | The key is missing, wrong, revoked or expired. Create a new one. |
| 403 | subscription_inactive | The account has no active subscription. Renew it in Workspace settings › Subscriptions. |
| 403 | insufficient_scope | The key lacks the area named in error.details.required. Create a key with it. |
| 404 | not_found | No such contact (or saved search) in this account. |
| 422 | validation_failed | A field or parameter is wrong or unknown. error.details names it. |
| 429 | rate_limited | Wait for the seconds in Retry-After, then retry. |