{"openapi":"3.1.0","info":{"title":"Panda IDX API","version":"1.0.0","summary":"MLS listings, CRM contacts, and website analytics for Panda IDX.","description":"Panda IDX REST API for real estate listings (RESO fields), CRM contacts, and website analytics.\n\n## Versioning\nPanda IDX versions the REST API in the URL path (/v1/). Breaking changes ship as a new path (/v2/) and never silently replace /v1/.\n\nWhen an operation is deprecated, responses include:\n- Deprecation: true\n- Sunset: an HTTP-date (RFC 8594) for the earliest removal day\n- Link: <https://www.pandaidx.com/docs/api>; rel=\"deprecation\"\n\n/v1/ remains supported for at least 12 months after a Sunset date is advertised. Non-breaking additive fields may appear on /v1/ without a version bump.\n\nClients may also send Panda-Api-Version: 1. The header is optional; the path version wins if both are present.\n\n## Errors\nTyped error object used by the Panda IDX REST API. Every 4xx and 5xx response includes a machine-readable code and a human-readable message. Clients should branch on error.code, not on the HTTP reason phrase.\n\n## Rate limits\nStandard: 60 requests/minute. Premium: 300 requests/minute.\nEvery response includes RateLimit, RateLimit-Policy, and X-RateLimit-* headers. 429 responses also include Retry-After.\n\n## Sandbox\nPublic mock data (no auth) is served at https://www.pandaidx.com/api/v1. Production data requires OAuth or a personal API key.\n\n## MCP\nPublic docs MCP: https://www.pandaidx.com/mcp. Authenticated product MCP: https://api.pandaidx.com/mcp.","contact":{"name":"Panda IDX Developer Support","email":"ivan@pandaidx.com","url":"https://www.pandaidx.com/developers"},"license":{"name":"Proprietary","url":"https://www.pandaidx.com/terms-and-conditions"}},"servers":[{"url":"https://api.pandaidx.com","description":"Production Panda IDX API. Requires OAuth 2.0 or a personal API key."},{"url":"https://www.pandaidx.com/api","description":"Public sandbox with mock RESO listings. No authentication required."},{"url":"https://login.pandaidx.com","description":"OAuth authorization and token endpoints."}],"tags":[{"name":"Authentication","description":"OAuth 2.0 authorize and token exchange."},{"name":"Listings","description":"MLS listing search, details, and change feed. Scope: listings."},{"name":"User","description":"Current user and CRM contacts. Scope: contacts (except /v1/me)."},{"name":"Analytics","description":"Website analytics. Scope: analytics."}],"paths":{"/authorize":{"get":{"operationId":"authorize","summary":"Authorize User","description":"Redirect the user to this URL in their browser to start the OAuth 2.0 flow. The user logs in, sees a consent screen, and authorizes your app. Panda IDX then redirects back to your redirect_uri with a one-time authorization code. No access token or client_secret needed — this is a browser redirect, not a server call. No authentication required. This is a browser redirect URL..","tags":["Authentication"],"security":[],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"client_id","in":"query","required":true,"description":"From Partner Account → Manage Apps → View Credentials","schema":{"type":"string","description":"From Partner Account → Manage Apps → View Credentials"}},{"name":"redirect_uri","in":"query","required":true,"description":"Must match a URI registered in your OAuth App settings","schema":{"type":"string","description":"Must match a URI registered in your OAuth App settings"}},{"name":"scope","in":"query","required":true,"description":"Comma-separated: listings, contacts, analytics","schema":{"type":"string","description":"Comma-separated: listings, contacts, analytics"}},{"name":"state","in":"query","required":false,"description":"Opaque value for CSRF protection (returned unchanged in callback)","schema":{"type":"string","description":"Opaque value for CSRF protection (returned unchanged in callback)"}}],"responses":{"200":{"description":"Successful Authorize User response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Authorize User response"}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/api/oauth/token":{"post":{"operationId":"tokenExchange","summary":"Exchange Code for Tokens","description":"Server-to-server call. Exchange the authorization code for an access_token. Use the access_token as a Bearer token in the Authorization header when calling API endpoints. Uses client_id + client_secret in the request body (not headers)..","tags":["Authentication"],"security":[],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"grant_type","in":"query","required":true,"description":"Must be 'authorization_code'","schema":{"type":"string","description":"Must be 'authorization_code'","default":"authorization_code"}},{"name":"code","in":"query","required":true,"description":"The authorization code from the callback redirect","schema":{"type":"string","description":"The authorization code from the callback redirect"}},{"name":"client_id","in":"query","required":true,"description":"From Partner Account → Manage Apps → View Credentials","schema":{"type":"string","description":"From Partner Account → Manage Apps → View Credentials"}},{"name":"client_secret","in":"query","required":true,"description":"From Partner Account → Manage Apps → View Credentials","schema":{"type":"string","description":"From Partner Account → Manage Apps → View Credentials"}},{"name":"redirect_uri","in":"query","required":false,"description":"Must match the URI used in the authorize step","schema":{"type":"string","description":"Must match the URI used in the authorize step"}}],"responses":{"200":{"description":"Successful Exchange Code for Tokens response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Exchange Code for Tokens response"}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/listings":{"get":{"operationId":"searchListings","summary":"Search Listings","description":"Search active MLS listings by location, price, beds, baths, property type, and keywords with pagination. Requires an OAuth access token. Requires OAuth access token (scope: listings).","tags":["Listings"],"security":[{"oauth2":["listings"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"PropertyType","in":"query","required":true,"description":"Sale: Residential, Residential Income, Land, Commercial Sale, Business Opportunity. Rent: Residential Lease, Commercial Lease.","schema":{"type":"string","enum":["Residential","Residential Income","Land","Land/Boat Docks","Commercial Sale","Business Opportunity","Residential Lease","Commercial Lease"],"description":"Sale: Residential, Residential Income, Land, Commercial Sale, Business Opportunity. Rent: Residential Lease, Commercial Lease.","default":"Residential"}},{"name":"Subtypes","in":"query","required":false,"description":"Comma-separated. Residential: Single Family Residence, Condominium, Townhouse, Villa, Condo - Hotel, 1/2 Duplex, Mobile Home. Residential Lease: Single Family Residence, Condominium, Townhouse, Villa, Apartment, Efficiency.","schema":{"type":"string","description":"Comma-separated. Residential: Single Family Residence, Condominium, Townhouse, Villa, Condo - Hotel, 1/2 Duplex, Mobile Home. Residential Lease: Single Family Residence, Condominium, Townhouse, Villa, Apartment, Efficiency."}},{"name":"Status","in":"query","required":true,"description":"Active, Pending, Closed (= Sold/Rented), Active Under Contract","schema":{"type":"string","enum":["Active","Pending","Closed","Active Under Contract"],"description":"Active, Pending, Closed (= Sold/Rented), Active Under Contract","default":"Active"}},{"name":"City","in":"query","required":false,"description":"Filter by city name","schema":{"type":"string","description":"Filter by city name"}},{"name":"PostalCode","in":"query","required":false,"description":"Filter by postal code","schema":{"type":"string","description":"Filter by postal code"}},{"name":"StreetNumber","in":"query","required":false,"description":"Street number for address search","schema":{"type":"string","description":"Street number for address search"}},{"name":"StreetName","in":"query","required":false,"description":"Street name for address search","schema":{"type":"string","description":"Street name for address search"}},{"name":"UnitNumber","in":"query","required":false,"description":"Unit/apartment number","schema":{"type":"string","description":"Unit/apartment number"}},{"name":"BuildingName","in":"query","required":false,"description":"Building name (phrase match)","schema":{"type":"string","description":"Building name (phrase match)"}},{"name":"SubdivisionName","in":"query","required":false,"description":"Subdivision name","schema":{"type":"string","description":"Subdivision name"}},{"name":"MinListPrice","in":"query","required":false,"description":"Price range filter","schema":{"type":"number","description":"Price range filter"}},{"name":"MaxListPrice","in":"query","required":false,"description":"Price range filter","schema":{"type":"number","description":"Price range filter"}},{"name":"MinBedroomsTotal","in":"query","required":false,"description":"Bedrooms range (0 = Studio)","schema":{"type":"number","description":"Bedrooms range (0 = Studio)"}},{"name":"MaxBedroomsTotal","in":"query","required":false,"description":"Bedrooms range (0 = Studio)","schema":{"type":"number","description":"Bedrooms range (0 = Studio)"}},{"name":"MinBathrooms","in":"query","required":false,"description":"Bathrooms range","schema":{"type":"number","description":"Bathrooms range"}},{"name":"MaxBathrooms","in":"query","required":false,"description":"Bathrooms range","schema":{"type":"number","description":"Bathrooms range"}},{"name":"MinLivingArea","in":"query","required":false,"description":"Living area range in sqft","schema":{"type":"number","description":"Living area range in sqft"}},{"name":"MaxLivingArea","in":"query","required":false,"description":"Living area range in sqft","schema":{"type":"number","description":"Living area range in sqft"}},{"name":"MinLotSize","in":"query","required":false,"description":"Lot size range in sqft","schema":{"type":"number","description":"Lot size range in sqft"}},{"name":"MaxLotSize","in":"query","required":false,"description":"Lot size range in sqft","schema":{"type":"number","description":"Lot size range in sqft"}},{"name":"MinYearBuilt","in":"query","required":false,"description":"Year built range","schema":{"type":"number","description":"Year built range"}},{"name":"MaxYearBuilt","in":"query","required":false,"description":"Year built range","schema":{"type":"number","description":"Year built range"}},{"name":"MinAssociationFee","in":"query","required":false,"description":"Minimum monthly HOA fee","schema":{"type":"number","description":"Minimum monthly HOA fee"}},{"name":"MaxAssociationFee","in":"query","required":false,"description":"Maximum monthly HOA fee","schema":{"type":"number","description":"Maximum monthly HOA fee"}},{"name":"Pool","in":"query","required":false,"description":"Private pool","schema":{"type":"boolean","description":"Private pool"}},{"name":"Waterfront","in":"query","required":false,"description":"Waterfront property","schema":{"type":"boolean","description":"Waterfront property"}},{"name":"Penthouse","in":"query","required":false,"description":"Penthouse units","schema":{"type":"boolean","description":"Penthouse units"}},{"name":"Furnished","in":"query","required":false,"description":"Furnished property","schema":{"type":"boolean","description":"Furnished property"}},{"name":"PetsAllowed","in":"query","required":false,"description":"Pets allowed","schema":{"type":"boolean","description":"Pets allowed"}},{"name":"Gated","in":"query","required":false,"description":"Gated community","schema":{"type":"boolean","description":"Gated community"}},{"name":"TennisCourt","in":"query","required":false,"description":"Tennis court","schema":{"type":"boolean","description":"Tennis court"}},{"name":"GolfCourse","in":"query","required":false,"description":"Golf course property","schema":{"type":"boolean","description":"Golf course property"}},{"name":"BoatDock","in":"query","required":false,"description":"Boat dock access","schema":{"type":"boolean","description":"Boat dock access"}},{"name":"ShortSale","in":"query","required":false,"description":"Short sale listing","schema":{"type":"boolean","description":"Short sale listing"}},{"name":"SeasonalRentals","in":"query","required":false,"description":"Short term lease","schema":{"type":"boolean","description":"Short term lease"}},{"name":"SeniorCommunity","in":"query","required":false,"description":"55+ community: true (include only), exclude (exclude), or omit","schema":{"type":"string","description":"55+ community: true (include only), exclude (exclude), or omit"}},{"name":"Agent","in":"query","required":false,"description":"Filter by agent MLS ID","schema":{"type":"string","description":"Filter by agent MLS ID"}},{"name":"Broker","in":"query","required":false,"description":"Filter by broker/office MLS ID","schema":{"type":"string","description":"Filter by broker/office MLS ID"}},{"name":"MaxDaysOnMarket","in":"query","required":false,"description":"Maximum days on market (e.g., 7, 30, 90)","schema":{"type":"number","description":"Maximum days on market (e.g., 7, 30, 90)"}},{"name":"Since","in":"query","required":false,"description":"ISO 8601 timestamp. Only listings added after this date (e.g., 2026-03-01T00:00:00Z)","schema":{"type":"string","description":"ISO 8601 timestamp. Only listings added after this date (e.g., 2026-03-01T00:00:00Z)"}},{"name":"Sort","in":"query","required":false,"description":"Sort: -listprice, listprice, -listdate, beds, baths","schema":{"type":"string","description":"Sort: -listprice, listprice, -listdate, beds, baths","default":"-listprice"}},{"name":"Offset","in":"query","required":false,"description":"Skip results for pagination","schema":{"type":"number","description":"Skip results for pagination","default":0}},{"name":"Limit","in":"query","required":false,"description":"Results per page (max 50)","schema":{"type":"number","description":"Results per page (max 50)","default":20}}],"responses":{"200":{"description":"Successful Search Listings response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"Search Listings response","properties":{"total":{"type":"number","description":"Total matching listings count"},"offset":{"type":"number","description":"Current pagination offset"},"limit":{"type":"number","description":"Results per page"},"listings":{"type":"array","items":{"type":"object"},"description":"Array of listing objects"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/listings/{ListingId}":{"get":{"operationId":"getListing","summary":"Get Listing Details","description":"Full listing details — description, all photos, and extended fields for a single MLS number. Requires an OAuth access token. Requires OAuth access token (scope: listings).","tags":["Listings"],"security":[{"oauth2":["listings"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"ListingId","in":"path","required":true,"description":"MLS listing number (URL path parameter)","schema":{"type":"string","description":"MLS listing number (URL path parameter)"}}],"responses":{"200":{"description":"Successful Get Listing Details response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"Get Listing Details response","properties":{"ListingId":{"type":"string","description":"MLS listing number"},"ListPrice":{"type":"number","description":"Current listing price in USD"},"PreviousListPrice":{"type":"number","description":"Previous listing price before last price change"},"ClosePrice":{"type":"number","description":"Final sale/close price (null if not sold)"},"BedroomsTotal":{"type":"number","description":"Total number of bedrooms"},"BathroomsTotalInteger":{"type":"number","description":"Total number of bathrooms"},"LivingArea":{"type":"number","description":"Living area in square feet"},"LotSizeSquareFeet":{"type":"number","description":"Lot size in square feet"},"YearBuilt":{"type":"number","description":"Year the property was built"},"YearBuiltDetails":{"type":"string","description":"New Construction or Resale"},"DaysOnMarket":{"type":"number","description":"Number of days the listing has been on market"},"City":{"type":"string","description":"City name"},"StateOrProvince":{"type":"string","description":"State abbreviation (e.g., FL)"},"PostalCode":{"type":"string","description":"ZIP/postal code"},"StreetNumber":{"type":"string","description":"Street number"},"StreetDirPrefix":{"type":"string","description":"Street direction prefix (e.g., NW, SE)"},"StreetName":{"type":"string","description":"Street name"},"UnitNumber":{"type":"string","description":"Unit or apartment number"},"UnparsedAddress":{"type":"string","description":"Full address as a single string"},"StandardStatus":{"type":"string","description":"Listing status: Active, Pending, Closed"},"PropertyType":{"type":"string","description":"Property type (Residential, Commercial Sale, etc.)"},"PropertySubType":{"type":"string","description":"Property subtype (Condominium, Townhouse, etc.)"},"SubdivisionName":{"type":"string","description":"Subdivision or community name"},"BuildingName":{"type":"string","description":"Building name (for condos)"},"CountyOrParish":{"type":"string","description":"County name"},"PublicRemarks":{"type":"string","description":"Public listing description/remarks"},"ListOfficeName":{"type":"string","description":"Listing office/brokerage name"},"ListingTerms":{"type":"string","description":"Accepted financing terms (Cash, Conventional, FHA, etc.)"},"Furnished":{"type":"string","description":"Furnished status (Furnished, Unfurnished, null)"},"WaterfrontYN":{"type":"boolean","description":"Whether the property is on the waterfront"},"WaterfrontFeatures":{"type":"array","items":{"type":"object"},"description":"Waterfront features (Ocean Front, Intracoastal, etc.)"},"PoolPrivateYN":{"type":"boolean","description":"Whether the property has a private pool"},"PoolFeatures":{"type":"array","items":{"type":"object"},"description":"Pool features (Association, Heated, etc.)"},"View":{"type":"string","description":"View description (Bay, Ocean, Garden, etc.)"},"SeniorCommunityYN":{"type":"boolean","description":"Whether it is a 55+ senior community"},"PetsAllowed":{"type":"string","description":"Pet policy (Yes, Breed Restrictions, No, etc.)"},"AssociationFee":{"type":"number","description":"Monthly HOA/association fee in USD"},"TaxAnnualAmount":{"type":"number","description":"Annual property tax amount"},"TaxYear":{"type":"number","description":"Tax year for TaxAnnualAmount"},"GarageSpaces":{"type":"number","description":"Number of garage spaces"},"CoveredSpaces":{"type":"number","description":"Number of covered parking spaces"},"ParkingFeatures":{"type":"string","description":"Parking features (Assigned, Valet, Driveway, etc.)"},"Stories":{"type":"number","description":"Number of stories in the property"},"ConstructionMaterials":{"type":"string","description":"Construction materials (Concrete, Block, Wood, etc.)"},"ArchitecturalStyle":{"type":"string","description":"Architectural style (High Rise, Detached, etc.)"},"Roof":{"type":"string","description":"Roof type (Barrel Roof, Shingle, Flat, etc.)"},"Cooling":{"type":"string","description":"Cooling system (Central Air, Ceiling Fan(s), etc.)"},"Heating":{"type":"string","description":"Heating system (Central, Electric, etc.)"},"Flooring":{"type":"string","description":"Flooring type (Tile, Hardwood, Laminate, etc.)"},"Appliances":{"type":"string","description":"Included appliances (Dishwasher, Refrigerator, etc.)"},"InteriorFeatures":{"type":"string","description":"Interior features (Walk-In Closet(s), Built-in Features, etc.)"},"ExteriorFeatures":{"type":"string","description":"Exterior features (Balcony, Pool, Patio, etc.)"},"CommunityFeatures":{"type":"string","description":"Community amenities (Pool, Fitness Center, Gated, etc.)"},"LaundryFeatures":{"type":"string","description":"Laundry features (In Unit, Common Area, etc.)"},"WindowFeatures":{"type":"string","description":"Window features (Impact Glass, Blinds, etc.)"},"Sewer":{"type":"string","description":"Sewer type (Public Sewer, Septic, etc.)"},"WaterSource":{"type":"string","description":"Water source (Municipal Water, Well, etc.)"},"LeaseTerm":{"type":"string","description":"Lease term (for rentals)"},"LeaseAmountFrequency":{"type":"string","description":"Lease payment frequency (Monthly, Annually, etc.)"},"SpecialListingConditions":{"type":"string","description":"Special conditions (Short Sale, REO, etc.)"},"VirtualTourURLUnbranded":{"type":"string","description":"Virtual tour URL (unbranded)"},"DirectionFaces":{"type":"string","description":"Direction the property faces (North, East, etc.)"},"LotFeatures":{"type":"string","description":"Lot features (Corner Lot, Cul-De-Sac, etc.)"},"Levels":{"type":"string","description":"Number of levels (One, Two, Three Or More)"},"OriginatingSystemKey":{"type":"string","description":"MLS data source identifier"},"OriginatingSystemName":{"type":"string","description":"MLS data source name"},"OriginalEntryTimestamp":{"type":"string","description":"ISO 8601 date when the listing was first entered"},"ModificationTimestamp":{"type":"string","description":"ISO 8601 date of last modification"},"MajorChangeTimestamp":{"type":"string","description":"ISO 8601 date of last major change (status/price)"},"CloseDate":{"type":"string","description":"Close/sale date (null if not sold)"},"Media":{"type":"array","items":{"type":"object"},"description":"Photos array with Order, MediaURL, and ShortDescription"},"coordinates":{"type":"object","additionalProperties":true,"description":"Property coordinates: { lng, lat }"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/listings/changes":{"get":{"operationId":"listingChanges","summary":"Listings Changes","description":"Track changes on specific listings since a given date. Detects price drops (ListPrice vs PreviousListPrice) and status changes (Active → Closed/Sold). Useful for building alerts like 'this listing dropped $50K' or 'your saved property just sold'. Requires OAuth access token (scope: listings).","tags":["Listings"],"security":[{"oauth2":["listings"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"Since","in":"query","required":true,"description":"ISO 8601 timestamp. Returns listings modified after this date (e.g., 2026-03-15T00:00:00Z)","schema":{"type":"string","description":"ISO 8601 timestamp. Returns listings modified after this date (e.g., 2026-03-15T00:00:00Z)"}},{"name":"ListingIds","in":"query","required":true,"description":"Comma-separated MLS numbers to track (e.g., A11855701,A11923847)","schema":{"type":"string","description":"Comma-separated MLS numbers to track (e.g., A11855701,A11923847)"}},{"name":"ChangeType","in":"query","required":false,"description":"Filter by change type","schema":{"type":"string","enum":["price_change","status_change"],"description":"Filter by change type"}},{"name":"Offset","in":"query","required":false,"description":"Skip results for pagination","schema":{"type":"number","description":"Skip results for pagination","default":0}},{"name":"Limit","in":"query","required":false,"description":"Results per page (max 50)","schema":{"type":"number","description":"Results per page (max 50)","default":20}}],"responses":{"200":{"description":"Successful Listings Changes response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Listings Changes response"}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/analytics":{"get":{"operationId":"analytics","summary":"Website Analytics","description":"Aggregated website analytics — visitors, page views, conversions, traffic sources, and breakdowns by page, referrer, country, browser, OS, and device. Same metrics shown in the Panda IDX dashboard. Requires OAuth access token (scope: analytics).","tags":["Analytics"],"security":[{"oauth2":["analytics"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"Period","in":"query","required":false,"description":"Time period for analytics data","schema":{"type":"string","enum":["24h","7d","30d","90d","1y"],"description":"Time period for analytics data","default":"30d"}},{"name":"Page","in":"query","required":false,"description":"Filter by page path (e.g., /search, /listing/A11855701)","schema":{"type":"string","description":"Filter by page path (e.g., /search, /listing/A11855701)"}},{"name":"Referrer","in":"query","required":false,"description":"Filter by referrer (e.g., google.com, Direct)","schema":{"type":"string","description":"Filter by referrer (e.g., google.com, Direct)"}},{"name":"Browser","in":"query","required":false,"description":"Filter by browser name (e.g., Chrome, Safari)","schema":{"type":"string","description":"Filter by browser name (e.g., Chrome, Safari)"}},{"name":"Country","in":"query","required":false,"description":"Filter by country name (e.g., United States)","schema":{"type":"string","description":"Filter by country name (e.g., United States)"}},{"name":"OS","in":"query","required":false,"description":"Filter by operating system (e.g., Windows, iOS)","schema":{"type":"string","description":"Filter by operating system (e.g., Windows, iOS)"}},{"name":"Device","in":"query","required":false,"description":"Filter by device type: desktop, mobile, tablet","schema":{"type":"string","description":"Filter by device type: desktop, mobile, tablet"}},{"name":"VisitorId","in":"query","required":false,"description":"Filter by specific visitor ID","schema":{"type":"string","description":"Filter by specific visitor ID"}},{"name":"UtmSource","in":"query","required":false,"description":"Filter by UTM source (e.g., google, facebook)","schema":{"type":"string","description":"Filter by UTM source (e.g., google, facebook)"}},{"name":"UtmMedium","in":"query","required":false,"description":"Filter by UTM medium (e.g., cpc, email, social)","schema":{"type":"string","description":"Filter by UTM medium (e.g., cpc, email, social)"}},{"name":"UtmCampaign","in":"query","required":false,"description":"Filter by UTM campaign name","schema":{"type":"string","description":"Filter by UTM campaign name"}}],"responses":{"200":{"description":"Successful Website Analytics response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"Website Analytics response","properties":{"period":{"type":"string","description":"The time period used for the query (e.g., 7d, 30d)"},"overview":{"type":"object","additionalProperties":true,"description":"Summary metrics for the period"},"timelines":{"type":"object","additionalProperties":true,"description":"Per-day time series for each metric"},"pages":{"type":"array","items":{"type":"object"},"description":"Breakdown by page path"},"referrers":{"type":"array","items":{"type":"object"},"description":"Breakdown by traffic source"},"countries":{"type":"array","items":{"type":"object"},"description":"Breakdown by visitor country"},"browsers":{"type":"array","items":{"type":"object"},"description":"Breakdown by browser"},"os":{"type":"array","items":{"type":"object"},"description":"Breakdown by operating system"},"devices":{"type":"array","items":{"type":"object"},"description":"Breakdown by device type"},"utm":{"type":"object","additionalProperties":true,"description":"UTM campaign attribution breakdowns"},"events":{"type":"array","items":{"type":"object"},"description":"Breakdown by event type (excludes page_view)"},"conversions":{"type":"array","items":{"type":"object"},"description":"Recent conversions (form submissions + signups), max 20"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/me":{"get":{"operationId":"getMe","summary":"Get Current User","description":"Verify an access token and get the authenticated user's info, application details, subscription plan, and granted scopes. Requires an OAuth access token. Requires OAuth access token.","tags":["User"],"security":[{"oauth2":["listings","contacts","analytics"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}}],"responses":{"200":{"description":"Successful Get Current User response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"Get Current User response","properties":{"user":{"type":"object","additionalProperties":true,"description":"Authenticated user info"},"application":{"type":"object","additionalProperties":true,"description":"Application (website) the token belongs to"},"scope":{"type":"array","items":{"type":"object"},"description":"Granted OAuth scopes for this token"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/contacts":{"get":{"operationId":"listContacts","summary":"List Contacts","description":"List the authenticated user's CRM contacts with search, filtering, and pagination. Requires an OAuth access token with 'contacts' scope. Requires OAuth access token (scope: contacts).","tags":["User"],"security":[{"oauth2":["contacts"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"query","in":"query","required":false,"description":"Search by name, email, or phone","schema":{"type":"string","description":"Search by name, email, or phone"}},{"name":"page","in":"query","required":false,"description":"Page number (default: 1)","schema":{"type":"number","description":"Page number (default: 1)"}},{"name":"limit","in":"query","required":false,"description":"Results per page (max 50, default: 25)","schema":{"type":"number","description":"Results per page (max 50, default: 25)"}},{"name":"since","in":"query","required":false,"description":"Contacts created/updated after this time","schema":{"type":"string","format":"date-time","description":"Contacts created/updated after this time"}},{"name":"stage","in":"query","required":false,"description":"Filter by pipeline stage","schema":{"type":"string","description":"Filter by pipeline stage"}},{"name":"tag","in":"query","required":false,"description":"Filter by tag","schema":{"type":"string","description":"Filter by tag"}},{"name":"Sort","in":"query","required":false,"description":"Sort field","schema":{"type":"string","enum":["createdAt","lastActivityDate","name"],"description":"Sort field","default":"createdAt"}},{"name":"Order","in":"query","required":false,"description":"Sort order","schema":{"type":"string","enum":["desc","asc"],"description":"Sort order","default":"desc"}}],"responses":{"200":{"description":"Successful List Contacts response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"List Contacts response","properties":{"total":{"type":"number","description":"Total matching contacts"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Results per page"},"contacts":{"type":"array","items":{"type":"object"},"description":"Array of contact objects"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/contacts/{contactId}":{"get":{"operationId":"getContact","summary":"Get Contact Details","description":"Contact details with address, links, and custom fields. Use the Scope parameter to include extra data like notes, collections, and saved searches (runs additional queries in parallel). Requires OAuth access token (scope: contacts).","tags":["User"],"security":[{"oauth2":["contacts"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"contactId","in":"path","required":true,"description":"Contact ID (URL path parameter)","schema":{"type":"string","description":"Contact ID (URL path parameter)"}},{"name":"scope","in":"query","required":false,"description":"Comma-separated extra data to include. Default: none (lightweight response)","schema":{"type":"string","enum":["notes","collections","savedSearches"],"description":"Comma-separated extra data to include. Default: none (lightweight response)"}}],"responses":{"200":{"description":"Successful Get Contact Details response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"Get Contact Details response","properties":{"id":{"type":"string","description":"Contact ID"},"name":{"type":"string","description":"Contact full name"},"email":{"type":"string","description":"Contact email"},"phones":{"type":"array","items":{"type":"object"},"description":"Phone numbers"},"stage":{"type":"string","description":"Pipeline stage"},"source":{"type":"string","description":"Lead source"},"tags":{"type":"array","items":{"type":"object"},"description":"Contact tags"},"type":{"type":"string","description":"Contact type (buyer, seller, etc.)"},"price":{"type":"number","description":"Budget or target price"},"birthday":{"type":"string","description":"ISO 8601 birth date"},"isRegistered":{"type":"boolean","description":"Whether the contact has a registered account"},"address":{"type":"object","additionalProperties":true,"description":"Structured address: formatted, locality, stateShort, postalCode, etc."},"streetAddress":{"type":"string","description":"Street address string"},"links":{"type":"object","additionalProperties":true,"description":"Social links: website, linkedin, facebook, instagram, twitter, youtube"},"spokenLanguages":{"type":"array","items":{"type":"object"},"description":"Languages the contact speaks"},"additional":{"type":"array","items":{"type":"object"},"description":"Custom fields: [{ name, value }]"},"notes":{"type":"array","items":{"type":"object"},"description":"Contact notes: [{ id, content, pinned, createdAt }]"},"savedSearches":{"type":"array","items":{"type":"object"},"description":"Saved property searches: [{ id, name }]"},"totalNotes":{"type":"number","description":"Total notes count"},"totalDocuments":{"type":"number","description":"Total documents count"},"totalSavedSearches":{"type":"number","description":"Total saved searches count"},"createdAt":{"type":"string","description":"ISO 8601 creation date"},"lastActivityDate":{"type":"string","description":"ISO 8601 date of last activity"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}},"/v1/contacts/{contactId}/activity":{"get":{"operationId":"contactActivity","summary":"Get Contact Activity","description":"Paginated activity feed for a specific contact — notes created, messages sent, property likes, saved searches, and more. Separate endpoint for performance since activity data can be large. Requires OAuth access token (scope: contacts).","tags":["User"],"security":[{"oauth2":["contacts"]},{"apiKey":[]}],"parameters":[{"name":"Panda-Api-Version","in":"header","required":false,"description":"Optional explicit API version. Path version (/v1/) wins if both are present.","schema":{"type":"string","enum":["1"],"default":"1"}},{"name":"contactId","in":"path","required":true,"description":"Contact ID (URL path parameter)","schema":{"type":"string","description":"Contact ID (URL path parameter)"}},{"name":"page","in":"query","required":false,"description":"Page number (default: 1)","schema":{"type":"number","description":"Page number (default: 1)"}},{"name":"limit","in":"query","required":false,"description":"Results per page (max 50, default: 20)","schema":{"type":"number","description":"Results per page (max 50, default: 20)"}},{"name":"types","in":"query","required":false,"description":"Comma-separated activity types to filter (e.g., NOTE_CREATED,MESSAGE_SENT)","schema":{"type":"string","description":"Comma-separated activity types to filter (e.g., NOTE_CREATED,MESSAGE_SENT)"}},{"name":"since","in":"query","required":false,"description":"ISO 8601 timestamp. Only activities after this date","schema":{"type":"string","description":"ISO 8601 timestamp. Only activities after this date"}}],"responses":{"200":{"description":"Successful Get Contact Activity response","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"type":"object","description":"Get Contact Activity response","properties":{"total":{"type":"number","description":"Total matching activities"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Results per page"},"activity":{"type":"array","items":{"type":"object"},"description":"Array of activity objects"}}}}}},"400":{"description":"Invalid or missing parameters","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"bad_request","message":"Invalid or missing parameters","status":400}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#bad_request","title":"bad request","status":400,"detail":"Invalid or missing parameters","code":"bad_request"}}}},"401":{"description":"Invalid or expired access token","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"invalid_token","message":"Invalid or expired access token","status":401}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#invalid_token","title":"invalid token","status":401,"detail":"Invalid or expired access token","code":"invalid_token"}}}},"403":{"description":"Token is missing the required OAuth scope","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"insufficient_scope","message":"Token is missing the required OAuth scope","status":403}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#insufficient_scope","title":"insufficient scope","status":403,"detail":"Token is missing the required OAuth scope","code":"insufficient_scope"}}}},"404":{"description":"Resource not found","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Resource not found","status":404}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#not_found","title":"not found","status":404,"detail":"Resource not found","code":"not_found"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds to wait before retrying a 429.","schema":{"type":"integer","example":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limit_exceeded","message":"Rate limit exceeded","status":429}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#rate_limit_exceeded","title":"rate limit exceeded","status":429,"detail":"Rate limit exceeded","code":"rate_limit_exceeded"}}}},"500":{"description":"Internal server error","headers":{"RateLimit":{"description":"RFC rate-limit header: limit, remaining, reset.","schema":{"type":"string","example":"limit=60, remaining=59, reset=60"}},"RateLimit-Policy":{"description":"Quota policy window.","schema":{"type":"string","example":"60;w=60"}},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59}},"X-RateLimit-Reset":{"schema":{"type":"integer","example":60}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"server_error","message":"Internal server error","status":500}}},"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://www.pandaidx.com/docs/api#server_error","title":"server error","status":500,"detail":"Internal server error","code":"server_error"}}}}}}}},"components":{"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth 2.0 authorization code. Request only the scopes your integration needs. Tokens are Bearer tokens.","flows":{"authorizationCode":{"authorizationUrl":"https://login.pandaidx.com/authorize","tokenUrl":"https://login.pandaidx.com/api/oauth/token","scopes":{"listings":"Read MLS listing search results, listing details, and listing change feeds. Does not grant write access.","contacts":"Read CRM contacts, contact details, and contact activity. Does not grant permission to send email or mutate records unless a future write scope is granted.","analytics":"Read website analytics (visitors, page views, conversions, traffic sources). Does not include listing or contact PII beyond conversion IDs."}}}},"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"API key","description":"Personal API key for Signature and Enterprise subscribers. Create keys at https://app.pandaidx.com/api-keys and optionally restrict the key to a listings, contacts, or analytics role."}},"schemas":{"ApiError":{"type":"object","required":["error"],"description":"Typed error object used by the Panda IDX REST API. Every 4xx and 5xx response includes a machine-readable code and a human-readable message. Clients should branch on error.code, not on the HTTP reason phrase.","properties":{"error":{"type":"object","required":["code","message","status"],"properties":{"code":{"type":"string","description":"Machine-readable error code","enum":["bad_request","missing_auth_header","invalid_token","insufficient_scope","subscription_inactive","not_found","rate_limit_exceeded","server_error"]},"message":{"type":"string","description":"Human-readable explanation"},"status":{"type":"integer","description":"HTTP status repeated in the body"}}}}},"Problem":{"type":"object","required":["type","title","status","detail","code"],"description":"RFC 9457 application/problem+json representation of the same error.","properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"code":{"type":"string"}}}}},"externalDocs":{"description":"Panda IDX developer resources","url":"https://www.pandaidx.com/developers"}}