{
  "openapi": "3.0.0",
  "info": {
    "title": "Cloud CMA API",
    "description": "Cloud CMA allows real estate agents to easily create custom CMA, Buyer Tour, and Property Reports. In order to enable this functionality to be embedded in other web sites, especially MLS sites, we have made an API publicly available. Using simple links or AJAX techniques, you can send listings (via MLS numbers) to Cloud CMA and kick off the desired report. Users can continue on your site without interruption while reports are being generated.\n\n## How the API Works\n\nYou can send the listings your user has currently selected, in the form of their MLS numbers, to Cloud CMA and initiate report creation. You can also use AJAX techniques to:\n- Send desired MLS numbers to Cloud CMA\n- Receive immediate feedback on success or failure\n- Allow the user to continue on your site without interruption\n- Track report status and delivery via webhooks\n\n## Authentication\n\nCloud CMA is a subscription-based service and requires an ID and password to use. There are two authentication approaches:\n\n**1. Session-Based (Automatic)**\n- All uses of the API will work immediately if the user is already logged into a Cloud CMA session\n- If a current session does not exist, Cloud CMA will handle the authentication by requesting the user log in first\n- After login, Cloud CMA automatically routes them to the requested page\n- Ideal for MLS integration where users are already authenticated\n\n**2. API Key-Based**\n- Use an API key from your Cloud CMA account (Settings > API or Account Settings > Integrations)\n- Pass the api_key parameter with each request\n- Ideal for server-to-server calls and lead capture forms\n\n## Getting Trial Access\n\nDevelopers who need a trial ID and password can request one from Cloud CMA support at developers@cloudcma.com\n\n## What You Can Build\n\n**Report Creation:** Agents can create CMAs, Buyer Tours, Property Reports, and Flyers with one or more MLS listings in a single API call.\n\n**Lead Generation:** Embed quick CMA forms or property report requests on your website. Capture consumer information and automatically generate branded reports.\n\n**Automated Campaigns:** Set up Homebeat market update automations that send periodic updates (monthly, quarterly, annually) to leads showing comparable sales trends.\n\n**Flexible Delivery:** Reports can be emailed directly to consumers by Cloud CMA, or delivered via webhook to your system for custom handling.\n\n## Architecture\n\nCloud CMA performs real-time queries to the MLS RETS server at the moment users request reports. No data replication is required. This ensures:\n- Always current MLS data\n- Better security (no full MLS database stored on Cloud CMA servers)\n- Reduced server load (only querying small subsets of data needed for each report)\n\n## Extensibility\n\nMore functionality of Cloud CMA can be exposed pretty easily using standard RESTful web services. Send your suggestions to developers@cloudcma.com",
    "version": "1.0.0",
    "contact": {
      "name": "Cloud CMA Developers",
      "email": "developers@cloudcma.com"
    }
  },
  "servers": [
    {
      "url": "https://cloudcma.com",
      "description": "Production API"
    }
  ],
  "paths": {
    "/docs/mls-security": {
      "get": {
        "tags": ["Documentation"],
        "summary": "MLS Security Methods",
        "description": "Cloud CMA supports four security methods to ensure only valid, active MLS members access listing data via RETS integration.\n\n## Method 1: User RETS Credentials\nUsers provide their individual MLS RETS credentials. Cloud CMA stores credentials using RSA public key encryption and uses them to authenticate directly with the RETS server.\n- **Pro:** MLS has complete control; users can be deactivated immediately via normal MLS workflow\n- **Con:** Not all MLSs have RETS credentials set up for every member; manual setup may be required\n\n## Method 2: MLS RETS Credentials + Agent Verification\nMLS provides Cloud CMA with RETS credentials. When users query data, Cloud CMA logs in with MLS credentials, then verifies the user exists and is active by querying the Agent/User table against their credentials.\n- **Pro:** MLS has complete control; users deactivated immediately\n- **Con:** MLS must allow querying on password field or return active member status\n\n## Method 3: Single Sign-On (SSO)\nUsers cannot log in directly at cloudcma.com. Instead, they log into their MLS system first, then access Cloud CMA via SSO link. Two options available:\n- **Custom SSO:** Parameters passed in URL (MLS code, user ID, secure hash, timestamp)\n- **SAML:** Cloud CMA is SAML certified and supports standard SAML providers\n- **Pro:** MLS controls both access to MLS and Cloud CMA; deepest integration with MLS systems\n- **Con:** MLS must set up the link/integration within their system\n\n## Method 4: Synchronized Agent Table\nCloud CMA maintains a synchronized table of currently active agents from the MLS. Users provide credentials which are verified against this table on each query.\n- **Pro:** MLS has complete control; users deactivated immediately via normal workflow\n- **Con:** Requires maintaining synchronized agent data\n\nAll methods ensure that only valid, active MLS members can access listing data through Cloud CMA.",
        "operationId": "mlsSecurityMethods",
        "responses": {
          "200": {
            "description": "MLS Security Methods documentation"
          }
        }
      }
    },
    "/docs/rets-queries": {
      "get": {
        "tags": ["Documentation"],
        "summary": "Cloud CMA RETS Queries",
        "description": "Cloud CMA does NOT download and maintain the entire MLS database. Instead, it performs real-time RETS queries at the moment users request reports. This provides better security (no full MLS replication) and reduces server load.\n\n## Three Query Types\n\n### 1. MLS Number Search\nSimplest query type. Single or multiple MLS numbers at a time.\n- Example: Query MLS #12345 and #12346\n- Straightforward RETS DMQL syntax\n- Very efficient\n\n### 2. Address Search\nQuery by street address. Cloud CMA breaks address into components (street number, street name, city, state, zip).\n- Example: 123 Main St, Huntington Beach, CA\n- Also straightforward DMQL\n- Address less accurate than MLS number due to MLS data entry typos\n\n### 3. Latitude/Longitude Range Search\nMost complex query type. Creates rectangular proximity search area around subject property using lat/lon ranges.\n- Example: Search all listings within lat range 44.866-44.868 and lon range -92.590--92.588\n- More useful for finding comparables but can stress RETS servers\n\n## Common RETS Server Issues & Solutions\n\n### Issue 1: Latitude/Longitude Not Indexed\nProblem: Lat/lon fields on some RETS servers are not indexed, causing slow or failed queries even though they're simple decimal values.\n\nSolution: Request MLS add an indexed field or create a view with indexed lat/lon support.\n\n### Issue 2: Double Negative Syntax Breaks Parser\nProblem: U.S. longitude is negative. Range queries with negative numbers create this DMQL syntax:\n```\n(LONGITUDE=-92.590--92.588),(LATITUDE=44.866-44.868)\n```\nThe double negative `--` can break some RETS parsers.\n\nSolution: Create new field `ABSLONGITUDE` containing absolute value of longitude:\n```\n(ABSLONGITUDE=92.588-92.590),(LATITUDE=44.866-44.868)\n```\nThen flag Cloud CMA to query the ABSLONGITUDE field instead. This is typically easy to implement and solves the parser issue.\n\n## Efficiency Notes\n- Cloud CMA queries only small subsets of MLS daily (10-30 listings per CMA/Buyer Tour, 1 per Property Report)\n- Real-time queries are more secure than replication\n- Proper indexing on RETS servers is critical for performance",
        "operationId": "retsQueries",
        "responses": {
          "200": {
            "description": "RETS Queries documentation"
          }
        }
      }
    },
    "/docs/error-handling": {
      "get": {
        "tags": ["Documentation"],
        "summary": "Error Handling & Troubleshooting",
        "description": "## Common API Errors\n\n### Authentication Errors\n**Error:** \"You need to sign in or sign up before continuing\"\n- **Cause:** Missing api_key parameter\n- **Solution:** Include api_key from Cloud CMA Settings > API (or Account Settings > Integrations)\n\n**Error:** \"User with api_key not found\"\n- **Cause:** Invalid or expired API key\n- **Solution:** Verify API key in Cloud CMA account settings; regenerate if needed\n\n### Resource Not Found Errors\n**Error:** \"No matching listings were found on the MLS\"\n- **Cause:** Address is outside the MLS's operating boundary (e.g., subject property in Florida but user's MLS is California)\n- **Solution:** Verify address is within the MLS service area; use MLS numbers when available instead of addresses\n\n**Error:** Property address returns no results\n- **Cause:** Address mistyped or not found in MLS database\n- **Solution:** Use MLS number instead of address; verify spelling and format\n\n### Feature/Permission Errors\n**Error:** \"This user does not have the Homebeat feature\"\n- **Cause:** Homebeat add-on is not enabled for this user or not available in this MLS\n- **Solution:** Contact Cloud CMA support to enable Homebeat; verify it's available in your MLS\n\n**Error:** \"Frequency is not a valid option\"\n- **Cause:** Invalid frequency value provided for Homebeat\n- **Solution:** Use one of the valid frequencies: monthly, quarterly, semi-annually, annually, never\n\n### Homebeat Specific Issues\n**Issue:** Welcome email not sent or subscription not active\n- **Check:** Verify lead email address is valid and opted in\n- **Check:** Confirm Homebeat feature is enabled for the user account\n- **Check:** If using custom callback, ensure callback_url is accessible and returning 200 OK\n\n**Issue:** Homebeat report shows no view counts\n- **Cause:** Report may be too new or leads haven't viewed it yet\n- **Solution:** Wait for updates according to the frequency (monthly, quarterly, etc.)\n\n### Webhook Issues\n**Webhooks not being called:**\n- Verify callback_url is publicly accessible (not localhost)\n- Ensure your endpoint returns HTTP 200 within 30 seconds\n- Check server logs for incoming POST requests\n- Cloud CMA will retry failed webhooks multiple times before giving up\n\n**Webhook Payload Issues:**\n- Verify you're parsing the JSON payload correctly\n- All webhook payloads include: id, user_id, type, title, notes, mls_code, created_at, updated_at, deleted_at, edit_url, pdf_url, action, and job_id (if provided)\n\n## Report Generation Issues\n**Report takes longer than expected:**\n- First report generation may take 1-2 minutes as Cloud CMA queries RETS and generates PDF\n- Subsequent reports typically faster due to caching\n- Check webhook callback for completion status\n\n**PDF URL not working:**\n- PDF URLs are temporarily available (typically 24-48 hours)\n- For permanent storage, download PDF immediately after notification\n- For permanent access, use edit_url to view in Cloud CMA interface\n\n## Best Practices\n1. Always use MLS numbers instead of addresses when available (more accurate, faster queries)\n2. Implement webhook callbacks to track report status and delivery\n3. Use job_id parameter to correlate callbacks with your internal systems\n4. Handle webhook retries gracefully\n5. Store pdf_url values immediately upon receipt; don't rely on them being available later\n6. For lead captures, validate email addresses before submission",
        "operationId": "errorHandling",
        "responses": {
          "200": {
            "description": "Error Handling & Troubleshooting guide"
          }
        }
      }
    },
    "/docs/webhooks": {
      "get": {
        "tags": ["Documentation"],
        "summary": "Webhooks & Callbacks",
        "description": "Webhooks allow you to receive real-time notifications when reports are created, updated, or deleted. This is useful for tracking report status, integrating with your CRM, and automating lead management.\n\n## How Webhooks Work\n1. Include `callback_url` parameter in your API request\n2. Cloud CMA creates the report\n3. When the report status changes (created, updated, deleted), Cloud CMA POSTs to your callback URL\n4. Your system processes the webhook and takes action (send email, log to CRM, etc.)\n\n## Optional Parameters\n- `callback_url` (optional): URL where Cloud CMA will POST webhook updates\n- `job_id` (optional): Your unique tracking ID that will be included in all webhook payloads for this report\n\n## Webhook Payload Format\nCloud CMA POSTs JSON to your callback_url:\n```json\n{\n  \"id\": 12345,\n  \"user_id\": 67890,\n  \"type\": \"Cma\",\n  \"title\": \"The Robertsons\",\n  \"notes\": \"\",\n  \"mls_code\": \"crmls\",\n  \"created_at\": \"2015-07-21T18:04:24Z\",\n  \"updated_at\": \"2015-07-21T18:04:24Z\",\n  \"deleted_at\": null,\n  \"edit_url\": \"https://cloudcma.com/cmas/12345/edit\",\n  \"pdf_url\": \"https://cloudcma.com/pdf/f6f280a379b61c88e9bb68c6f996d501\",\n  \"action\": \"update\",\n  \"job_id\": \"your-tracking-id\"\n}\n```\n\n## Webhook Actions\n- `create`: Report was just created\n- `update`: Report was updated (usually when PDF is ready)\n- `delete`: Report was deleted\n\n## Implementation Requirements\n1. Your endpoint must return HTTP 200 within 30 seconds\n2. Your endpoint should be publicly accessible (not localhost or private network)\n3. Use HTTPS when possible\n4. Cloud CMA will retry failed webhooks automatically (several attempts with backoff)\n5. Store the job_id and pdf_url immediately for permanent reference\n\n## Use Cases\n### Scenario 1: Cloud CMA Handles Email\nDon't provide `job_id`, provide `callback_url`. Cloud CMA creates report and:\n- Sends email to consumer with report link\n- POSTs webhook to your callback_url when report is ready\n- You log the report in your system for tracking\n\n### Scenario 2: Your System Handles Email\nProvide both `callback_url` and `job_id`, but don't provide consumer email. Cloud CMA creates report and:\n- POSTs webhook to your callback_url with pdf_url\n- Your system uses job_id to look up which consumer requested it\n- Your system sends custom-formatted email with your branding\n\n### Scenario 3: Homebeat Tracking\nFor Homebeat automations with `callback_url`, Cloud CMA:\n- POSTs on each frequency update (monthly, quarterly, etc.)\n- Includes pdf_url for each update\n- Allows you to track view counts and engagement\n- If no consumer email provided, you handle all email delivery",
        "operationId": "webhooks",
        "responses": {
          "200": {
            "description": "Webhooks documentation"
          }
        }
      }
    },
    "/cmas/new": {
      "get": {
        "tags": ["Report Creation - Agent APIs"],
        "summary": "Create a new CMA",
        "description": "Create a new Comparative Market Analysis report with one or more MLS listings. Can be initiated directly from an MLS site or broker website.",
        "operationId": "createCMA",
        "parameters": [
          {
            "name": "mlsnums",
            "in": "query",
            "description": "Comma-separated list of MLS numbers for subject properties in the CMA",
            "schema": {
              "type": "string"
            },
            "example": "12345,12346,12347"
          },
          {
            "name": "address",
            "in": "query",
            "description": "Single address for the subject property. Used for geocoding to set proximity search area.",
            "schema": {
              "type": "string"
            },
            "example": "123 Main St, Huntington Beach, CA"
          },
          {
            "name": "title",
            "in": "query",
            "description": "Title for the CMA report. User can edit in Cloud CMA if not provided.",
            "schema": {
              "type": "string"
            },
            "example": "The Smith Family"
          },
          {
            "name": "notes",
            "in": "query",
            "description": "Internal notes for the report. Agents see these, consumers do not.",
            "schema": {
              "type": "string"
            },
            "example": "Initiated from your MLS"
          },
          {
            "name": "beds",
            "in": "query",
            "description": "Bedrooms of subject property. Used to filter comparable properties.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "baths",
            "in": "query",
            "description": "Bathrooms of subject property. Used to filter comparable properties.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "sqft",
            "in": "query",
            "description": "Square feet of subject property. Used to filter comparable properties.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "prop_type",
            "in": "query",
            "description": "Property type for proximity search filter (e.g., RES, Commercial). Must match MLS RETS metadata.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "min_listings",
            "in": "query",
            "description": "Minimum number of comparable listings to include. Default varies by MLS.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "lat",
            "in": "query",
            "description": "Override geocoded latitude for proximity search center point",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "lon",
            "in": "query",
            "description": "Override geocoded longitude for proximity search center point",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "callback_url",
            "in": "query",
            "description": "Webhook URL for report status updates. See Webhooks section.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Cloud CMA report creation page. User logged in → goes directly to new CMA. User not logged in → sent to login first."
          },
          "400": {
            "description": "Invalid parameters (e.g., invalid MLS numbers, address outside MLS boundary)"
          }
        }
      },
      "post": {
        "tags": ["Report Creation - Agent APIs"],
        "summary": "Create a new CMA (POST)",
        "description": "Create a new CMA using POST method. Same parameters as GET.",
        "operationId": "createCMAPost",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CMACreateRequest"
              }
            }
          }
        },
        "responses": {
          "302": {
            "description": "Redirect to Cloud CMA report creation"
          }
        }
      }
    },
    "/tours/new": {
      "get": {
        "tags": ["Report Creation - Agent APIs"],
        "summary": "Create a new Buyer Tour",
        "description": "Create a Buyer Tour report showcasing multiple properties to a potential buyer.",
        "operationId": "createBuyerTour",
        "parameters": [
          {
            "name": "mlsnums",
            "in": "query",
            "description": "Comma-separated list of MLS numbers for properties in the tour",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "name": "title",
            "in": "query",
            "description": "Title for the Buyer Tour",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "notes",
            "in": "query",
            "description": "Internal notes for the tour",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "callback_url",
            "in": "query",
            "description": "Webhook URL for tour status updates",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Cloud CMA Buyer Tour creation"
          }
        }
      }
    },
    "/properties/new": {
      "get": {
        "tags": ["Report Creation - Agent APIs"],
        "summary": "Create a new Property Report",
        "description": "Create a single-property detailed report. Can be initiated by MLS number or address.",
        "operationId": "createPropertyReport",
        "parameters": [
          {
            "name": "mlsnums",
            "in": "query",
            "description": "MLS number of the subject property (single only)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "in": "query",
            "description": "Address of the subject property. Less accurate than MLS number.",
            "schema": {
              "type": "string"
            },
            "example": "123 Main Street, Costa Mesa, CA 92626"
          },
          {
            "name": "title",
            "in": "query",
            "description": "Title for the report",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "notes",
            "in": "query",
            "description": "Internal notes",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "callback_url",
            "in": "query",
            "description": "Webhook URL for report status updates",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Cloud CMA Property Report creation"
          }
        }
      }
    },
    "/flyers/new": {
      "get": {
        "tags": ["Report Creation - Agent APIs"],
        "summary": "Create a new Flyer",
        "description": "Create a property flyer for a single listing.",
        "operationId": "createFlyer",
        "parameters": [
          {
            "name": "mlsnums",
            "in": "query",
            "description": "MLS number of the property",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "in": "query",
            "description": "Address of the property",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "title",
            "in": "query",
            "description": "Flyer title",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "notes",
            "in": "query",
            "description": "Internal notes",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "callback_url",
            "in": "query",
            "description": "Webhook URL for status updates",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Cloud CMA Flyer creation"
          }
        }
      }
    },
    "/cmas/widget": {
      "get": {
        "tags": ["Lead Generation - Widget APIs"],
        "summary": "Create and deliver Quick CMA for lead",
        "description": "Consumer-facing API to create a Quick CMA from website lead form, automatically branded to agent, and email to consumer. Captures lead data for agent tracking.",
        "operationId": "quickCMAWidget",
        "parameters": [
          {
            "name": "api_key",
            "in": "query",
            "description": "Cloud CMA API key for the user (from Settings > API)",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "name": "name",
            "in": "query",
            "description": "Consumer's full name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email_to",
            "in": "query",
            "description": "Consumer's email address for report delivery",
            "schema": {
              "type": "string",
              "format": "email"
            },
            "required": true
          },
          {
            "name": "address",
            "in": "query",
            "description": "Consumer's subject property address",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "name": "sqft",
            "in": "query",
            "description": "Square feet of subject property",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "beds",
            "in": "query",
            "description": "Bedrooms",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "baths",
            "in": "query",
            "description": "Bathrooms",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "prop_type",
            "in": "query",
            "description": "Property type to restrict comparable search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "title",
            "in": "query",
            "description": "Report title. Default: consumer's name or email.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "headline",
            "in": "query",
            "description": "Cover page headline. Default: 'Quick CMA'",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "min_listings",
            "in": "query",
            "description": "Minimum comparable listings. Default: 10",
            "schema": {
              "type": "integer",
              "default": 10
            }
          },
          {
            "name": "months_back",
            "in": "query",
            "description": "Historical period for comparables. Default: 12 months",
            "schema": {
              "type": "integer",
              "default": 12
            }
          },
          {
            "name": "email_subject",
            "in": "query",
            "description": "Email subject line",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email_msg",
            "in": "query",
            "description": "Email message body. Default: just the report link.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "template",
            "in": "query",
            "description": "Report template. Default: 'Web Leads'. Must exist in user's account.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "job_id",
            "in": "query",
            "description": "Unique ID to track in callback (for webhook integration)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "callback_url",
            "in": "query",
            "description": "Webhook URL called when report is ready. Receives pdf_url and job_id.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Quick CMA created and queued for delivery",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuickCMAResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid API key or missing required parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Lead Generation - Widget APIs"],
        "summary": "Create and deliver Quick CMA (POST)",
        "description": "POST version of Quick CMA widget endpoint",
        "operationId": "quickCMAWidgetPost",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/QuickCMARequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quick CMA created successfully"
          },
          "400": {
            "description": "Error creating Quick CMA"
          }
        }
      }
    },
    "/properties/widget": {
      "get": {
        "tags": ["Lead Generation - Widget APIs"],
        "summary": "Create Property Report for email delivery",
        "description": "Consumer requests a Property Report for the property they're viewing. Cloud CMA creates and emails the PDF to the consumer.",
        "operationId": "propertyReportWidget",
        "parameters": [
          {
            "name": "api_key",
            "in": "query",
            "description": "Cloud CMA API key (required)",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "name": "mlsnum",
            "in": "query",
            "description": "MLS number of the subject property (required if address not provided)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "in": "query",
            "description": "Address of the subject property (less accurate than MLS number)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email_to",
            "in": "query",
            "description": "Consumer email for report delivery (required)",
            "schema": {
              "type": "string",
              "format": "email"
            },
            "required": true
          },
          {
            "name": "email_subject",
            "in": "query",
            "description": "Email subject. Default: 'Your Cloud CMA Property Report'",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email_msg",
            "in": "query",
            "description": "Email message body. Default: just the report link.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "theme",
            "in": "query",
            "description": "Report theme. Default: broker's last used theme.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "title",
            "in": "query",
            "description": "Report title shown on cover ('Prepared for' section). Default: email_to.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "notes",
            "in": "query",
            "description": "Internal notes (consumer never sees)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "callback_url",
            "in": "query",
            "description": "Webhook URL. If provided with job_id, you handle email delivery instead of Cloud CMA.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "job_id",
            "in": "query",
            "description": "Unique tracking ID for webhook callbacks",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Property Report created successfully"
          },
          "400": {
            "description": "Invalid parameters or property not found"
          }
        }
      },
      "post": {
        "tags": ["Lead Generation - Widget APIs"],
        "summary": "Create Property Report for email delivery (POST)",
        "operationId": "propertyReportWidgetPost",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PropertyReportRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Property Report created and queued"
          }
        }
      }
    },
    "/homebeats/widget": {
      "get": {
        "tags": ["Homebeat Automation"],
        "summary": "Get Homebeat metadata",
        "description": "Retrieve metadata about Homebeat feature availability, MLS property types, and supported frequencies for a user.",
        "operationId": "getHomebeatMetadata",
        "parameters": [
          {
            "name": "api_key",
            "in": "query",
            "description": "Cloud CMA API key (from Account Settings > Integrations)",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Homebeat metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HomebeatMetadata"
                }
              }
            }
          },
          "400": {
            "description": "Invalid API key or user not found"
          }
        }
      },
      "post": {
        "tags": ["Homebeat Automation"],
        "summary": "Create new Homebeat automation",
        "description": "Create an automated Homebeat that sends market updates to leads at specified frequency (monthly, quarterly, etc). Can email leads directly or use webhook for custom delivery.",
        "operationId": "createHomebeat",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HomebeatCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Homebeat created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HomebeatCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or user does not have Homebeat feature"
          }
        }
      }
    },
    "/homebeats/report": {
      "get": {
        "tags": ["Homebeat Automation"],
        "summary": "Get Homebeat report",
        "description": "Download a report of all created Homebeats with view counts in CSV or JSON format.",
        "operationId": "getHomebeatReport",
        "parameters": [
          {
            "name": "api_key",
            "in": "query",
            "description": "Cloud CMA API key (optional - defaults to current logged-in user if omitted)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "description": "Response format: text/csv or application/json",
            "schema": {
              "type": "string",
              "enum": ["text/csv", "application/json"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Homebeat report data",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/HomebeatReportItem"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CMACreateRequest": {
        "type": "object",
        "properties": {
          "mlsnums": {
            "type": "string",
            "description": "Comma-separated MLS numbers"
          },
          "address": {
            "type": "string",
            "description": "Subject property address"
          },
          "title": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "beds": {
            "type": "integer"
          },
          "baths": {
            "type": "number"
          },
          "sqft": {
            "type": "integer"
          },
          "prop_type": {
            "type": "string"
          },
          "min_listings": {
            "type": "integer"
          },
          "lat": {
            "type": "number",
            "format": "double"
          },
          "lon": {
            "type": "number",
            "format": "double"
          },
          "callback_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "QuickCMARequest": {
        "type": "object",
        "required": ["api_key", "email_to", "address"],
        "properties": {
          "api_key": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email_to": {
            "type": "string",
            "format": "email"
          },
          "address": {
            "type": "string"
          },
          "sqft": {
            "type": "integer"
          },
          "beds": {
            "type": "integer"
          },
          "baths": {
            "type": "number"
          },
          "prop_type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "headline": {
            "type": "string"
          },
          "min_listings": {
            "type": "integer"
          },
          "months_back": {
            "type": "integer"
          },
          "email_subject": {
            "type": "string"
          },
          "email_msg": {
            "type": "string"
          },
          "template": {
            "type": "string"
          },
          "job_id": {
            "type": "string"
          },
          "callback_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "PropertyReportRequest": {
        "type": "object",
        "required": ["api_key", "email_to"],
        "properties": {
          "api_key": {
            "type": "string"
          },
          "mlsnum": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "email_to": {
            "type": "string",
            "format": "email"
          },
          "email_subject": {
            "type": "string"
          },
          "email_msg": {
            "type": "string"
          },
          "theme": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "callback_url": {
            "type": "string",
            "format": "uri"
          },
          "job_id": {
            "type": "string"
          }
        }
      },
      "QuickCMAResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": ["queued", "processing", "completed"]
          },
          "job_id": {
            "type": "string"
          },
          "pdf_url": {
            "type": "string",
            "format": "uri",
            "description": "URL to download the generated PDF"
          },
          "email_sent": {
            "type": "boolean"
          }
        }
      },
      "HomebeatMetadata": {
        "type": "object",
        "properties": {
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "api_key": {
                "type": "string"
              }
            }
          },
          "mls": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "MLS code identifier"
              },
              "title": {
                "type": "string",
                "description": "Full MLS name"
              },
              "prop_types": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Property types available in this MLS"
              },
              "default_prop_type": {
                "type": "string"
              }
            }
          },
          "homebeat": {
            "type": "object",
            "properties": {
              "has_feature": {
                "type": "boolean",
                "description": "Whether user has Homebeat add-on enabled"
              },
              "frequencies": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": ["monthly", "quarterly", "semi-annually", "annually", "never"]
                },
                "description": "Supported update frequencies"
              }
            }
          }
        }
      },
      "HomebeatCreateRequest": {
        "type": "object",
        "required": ["automation"],
        "properties": {
          "automation": {
            "type": "object",
            "required": ["api_key", "frequency", "subject_property", "lead"],
            "properties": {
              "api_key": {
                "type": "string"
              },
              "frequency": {
                "type": "string",
                "enum": ["monthly", "quarterly", "semi-annually", "annually", "never"],
                "description": "How often to send Homebeat updates"
              },
              "welcome_email": {
                "type": "boolean",
                "default": true,
                "description": "Send double opt-in welcome email"
              },
              "report": {
                "type": "object",
                "properties": {
                  "prop_type": {
                    "type": "string",
                    "nullable": true,
                    "description": "Filter comparables to property type. Null = use MLS default."
                  },
                  "callback_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Webhook URL for Homebeat updates"
                  }
                }
              },
              "subject_property": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string"
                  },
                  "geo_lat": {
                    "type": "number",
                    "nullable": true
                  },
                  "geo_lon": {
                    "type": "number",
                    "nullable": true
                  },
                  "sqft": {
                    "type": "string"
                  },
                  "beds": {
                    "type": "string"
                  },
                  "baths": {
                    "type": "string"
                  },
                  "garages": {
                    "type": "string",
                    "nullable": true
                  },
                  "lot_size": {
                    "type": "string",
                    "nullable": true
                  },
                  "taxes": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "lead": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "email_address": {
                    "type": "string",
                    "format": "email"
                  },
                  "phone": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "HomebeatCreateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Homebeat record ID"
          },
          "status": {
            "type": "string",
            "enum": ["created", "error"]
          },
          "error": {
            "type": "string",
            "description": "Error message if creation failed"
          },
          "first_report_sent": {
            "type": "boolean"
          }
        }
      },
      "HomebeatReportItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "lead_name": {
            "type": "string"
          },
          "lead_email": {
            "type": "string"
          },
          "subject_address": {
            "type": "string"
          },
          "frequency": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "view_count": {
            "type": "integer"
          }
        }
      },
      "WebhookPayload": {
        "type": "object",
        "description": "Webhook callback payload sent to callback_url",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Report ID"
          },
          "user_id": {
            "type": "integer",
            "description": "Cloud CMA user ID"
          },
          "type": {
            "type": "string",
            "enum": ["Cma", "BuyerTour", "PropertyReport", "Flyer"],
            "description": "Report type"
          },
          "title": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "mls_code": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "edit_url": {
            "type": "string",
            "format": "uri",
            "description": "Link to edit report in Cloud CMA"
          },
          "pdf_url": {
            "type": "string",
            "format": "uri",
            "description": "Link to download PDF"
          },
          "action": {
            "type": "string",
            "enum": ["create", "update", "delete"],
            "description": "What triggered the webhook"
          },
          "job_id": {
            "type": "string",
            "description": "Your tracking ID from callback_url parameter"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "query",
        "name": "api_key",
        "description": "Cloud CMA API key from Settings > API (or Account Settings > Integrations)"
      }
    }
  },
  "security": [
    {
      "ApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Report Creation - Agent APIs",
      "description": "APIs for agents to create CMAs, Buyer Tours, Property Reports, and Flyers. Can redirect user to Cloud CMA UI or trigger report generation."
    },
    {
      "name": "Lead Generation - Widget APIs",
      "description": "Consumer-facing APIs for capturing leads via website forms. Creates reports and manages email delivery with optional webhook callbacks for custom handling."
    },
    {
      "name": "Homebeat Automation",
      "description": "Automated market update campaigns sent to leads at specified frequency. Includes metadata retrieval, creation, and reporting."
    },
    {
      "name": "Documentation",
      "description": "Comprehensive guides covering MLS security methods, RETS query types, webhooks, error handling, and best practices."
    }
  ]
}
