{"openapi":"3.1.0","info":{"title":"Yarda AI Landscape Studio","description":"API for AI-powered landscape design generation","version":"1.0.0"},"paths":{"/auth/register":{"post":{"tags":["authentication"],"summary":"Register","description":"Register new user with email/password.\n\nRate limit: 3 requests per minute per IP (YAR-246)\n\nRequirements:\n- FR-001: Email/password registration\n- FR-002: Email format validation (handled by Pydantic EmailStr)\n- FR-003: Password minimum 8 characters (handled by Pydantic validator)\n- FR-004: Prevent duplicate email registration\n- FR-010: Initialize trial_remaining=3, trial_used=0\n- FR-006: Send verification email\n\nReturns:\n    UserRegisterResponse with user_id, email, trial_remaining=3\n\nRaises:\n    HTTPException 400: Email already exists\n    HTTPException 500: Database error","operationId":"register_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRegisterResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/verify-email":{"post":{"tags":["authentication"],"summary":"Verify Email","description":"Verify user email with verification token.\n\nRequirements:\n- FR-007: Email verification within 30 seconds\n- FR-008: Verification link valid for 24 hours\n- FR-009: Set email_verified=true after verification\n\nReturns:\n    Success message\n\nRaises:\n    HTTPException 400: Invalid or expired token\n    HTTPException 500: Database error","operationId":"verify_email_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/resend-verification":{"post":{"tags":["authentication"],"summary":"Resend Verification","description":"Resend verification email.\n\nRequirements:\n- Rate limit: 3 emails per hour per email address\n\nReturns:\n    Success message\n\nRaises:\n    HTTPException 429: Too many requests\n    HTTPException 400: Email not found or already verified\n    HTTPException 500: Server error","operationId":"resend_verification_auth_resend_verification_post","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login":{"post":{"tags":["authentication"],"summary":"Login","description":"User login with email/password.\n\nRate limit: 5 requests per minute per IP (YAR-246)\n\nReturns:\n    LoginResponse with access_token and user profile\n\nRaises:\n    HTTPException 401: Invalid credentials\n    HTTPException 500: Database error","operationId":"login_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/logout":{"post":{"tags":["authentication"],"summary":"Logout","description":"User logout (client-side token removal).\n\nReturns:\n    Success message","operationId":"logout_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/unsubscribe":{"get":{"tags":["authentication"],"summary":"Unsubscribe Email","description":"One-click unsubscribe from Yarda marketing emails (CAN-SPAM compliant).\n\nValidates the HMAC token and marks the user's email_unsubscribed_at timestamp.\nThis endpoint is safe to expose publicly — it's protected by the HMAC signature.\n\nReturns:\n    Success message confirming unsubscribe","operationId":"unsubscribe_email_auth_unsubscribe_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","description":"User email address","title":"Email"},"description":"User email address"},{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"HMAC unsubscribe token","title":"Token"},"description":"HMAC unsubscribe token"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/payment-status":{"get":{"tags":["users"],"summary":"Get Payment Status","description":"Get user's current payment capabilities.\n\nReturns payment status including trial credits, token balance, and subscription info.\n\n**Payment Hierarchy** (FR-007):\n1. Subscription (unlimited if active) - HIGHEST PRIORITY\n2. Trial credits (3 free on registration) - SECOND PRIORITY\n3. Token balance (purchased via Stripe) - LOWEST PRIORITY\n\n**UI Display** (FR-019):\n- Show trial credits remaining prominently if user has them\n- Show token balance if no trial credits\n- Show \"Active Subscription\" badge if subscribed\n- Show \"Purchase Required\" CTA if none available\n\nRequirements:\n- FR-007: Implement payment hierarchy\n- FR-019: Display active payment method in generate button\n- FR-020: Show trial credits remaining prominently","operationId":"get_payment_status_v1_users_payment_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/me/whats-new-modal":{"patch":{"tags":["users"],"summary":"Update Whats New Modal State","description":"Mark the What's New modal as shown for the current user.\n\nThis endpoint is called when the user dismisses the holiday feature announcement modal.\nEnsures the modal is only shown once per user.\n\n**Authentication:** Required\n\n**Request Body:**\n- modal_shown: Boolean to set modal state (default: true)\n\n**Response:**\n- success: Whether the update was successful\n- whats_new_modal_shown: New state of the modal flag\n\n**Example:**\n```bash\ncurl -X PATCH https://api.yarda.app/v1/users/me/whats-new-modal       -H \"Authorization: Bearer YOUR_TOKEN\"       -H \"Content-Type: application/json\"       -d '{\"modal_shown\": true}'\n```","operationId":"update_whats_new_modal_state_v1_users_me_whats_new_modal_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateModalStateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateModalStateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/me/profile":{"get":{"tags":["users"],"summary":"Get User Profile","description":"Get current user's full profile including language preference.\n\nThis endpoint returns the user's complete profile with all available information\nincluding email, subscription status, trial balance, and language preference.\n\n**Authentication:** Required\n\n**Response:**\n- user_id: User's unique identifier\n- email: User's email address\n- email_verified: Whether email is verified\n- trial_remaining: Trial credits remaining\n- trial_used: Trial credits used\n- subscription_tier: Current subscription tier (if any)\n- subscription_status: Subscription status (active/inactive/past_due)\n- preferred_language: User's preferred language (en/es/zh)\n- created_at: Account creation timestamp\n\n**Example:**\n```bash\ncurl https://api.yarda.app/v1/users/me/profile       -H \"Authorization: Bearer YOUR_TOKEN\"\n```","operationId":"get_user_profile_v1_users_me_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/preferences/language":{"put":{"tags":["users"],"summary":"Update Language Preference","description":"Update user's preferred language.\n\nThis endpoint allows users to set their preferred language for the UI.\nThe preference is persisted in the database and returned in user profile responses.\n\n**Authentication:** Required\n\n**Supported Languages:**\n- en: English\n- es: Spanish (Español)\n- zh: Chinese Simplified (简体中文)\n\n**Request Body:**\n- language: Language code (en, es, or zh)\n\n**Response:**\n- success: Whether the update was successful\n- preferred_language: The new language preference\n\n**Example:**\n```bash\ncurl -X PUT https://api.yarda.app/v1/users/preferences/language       -H \"Authorization: Bearer YOUR_TOKEN\"       -H \"Content-Type: application/json\"       -d '{\"language\": \"es\"}'\n```\n\n**Error Responses:**\n- 400: Invalid language code (must be en, es, or zh)\n- 401: Unauthorized (missing or invalid token)\n- 500: Server error","operationId":"update_language_preference_v1_users_preferences_language_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguagePreferenceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguagePreferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/me/feedback-opt-in":{"get":{"tags":["users"],"summary":"Get Feedback Opt In","description":"Get current user's feedback opt-in status.\n\nReturns whether the user has opted in to see the feedback button.\n\n**Authentication:** Required\n\n**Response:**\n- feedback_opt_in: Boolean indicating opt-in status\n\n**Example:**\n```bash\ncurl https://api.yarda.app/v1/users/me/feedback-opt-in       -H \"Authorization: Bearer YOUR_TOKEN\"\n```","operationId":"get_feedback_opt_in_v1_users_me_feedback_opt_in_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackOptInResponse"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["users"],"summary":"Update Feedback Opt In","description":"Update user's feedback opt-in status.\n\nThis endpoint allows users to opt in or out of seeing the feedback button.\nWhen opted in, a floating feedback button will appear on all pages.\n\n**Authentication:** Required\n\n**Request Body:**\n- opt_in: Boolean to set opt-in status (true = show feedback button)\n\n**Response:**\n- success: Whether the update was successful\n- feedback_opt_in: The new opt-in status\n\n**Example:**\n```bash\ncurl -X PUT https://api.yarda.app/v1/users/me/feedback-opt-in       -H \"Authorization: Bearer YOUR_TOKEN\"       -H \"Content-Type: application/json\"       -d '{\"opt_in\": true}'\n```","operationId":"update_feedback_opt_in_v1_users_me_feedback_opt_in_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFeedbackOptInRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFeedbackOptInResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/me/preferences/pro-mode":{"get":{"tags":["users"],"summary":"Get Pro Mode Preferences","description":"Get current user's Pro Mode preferences.\n\nReturns the user's design mode preference (quick vs studio) and\nwhether they have seen the mode explainer modal.\n\n**Authentication:** Required\n\n**Response:**\n- design_mode: Current mode preference (quick/studio)\n- design_mode_set_at: When mode was last changed\n- has_seen_mode_explainer: Whether explainer modal has been shown\n\n**Example:**\n```bash\ncurl https://api.yarda.app/v1/users/me/preferences/pro-mode \\\n  -H \"Authorization: Bearer YOUR_TOKEN\"\n```","operationId":"get_pro_mode_preferences_v1_users_me_preferences_pro_mode_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProModePreferencesResponse"}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["users"],"summary":"Update Pro Mode Preferences","description":"Update user's Pro Mode preferences.\n\nUpdates the user's design mode preference and/or explainer modal state.\nBoth fields are optional - only provided fields will be updated.\n\n**Authentication:** Required\n\n**Request Body:**\n- design_mode (optional): New mode preference (quick/studio)\n- has_seen_mode_explainer (optional): Mark explainer as seen\n\n**Response:**\n- Updated preferences\n\n**Example:**\n```bash\ncurl -X PATCH https://api.yarda.app/v1/users/me/preferences/pro-mode \\\n  -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"design_mode\": \"studio\"}'\n```","operationId":"update_pro_mode_preferences_v1_users_me_preferences_pro_mode_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProModePreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProModePreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/me/signup-attribution":{"patch":{"tags":["users"],"summary":"Save Signup Attribution","description":"Store UTM attribution at the moment of signup (first-touch, write-once).\n\nOnly populates the columns if they are currently NULL — subsequent calls\nare silently ignored so first-touch attribution is preserved.\n\nCalled by the frontend auth callback for new users immediately after account creation.\n\n**Authentication:** Required","operationId":"save_signup_attribution_v1_users_me_signup_attribution_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupAttributionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupAttributionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/users/me/storage":{"get":{"tags":["users"],"summary":"Get Storage Quota","description":"Get current user's storage quota and usage.\n\nReturns storage usage details including bytes used, limit, and grace period status.\nPro users get 1TB of storage. After subscription ends, designs are available\nfor 7 days before being soft-deleted.\n\n**Authentication:** Required\n\n**Response:**\n- storage_used_bytes: Total bytes used by designs\n- storage_limit_bytes: Maximum allowed (1TB for Pro, 0 for free)\n- percentage_used: Usage percentage (0-100)\n- is_near_limit: True if > 80% used\n- is_over_limit: True if over limit\n- grace_period_active: True if in 7-day post-cancellation period\n- grace_period_end: When grace period ends (if active)\n- days_until_deletion: Days until designs are deleted (if in grace)\n\n**Example:**\n```bash\ncurl https://api.yarda.app/v1/users/me/storage \\\n  -H \"Authorization: Bearer YOUR_TOKEN\"\n```","operationId":"get_storage_quota_v1_users_me_storage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageQuotaResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/generations/multi":{"post":{"tags":["generations"],"summary":"Create Multi Area Generation","description":"Create multi-area landscape generation request (Feature 004-generation-flow).\n\nThis endpoint implements the new generation flow that supports 1-5 areas per request.\nPayment is deducted atomically BEFORE Street View retrieval.\n\n**Payment Hierarchy** (FR-007):\n1. Active subscription → unlimited generations (NO DEDUCTION)\n2. Trial credits → limited generations (DEDUCT N TRIALS, N = number of areas)\n3. Token balance → pay-per-use (DEDUCT N TOKENS)\n\n**Workflow**:\n1. Validate request (address, areas uniqueness, 1-5 areas)\n2. Authorize and deduct payment atomically\n3. Create generation record + generation_areas records\n4. Retrieve Street View imagery (if available)\n5. Store source image metadata in generation_source_images\n6. Return generation ID with status='pending'\n7. Background worker processes generation asynchronously\n\n**Requirements**:\n- FR-008: Atomic payment deduction BEFORE generation\n- FR-001: Address validation via Google Maps Geocoding API\n- FR-060: Multi-area support (1-5 areas, 1 credit each)\n- FR-011: Automatic refund on failure\n- FR-010: Progress persists across page refresh (via polling)\n\nArgs:\n    request: Starlette Request (for rate limiter)\n    body: CreateGenerationRequest with address and areas list\n    user: Current authenticated user\n    trial_service: Trial service for checking trial balance\n\nReturns:\n    MultiAreaGenerationResponse with generation ID, status, and area details\n\nRaises:\n    HTTPException 400: Invalid address, duplicate areas, or validation error\n    HTTPException 403: Insufficient payment (no trial/token/subscription)\n    HTTPException 500: Generation creation failed","operationId":"create_multi_area_generation_v1_generations_multi_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ground_level_photo_bytes","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Ground Level Photo Bytes"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGenerationRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MultiAreaGenerationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generations/multi-with-photo":{"post":{"tags":["generations"],"summary":"Create Multi Area Generation With Photo","description":"Create multi-area landscape generation with optional backyard photo upload.\n\nThis endpoint extends the standard /multi endpoint to support file uploads.\nThe request data is sent as a JSON string in the 'data' form field,\nand the optional backyard photo is sent as a file.\n\nThe backyard photo helps the AI understand existing backyard features\nto generate more personalized designs. Currently, the photo is uploaded\nto blob storage and logged for future use in AI context.\n\nArgs:\n    data: JSON string containing CreateGenerationRequest fields\n    backyard_photo: Optional ground-level photo of backyard (JPG/PNG, max 5MB)\n    background_tasks: FastAPI background tasks\n    user: Current authenticated user\n    trial_service: Trial service for checking trial balance\n\nReturns:\n    MultiAreaGenerationResponse with generation ID, status, and area details","operationId":"create_multi_area_generation_with_photo_v1_generations_multi_with_photo_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_multi_area_generation_with_photo_v1_generations_multi_with_photo_post"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MultiAreaGenerationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/generations/":{"post":{"tags":["generations"],"summary":"Create Generation","description":"Create new landscape generation.\n\nAuthorization Hierarchy (FR-034, FR-047, FR-048):\n1. Active subscription → unlimited generations (NO DEDUCTION)\n2. Trial credits → limited generations (DEDUCT 1 TRIAL)\n3. Token balance → pay-per-use (DEDUCT 1 TOKEN)\n\nPayment Flow:\n1. Check authorization (hierarchy)\n2. Deduct payment BEFORE Gemini API call (if not subscription)\n3. Call Gemini API\n4. If success: save results, return generation\n5. If failure: refund payment, return error\n\nArgs:\n    address: Property address\n    area: Landscape area (front_yard, back_yard, side_yard, full_property)\n    style: Design style (modern_minimalist, tropical_paradise, etc.)\n    custom_prompt: Optional custom design instructions\n    image: Uploaded property image\n    user: Current authenticated user\n    trial_service: Trial service\n\nReturns:\n    Generation object with status='pending'\n\nRaises:\n    HTTPException 403: No payment method available\n    HTTPException 400: Invalid input\n    HTTPException 500: Generation failed","operationId":"create_generation_v1_generations__post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_generation_v1_generations__post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["generations"],"summary":"List Generations","description":"List user's generation history with pagination.\n\nRequirements:\n- FR-041: View generation history\n- Feature 008: Proper history implementation with pagination\n\nArgs:\n    limit: Maximum number of generations to return (default: 20, max: 50)\n    page: Page number for pagination (1-indexed, default: 1)\n    status: Optional status filter (pending, processing, completed, failed)\n    sort: Optional sort field (default: created_at DESC)\n    user: Current authenticated user\n\nReturns:\n    Paginated list of generations with metadata","operationId":"list_generations_v1_generations__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generations/{generation_id}":{"get":{"tags":["generations"],"summary":"Get Generation","description":"Get generation status and details (Feature 004-generation-flow).\n\nThis endpoint is polled by the frontend to track generation progress.\nReturns complete generation state including per-area progress.\n\n**Polling Strategy** (FR-010):\n- Frontend polls every 2 seconds while status is 'pending' or 'processing'\n- Stops polling when status is 'completed', 'partial_failed', or 'failed'\n- Progress persists in localStorage via Zustand store\n\n**Status Values**:\n- pending: Payment deducted, generation queued\n- processing: Background worker is generating designs\n- completed: All areas completed successfully\n- partial_failed: Some areas completed, some failed\n- failed: All areas failed or Street View retrieval failed\n\n**Requirements**:\n- FR-010: Progress persists across page refresh\n- FR-014: Background processing continues during page refresh\n- Credit Systems Consolidation: Returns credits_remaining for frontend sync\n\nArgs:\n    generation_id: Generation UUID\n    user: Current authenticated user\n\nReturns:\n    MultiAreaGenerationResponse with generation status and area details\n\nRaises:\n    HTTPException 404: Generation not found\n    HTTPException 403: Not authorized to view generation","operationId":"get_generation_v1_generations__generation_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MultiAreaGenerationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["generations"],"summary":"Update Generation","description":"Update generation metadata (title, notes).\n\nArgs:\n    generation_id: Generation UUID\n    request: Contains optional title and notes\n    user: Current authenticated user\n\nReturns:\n    Updated generation metadata","operationId":"update_generation_v1_generations__generation_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Generation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGenerationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["generations"],"summary":"Delete Generation","description":"Soft-delete a generation.\n\nArgs:\n    generation_id: Generation UUID\n    user: Current authenticated user\n\nReturns:\n    Success message","operationId":"delete_generation_v1_generations__generation_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generations/history":{"get":{"tags":["generations"],"summary":"Get Generation History","description":"Get Pro user's generation history with project grouping.\n\nFeatures:\n- Paginated list of generations (newest first)\n- Project grouping by place_id\n- Filter by generation_type, place_id, favorites\n- Search by address/title\n- Shows last 30 days + all favorites\n\nArgs:\n    page: Page number (1-indexed)\n    page_size: Items per page (max 50)\n    days: Number of days to show (default 30, max 45)\n    generation_type: Filter by type (standard, pro_2d_site_plan, pro_3d_render)\n    place_id: Filter by project (Google Place ID)\n    favorites_only: Only return favorites\n    search: Search in address/title\n    user: Current authenticated user\n\nReturns:\n    GenerationHistoryResponse with generations and project summaries","operationId":"get_generation_history_v1_generations_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Page Size"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"generation_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Type"}},{"name":"place_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place Id"}},{"name":"favorites_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Favorites Only"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerationHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generations/{generation_id}/favorite":{"post":{"tags":["generations"],"summary":"Toggle Favorite","description":"Toggle favorite status for a generation.\n\nFavorited generations are exempt from automatic cleanup.\n\nArgs:\n    generation_id: Generation UUID\n    request: Contains is_favorite boolean\n    user: Current authenticated user\n\nReturns:\n    Updated generation with favorite status","operationId":"toggle_favorite_v1_generations__generation_id__favorite_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Generation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToggleFavoriteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/generations/history/by-address":{"get":{"tags":["generations"],"summary":"Get History By Address","description":"Get previous Pro Mode generations for a specific address.\n\nUsed by the \"Previous Generations\" thumbnails feature to show\nthe user their previous designs for the current property.\n\nArgs:\n    address: Property address to search for (exact match)\n    limit: Maximum number of results (default 10, max 20)\n    user: Current authenticated user\n\nReturns:\n    AddressHistoryResponse with thumbnails and metadata","operationId":"get_history_by_address_v1_generations_history_by_address_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"address","in":"query","required":true,"schema":{"type":"string","title":"Address"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tokens/packages":{"get":{"tags":["tokens"],"summary":"List Token Packages","description":"Get all available token packages.\n\nRequirements:\n- FR-021 to FR-024: All 4 token packages\n- FR-025: Token package selection UI\n\nReturns:\n    List of token packages with pricing","operationId":"list_token_packages_tokens_packages_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Token Packages Tokens Packages Get"}}}}}}},"/tokens/purchase/checkout":{"post":{"tags":["tokens"],"summary":"Create Checkout Session","description":"Create Stripe Checkout session for token purchase.\n\nRequirements:\n- T050: Token purchase endpoint\n- FR-017: Token purchase via Stripe\n\nWorkflow:\n1. Validate package_id\n2. Create Stripe Checkout session\n3. Return session URL for redirect\n\nArgs:\n    request: CreateCheckoutSessionRequest with package_id\n    http_request: FastAPI Request for extracting origin\n    user: Current authenticated user\n\nReturns:\n    CreateCheckoutSessionResponse with session_id and URL\n\nRaises:\n    HTTPException 400: Invalid package_id\n    HTTPException 500: Stripe API error","operationId":"create_checkout_session_tokens_purchase_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutSessionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/tokens/balance":{"get":{"tags":["tokens"],"summary":"Get Token Balance","description":"Get user's current token balance.\n\nRequirements:\n- T051: Token balance endpoint (<100ms)\n- FR-015: Display token balance in UI\n\nPerformance:\n- Single database query\n- Target response time: <100ms\n- Future optimization: Redis caching\n\nArgs:\n    user: Current authenticated user\n    db_pool: Database connection pool\n\nReturns:\n    TokenAccountResponse with balance, total_purchased, total_spent\n\nRaises:\n    HTTPException 500: Database error","operationId":"get_token_balance_tokens_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenAccountResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/tokens/transactions":{"get":{"tags":["tokens"],"summary":"Get Transaction History","description":"Get user's token transaction history.\n\nArgs:\n    limit: Number of transactions to return (default: 50, max: 100)\n    offset: Pagination offset (default: 0)\n    user: Current authenticated user\n    db_pool: Database connection pool\n\nReturns:\n    List of TokenTransactionResponse\n\nRaises:\n    HTTPException 400: Invalid pagination parameters\n    HTTPException 500: Database error","operationId":"get_transaction_history_tokens_transactions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TokenTransactionResponse"},"title":"Response Get Transaction History Tokens Transactions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tokens/purchase/success":{"get":{"tags":["tokens"],"summary":"Purchase Success","description":"Handle successful purchase redirect from Stripe.\n\nThis endpoint is called when user returns from Stripe after successful payment.\nThe actual token crediting happens via webhook.\n\nArgs:\n    session_id: Stripe checkout session ID\n    user: Current authenticated user\n\nReturns:\n    Success message with session details","operationId":"purchase_success_tokens_purchase_success_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"query","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tokens/auto-reload":{"get":{"tags":["tokens"],"summary":"Get Auto Reload Config","description":"Get user's current auto-reload configuration.\n\nRequirements:\n- T071: GET /tokens/auto-reload endpoint\n- FR-034 to FR-042: Auto-reload configuration\n\nArgs:\n    user: Current authenticated user\n    db_pool: Database connection pool\n\nReturns:\n    AutoReloadConfigResponse with current configuration\n\nRaises:\n    HTTPException 500: Database error","operationId":"get_auto_reload_config_tokens_auto_reload_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoReloadConfigResponse"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["tokens"],"summary":"Configure Auto Reload","description":"Configure auto-reload settings for the user.\n\nRequirements:\n- T070: PUT /tokens/auto-reload endpoint\n- FR-034: Enable auto-reload with threshold (1-100) and amount (min 10)\n- FR-035: Validate payment method on file (TODO: integrate with Stripe)\n\nWorkflow:\n1. Validate request (threshold 1-100, amount >= 10)\n2. TODO: Check user has payment method on file (FR-035)\n3. Update auto-reload configuration in database\n4. Return updated configuration\n\nArgs:\n    request: ConfigureAutoReloadRequest with enabled, threshold, amount\n    user: Current authenticated user\n    db_pool: Database connection pool\n\nReturns:\n    AutoReloadConfigResponse with updated configuration\n\nRaises:\n    HTTPException 400: Invalid configuration\n    HTTPException 402: Payment method required (FR-035, TODO)\n    HTTPException 500: Database error","operationId":"configure_auto_reload_tokens_auto_reload_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigureAutoReloadRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoReloadConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/webhooks/stripe":{"post":{"tags":["webhooks"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.\n\nRequirements:\n- T052: Stripe webhook endpoint\n- FR-018: Credit tokens after successful payment\n- FR-027: Idempotent webhook processing (prevents duplicate credits)\n\nSupported Events:\n- checkout.session.completed: Credit tokens after successful purchase\n\nWorkflow:\n1. Verify webhook signature (security)\n2. Parse event\n3. Process event based on type\n4. Return 200 immediately (Stripe expects fast response)\n\nArgs:\n    request: FastAPI request with raw body\n    stripe_signature: Stripe signature header for verification\n    db_pool: Database connection pool\n\nReturns:\n    200 OK with processing result\n\nRaises:\n    HTTPException 400: Invalid signature or payload\n    HTTPException 500: Processing error (Stripe will retry)","operationId":"stripe_webhook_webhooks_stripe_post","parameters":[{"name":"Stripe-Signature","in":"header","required":false,"schema":{"type":"string","title":"Stripe-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/webhooks/stripe/test":{"get":{"tags":["webhooks"],"summary":"Test Webhook Endpoint","description":"Test endpoint to verify webhook endpoint is reachable.\n\nThis is NOT a real webhook - just for testing connectivity.\n\nReturns:\n    200 OK with message","operationId":"test_webhook_endpoint_webhooks_stripe_test_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/stripe/health":{"get":{"tags":["webhooks"],"summary":"Webhook Health","description":"Webhook delivery health stats for the last N hours (default 24h).\n\nReturns:\n- Total events received\n- Success / failure / skipped counts\n- Success rate %\n- Breakdown by event type\n- 10 most recent failures for quick triage\n\nYAR-296: Stripe webhook monitoring","operationId":"webhook_health_webhooks_stripe_health_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"description":"Lookback window in hours","default":24,"title":"Hours"},"description":"Lookback window in hours"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/webhooks/stripe/reconciliation":{"get":{"tags":["webhooks"],"summary":"Webhook Reconciliation","description":"Revenue reconciliation: detect Stripe payments that didn't result in token credits.\n\nQueries recent checkout.session.completed webhook events and cross-references\nthem against users_token_transactions to find any \"payment without credit\" gaps.\n\nYAR-296: Revenue reconciliation to catch silent webhook failures.","operationId":"webhook_reconciliation_webhooks_stripe_reconciliation_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":72,"minimum":1,"description":"Lookback window in hours","default":24,"title":"Hours"},"description":"Lookback window in hours"},{"name":"alert","in":"query","required":false,"schema":{"type":"boolean","description":"Send Slack alert if gaps found","default":false,"title":"Alert"},"description":"Send Slack alert if gaps found"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscriptions/plans":{"get":{"tags":["subscriptions"],"summary":"List Subscription Plans","description":"List available subscription plans.\n\nRequirements:\n- FR-033: Show Monthly Pro plan details\n- T087: GET /subscriptions/plans endpoint\n\nReturns:\n    List of available subscription plans with pricing and features","operationId":"list_subscription_plans_subscriptions_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SubscriptionPlan"},"type":"array","title":"Response List Subscription Plans Subscriptions Plans Get"}}}}}}},"/subscriptions/subscribe":{"post":{"tags":["subscriptions"],"summary":"Create Subscription","description":"Create Stripe Checkout session for subscription.\n\nRequirements:\n- FR-033: Monthly Pro subscription checkout\n- T088: POST /subscriptions/subscribe endpoint\n\nWorkflow:\n1. Validate plan_id\n2. Create Stripe customer (if needed)\n3. Create Stripe Checkout session\n4. Return session_id and redirect URL\n\nArgs:\n    request: CreateSubscriptionRequest with plan_id and redirect URLs\n    user: Current authenticated user (verified email required)\n    subscription_service: Subscription service\n\nReturns:\n    CreateSubscriptionResponse with Stripe Checkout session URL\n\nRaises:\n    HTTPException 400: Invalid plan_id\n    HTTPException 409: User already has active subscription\n    HTTPException 500: Stripe API error","operationId":"create_subscription_subscriptions_subscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/subscriptions/current":{"get":{"tags":["subscriptions"],"summary":"Get Current Subscription","description":"Get current subscription status for authenticated user.\n\nRequirements:\n- FR-034: Check if user has active subscription\n- T089: GET /subscriptions/current endpoint\n\nArgs:\n    user: Current authenticated user\n    subscription_service: Subscription service\n\nReturns:\n    SubscriptionStatus with current subscription details\n\nRaises:\n    HTTPException 500: Database error","operationId":"get_current_subscription_subscriptions_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatus"}}}}},"security":[{"HTTPBearer":[]}]}},"/subscriptions/cancel":{"post":{"tags":["subscriptions"],"summary":"Cancel Subscription","description":"Cancel subscription (at period end by default).\n\nRequirements:\n- FR-036: Cancel subscription at period end\n- T090: POST /subscriptions/cancel endpoint\n\nWorkflow:\n1. Verify user has active subscription\n2. Cancel in Stripe (at period end or immediately)\n3. Update database\n4. Return cancellation details\n\nArgs:\n    request: CancelSubscriptionRequest with cancel_immediately flag\n    user: Current authenticated user\n    subscription_service: Subscription service\n\nReturns:\n    CancelSubscriptionResponse with cancellation details\n\nRaises:\n    HTTPException 400: No active subscription\n    HTTPException 500: Stripe API error","operationId":"cancel_subscription_subscriptions_cancel_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/subscriptions/portal":{"get":{"tags":["subscriptions"],"summary":"Get Customer Portal","description":"Get Stripe Customer Portal URL for subscription management.\n\nRequirements:\n- FR-037: Customer portal for self-service subscription management\n- T091: GET /subscriptions/portal endpoint\n\nThe customer portal allows users to:\n- Update payment method\n- View invoices\n- Download receipts\n- Update billing information\n- Cancel subscription\n\nArgs:\n    return_url: URL to return to after portal session (query param)\n    user: Current authenticated user\n    subscription_service: Subscription service\n\nReturns:\n    CustomerPortalResponse with portal URL\n\nRaises:\n    HTTPException 400: User has no Stripe customer ID\n    HTTPException 500: Stripe API error","operationId":"get_customer_portal_subscriptions_portal_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"return_url","in":"query","required":true,"schema":{"type":"string","title":"Return Url"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscriptions/pro/status":{"get":{"tags":["subscriptions"],"summary":"Get Pro Usage Status","description":"Get Pro Mode usage status including quota and G3P credit balance.\n\nReturns:\n    ProUsageStatus with:\n    - has_pro_access: Whether user has active Pro subscription\n    - quota_used/quota_total/quota_remaining: Monthly quota info\n    - g3p_credits_available: Purchased G3P credits\n    - total_generations_available: Combined quota + G3P credits\n    - can_generate: Whether user can generate right now","operationId":"get_pro_usage_status_subscriptions_pro_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProUsageStatus"}}}}},"security":[{"HTTPBearer":[]}]}},"/subscriptions/pro/g3p-credits":{"get":{"tags":["subscriptions"],"summary":"List G3P Credit Packs","description":"List available G3P credit packs for purchase.\n\nG3P credits are used for Pro Mode generations using Gemini 3 Pro.\nThey are distinct from regular homeowner credits.\n\nReturns:\n    List of G3PCreditPack with pricing and discount info","operationId":"list_g3p_credit_packs_subscriptions_pro_g3p_credits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/G3PCreditPack"},"type":"array","title":"Response List G3P Credit Packs Subscriptions Pro G3P Credits Get"}}}}}}},"/subscriptions/pro/g3p-credits/purchase":{"post":{"tags":["subscriptions"],"summary":"Purchase G3P Credits","description":"Create Stripe Checkout session for G3P credit purchase.\n\nG3P credits are used for Pro Mode generations using Gemini 3 Pro.\nThey are distinct from regular homeowner credits.\n\nArgs:\n    request: G3PCreditPurchaseRequest with pack_id and redirect URLs\n\nReturns:\n    G3PCreditPurchaseResponse with Stripe Checkout session URL","operationId":"purchase_g3p_credits_subscriptions_pro_g3p_credits_purchase_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/G3PCreditPurchaseRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/G3PCreditPurchaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/subscriptions/pro/history":{"get":{"tags":["subscriptions"],"summary":"Get Pro Usage History","description":"Get Pro Mode usage history.\n\nReturns:\n    List of usage records with timestamps and details","operationId":"get_pro_usage_history_subscriptions_pro_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/balance":{"get":{"tags":["credits"],"summary":"Get Unified Balance","description":"Get unified balance for all credit types.\n\nReturns detailed balance information for trial and token credits\nin a single atomic database query. Replaces individual balance endpoints\nfor better performance and consistency.\n\n**Performance:** Target <100ms response time with optimized LEFT JOIN query.\n\n**Response:**\n```json\n{\n    \"trial\": {\n        \"remaining\": 2,\n        \"used\": 1,\n        \"total_granted\": 3\n    },\n    \"token\": {\n        \"balance\": 50,\n        \"total_purchased\": 100,\n        \"total_spent\": 48,\n        \"total_refunded\": 2\n    }\n}\n```\n\n**Use Cases:**\n- Frontend credit display components\n- Credit status checks before operations\n- Admin dashboard balance views\n- Generation eligibility checks\n\nArgs:\n    current_user: Authenticated user (injected by dependency)\n    credit_service: Unified credit service (injected)\n\nReturns:\n    UnifiedBalanceResponse with detailed balances for all credit types\n\nRaises:\n    HTTPException 404: User not found in database\n    HTTPException 500: Database query error","operationId":"get_unified_balance_v1_credits_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedBalanceResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/credits/balance/simple":{"get":{"tags":["credits"],"summary":"Get Simple Balance","description":"Get lightweight balance (numbers only, no metadata).\n\nOptimized endpoint for cases where only current balances are needed\nwithout detailed metadata. Uses single LEFT JOIN query for optimal performance.\n\n**Performance:** Target <50ms response time (faster than detailed endpoint).\n\n**Response:**\n```json\n{\n    \"trial\": 2,\n    \"token\": 50\n}\n```\n\n**Use Cases:**\n- Quick balance checks in middleware\n- Pre-flight checks before operations\n- High-frequency polling scenarios\n\nArgs:\n    current_user: Authenticated user (injected by dependency)\n    credit_service: Unified credit service (injected)\n\nReturns:\n    SimpleBalanceResponse with just the balance numbers\n\nRaises:\n    HTTPException 404: User not found in database\n    HTTPException 500: Database query error","operationId":"get_simple_balance_v1_credits_balance_simple_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleBalanceResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/feedback":{"post":{"tags":["feedback"],"summary":"Submit feedback","description":"Submit user feedback.\n\nAnyone can submit feedback (logged in or not).\nIf logged in, user_id is automatically captured.","operationId":"submit_feedback_feedback_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["feedback"],"summary":"Get all feedback (admin only)","description":"Get all feedback submissions.\n\n**Admin only** - requires admin role.\n\nQuery parameters:\n- status: Filter by status (new, reviewed, implemented, dismissed)\n- limit: Maximum results (default: 100)\n- offset: Pagination offset (default: 0)","operationId":"get_feedback_feedback_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FeedbackResponse"},"title":"Response Get Feedback Feedback Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feedback/{feedback_id}":{"patch":{"tags":["feedback"],"summary":"Update feedback (admin only)","description":"Update feedback record.\n\n**Admin only** - requires admin role.","operationId":"update_feedback_feedback__feedback_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"feedback_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Feedback Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes":{"get":{"tags":["property-passes"],"summary":"List Property Passes","description":"List all property passes for the current user.\n\nReturns both active and optionally expired passes.","operationId":"list_property_passes_v1_property_passes_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"include_expired","in":"query","required":false,"schema":{"type":"boolean","description":"Include expired passes","default":true,"title":"Include Expired"},"description":"Include expired passes"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPassListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes/social-share/confirm":{"post":{"tags":["property-passes"],"summary":"Confirm Social Share","description":"Confirm social share and grant a free 5-day property pass.\n\nHonor-system verification — user self-confirms they shared.\nRate limit: 1 active social share pass per address per 5 days.","operationId":"confirm_social_share_v1_property_passes_social_share_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SocialShareConfirmRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SocialShareConfirmResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/property-passes/social-share/status":{"get":{"tags":["property-passes"],"summary":"Get Social Share Status","description":"Check if user has an active social share pass for a specific address.\nUsed by the frontend to show pass status on results page.","operationId":"get_social_share_status_v1_property_passes_social_share_status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"place_id","in":"query","required":true,"schema":{"type":"string","description":"Google Place ID to check","title":"Place Id"},"description":"Google Place ID to check"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPassCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes/check":{"get":{"tags":["property-passes"],"summary":"Check Property Pass","description":"Check if user has an active property pass for a specific address.\n\nUsed by the generation form to determine if user can generate\nunlimited designs for this address.","operationId":"check_property_pass_v1_property_passes_check_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"place_id","in":"query","required":true,"schema":{"type":"string","description":"Google Place ID to check","title":"Place Id"},"description":"Google Place ID to check"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPassCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes/checkout":{"post":{"tags":["property-passes"],"summary":"Create Property Pass Checkout","description":"Create Stripe Checkout session for property pass purchase.\n\nAfter successful payment, webhook will create the property pass.","operationId":"create_property_pass_checkout_v1_property_passes_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPassCheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPassCheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/property-passes/{pass_id}":{"get":{"tags":["property-passes"],"summary":"Get Property Pass","description":"Get details for a specific property pass.","operationId":"get_property_pass_v1_property_passes__pass_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"pass_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Pass Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyPassResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes/{pass_id}/generations-count":{"get":{"tags":["property-passes"],"summary":"Get Pass Generation Count","description":"Get the number of generations made using this property pass.","operationId":"get_pass_generation_count_v1_property_passes__pass_id__generations_count_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"pass_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Pass Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes/purchase/success":{"get":{"tags":["property-passes"],"summary":"Verify Property Pass Purchase","description":"Verify property pass purchase was successful.\n\nCalled by success page to confirm purchase and display pass details.","operationId":"verify_property_pass_purchase_v1_property_passes_purchase_success_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"query","required":true,"schema":{"type":"string","description":"Stripe checkout session ID","title":"Session Id"},"description":"Stripe checkout session ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/property-passes/{pass_id}/generate-cad":{"post":{"tags":["property-passes"],"summary":"Generate Property Pass Cad","description":"Generate a professional 2D landscape site plan for Property Pass holders.\n\nUses satellite imagery + Gemini 2.5 Flash for cost-effective generation.\nStreams progress via Server-Sent Events (SSE).\n\nPipeline:\n1. Validate Property Pass is active for this place_id\n2. Fetch satellite image (Google Maps Static API)\n3. Analyze site for street edge detection\n4. Generate 2D landscape plan with Gemini\n5. Upload result to blob storage\n6. Return via SSE stream","operationId":"generate_property_pass_cad_v1_property_passes__pass_id__generate_cad_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"pass_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Pass Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CADGenerationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/proxy-map":{"post":{"tags":["pro-mode"],"summary":"Proxy Google Map","description":"Proxy Google Maps Static API requests.\n\nThis endpoint allows the frontend to fetch satellite images without CORS issues.\nThe backend fetches the image server-side using the API key.\n\nNote: This replaces the need for a separate proxy server (server.js in pro_mode/).","operationId":"proxy_google_map_v1_pro_mode_proxy_map_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyMapRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyMapResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/satellite-image":{"post":{"tags":["pro-mode"],"summary":"Get Satellite Image","description":"Get satellite image for an address using existing MapsService.\n\nThis uses the Railway backend's existing geocoding and satellite fetch\ncapabilities - no proxy workaround needed.","operationId":"get_satellite_image_v1_pro_mode_satellite_image_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_get_satellite_image_v1_pro_mode_satellite_image_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/align-coordinates":{"post":{"tags":["pro-mode"],"summary":"Align Coordinates","description":"Use AI vision to align coordinates to the correct property.\n\nGoogle Geocoding often returns RANGE_INTERPOLATED results for residential\naddresses, which can be ~30ft off from the actual property center. This\nendpoint uses Gemini's vision capabilities to:\n\n1. Fetch satellite image at the geocoded coordinates\n2. Ask Gemini to identify the target property by house number\n3. Calculate the pixel offset from image center to property center\n4. Convert pixel offset to lat/lng correction\n\nAt zoom 20 with 600x400 image:\n- Approximately 0.3 feet per pixel\n- Image covers roughly 180ft x 120ft\n- Typical correction: 10-50ft adjustment","operationId":"align_coordinates_v1_pro_mode_align_coordinates_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlignCoordinatesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlignCoordinatesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/detect-boundary-polygon":{"post":{"tags":["pro-mode"],"summary":"Detect Boundary Polygon","description":"Detect property boundary polygon vertices from satellite imagery.\n\nReturns SSE stream with keepalive heartbeats during Gemini call,\nthen a single 'result' event with normalized (0-1) pixel coordinates.\nNo auth required - lightweight utility for Step 2 preview.","operationId":"detect_boundary_polygon_v1_pro_mode_detect_boundary_polygon_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectBoundaryPolygonRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/analyze-inspiration":{"post":{"tags":["pro-mode"],"summary":"Analyze Inspiration","description":"YAR-95: Analyze inspiration photos to extract design direction.\n\nTakes 1-5 inspiration photos with user captions and uses Gemini Flash\nto identify the detected design style, features, mood, materials,\nand generate a custom prompt for generation.\n\nNo auth required — lightweight analysis utility.","operationId":"analyze_inspiration_v1_pro_mode_analyze_inspiration_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeInspirationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeInspirationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/analyze-property":{"post":{"tags":["pro-mode"],"summary":"Analyze Property","description":"Pipeline Call 1: Unified property analysis (prefetch).\n\nReturns SSE stream with keepalive heartbeats during Gemini call,\nthen a single 'result' event with analysis_json and boundary overlay.\n\nNo auth required — lightweight prefetch for pipeline acceleration.","operationId":"analyze_property_v1_pro_mode_analyze_property_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzePropertyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/detect-feature-positions":{"post":{"tags":["pro-mode"],"summary":"Detect Feature Positions","description":"Detect positions of key features in a generated landscape design image.\n\nThis endpoint analyzes a generated design image and returns the visual\npositions of:\n1. Front yard area - where the front yard appears in the image\n2. Backyard area - where the backyard appears in the image\n3. Key feature - where the main user-selected feature appears (e.g., pool, pergola)\n\nPositions are returned as percentages (0-100) where:\n- X: 0 = left edge, 100 = right edge\n- Y: 0 = top edge, 100 = bottom edge\n\nUse these positions to place interactive viewpoint dots on the UI.","operationId":"detect_feature_positions_v1_pro_mode_detect_feature_positions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectFeaturePositionsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectFeaturePositionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/detect-all-feature-positions":{"post":{"tags":["pro-mode"],"summary":"Detect All Feature Positions","description":"Detect positions of ALL features in a generated landscape design image.\n\nThis endpoint analyzes a generated design image and returns the visual\npositions of all specified features plus front yard and backyard areas.\n\nPositions are returned as percentages (0-100) where:\n- X: 0 = left edge, 100 = right edge\n- Y: 0 = top edge, 100 = bottom edge\n\nUse these positions to place interactive viewpoint dots on the UI.","operationId":"detect_all_feature_positions_v1_pro_mode_detect_all_feature_positions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectAllFeaturePositionsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectAllFeaturePositionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/estimate-materials":{"post":{"tags":["pro-mode"],"summary":"Estimate Materials","description":"Analyze a landscape design image and estimate materials, quantities, and pricing.\n\nThis endpoint uses AI vision to:\n1. Detect all hardscaping and softscaping elements in the design\n2. Estimate quantities (square feet, linear feet, or units)\n3. Apply unit pricing and labor rates\n4. Return a complete bill of materials with cost estimates\n\nUse this to pre-populate proposal pricing for partners.","operationId":"estimate_materials_v1_pro_mode_estimate_materials_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateMaterialsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateMaterialsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/analyze-reference-design":{"post":{"tags":["pro-mode"],"summary":"Analyze Reference Design","description":"Analyze a generated reference design image to extract design elements\nwith dimensions and a recommended 3D camera viewpoint.\n\nCalled after generation completes. Non-blocking from the user's perspective.\nReturns design elements (name, material, dimensions) and a recommended\nviewpoint position for 3D rendering.","operationId":"analyze_reference_design_v1_pro_mode_analyze_reference_design_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeReferenceDesignRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeReferenceDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/optimize-backyard-camera":{"post":{"tags":["pro-mode"],"summary":"Optimize Backyard Camera","description":"Evaluate a 3D tiles backyard screenshot and suggest camera adjustments.\n\nThis endpoint uses AI vision to analyze how well the current camera\nposition captures the backyard of a property. It returns:\n- Quality score (1-10)\n- Detailed criteria scores\n- Specific adjustment recommendations\n- Suggested new camera parameters\n\nThe frontend can call this iteratively (max 3 times) to refine the view\nuntil quality_score >= 7 or is_acceptable = true.\n\nCost: ~$0.001 per call (uses gemini-3-flash-preview for fast analysis)","operationId":"optimize_backyard_camera_v1_pro_mode_optimize_backyard_camera_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimizeBackyardCameraRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimizeBackyardCameraResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/get-initial-camera-position":{"post":{"tags":["pro-mode"],"summary":"Get Initial Camera Position","description":"Get recommended initial camera position for backyard view based on street edge.\n\nThis returns the \"golden shot\" parameters tuned from the reference property\n(2164 Lakewood Ct, San Jose, CA), rotated appropriately for the detected\nstreet edge orientation.\n\nUse this before calling /optimize-backyard-camera to get a good starting point.","operationId":"get_initial_camera_position_v1_pro_mode_get_initial_camera_position_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInitialCameraPositionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInitialCameraPositionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/calculate-backyard-camera":{"post":{"tags":["pro-mode"],"summary":"Calculate Backyard Camera","description":"Calculate optimal backyard camera position using the TIERED orientation detection system.\n\nTIERED DETECTION ALGORITHM (in order of preference):\n\nTIER 1 - Street View Metadata (FREE, <100ms):\n- Uses Street View Metadata API to find camera position that photographed the house\n- Calculates heading from camera to house = house front direction\n- Confidence: HIGH when available\n\nTIER 2 - Gemini 3 Flash Satellite Analysis (~2-3s):\n- Uses AI vision to analyze satellite image\n- Detects driveway, garage, and front door position\n- Infers house orientation from these features\n- Confidence: MEDIUM (requires satellite_image_base64 in request)\n\nTIER 3 - Default Assumption (instant):\n- Fallback when other methods fail\n- Assumes house faces South (common US suburb orientation)\n- Confidence: LOW\n\nCAMERA POSITIONING (after orientation detected):\n1. Calculate backyard direction = house_heading + 180°\n2. Add 15° diagonal offset for natural perspective\n3. Use Haversine formula to position camera behind house\n4. Set altitude to 180m for wide property overview\n\nCost: FREE for Tier 1, ~$0.001 for Tier 2\nSpeed: <100ms (Tier 1), 2-3s (Tier 2), instant (Tier 3)","operationId":"calculate_backyard_camera_v1_pro_mode_calculate_backyard_camera_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalculateBackyardCameraRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalculateBackyardCameraResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/enhance":{"post":{"tags":["pro-mode"],"summary":"Enhance Image","description":"Enhance satellite image to CAD-style base plan.\n\nStep 1 of the Pro Mode pipeline.","operationId":"enhance_image_v1_pro_mode_enhance_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnhanceImageRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnhanceImageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/design-to-cad":{"post":{"tags":["pro-mode"],"summary":"Design To Cad","description":"Convert a rendered landscape design to professional CAD drawing.\n\nTakes an existing landscape design rendering (with pools, patios,\nlabels, dimensions) and transforms it into a clean architectural\nCAD-style site plan suitable for:\n- Client presentation\n- Contractor documentation\n- Permit submission\n- Professional portfolio\n\nSupports two CAD styles:\n- \"2D\": Flat top-down architectural plan - when satellite provided, generates FRESH from satellite\n- \"Oblique\": 3D axonometric/isometric view\n\nFor CAD 2D with satellite image:\n- Uses satellite as PRIMARY input (not conversion from 3D)\n- Generates true flat blueprint directly from aerial view\n- This produces better results than converting a 3D rendered image","operationId":"design_to_cad_v1_pro_mode_design_to_cad_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignToCADRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignToCADResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/analyze":{"post":{"tags":["pro-mode"],"summary":"Analyze Site","description":"Analyze site features from satellite/CAD image.\n\nStep 2 of the Pro Mode pipeline.\nReturns scale calibration and site geometry.","operationId":"analyze_site_v1_pro_mode_analyze_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeSiteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAnalysisResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/generate-full-stream":{"post":{"tags":["pro-mode"],"summary":"Generate Full Pipeline Stream","description":"Run the complete Pro Mode pipeline with Server-Sent Events (SSE) streaming.\n\nRequires authentication and Pro Mode quota/tokens.\n\nSends real-time progress updates to the frontend as each step completes.\nUses parallel processing for enhance + analyze steps to improve performance.\n\nQuota/Token System:\n- Pro subscribers get monthly quota (100 for Pro, 200 for Pro Plus)\n- Additional generations available via Pro tokens\n- Deduction happens atomically before generation starts\n- Refund on generation failure\n\nSSE Events:\n- progress: Step completion updates with satellite image when available\n- result: Final design result\n- error: Error information\n\nSteps:\n1. Geocode address -> coordinates\n2. Fetch satellite image (sent immediately to frontend)\n3. Enhance to CAD + Analyze site (PARALLEL - saves ~3-4 seconds)\n4. Generate 2D landscape design","operationId":"generate_full_pipeline_stream_v1_pro_mode_generate_full_stream_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneratePlanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/generate-from-upload":{"post":{"tags":["pro-mode"],"summary":"Generate From Upload","description":"Generate 2D landscape plan from uploaded image.\n\nUse this when user provides their own image (satellite screenshot or 3D tiles).\n\nArgs:\n    skip_cad_enhance: Set True for 3D tiles (already rendered, don't need CAD conversion).\n                     This saves ~$0.134 per generation!\n    use_flash_model: Set True to use Gemini 2.5 Flash Image instead of Gemini 3 Pro.\n                    Flash is 3.4x cheaper ($0.039 vs $0.134) but may have lower quality.\n    is_3d_tiles: Set True when input is a 3D tiles screenshot (perspective view).\n                This uses specialized prompts for photorealistic or CAD rendering.\n    map_style: Output style - \"Colorful\", \"CAD Oblique\", or \"CAD 2D\"\n    ai_model: Optional AI model override (default: gemini-3.1-flash-image-preview)","operationId":"generate_from_upload_v1_pro_mode_generate_from_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_generate_from_upload_v1_pro_mode_generate_from_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneratePlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/generate-multi-source-fusion":{"post":{"tags":["pro-mode"],"summary":"Generate Multi Source Fusion","description":"MULTI-SOURCE FUSION: Generate landscape plan using 3D tiles + 2D satellite + Street View.\n\nRequires authentication and Pro Mode quota/credits (or freemium trial).\n\nThis endpoint combines multiple visual sources for more accurate generation:\n- 3D Tiles Screenshot: Shows backyard perspective, depth, existing features\n- 2D Satellite Image: Accurate property boundaries and lot dimensions\n- Street View (optional): House facade and front yard context\n\nFusion Modes:\n- **standard**: Forces TOP-DOWN 2D output (like satellite view) - good for CAD 2D\n- **oblique**: Preserves 45° 3D tiles perspective - best quality, good for CAD Oblique\n\nKey benefits:\n- Addresses pitch distortion in 3D views (yard looks smaller than it is)\n- Shows what's behind fences (3D view) that satellite might miss\n- Front yard context from Street View informs driveway placement\n- Oblique mode preserves depth perception for better 3D-like outputs","operationId":"generate_multi_source_fusion_v1_pro_mode_generate_multi_source_fusion_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MultiSourceFusionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneratePlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/generate-multi-source-fusion-stream":{"post":{"tags":["pro-mode"],"summary":"Generate Multi Source Fusion Stream","description":"SSE streaming version of /generate-multi-source-fusion.\n\nSends the 2D site plan immediately after Call 2 completes, then streams\noblique views individually as they finish. This lets the frontend show\nthe primary design ~15-20s earlier instead of waiting for all images.\n\nSSE Events (in order):\n- progress: Step updates (analyzing, designing, obliques)\n- plan_ready: 2D site plan with base64 image + layout\n- oblique_ready: Each oblique view as it completes (label + image)\n- complete: Final metadata (smart dots, material estimation)\n- error: On failure, includes refund status","operationId":"generate_multi_source_fusion_stream_v1_pro_mode_generate_multi_source_fusion_stream_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MultiSourceFusionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/render-ground-level":{"post":{"tags":["pro-mode"],"summary":"Render Ground Level","description":"Generate photorealistic ground-level 3D rendering from 2D design plan.\n\nTransforms the top-down 2D landscape plan into a perspective view\nas if standing in the yard looking at the design.\n\nUses the layout_description from 2D generation to ensure exact coherence\nbetween the 2D plan and 3D rendering (feature positions, sizes, adjacencies).\n\nView angles:\n- front_yard: Uses Google Street View as base, facing the house\n- backyard: Standing at back of property looking toward house\n- pool_area: Standing near pool looking across entertainment space\n- patio: Standing on patio looking across yard\n- side_yard: Along the side of the house","operationId":"render_ground_level_v1_pro_mode_render_ground_level_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderGroundLevelRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderGroundLevelResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/save-generation":{"post":{"tags":["pro-mode"],"summary":"Save Pro Mode Generation","description":"Save a Pro Mode 2D generation to the user's history.\n\nThis endpoint:\n1. Checks storage quota before uploading (YAR-73)\n2. Uploads design image to Vercel Blob storage\n3. Optionally uploads satellite image\n4. Creates a record in the generations table with generation_type='pro_2d_site_plan'\n5. Stores Pro Mode metadata (style, features, site_analysis, layout_description)\n6. Updates user's storage_used_bytes (YAR-73)\n\nReturns generation_id for linking 3D renderings.\n\nRaises:\n- 413 Payload Too Large: If user has exceeded storage quota","operationId":"save_pro_mode_generation_v1_pro_mode_save_generation_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveProModeGenerationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveProModeGenerationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/generations/{generation_id}/status":{"get":{"tags":["pro-mode"],"summary":"Get Generation Status","description":"Poll the status of an async generation (YAR-276).\n\nReturns the current pipeline status and results if completed.\nFrontend polls this every 3-5 seconds when reconnecting to an\nin-progress generation.","operationId":"get_generation_status_v1_pro_mode_generations__generation_id__status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/generations/active":{"get":{"tags":["pro-mode"],"summary":"Get Active Generation","description":"Check if the current user has an active (processing or recently completed)\ngeneration for reconnection detection (YAR-276).\n\nCalled on Pro Mode page load to detect if there's a generation to resume or show.","operationId":"get_active_generation_v1_pro_mode_generations_active_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/save-rendering":{"post":{"tags":["pro-mode"],"summary":"Save Pro Mode Rendering","description":"Save a Pro Mode 3D rendering to the user's history.\n\nLinks to an existing 2D generation via generation_id.\n\nThis endpoint:\n1. Validates the parent generation exists and belongs to user\n2. Uploads rendering image to Vercel Blob storage\n3. Creates a record in pro_mode_renderings table","operationId":"save_pro_mode_rendering_v1_pro_mode_save_rendering_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveProModeRenderingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveProModeRenderingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/my-designs":{"get":{"tags":["pro-mode"],"summary":"Get My Designs","description":"Get the current user's Pro Mode generation history.\n\nReturns a paginated list of designs with thumbnails for gallery display.\nSupports filtering for favorites-only.","operationId":"get_my_designs_v1_pro_mode_my_designs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"favorites_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Favorites Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyDesignsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/my-designs/{generation_id}":{"get":{"tags":["pro-mode"],"summary":"Get Generation Detail","description":"Get full details of a single Pro Mode generation.\n\nReturns all metadata, renderings, and variants for loading a saved design.","operationId":"get_generation_detail_v1_pro_mode_my_designs__generation_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerationDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/my-designs/{generation_id}/favorite":{"patch":{"tags":["pro-mode"],"summary":"Toggle Favorite","description":"Toggle favorite status for a generation.\nFavorited designs are exempt from auto-deletion.","operationId":"toggle_favorite_v1_pro_mode_my_designs__generation_id__favorite_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/save-variant":{"post":{"tags":["pro-mode"],"summary":"Save Design Variant","description":"Save a design variant (CAD conversion) to an existing generation.\n\nDesign variants allow users to have multiple styles (Colorful, CAD 2D, CAD Oblique)\nfor the same property design while maintaining layout consistency.\n\nThis endpoint:\n1. Validates the parent generation exists and belongs to user\n2. Uploads variant image to Vercel Blob storage\n3. Updates pro_mode_metadata.variants array in the generations table","operationId":"save_design_variant_v1_pro_mode_save_variant_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveDesignVariantRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveDesignVariantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/analyze-shot":{"post":{"tags":["pro-mode"],"summary":"Analyze Shot Endpoint","description":"Analyze a 3D view screenshot to determine shot quality and recommend adjustments.\n\nThis endpoint uses OpenCV to:\n1. Detect the red Yarda property marker position\n2. Calculate how well-centered the property is\n3. Analyze sky/vegetation/building percentages\n4. Recommend camera adjustments to achieve 80%+ property fill\n\nThe frontend can call this in a loop, applying adjustments until is_acceptable=True.\n\nNo authentication required - this is a utility endpoint for shot refinement.","operationId":"analyze_shot_endpoint_v1_pro_mode_analyze_shot_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeShotRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeShotResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/walkthrough-viewpoints":{"get":{"tags":["pro-mode"],"summary":"Get Walkthrough Viewpoints","description":"Get available viewpoints for walkthrough generation.\n\nIf generation_id is provided, returns viewpoints tailored to that generation's\nlayout (including feature-specific viewpoints like pool_deck if a pool exists).\nOtherwise returns all core viewpoints.\n\nNo auth required - this is a configuration endpoint.","operationId":"get_walkthrough_viewpoints_v1_pro_mode_walkthrough_viewpoints_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalkthroughViewpointsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/generate-walkthrough":{"post":{"tags":["pro-mode"],"summary":"Generate Walkthrough","description":"Generate multiple 3D views for a walkthrough experience.\n\nFetches the saved generation data, downloads reference images from blob\nstorage, and generates oblique views from different camera angles using\nthe same generate_oblique_from_plan() pipeline as Calls 3/4.\n\nSSE events:\n- start: Generation starting with total viewpoint count\n- viewpoint_start: Starting generation for a viewpoint\n- viewpoint_complete: Viewpoint generation complete with image URL\n- viewpoint_error: Error generating a specific viewpoint\n- complete: All viewpoints generated\n- error: Fatal error, generation stopped\n\nEach viewpoint costs 1 G3P credit.","operationId":"generate_walkthrough_v1_pro_mode_generate_walkthrough_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateWalkthroughRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/generate-high-angle-3d":{"post":{"tags":["pro-mode"],"summary":"Generate High Angle 3D","description":"Generate a high-angle 3D bird's-eye perspective of the full property.\n\nTakes a generation_id, fetches the saved satellite image and layout from\nthe existing generation, and produces a colored 3D bird's-eye view with\nlabeled landscape features. Costs 1 credit. Pro subscribers only.","operationId":"generate_high_angle_3d_v1_pro_mode_generate_high_angle_3d_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateHighAngle3DRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateHighAngle3DResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/score-camera-view":{"post":{"tags":["pro-mode"],"summary":"Score Camera View V27","description":"Score a camera view using the v27 auto-tuning algorithm.\n\nThis endpoint evaluates a 3D rendered screenshot and returns:\n- 4-dimension scores (orientation, isolation, geometry, visibility)\n- Composite weighted score\n- Whether to accept this camera position\n- Recommended adjustments if not accepted\n\nThe v27 algorithm is orientation-heavy (40% weight) with isolation\nas secondary (25%). Early exit is allowed if composite >= 7.0 AND\n(isolation >= 6.0 OR orientation >= 8.0).","operationId":"score_camera_view_v27_v1_pro_mode_score_camera_view_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V27ScoreCameraViewRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V27ScoreCameraViewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/auto-tune-camera":{"post":{"tags":["pro-mode"],"summary":"Auto Tune Camera V27","description":"Run the complete v27 auto-tuning loop for a camera position.\n\nThis endpoint:\n1. Starts with initial camera parameters\n2. Scores the view using Gemini\n3. If not accepted, calculates adjustments\n4. Repeats up to max_iterations (default: 2)\n5. Returns the best position found\n\nNote: This endpoint does NOT capture screenshots - that must be done\nby the frontend. Use the /score-camera-view endpoint for iterative\nscoring during the frontend capture loop.\n\nFor full auto-tuning with screenshots, the frontend should:\n1. Capture initial screenshot\n2. Call /score-camera-view\n3. If not accepted, apply adjustments, capture new screenshot\n4. Repeat until accepted or max iterations","operationId":"auto_tune_camera_v27_v1_pro_mode_auto_tune_camera_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V27AutoTuneCameraRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V27AutoTuneCameraResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/autocam-config":{"get":{"tags":["pro-mode"],"summary":"Get Autocam V27 Config","description":"Get the v27 autocam algorithm configuration.\n\nReturns all configurable parameters including:\n- Scoring weights\n- Acceptance thresholds\n- Parameter bounds (FOV, distance, pitch, altitude)\n- Lot size defaults\n- Regional achievability rates\n\nThis endpoint is useful for:\n- Frontend display of scoring weights\n- Debugging parameter tuning\n- Documentation","operationId":"get_autocam_v27_config_v1_pro_mode_autocam_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V27ConfigResponse"}}}}}}},"/v1/pro-mode/plan-to-render/parse":{"post":{"tags":["pro-mode"],"summary":"Parse Landscape Plan","description":"YAR-234: Parse a 2D landscape plan and extract features.\n\nStep 1 of Plan-to-Render: Analyze the uploaded plan and extract\nall design elements, dimensions, and materials.\n\nSupports:\n- PDF files (single or multi-page)\n- Images (PNG, JPEG, HEIC)\n\nReturns extracted features for user review before render generation.","operationId":"parse_landscape_plan_v1_pro_mode_plan_to_render_parse_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanToRenderRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/plan-to-render/generate":{"post":{"tags":["pro-mode"],"summary":"Generate Plan Renders","description":"YAR-234: Generate photorealistic renders from a parsed 2D landscape plan.\n\nStep 2 of Plan-to-Render: SSE streaming endpoint that generates\n8-12 photorealistic 3D renders from the parsed plan.\n\nFeatures:\n- Day and night variants (minimum 4 each)\n- Multiple perspectives (backyard, patio, pool area, etc.)\n- House photo matching (if provided)\n- Real-time progress updates via SSE\n\nIncluded in Pro Mode subscription.","operationId":"generate_plan_renders_v1_pro_mode_plan_to_render_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanToRenderRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/refine":{"post":{"tags":["pro-mode"],"summary":"Refine Design","description":"YAR-247: Refine an existing design using NB2 multi-turn conversational editing.\n\nAccepts a session_id (to retrieve previous generation context) and\na natural language instruction for what to change. Sends the original\nimage + instruction to NB2 as a refinement turn and returns the\nmodified image.\n\nRequires Pro Mode subscription or active trial.","operationId":"refine_design_v1_pro_mode_refine_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefineDesignRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefineDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/regenerate-oblique":{"post":{"tags":["pro-mode"],"summary":"Regenerate Oblique","description":"YAR-292: Regenerate a single oblique view to match an updated 2D plan.\n\nCosts 1 credit. Uses the same pipeline as Call 3/4 but as a standalone\nendpoint so users can regenerate obliques after fine-tuning the 2D plan.\n\nFlow:\n1. Validate generation exists and belongs to user\n2. Check authorization hierarchy (subscription > trial > token)\n3. Deduct 1 credit atomically\n4. Call generate_oblique_from_plan() with the updated plan\n5. Upload result to storage\n6. Update generation record with new oblique URL\n7. Return the new oblique image","operationId":"regenerate_oblique_v1_pro_mode_regenerate_oblique_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateObliqueRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateObliqueResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/showcase":{"get":{"tags":["pro-mode"],"summary":"Get Showcase Designs","description":"Public endpoint (no auth required) returning recent Pro Mode designs\nfrom demo/test accounts for the promo page carousel.\nResults are cached for 5 minutes.","operationId":"get_showcase_designs_v1_pro_mode_showcase_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShowcaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/send-neighbor-design":{"post":{"tags":["pro-mode"],"summary":"Send Neighbor Design","description":"Send a landscape design to a neighbor via email.\n\nThis endpoint supports the viral \"Design Your Neighbor's Yard\" loop (YAR-920).\nRate limited to 10 requests per minute per IP to prevent abuse.\n\nSecurity (YAR-948):\n- Validates design_image_url is from a trusted domain (vercel-storage.com, etc.)\n- Rejects javascript:, data:, and other dangerous URL schemes\n- HTML-escapes all user-provided text in the email","operationId":"send_neighbor_design_v1_pro_mode_send_neighbor_design_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendNeighborDesignRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendNeighborDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pro-mode/editor/detect-footprint":{"post":{"tags":["pro-mode"],"summary":"Detect Footprint","description":"Detect the building footprint polygon from satellite imagery.\n\nAccepts either:\n- generation_id: fetches satellite image from the saved generation\n- satellite_image_base64 / satellite_image_url: direct image input\n\nReturns a polygon in meters relative to the property center plus metadata.\nRequires authentication (pro users only in production).","operationId":"detect_footprint_v1_pro_mode_editor_detect_footprint_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectFootprintRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectFootprintResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/editor/generate-floorplan":{"post":{"tags":["pro-mode"],"summary":"Generate Floorplan","description":"Generate a plausible interior floor plan from a building footprint polygon.\n\nAccepts the outer footprint in meters (relative to property center) and\nreturns interior wall segments plus labeled room polygons.\nRequires authentication.","operationId":"generate_floorplan_v1_pro_mode_editor_generate_floorplan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateFloorplanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateFloorplanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/pro-mode/editor/{generation_id}/scene":{"put":{"tags":["pro-mode"],"summary":"Save Editor Scene","description":"Save (upsert) the editor scene JSON for a Pro Mode generation.\n\nThe scene is stored in the editor_scene JSONB column on the generations\ntable. Overwrites any previously saved scene for this generation.\nRequires authentication and ownership of the generation.","operationId":"save_editor_scene_v1_pro_mode_editor__generation_id__scene_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveEditorSceneRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveEditorSceneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["pro-mode"],"summary":"Load Editor Scene","description":"Load the editor scene JSON for a Pro Mode generation.\n\nReturns the previously saved scene dict, or scene=null if none has been\nsaved yet. Requires authentication and ownership of the generation.","operationId":"load_editor_scene_v1_pro_mode_editor__generation_id__scene_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoadEditorSceneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/promo/validate/{code}":{"get":{"tags":["promo"],"summary":"Validate Promo Code","description":"Validate a promo code without redeeming it.\n\nThis endpoint can be called with or without authentication.\nIf authenticated, email restrictions will be validated.\n\nArgs:\n    code: The promo code to validate\n\nReturns:\n    PromoCodeInfo with validation status","operationId":"validate_promo_code_promo_validate__code__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoCodeInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/promo/redeem":{"post":{"tags":["promo"],"summary":"Redeem Promo Code","description":"Redeem a promo code and grant Pro access.\n\nRequires authentication. The user will receive Pro subscription\naccess for the duration specified by the code.\n\nArgs:\n    request: Contains the promo code to redeem\n\nReturns:\n    RedeemPromoCodeResponse with result and subscription details","operationId":"redeem_promo_code_promo_redeem_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemPromoCodeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemPromoCodeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/promo/redemptions":{"get":{"tags":["promo"],"summary":"Get User Redemptions","description":"Get all promo code redemptions for the current user.\n\nReturns:\n    List of promo code redemption records","operationId":"get_user_redemptions_promo_redemptions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors":{"post":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Create Contractor Profile","description":"Create a contractor profile for the current user.\n\nEach user can only have one contractor profile.\nThe same user can be both a homeowner and a contractor.","operationId":"create_contractor_profile_api_v1_marketplace_contractors_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get My Contractor Profile","description":"Get the current user's contractor profile.\n\nReturns 404 if user has not created a contractor profile.","operationId":"get_my_contractor_profile_api_v1_marketplace_contractors_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorResponse"}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Update My Contractor Profile","description":"Update the current user's contractor profile.","operationId":"update_my_contractor_profile_api_v1_marketplace_contractors_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me/onboarding-status":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get Onboarding Status","description":"Get onboarding status for the current partner.\n\nReturns whether onboarding is complete and the current step.\nSteps: business_identity → service_areas → specializations → completed","operationId":"get_onboarding_status_api_v1_marketplace_contractors_me_onboarding_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me/complete-onboarding":{"post":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Complete Onboarding","description":"Mark onboarding as complete.\n\nCalled when the partner finishes the onboarding wizard.\nValidates that minimum requirements are met before marking complete.","operationId":"complete_onboarding_api_v1_marketplace_contractors_me_complete_onboarding_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me/completion-status":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get Completion Status","description":"Get profile completion status.\n\nReturns completion percentage and list of missing fields.\nUseful for showing profile completion progress to partners.","operationId":"get_completion_status_api_v1_marketplace_contractors_me_completion_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/{contractor_id}/public":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get Public Contractor Profile","description":"Get a contractor's public profile.\n\nReturns limited info suitable for homeowner browsing.\nDoes NOT include contact information.","operationId":"get_public_contractor_profile_api_v1_marketplace_contractors__contractor_id__public_get","parameters":[{"name":"contractor_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contractor Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorPublicResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/contractors/{contractor_id}/public-profile":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get Contractor Public Profile With Contact","description":"Get contractor's complete public profile including contact information.\n\n**Public Endpoint** - No authentication required\n\nThis endpoint is used when homeowners view contractor profiles from proposals.\nIncludes contact info so homeowners can reach out to contractors.\n\nReturns:\n- Business name and contact details\n- Bio and specializations\n- Years in business and stats\n- Service area information\n- Mock reviews (TODO: implement real reviews system)","operationId":"get_contractor_public_profile_with_contact_api_v1_marketplace_contractors__contractor_id__public_profile_get","parameters":[{"name":"contractor_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contractor Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/contractors/me/service-areas":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"List My Service Areas","description":"List all service areas for the current contractor.","operationId":"list_my_service_areas_api_v1_marketplace_contractors_me_service_areas_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ServiceAreaResponse"},"type":"array","title":"Response List My Service Areas Api V1 Marketplace Contractors Me Service Areas Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Add Service Area","description":"Add a service area to the contractor's profile.\n\nService areas define where the contractor operates.\nCan be zip codes or cities.","operationId":"add_service_area_api_v1_marketplace_contractors_me_service_areas_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceAreaCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceAreaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me/service-areas/{area_id}":{"delete":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Remove Service Area","description":"Remove a service area from the contractor's profile.","operationId":"remove_service_area_api_v1_marketplace_contractors_me_service_areas__area_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"area_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Area Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/contractors/me/business-location":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get Business Location","description":"Get contractor's current business location.","operationId":"get_business_location_api_v1_marketplace_contractors_me_business_location_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessLocationResponse"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Set Business Location","description":"Set or update contractor's business location.\n\nThis enables radius-based service area matching.\nIf lat/lng not provided, will attempt geocoding from address.","operationId":"set_business_location_api_v1_marketplace_contractors_me_business_location_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessLocationUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessLocationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me/travel-radius":{"patch":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Update Travel Radius","description":"Update the contractor's default travel radius.\n\nRequires business location to be set first.","operationId":"update_travel_radius_api_v1_marketplace_contractors_me_travel_radius_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"radius_miles","in":"query","required":true,"schema":{"type":"number","title":"Radius Miles"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/contractors/metro-areas":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"List Metro Areas","description":"List all available metro area definitions.\n\nOptionally filter by state code.\nUse these codes when adding metro_area type service areas.","operationId":"list_metro_areas_api_v1_marketplace_contractors_metro_areas_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MetroAreaResponse"},"title":"Response List Metro Areas Api V1 Marketplace Contractors Metro Areas Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/contractors/metro-areas/{code}":{"get":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Get Metro Area","description":"Get details of a specific metro area.\n\nReturns cities, counties, and zip prefixes included in the metro.","operationId":"get_metro_area_api_v1_marketplace_contractors_metro_areas__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetroAreaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/contractors/me/deactivate":{"post":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Deactivate Contractor Profile","description":"Deactivate contractor profile (soft delete).\n\nProfile will no longer appear in searches or receive leads.","operationId":"deactivate_contractor_profile_api_v1_marketplace_contractors_me_deactivate_post","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/contractors/me/reactivate":{"post":{"tags":["Marketplace","Marketplace - Contractors"],"summary":"Reactivate Contractor Profile","description":"Reactivate a deactivated contractor profile.","operationId":"reactivate_contractor_profile_api_v1_marketplace_contractors_me_reactivate_post","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/projects":{"post":{"tags":["Marketplace","Marketplace - Projects"],"summary":"Create Project","description":"Create a marketplace project from a completed generation.\n\nCalled when homeowner clicks \"Get Build Estimates\" on their AI design.\nGenerates an AI project brief and notifies matching contractors.\n\nCCPA Compliance: Requires explicit user consent to share contact info with contractors.","operationId":"create_project_api_v1_marketplace_projects_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Marketplace","Marketplace - Projects"],"summary":"List My Projects","description":"List the current homeowner's marketplace projects.\n\nSupports filtering by status and pagination.","operationId":"list_my_projects_api_v1_marketplace_projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/MarketplaceProjectStatus"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/available":{"get":{"tags":["Marketplace","Marketplace - Projects"],"summary":"List Available Projects","description":"List open projects in the contractor's service areas.\n\nOnly returns projects where the contractor has matching service areas.","operationId":"list_available_projects_api_v1_marketplace_projects_available_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContractorListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/{project_id}":{"get":{"tags":["Marketplace","Marketplace - Projects"],"summary":"Get Project","description":"Get a specific project (homeowner view).\n\nReturns full project details including brief and all bids.","operationId":"get_project_api_v1_marketplace_projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/{project_id}/cancel":{"post":{"tags":["Marketplace","Marketplace - Projects"],"summary":"Cancel Project","description":"Cancel a project (homeowner only).\n\nOnly open projects can be cancelled.","operationId":"cancel_project_api_v1_marketplace_projects__project_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/{project_id}/complete":{"post":{"tags":["Marketplace","Marketplace - Projects"],"summary":"Mark Project Completed","description":"Mark a project as completed (homeowner only).\n\nOnly projects with accepted bids can be marked as completed.","operationId":"mark_project_completed_api_v1_marketplace_projects__project_id__complete_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/{project_id}/contractor-view":{"get":{"tags":["Marketplace","Marketplace - Projects"],"summary":"Get Project Contractor View","description":"Get project details for contractors (pre-bid view).\n\nShows address and AI image but NO homeowner contact info.\nContractor must have matching service area to view.","operationId":"get_project_contractor_view_api_v1_marketplace_projects__project_id__contractor_view_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContractorViewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/{project_id}/proposals":{"get":{"tags":["Marketplace","Marketplace - Projects"],"summary":"List Project Proposals","description":"List all proposals for a project (homeowner view).\n\nReturns proposals with contractor public info and optionally designs.\nOnly the project owner can view proposals.","operationId":"list_project_proposals_api_v1_marketplace_projects__project_id__proposals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"include_designs","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Designs"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/projects/{project_id}/proposals/{proposal_id}/accept":{"post":{"tags":["Marketplace","Marketplace - Projects"],"summary":"Accept Proposal","description":"Accept a proposal for a project (homeowner only).\n\nThis will:\n1. Update project status to proposal_accepted\n2. Mark the proposal as accepted\n3. Notify the contractor\n4. Exchange contact information","operationId":"accept_proposal_api_v1_marketplace_projects__project_id__proposals__proposal_id__accept_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/proposals/from-lead":{"post":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"Create Proposal From Lead","description":"Convert a lead into a proposal.\n\nThis is the primary lead conversion flow for contractors:\n1. Contractor views a lead in their inbox\n2. Creates a Pro Mode design for the property\n3. Converts the lead to a proposal with their design attached\n\nRequirements:\n- Contractor must have access to the lead (via lead_distributions)\n- At least one Pro Mode design is required (enforced by Pydantic)\n- The lead must be in 'pending' or 'viewed' status (not already converted)\n- Pro subscription required to submit proposals","operationId":"create_proposal_from_lead_api_v1_marketplace_proposals_from_lead_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFromLeadRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFromLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/proposals/create-direct":{"post":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"Create Proposal Direct","description":"Create a proposal directly, auto-creating lead/distribution if needed.\n\nThis is the primary proposal creation flow from Pro Mode:\n1. Contractor creates a design in Pro Mode\n2. Opens proposal modal and fills in pricing + message\n3. This endpoint handles everything: lead, distribution, project, proposal\n\nRequirements:\n- Pro subscription required\n- At least one Pro Mode design (enforced by Pydantic)","operationId":"create_proposal_direct_api_v1_marketplace_proposals_create_direct_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDirectRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFromLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/proposals":{"post":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"Submit Proposal","description":"Submit a proposal for a project.\n\nContractor must:\n1. Have an active contractor profile\n2. Have a matching service area for the project location\n3. Not already have a proposal on this project\n4. Have an active Pro subscription","operationId":"submit_proposal_api_v1_marketplace_proposals_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/proposals/my-proposals":{"get":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"List My Proposals","description":"List all proposals submitted by the current contractor.\n\nSupports filtering by status.","operationId":"list_my_proposals_api_v1_marketplace_proposals_my_proposals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/MarketplaceProposalStatus"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProposalResponse"},"title":"Response List My Proposals Api V1 Marketplace Proposals My Proposals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/proposals/{proposal_id}":{"get":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"Get Proposal","description":"Get a specific proposal.\n\nContractor can only view their own proposals.","operationId":"get_proposal_api_v1_marketplace_proposals__proposal_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"Update Proposal","description":"Update an existing proposal.\n\nOnly pending proposals can be updated.","operationId":"update_proposal_api_v1_marketplace_proposals__proposal_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/proposals/{proposal_id}/withdraw":{"post":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"Withdraw Proposal","description":"Withdraw a pending proposal.\n\nOnly pending/viewed proposals can be withdrawn.","operationId":"withdraw_proposal_api_v1_marketplace_proposals__proposal_id__withdraw_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/proposals/project/{project_id}":{"get":{"tags":["Marketplace","Marketplace - Proposals"],"summary":"List Proposals For Project","description":"List all proposals for a project (public view for testing).\n\nReturns proposals with contractor public info.\nNOTE: In production, this should verify the user is the project owner.","operationId":"list_proposals_for_project_api_v1_marketplace_proposals_project__project_id__get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProposalWithContractorResponse"},"title":"Response List Proposals For Project Api V1 Marketplace Proposals Project  Project Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/estimates":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Generate Estimate","description":"Generate property estimate from satellite imagery.\n\nUses SAMGeo for segmentation and Google Solar API for calibration.\nReturns area measurements for all property features.","operationId":"generate_estimate_api_v1_marketplace_pro_engine_estimates_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyEstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/pro-engine/estimates/{project_id}":{"get":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Get Estimate","description":"Get existing property estimate for a project.","operationId":"get_estimate_api_v1_marketplace_pro_engine_estimates__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyEstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/estimates/{estimate_id}/verify":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Verify Estimate","description":"Mark an estimate as manually verified by user.","operationId":"verify_estimate_api_v1_marketplace_pro_engine_estimates__estimate_id__verify_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Verify Estimate Api V1 Marketplace Pro Engine Estimates  Estimate Id  Verify Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/bid-packs":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Generate Bid Pack","description":"Generate bid pack with material quantities.\n\nUses property estimate and landscape style to calculate\nmaterials, labor hours, and equipment needed.","operationId":"generate_bid_pack_api_v1_marketplace_pro_engine_bid_packs_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidPackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidPackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/pro-engine/bid-packs/{project_id}":{"get":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"List Bid Packs","description":"List all bid packs for a project.","operationId":"list_bid_packs_api_v1_marketplace_pro_engine_bid_packs__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BidPackResponse"},"title":"Response List Bid Packs Api V1 Marketplace Pro Engine Bid Packs  Project Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/bid-packs/{project_id}/{area_type}":{"get":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Get Bid Pack","description":"Get specific bid pack for a project/area.","operationId":"get_bid_pack_api_v1_marketplace_pro_engine_bid_packs__project_id___area_type__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"area_type","in":"path","required":true,"schema":{"type":"string","title":"Area Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidPackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/stripe/onboard":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Start Stripe Onboarding","description":"Start Stripe Connect onboarding for contractor.\n\nReturns a URL to redirect the contractor to complete\ntheir Stripe Express account setup.","operationId":"start_stripe_onboarding_api_v1_marketplace_pro_engine_stripe_onboard_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeOnboardingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeOnboardingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/pro-engine/stripe/status":{"get":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Get Stripe Status","description":"Get contractor's Stripe Connect account status.","operationId":"get_stripe_status_api_v1_marketplace_pro_engine_stripe_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeAccountStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/pro-engine/stripe/refresh-link":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Refresh Onboarding Link","description":"Get a new onboarding link for incomplete setup.","operationId":"refresh_onboarding_link_api_v1_marketplace_pro_engine_stripe_refresh_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeOnboardingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Refresh Onboarding Link Api V1 Marketplace Pro Engine Stripe Refresh Link Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/pro-engine/milestones/{project_id}":{"get":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Get Project Milestones","description":"Get all milestones for a project with summary stats.","operationId":"get_project_milestones_api_v1_marketplace_pro_engine_milestones__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/milestones/{milestone_id}/start":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Start Milestone","description":"Mark milestone as in_progress (contractor action).","operationId":"start_milestone_api_v1_marketplace_pro_engine_milestones__milestone_id__start_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Milestone Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/milestones/{milestone_id}/complete":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Complete Milestone","description":"Mark milestone as completed with evidence (contractor action).","operationId":"complete_milestone_api_v1_marketplace_pro_engine_milestones__milestone_id__complete_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Milestone Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneComplete"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/milestones/{milestone_id}/approve":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Approve Milestone","description":"Approve milestone and release payment (homeowner action).\n\nThis triggers transfer of escrowed funds to contractor.","operationId":"approve_milestone_api_v1_marketplace_pro_engine_milestones__milestone_id__approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Milestone Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/milestones/{milestone_id}/dispute":{"post":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Dispute Milestone","description":"Dispute a completed milestone.","operationId":"dispute_milestone_api_v1_marketplace_pro_engine_milestones__milestone_id__dispute_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Milestone Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneDispute"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/pro-engine/payments/{project_id}/summary":{"get":{"tags":["Marketplace","Marketplace - Pro Engine"],"summary":"Get Payment Summary","description":"Get complete payment summary for a project.","operationId":"get_payment_summary_api_v1_marketplace_pro_engine_payments__project_id__summary_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectPaymentSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partners/signup":{"post":{"tags":["Marketplace","Marketplace - Partner Signup"],"summary":"Initiate Partner Signup","description":"Initiate partner signup (unauthenticated).\n\nThis endpoint:\n1. Validates the partner data\n2. Stores pending signup in database\n3. Returns success - frontend then sends magic link via Supabase\n\nThe flow continues when user clicks magic link and auth callback\ncompletes the profile creation.\n\nNo authentication required - this is the entry point for new partners.","operationId":"initiate_partner_signup_api_v1_marketplace_partners_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerSignupRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerSignupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partners/signup/check/{email}":{"get":{"tags":["Marketplace","Marketplace - Partner Signup"],"summary":"Check Pending Signup","description":"Check if there's a pending signup for an email.\n\nUsed by auth callback to determine if profile should be created.","operationId":"check_pending_signup_api_v1_marketplace_partners_signup_check__email__get","parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partners/signup/auth-method/{email}":{"get":{"tags":["Marketplace","Marketplace - Partner Signup"],"summary":"Check Auth Method","description":"Check if an email exists and what authentication method was used.\n\nReturns whether the user should use OAuth (Google) or magic link.\nUsed by partner signup form to auto-select the right auth method.\n\nAlso checks if user already has a contractor profile.\n\nLogic:\n- If user exists with contractor profile → has_contractor_profile: true\n- If user exists with OAuth provider (google) → use_oauth: true\n- If user exists without OAuth (email/password) → use_oauth: false\n- If user doesn't exist → use_oauth: false (magic link for new users)","operationId":"check_auth_method_api_v1_marketplace_partners_signup_auth_method__email__get","parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partners/signup/check-phone/{phone}":{"get":{"tags":["Marketplace","Marketplace - Partner Signup"],"summary":"Check Phone Exists","description":"Check if a phone number is already associated with a contractor profile.\n\nUsed by partner signup form to detect existing partners by phone number.\nThis is a secondary check in addition to email.\n\nReturns the associated email so the user can sign in.","operationId":"check_phone_exists_api_v1_marketplace_partners_signup_check_phone__phone__get","parameters":[{"name":"phone","in":"path","required":true,"schema":{"type":"string","title":"Phone"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partners/signup/complete":{"post":{"tags":["Marketplace","Marketplace - Partner Signup"],"summary":"Complete Partner Signup","description":"Complete partner signup after magic link verification.\n\nThis endpoint is called after the user clicks the magic link and\nauthenticates. It creates the contractor profile from pending signup data.\n\nUses get_current_user_or_create to handle new OAuth users who may not\nyet exist in public.users (race condition with Supabase trigger).\n\nRequires authentication - user must have verified via magic link.","operationId":"complete_partner_signup_api_v1_marketplace_partners_signup_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteSignupResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/partners/extract-business-info":{"post":{"tags":["Marketplace","Marketplace - Partner Signup"],"summary":"Extract Business Info","description":"Extract business information from a Facebook page or website URL.\n\nThis endpoint helps partners auto-fill their signup form by scraping\nbusiness information from their existing online presence.\n\nSupports:\n- Facebook Business Pages (extracts OpenGraph data)\n- Business Websites (extracts Schema.org, meta tags, and HTML patterns)\n\nReturns extracted fields that can be used to pre-populate the signup form.\n\nNo authentication required - this is a helper for the signup flow.","operationId":"extract_business_info_api_v1_marketplace_partners_extract_business_info_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessInfoRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessInfoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/estimates/":{"post":{"tags":["Marketplace","Estimates"],"summary":"Create Estimate","description":"Create a new estimate for a proposal.\n\n- Contractor must own the proposal\n- If an active estimate exists, it will be marked as superseded\n- New estimate starts in 'draft' status","operationId":"create_estimate_api_v1_marketplace_estimates__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/estimates/{estimate_id}":{"get":{"tags":["Marketplace","Estimates"],"summary":"Get Estimate","description":"Get an estimate by ID.\n\n- Contractors can view their own estimates\n- Homeowners can view submitted estimates for their projects","operationId":"get_estimate_api_v1_marketplace_estimates__estimate_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Marketplace","Estimates"],"summary":"Update Estimate","description":"Update an existing draft estimate.\n\n- Only the owning contractor can update\n- Only draft estimates can be updated","operationId":"update_estimate_api_v1_marketplace_estimates__estimate_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Marketplace","Estimates"],"summary":"Delete Estimate","description":"Delete a draft estimate.\n\n- Only the owning contractor can delete\n- Only draft estimates can be deleted","operationId":"delete_estimate_api_v1_marketplace_estimates__estimate_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/estimates/{estimate_id}/submit":{"post":{"tags":["Marketplace","Estimates"],"summary":"Submit Estimate","description":"Submit a draft estimate to the homeowner.\n\n- Estimate must be in 'draft' status\n- Estimate must have at least one labor or material item\n- Changes status to 'submitted' and sets submitted_at timestamp","operationId":"submit_estimate_api_v1_marketplace_estimates__estimate_id__submit_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/estimates/{estimate_id}/accept":{"post":{"tags":["Marketplace","Estimates"],"summary":"Accept Estimate","description":"Homeowner accepts an estimate.\n\n- Only the project homeowner can accept\n- Estimate must be in 'submitted' status","operationId":"accept_estimate_api_v1_marketplace_estimates__estimate_id__accept_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/estimates/{estimate_id}/reject":{"post":{"tags":["Marketplace","Estimates"],"summary":"Reject Estimate","description":"Homeowner rejects an estimate.\n\n- Only the project homeowner can reject\n- Estimate must be in 'submitted' status","operationId":"reject_estimate_api_v1_marketplace_estimates__estimate_id__reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"estimate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Estimate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/estimates/proposal/{proposal_id}":{"get":{"tags":["Marketplace","Estimates"],"summary":"Get Estimate By Proposal","description":"Get the active estimate for a proposal.\n\n- Returns the most recent non-superseded estimate\n- Contractors see all their estimates\n- Homeowners only see submitted/accepted/rejected estimates","operationId":"get_estimate_by_proposal_api_v1_marketplace_estimates_proposal__proposal_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/EstimateResponse"},{"type":"null"}],"title":"Response Get Estimate By Proposal Api V1 Marketplace Estimates Proposal  Proposal Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/estimates/my-estimates":{"get":{"tags":["Marketplace","Estimates"],"summary":"List My Estimates","description":"List all estimates for the current contractor.\n\n- Can filter by status\n- Paginated results","operationId":"list_my_estimates_api_v1_marketplace_estimates_my_estimates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EstimateStatus"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EstimateListItem"},"title":"Response List My Estimates Api V1 Marketplace Estimates My Estimates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/leads/inbox":{"get":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Get Lead Inbox","description":"Get the contractor's lead inbox.\n\nReturns leads distributed to this contractor, with tiered access:\n- Free partners see redacted \"peek\" view\n- Pro subscribers see full contact details\n- Leads that have been viewed show full details to all\n\nFilter options:\n- pending: New leads awaiting action\n- viewed: Leads that have been viewed\n- accepted: Leads the contractor accepted\n- rejected: Leads the contractor passed on\n- expired: Leads that expired before action","operationId":"get_lead_inbox_api_v1_marketplace_leads_inbox_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status: pending, viewed, accepted, rejected, expired","title":"Status"},"description":"Filter by status: pending, viewed, accepted, rejected, expired"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/leads/inbox/{distribution_id}":{"get":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Get Lead Detail","description":"Get details of a specific lead distribution.\n\nAutomatically marks the lead as viewed if not already.\nReturns full details for Pro subscribers or if already viewed.","operationId":"get_lead_detail_api_v1_marketplace_leads_inbox__distribution_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/leads/inbox/{distribution_id}/respond":{"post":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Respond To Lead","description":"Respond to a lead (accept or reject).\n\n- accepted: Contractor wants this lead, will contact homeowner\n- rejected: Contractor passes on this lead\n\nFor Pro subscribers who accept: Lead is moved to their CRM pipeline.","operationId":"respond_to_lead_api_v1_marketplace_leads_inbox__distribution_id__respond_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadResponseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/leads/stats":{"get":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Get Lead Stats","description":"Get lead distribution statistics for the current contractor.\n\nReturns counts by status:\n- pending: New leads awaiting action\n- viewed: Leads that have been viewed\n- accepted: Leads accepted\n- rejected: Leads passed on\n- expired: Leads that expired\n- total: Total leads received","operationId":"get_lead_stats_api_v1_marketplace_leads_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadStatsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/leads/notification-preference":{"get":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Get Notification Preference","description":"Get current lead notification preference.\n\nNote: Paused partners can still view their preferences.","operationId":"get_notification_preference_api_v1_marketplace_leads_notification_preference_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Update Notification Preference","description":"Update lead notification preference.\n\nOptions:\n- immediate: Email for every new lead (default)\n- hourly: Digest email every hour with new leads\n- daily: Digest email once per day with new leads\n\nNote: Paused partners can still update their preferences.","operationId":"update_notification_preference_api_v1_marketplace_leads_notification_preference_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferenceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/leads/{distribution_id}/link-design":{"post":{"tags":["Marketplace","Marketplace - Lead Distributions"],"summary":"Link Design To Lead","description":"Link a Pro Mode generation (design) to a lead.\n\nThis endpoint:\n1. Links the generation to the lead via lead_distribution_id\n2. Updates the lead stage to '2-design' (Designing)\n3. Returns the updated design count\n\nUse this when a contractor creates a design for a lead from Pro Mode.\nThe generation will appear in the lead's design gallery.\n\nRequires Pro subscription to create/link designs.","operationId":"link_design_to_lead_api_v1_marketplace_leads__distribution_id__link_design_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkDesignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/leads/manual":{"post":{"tags":["Marketplace","Marketplace - Leads Management"],"summary":"Create Manual Lead","description":"Manually enter a new lead into the system.\n\n1. Parsing: Uses AI to parse the 'notes' field for structured info.\n2. Geocoding: Geocodes the address.\n3. Creation: Creates the lead record.\n4. Assignment: Automatically assigns (distributes) this lead to the creating partner.","operationId":"create_manual_lead_api_v1_marketplace_leads_manual_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualLeadCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/leads/{distribution_id}":{"put":{"tags":["Marketplace","Marketplace - Leads Management"],"summary":"Update Lead","description":"Update an existing lead's information.\n\nOnly the partner who owns this lead distribution can update it.\nUpdates are made to the underlying lead record.","operationId":"update_lead_api_v1_marketplace_leads__distribution_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Marketplace","Marketplace - Leads Management"],"summary":"Delete Lead","description":"Delete a lead from the partner's CRM.\n\nThis removes the lead distribution record. If the partner originally\ncreated this lead (manual entry), the lead itself is also deleted.","operationId":"delete_lead_api_v1_marketplace_leads__distribution_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadDeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/leads/{distribution_id}/stage":{"patch":{"tags":["Marketplace","Marketplace - Leads Management"],"summary":"Update Lead Stage","description":"Update a lead's CRM stage.\n\nValid stages:\n- 1-new: Just added, not yet worked on\n- 2-design: Currently creating designs for this lead\n- 3-proposal-sent: Proposal has been sent to the customer\n- 4-proposal-accepted: Customer accepted, won!","operationId":"update_lead_stage_api_v1_marketplace_leads__distribution_id__stage_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadStageUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadStageUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/portfolio":{"post":{"tags":["Marketplace","Portfolio"],"summary":"Create Portfolio Project","description":"Create a new portfolio project for the authenticated contractor.\n\nRequires contractor profile to exist.","operationId":"create_portfolio_project_api_v1_marketplace_portfolio_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioProjectCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioProjectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/portfolio/me":{"get":{"tags":["Marketplace","Portfolio"],"summary":"Get My Portfolio Projects","description":"Get all portfolio projects for the authenticated contractor (including private).\n\nRequires contractor profile to exist.","operationId":"get_my_portfolio_projects_api_v1_marketplace_portfolio_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PortfolioProjectResponse"},"type":"array","title":"Response Get My Portfolio Projects Api V1 Marketplace Portfolio Me Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/portfolio/contractor/{contractor_id}":{"get":{"tags":["Marketplace","Portfolio"],"summary":"Get Contractor Public Portfolio","description":"Get public portfolio projects for any contractor (public view for homeowners).\n\nNo authentication required - this is public data.","operationId":"get_contractor_public_portfolio_api_v1_marketplace_portfolio_contractor__contractor_id__get","parameters":[{"name":"contractor_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contractor Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioProjectPublicResponse"},"title":"Response Get Contractor Public Portfolio Api V1 Marketplace Portfolio Contractor  Contractor Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/portfolio/contractor/{contractor_id}/stats":{"get":{"tags":["Marketplace","Portfolio"],"summary":"Get Contractor Portfolio Stats","description":"Get portfolio statistics for a contractor (public data).\n\nNo authentication required.","operationId":"get_contractor_portfolio_stats_api_v1_marketplace_portfolio_contractor__contractor_id__stats_get","parameters":[{"name":"contractor_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contractor Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/portfolio/{project_id}":{"get":{"tags":["Marketplace","Portfolio"],"summary":"Get Portfolio Project","description":"Get a specific portfolio project by ID.\n\nOnly the owning contractor can view their own projects (public + private).","operationId":"get_portfolio_project_api_v1_marketplace_portfolio__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioProjectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Marketplace","Portfolio"],"summary":"Update Portfolio Project","description":"Update a portfolio project.\n\nOnly the owning contractor can update their projects.","operationId":"update_portfolio_project_api_v1_marketplace_portfolio__project_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioProjectUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioProjectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Marketplace","Portfolio"],"summary":"Delete Portfolio Project","description":"Delete a portfolio project.\n\nOnly the owning contractor can delete their projects.","operationId":"delete_portfolio_project_api_v1_marketplace_portfolio__project_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/portfolio/reorder":{"patch":{"tags":["Marketplace","Portfolio"],"summary":"Reorder Portfolio Projects","description":"Reorder portfolio projects.\n\nFeature: 014-partner-profile-editor\n\nAccepts a list of {id, display_order} objects and updates all projects.\nOnly the owning contractor can reorder their projects.","operationId":"reorder_portfolio_projects_api_v1_marketplace_portfolio_reorder_patch","requestBody":{"content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Reorder Data"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/admin/metrics":{"get":{"tags":["Marketplace","Admin"],"summary":"Get Marketplace Metrics","description":"Get high-level marketplace metrics.\n\nRequires admin privileges.","operationId":"get_marketplace_metrics_api_v1_marketplace_admin_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceMetrics"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/admin/projects":{"get":{"tags":["Marketplace","Admin"],"summary":"Get Admin Projects","description":"Get all marketplace projects with filters (admin view).\n\nRequires admin privileges.","operationId":"get_admin_projects_api_v1_marketplace_admin_projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by project status","title":"Status Filter"},"description":"Filter by project status"},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by city","title":"City"},"description":"Filter by city"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/src__marketplace__api__admin__ProjectSummary"},"title":"Response Get Admin Projects Api V1 Marketplace Admin Projects Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/admin/proposals":{"get":{"tags":["Marketplace","Admin"],"summary":"Get Admin Proposals","description":"Get all marketplace proposals with filters (admin view).\n\nRequires admin privileges.","operationId":"get_admin_proposals_api_v1_marketplace_admin_proposals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by proposal status","title":"Status Filter"},"description":"Filter by proposal status"},{"name":"contractor_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by contractor","title":"Contractor Id"},"description":"Filter by contractor"},{"name":"min_price","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Min price filter","title":"Min Price"},"description":"Min price filter"},{"name":"max_price","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Max price filter","title":"Max Price"},"description":"Max price filter"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProposalSummary"},"title":"Response Get Admin Proposals Api V1 Marketplace Admin Proposals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/admin/contractors":{"get":{"tags":["Marketplace","Admin"],"summary":"Get Admin Contractors","description":"Get all contractors with filters (admin view).\n\nRequires admin privileges.","operationId":"get_admin_contractors_api_v1_marketplace_admin_contractors_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"verification_status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by verification status","title":"Verification Status"},"description":"Filter by verification status"},{"name":"is_active","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by active status","title":"Is Active"},"description":"Filter by active status"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max results","default":50,"title":"Limit"},"description":"Max results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContractorSummary"},"title":"Response Get Admin Contractors Api V1 Marketplace Admin Contractors Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/admin/projects/{project_id}":{"get":{"tags":["Marketplace","Admin"],"summary":"Get Admin Project","description":"Get full project details for admin view.\n\nRequires admin privileges. Returns complete project data including\nproject_brief, homeowner info, and all associated data.","operationId":"get_admin_project_api_v1_marketplace_admin_projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/reviews/import/google":{"post":{"tags":["Marketplace","reviews"],"summary":"Import Google Reviews","description":"Import reviews from Google Business Profile.\n\nRequires a valid Google OAuth access token and Google Place ID.\nReturns imported reviews and any errors encountered.","operationId":"import_google_reviews_api_v1_marketplace_reviews_import_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleReviewImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/reviews/sync/google":{"post":{"tags":["Marketplace","reviews"],"summary":"Sync Google Reviews","description":"Sync reviews from Google (manual refresh).\n\nFetches new reviews from Google Business Profile.\nUpdates existing reviews if they've changed.","operationId":"sync_google_reviews_api_v1_marketplace_reviews_sync_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleReviewImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/reviews":{"get":{"tags":["Marketplace","reviews"],"summary":"Get My Reviews","description":"Get all reviews for the authenticated contractor.\n\nSupports filtering by source platform, minimum rating, and visibility.","operationId":"get_my_reviews_api_v1_marketplace_reviews_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by source platform","title":"Source"},"description":"Filter by source platform"},{"name":"min_rating","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":5,"minimum":1},{"type":"null"}],"description":"Minimum rating","title":"Min Rating"},"description":"Minimum rating"},{"name":"visible_only","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Only visible reviews","title":"Visible Only"},"description":"Only visible reviews"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Marketplace","reviews"],"summary":"Create Manual Review","description":"Create a manual review entry.\n\nFor reviews that can't be imported automatically.","operationId":"create_manual_review_api_v1_marketplace_reviews_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualReviewCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportedReview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/reviews/stats":{"get":{"tags":["Marketplace","reviews"],"summary":"Get Review Stats","description":"Get review statistics for the authenticated contractor.\n\nReturns average rating, distribution, and source breakdown.","operationId":"get_review_stats_api_v1_marketplace_reviews_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/reviews/{review_id}":{"patch":{"tags":["Marketplace","reviews"],"summary":"Update Review","description":"Update review visibility or add a response.\n\nPartners can hide reviews and add responses to imported reviews.","operationId":"update_review_api_v1_marketplace_reviews__review_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Review Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportedReviewUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportedReview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Marketplace","reviews"],"summary":"Delete Review","description":"Delete a review.\n\nOnly manual reviews can be deleted.\nImported reviews should be hidden instead.","operationId":"delete_review_api_v1_marketplace_reviews__review_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/reviews/public/{contractor_id}":{"get":{"tags":["Marketplace","reviews"],"summary":"Get Public Reviews","description":"Get public reviews for a contractor.\n\nPublic endpoint - no authentication required.\nOnly returns visible reviews.","operationId":"get_public_reviews_api_v1_marketplace_reviews_public__contractor_id__get","parameters":[{"name":"contractor_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contractor Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum reviews to return","default":10,"title":"Limit"},"description":"Maximum reviews to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicReviewListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner/projects":{"get":{"tags":["Marketplace","Partner Projects"],"summary":"List Partner Projects","description":"List all partner projects for the current contractor.\n\nProjects group Pro Mode generations by property address for easy organization.\nSorted by most recent generation by default.","operationId":"list_partner_projects_api_v1_marketplace_partner_projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Search by address","title":"Search"},"description":"Search by address"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Sort by: last_generation_at, created_at, generation_count","default":"last_generation_at","title":"Sort"},"description":"Sort by: last_generation_at, created_at, generation_count"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerProjectsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner/projects/{project_id}":{"get":{"tags":["Marketplace","Partner Projects"],"summary":"Get Partner Project","description":"Get a single partner project with recent designs.\n\nReturns the project details along with the 10 most recent designs.","operationId":"get_partner_project_api_v1_marketplace_partner_projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerProjectWithDesigns"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner/projects/{project_id}/designs":{"get":{"tags":["Marketplace","Partner Projects"],"summary":"List Project Designs","description":"Get all designs for a partner project with pagination.\n\nReturns all Pro Mode generations associated with this project.","operationId":"list_project_designs_api_v1_marketplace_partner_projects__project_id__designs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Limit"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDesignsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner/leads/match":{"get":{"tags":["Marketplace","Partner Projects"],"summary":"Match Lead By Address","description":"Check if an address matches any pending leads for the contractor.\n\nThis is called during Pro Mode completion to detect if the address\nbeing designed matches a lead that the contractor received.\n\nMatching priority:\n1. Exact place_id match (if both have place_id)\n2. Fuzzy normalized address match (Levenshtein distance < 3)\n\nReturns match details if found, including whether a proposal already exists.","operationId":"match_lead_by_address_api_v1_marketplace_partner_leads_match_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"address","in":"query","required":true,"schema":{"type":"string","minLength":5,"maxLength":500,"description":"Full address to match","title":"Address"},"description":"Full address to match"},{"name":"place_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Google Place ID for exact matching","title":"Place Id"},"description":"Google Place ID for exact matching"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadMatchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner/generations/{generation_id}/dimensions":{"get":{"tags":["Marketplace","Partner Projects"],"summary":"Get Generation Dimensions","description":"Get parsed dimension data for a generation.\n\nReturns structured dimension data for rendering overlays on designs.\nExtracted from the site_analysis.dimensions field of the generation.\n\nUsed by the dimension overlay toggle feature.","operationId":"get_generation_dimensions_api_v1_marketplace_partner_generations__generation_id__dimensions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DimensionDataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner-designs":{"get":{"tags":["Marketplace","partner-designs"],"summary":"List Designs","description":"List the partner's saved designs.\n\nCan filter by:\n- lead_distribution_id: Show designs for a specific lead\n- favorites_only: Show only favorited designs","operationId":"list_designs_api_v1_marketplace_partner_designs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_distribution_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by lead","title":"Lead Distribution Id"},"description":"Filter by lead"},{"name":"favorites_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only show favorited designs","default":false,"title":"Favorites Only"},"description":"Only show favorited designs"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDesignListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Marketplace","partner-designs"],"summary":"Create Design","description":"Save a generation as a partner design.\n\nOptionally links it to a lead for CRM tracking.\nIf linked to a lead in stage '1-new', automatically moves lead to '2-design'.","operationId":"create_design_api_v1_marketplace_partner_designs_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDesignCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/partner-designs/{design_id}":{"get":{"tags":["Marketplace","partner-designs"],"summary":"Get Design","description":"Get a specific saved design.","operationId":"get_design_api_v1_marketplace_partner_designs__design_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Marketplace","partner-designs"],"summary":"Update Design","description":"Update a saved design's metadata.","operationId":"update_design_api_v1_marketplace_partner_designs__design_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDesignUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Marketplace","partner-designs"],"summary":"Delete Design","description":"Delete a saved design.","operationId":"delete_design_api_v1_marketplace_partner_designs__design_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/clients":{"get":{"tags":["Marketplace","Marketplace - Clients"],"summary":"List Clients","description":"List all clients for the authenticated partner.\n\nSupports filtering by stage, status, and search (Pro only).\nReturns unified view of leads and proposals.","operationId":"list_clients_api_v1_marketplace_clients_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"stage","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ClientStage"},{"type":"null"}],"description":"Filter by pipeline stage","title":"Stage"},"description":"Filter by pipeline stage"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/DistributionStatus"},{"type":"null"}],"description":"Filter by distribution status","title":"Status"},"description":"Filter by distribution status"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name, email, or address (Pro only)","title":"Search"},"description":"Search by name, email, or address (Pro only)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of results to return","default":20,"title":"Limit"},"description":"Number of results to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Marketplace","Marketplace - Clients"],"summary":"Create Client","description":"Create a new client manually.\n\nAllows partners to add clients acquired outside the marketplace\n(referrals, walk-ins, existing customers).\n\nThe client is automatically linked to the partner and marked as viewed.","operationId":"create_client_api_v1_marketplace_clients_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClientRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/clients/stats":{"get":{"tags":["Marketplace","Marketplace - Clients"],"summary":"Get Client Stats","description":"Get client statistics for badge display.\n\nLightweight endpoint optimized for 60-second polling.\nReturns counts by stage for the notification badge.","operationId":"get_client_stats_api_v1_marketplace_clients_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/marketplace/clients/{distribution_id}":{"get":{"tags":["Marketplace","Marketplace - Clients"],"summary":"Get Client","description":"Get full details for a specific client.\n\nReturns generation prompts, designs, and proposals.\nContact info is redacted for free-tier partners unless already viewed.","operationId":"get_client_api_v1_marketplace_clients__distribution_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/clients/{distribution_id}/stage":{"patch":{"tags":["Marketplace","Marketplace - Clients"],"summary":"Update Client Stage","description":"Update client stage (can only advance forward).\n\nStage transitions:\n- 1-new → 2-design (on first design creation, automatic)\n- 2-design → 3-proposal-sent (manual)\n- 3-proposal-sent → 4-proposal-accepted (manual)","operationId":"update_client_stage_api_v1_marketplace_clients__distribution_id__stage_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/clients/{distribution_id}/view":{"post":{"tags":["Marketplace","Marketplace - Clients"],"summary":"Mark Client Viewed","description":"Mark a client as viewed.\n\nCalled when partner opens a client card.\nUpdates viewed_at timestamp and changes status from 'pending' to 'viewed'.","operationId":"mark_client_viewed_api_v1_marketplace_clients__distribution_id__view_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"distribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Distribution Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/proposals/{proposal_id}/export/docx":{"get":{"tags":["Marketplace","Marketplace - Proposal Exports"],"summary":"Export Proposal Docx","description":"Download proposal as a .docx file.\n\nGenerates a professionally formatted Word document with:\n- Contractor business information\n- Project address and date\n- Proposal message and design notes\n- Line items table with category grouping and totals\n- Estimated duration","operationId":"export_proposal_docx_api_v1_marketplace_proposals__proposal_id__export_docx_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/proposals/{proposal_id}/export/gdoc":{"post":{"tags":["Marketplace","Marketplace - Proposal Exports"],"summary":"Export Proposal Google Doc","description":"Export proposal to Google Docs.\n\nCreates a new Google Doc in the user's Google Drive containing\nthe full proposal content. Requires a Google OAuth access token\nwith at minimum the drive.file scope.\n\nReturns the URL of the created document.","operationId":"export_proposal_google_doc_api_v1_marketplace_proposals__proposal_id__export_gdoc_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleDocExportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleDocExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/health":{"get":{"tags":["Marketplace"],"summary":"Marketplace Health","description":"Health check for marketplace module.","operationId":"marketplace_health_api_v1_marketplace_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/llm-logs/recent":{"get":{"tags":["LLM Logs"],"summary":"Get Recent Calls","description":"Get recent LLM calls from memory buffer.\n\nReturns summary information without full prompt text.","operationId":"get_recent_calls_llm_logs_recent_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Number of calls to return","default":50,"title":"Limit"},"description":"Number of calls to return"},{"name":"call_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by call type (2d_plan, 3d_render, etc.)","title":"Call Type"},"description":"Filter by call type (2d_plan, 3d_render, etc.)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LLMCallSummary"},"title":"Response Get Recent Calls Llm Logs Recent Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/llm-logs/date/{date_str}":{"get":{"tags":["LLM Logs"],"summary":"Get Calls By Date","description":"Get all LLM calls from a specific date.\n\nDate format: YYYY-MM-DD (e.g., 2025-12-07)","operationId":"get_calls_by_date_llm_logs_date__date_str__get","parameters":[{"name":"date_str","in":"path","required":true,"schema":{"type":"string","title":"Date Str"}},{"name":"call_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by call type","title":"Call Type"},"description":"Filter by call type"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LLMCallDetail"},"title":"Response Get Calls By Date Llm Logs Date  Date Str  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/llm-logs/call/{call_id}":{"get":{"tags":["LLM Logs"],"summary":"Get Call By Id","description":"Get a specific LLM call by its ID.\n\nSearches in the memory buffer first, then today's logs.","operationId":"get_call_by_id_llm_logs_call__call_id__get","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMCallDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/llm-logs/stats":{"get":{"tags":["LLM Logs"],"summary":"Get Stats","description":"Get summary statistics for LLM calls.","operationId":"get_stats_llm_logs_stats_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"description":"Number of days to include","default":7,"title":"Days"},"description":"Number of days to include"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/llm-logs/export/prompts":{"post":{"tags":["LLM Logs"],"summary":"Export Prompts","description":"Export prompts to a text file for analysis.\n\nReturns the path to the exported file.","operationId":"export_prompts_llm_logs_export_prompts_post","parameters":[{"name":"date_str","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Date (YYYY-MM-DD) or empty for today","title":"Date Str"},"description":"Date (YYYY-MM-DD) or empty for today"},{"name":"call_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by call type","title":"Call Type"},"description":"Filter by call type"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/llm-logs/prompt/{call_id}":{"get":{"tags":["LLM Logs"],"summary":"Get Prompt Only","description":"Get just the prompt text for a specific call.\n\nUseful for quick analysis without all the metadata.","operationId":"get_prompt_only_llm_logs_prompt__call_id__get","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/leads":{"post":{"tags":["leads"],"summary":"Create Lead","description":"Create a new lead from a quote request.\n\nThis endpoint is public - users don't need to be authenticated\nto request a quote for their landscape design.","operationId":"create_lead_leads_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLeadRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__leads__LeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/costs/budget":{"get":{"tags":["admin"],"summary":"Get Budget Status","description":"Get current budget status.\n\nReturns daily and monthly spend, limits, and percentages.\nRequires admin access.","operationId":"get_budget_status_admin_costs_budget_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/costs/summary":{"get":{"tags":["admin"],"summary":"Get Cost Summary","description":"Get cost summary for the specified number of days.\n\nArgs:\n    days: Number of days to include (1-90, default 7)\n\nReturns:\n    Cost breakdown by date and model\nRequires admin access.","operationId":"get_cost_summary_admin_costs_summary_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CostSummaryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/costs/users":{"get":{"tags":["admin"],"summary":"Get Top Users","description":"Get users with highest spend in the last 30 days.\n\nArgs:\n    limit: Maximum number of users to return (1-100, default 10)\n\nReturns:\n    List of top users by cost\nRequires admin access.","operationId":"get_top_users_admin_costs_users_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TopUserResponse"},"title":"Response Get Top Users Admin Costs Users Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/costs/today":{"get":{"tags":["admin"],"summary":"Get Today Costs","description":"Get cost breakdown for today.\n\nReturns:\n    Today's costs by model and call type\nRequires admin access.","operationId":"get_today_costs_admin_costs_today_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/costs/check":{"get":{"tags":["admin"],"summary":"Check Budget For Request","description":"Check if a hypothetical request would be allowed under budget.\n\nUseful for pre-flight checks before expensive operations.\n\nArgs:\n    user_id: User making the request\n    model: Model to use\n    images: Number of images to generate\n\nReturns:\n    Whether the request would be allowed and why\nRequires admin access.","operationId":"check_budget_for_request_admin_costs_check_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"}},{"name":"model","in":"query","required":false,"schema":{"type":"string","default":"gemini-3.1-flash-image-preview","title":"Model"}},{"name":"images","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"default":1,"title":"Images"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/health":{"get":{"tags":["admin"],"summary":"Admin Health Check","description":"Admin-level health check with budget status.\n\nReturns:\n    System health including budget warnings\nRequires admin access.","operationId":"admin_health_check_admin_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/costs/models":{"get":{"tags":["admin"],"summary":"Get Model Costs","description":"Get cumulative costs per model.\n\nReturns:\n    Cost breakdown by model with totals\nRequires admin access.","operationId":"get_model_costs_admin_costs_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/costs/daily":{"get":{"tags":["admin"],"summary":"Get Daily Breakdown","description":"Get daily cost breakdown.\n\nReturns:\n    List of daily totals\nRequires admin access.","operationId":"get_daily_breakdown_admin_costs_daily_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/costs/user/{user_id}":{"get":{"tags":["admin"],"summary":"Get User Costs","description":"Get detailed cost breakdown for a specific user.\n\nArgs:\n    user_id: The user's UUID\n    days: Number of days to include (1-90, default 30)\n\nReturns:\n    Detailed breakdown by date, model, and call type\nRequires admin access.","operationId":"get_user_costs_admin_costs_user__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/costs/users/all":{"get":{"tags":["admin"],"summary":"Get All Users Costs","description":"Get cost summary for ALL users with daily breakdown.\n\nArgs:\n    days: Number of days to include (1-30, default 7)\n\nReturns:\n    List of all users with their cost summaries and daily breakdown\nRequires admin access.","operationId":"get_all_users_costs_admin_costs_users_all_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/payments/dashboard":{"get":{"tags":["admin"],"summary":"Get Payment Dashboard","description":"Get complete payment visibility dashboard.\n\nIncludes:\n- Token purchase summary (last N days)\n- Subscription breakdown\n- Current token balances\n- Recent transactions\n\nRequires admin access.","operationId":"get_payment_dashboard_admin_payments_dashboard_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDashboard"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/payments/subscriptions":{"get":{"tags":["admin"],"summary":"List Subscriptions","description":"List all users with subscriptions. Requires admin access.","operationId":"list_subscriptions_admin_payments_subscriptions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/payments/transactions":{"get":{"tags":["admin"],"summary":"List Token Transactions","description":"List token transactions with pagination. Requires admin access.","operationId":"list_token_transactions_admin_payments_transactions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by type: purchase, deduction, refund","title":"Type"},"description":"Filter by type: purchase, deduction, refund"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/payments/revenue":{"get":{"tags":["admin"],"summary":"Get Revenue Summary","description":"Get revenue summary by time period. Requires admin access.","operationId":"get_revenue_summary_admin_payments_revenue_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/trial-engagement/send-day3":{"post":{"tags":["admin"],"summary":"Send Day3 Trial Emails","description":"Send Day 3 trial engagement emails to all eligible users.\n\nThis endpoint:\n1. Finds users on Day 3 of their 7-day trial\n2. Queries which styles they've already tried\n3. Sends an email suggesting 3 untried styles\n4. Marks users to prevent duplicate sends\n\nCalled by Railway cron job daily.\nRequires admin access.\n\nReturns:\n    Count of eligible users, emails sent, and failures","operationId":"send_day3_trial_emails_admin_trial_engagement_send_day3_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Day3EmailResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/onboarding/send-nudge":{"post":{"tags":["admin"],"summary":"Send Onboarding Nudge Emails","description":"Send 3-day onboarding nudge emails to eligible new users.\n\nTargets users who:\n- Signed up >= 3 days ago\n- Have 0 designs generated\n- Haven't received the nudge yet\n- Haven't unsubscribed from marketing emails\n\nCalled daily by Railway cron job. Requires admin access.\n\nReturns:\n    Count of eligible users, emails sent, and failures","operationId":"send_onboarding_nudge_emails_admin_onboarding_send_nudge_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingNudgeResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/onboarding/send-sequence":{"post":{"tags":["admin"],"summary":"Send Onboarding Sequence Emails","description":"Send all onboarding sequence emails (YAR-935).\n\nProcesses:\n- Day 2 tutorial emails\n- Day 5 social proof emails\n- Day 25 trial reminder emails (if still on trial)\n- Day 31 trial expired win-back emails\n\nCalled daily by Railway cron job. Requires admin access.\n\nReturns:\n    Counts of eligible users and emails sent/failed for each email type","operationId":"send_onboarding_sequence_emails_admin_onboarding_send_sequence_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingSequenceResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/migrate/inpaint-variants":{"post":{"tags":["admin"],"summary":"Migrate Inpaint Variants","description":"Migrate inpaint variants from pro_mode_metadata.variants to separate generation records.\n\nMigration completed 2026-02-02 - endpoint disabled.","operationId":"migrate_inpaint_variants_admin_migrate_inpaint_variants_post","parameters":[{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","description":"Preview changes without making them","default":true,"title":"Dry Run"},"description":"Preview changes without making them"},{"name":"api_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Internal API key (alternative to user auth)","title":"Api Key"},"description":"Internal API key (alternative to user auth)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/migrate/inpaint-status":{"get":{"tags":["admin"],"summary":"Get Inpaint Status","description":"Check status of inpaint data after migration.\n\nMigration completed 2026-02-02 - endpoint disabled.","operationId":"get_inpaint_status_admin_migrate_inpaint_status_get","parameters":[{"name":"api_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__admin__InpaintStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/tickets":{"get":{"tags":["admin"],"summary":"Get all support tickets (admin)","description":"Get all support tickets with optional filters.\n\nQuery parameters:\n- status: Filter by ticket status\n- priority: Filter by priority\n- assigned_to: Filter by assigned agent\n- limit: Max results (default: 50)\n- offset: Pagination offset\n\n**Admin only.**","operationId":"admin_get_all_tickets_admin_support_tickets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TicketStatus"},{"type":"null"}],"title":"Status"}},{"name":"priority","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TicketPriority"},{"type":"null"}],"title":"Priority"}},{"name":"assigned_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Assigned To"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SupportTicketSummary"},"title":"Response Admin Get All Tickets Admin Support Tickets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/tickets/{ticket_id}":{"get":{"tags":["admin"],"summary":"Get support ticket details (admin)","description":"Get a support ticket with full details including internal notes.\n\n**Admin only.**","operationId":"admin_get_ticket_admin_support_tickets__ticket_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicket"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/tickets/{ticket_id}/status":{"patch":{"tags":["admin"],"summary":"Update ticket status (admin)","description":"Update ticket status and/or priority.\n\n**Admin only.**","operationId":"admin_update_ticket_status_admin_support_tickets__ticket_id__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicket"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/tickets/{ticket_id}/assign":{"post":{"tags":["admin"],"summary":"Assign ticket to agent (admin)","description":"Assign a ticket to a support agent.\n\n**Admin only.**","operationId":"admin_assign_ticket_admin_support_tickets__ticket_id__assign_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketAssignment"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicket"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/tickets/{ticket_id}/notes":{"post":{"tags":["admin"],"summary":"Add internal note (admin)","description":"Add an internal note to a ticket (not visible to user).\n\n**Admin only.**","operationId":"admin_add_internal_note_admin_support_tickets__ticket_id__notes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalNoteCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/tickets/{ticket_id}/reply":{"post":{"tags":["admin"],"summary":"Send reply to user (admin)","description":"Send a reply to the user on a ticket.\n\n**Admin only.**","operationId":"admin_reply_to_ticket_admin_support_tickets__ticket_id__reply_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalNoteCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/support/analytics":{"get":{"tags":["admin"],"summary":"Get support analytics (admin)","description":"Get support ticket analytics.\n\nQuery parameters:\n- days: Number of days to include (default: 30)\n\n**Admin only.**","operationId":"admin_get_support_analytics_admin_support_analytics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportAnalytics"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/lookup":{"get":{"tags":["admin"],"summary":"Admin Lookup User","description":"Look up a user by email and return all their data in one view.\n\nReturns: profile, generations, token transactions, pro token transactions,\nsubscription info, and LLM API costs.\n\n**Admin only.**","operationId":"admin_lookup_user_admin_users_lookup_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","description":"User email to look up","title":"Email"},"description":"User email to look up"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/grant-credits":{"post":{"tags":["admin"],"summary":"Admin Grant Credits","description":"Grant credits to a user by email. Admin only.\n\nSupported credit types:\n- pro_quota: Set Pro generation quota (resets used to 0, activates subscription)\n- trial: Set trial credits (resets used to 0)\n- token: Set token balance (upserts token account)\n- holiday: Set holiday credits","operationId":"admin_grant_credits_admin_users_grant_credits_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantCreditsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/dau":{"get":{"tags":["admin"],"summary":"Get Dau Metrics","description":"Daily/Weekly/Monthly Active Users based on generation and credit consumption.\n\nActive = user created a generation OR had a token transaction in the window.","operationId":"get_dau_metrics_admin_dau_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/agent-metrics":{"get":{"tags":["admin"],"summary":"Get Agent Metrics","description":"Get agent/MCP analytics: API key stats, designs by origin, top consumers,\nand MCP tool invocation breakdown.\n\n**Admin only.**","operationId":"get_agent_metrics_admin_agent_metrics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Period"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMetricsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/assets/generate":{"post":{"tags":["marketing"],"summary":"Generate Marketing Assets","description":"Generate marketing assets in social media formats from design images.\n\nSupports:\n- Instagram Square (1080x1080)\n- Instagram Portrait (1080x1350)\n- Twitter Card (1200x628)\n- Facebook Post (1200x630)\n\nAccepts either a generation_id to fetch existing images, or base64-encoded images.","operationId":"generate_marketing_assets_marketing_assets_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateMarketingAssetsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketingAssetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/topic-of-day":{"get":{"tags":["marketing"],"summary":"Get Topic Of Day","description":"Get today's trending landscape/hardscape topic. Auto-generates if none exists.","operationId":"get_topic_of_day_marketing_topic_of_day_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/topic-of-day/generate":{"post":{"tags":["marketing"],"summary":"Generate Topic For Date","description":"Generate a topic for a specific date (YYYY-MM-DD). Used by cron job or marketing users.","operationId":"generate_topic_for_date_marketing_topic_of_day_generate_post","parameters":[{"name":"target_date","in":"query","required":false,"schema":{"type":"string","title":"Target Date"}},{"name":"api_key","in":"query","required":false,"schema":{"type":"string","description":"Internal API key for cron jobs","title":"Api Key"},"description":"Internal API key for cron jobs"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/content":{"post":{"tags":["marketing"],"summary":"Generate Content","description":"Generate content for a specific platform.\n\nSupports model selection: gpt-5-mini (OpenAI) or gemini-3.0-flash (Google).\nRequires marketing access.","operationId":"generate_content_marketing_generate_content_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateContentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneratedContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/generate/blog":{"post":{"tags":["marketing"],"summary":"Generate Blog Post","description":"Generate a full blog post with SEO optimization and companion social posts.\n\nAlso generates social posts for Pinterest and Instagram to promote the blog.\n\nRequires marketing access.","operationId":"generate_blog_post_marketing_generate_blog_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateBlogRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/generate/linkedin":{"post":{"tags":["marketing"],"summary":"Generate Linkedin Post","description":"Generate LinkedIn content for B2B (service providers).\n\nRequires marketing access.","operationId":"generate_linkedin_post_marketing_generate_linkedin_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateLinkedInRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/generate/hooks":{"post":{"tags":["marketing"],"summary":"Generate Hooks","description":"Generate scroll-stopping hooks/opening lines.\n\nRequires marketing access.","operationId":"generate_hooks_marketing_generate_hooks_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"topic","in":"query","required":true,"schema":{"type":"string","description":"Topic for hooks","title":"Topic"},"description":"Topic for hooks"},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Count"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","description":"Target platform","default":"tiktok","title":"Platform"},"description":"Target platform"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HooksResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/hashtags":{"get":{"tags":["marketing"],"summary":"Generate Hashtags","description":"Generate relevant hashtags for a topic.\n\nRequires marketing access.","operationId":"generate_hashtags_marketing_generate_hashtags_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"platform","in":"query","required":true,"schema":{"type":"string","description":"Target platform","title":"Platform"},"description":"Target platform"},{"name":"topic","in":"query","required":true,"schema":{"type":"string","description":"Topic for hashtags","title":"Topic"},"description":"Topic for hashtags"},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"default":10,"title":"Count"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/video-prompts":{"post":{"tags":["marketing"],"summary":"Generate Video Prompts","description":"Generate AI video prompts for tools like Runway, Veo, Kling, Pika.\n\nReturns prompts optimized for the selected AI video generation tool,\nincluding camera movements, motion elements, and ready-to-use social captions.\n\nRequires marketing access.","operationId":"generate_video_prompts_marketing_generate_video_prompts_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"topic","in":"query","required":true,"schema":{"type":"string","description":"Topic for video content","title":"Topic"},"description":"Topic for video content"},{"name":"video_tool","in":"query","required":false,"schema":{"type":"string","description":"AI video tool: runway, veo, kling, pika","default":"runway","title":"Video Tool"},"description":"AI video tool: runway, veo, kling, pika"},{"name":"concept","in":"query","required":false,"schema":{"type":"string","description":"Video concept: transformation, walkthrough, detail_focus, time_of_day, seasonal, lifestyle","default":"transformation","title":"Concept"},"description":"Video concept: transformation, walkthrough, detail_focus, time_of_day, seasonal, lifestyle"},{"name":"duration","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Duration in seconds (auto if not specified)","title":"Duration"},"description":"Duration in seconds (auto if not specified)"},{"name":"aspect_ratio","in":"query","required":false,"schema":{"type":"string","description":"Aspect ratio: 9:16 (vertical), 16:9 (horizontal), 1:1 (square)","default":"9:16","title":"Aspect Ratio"},"description":"Aspect ratio: 9:16 (vertical), 16:9 (horizontal), 1:1 (square)"},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":5,"minimum":1,"description":"Number of prompt variations","default":3,"title":"Count"},"description":"Number of prompt variations"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"AI model to use","default":"gpt-5-mini","title":"Model"},"description":"AI model to use"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/video-prompts-all-tools":{"post":{"tags":["marketing"],"summary":"Generate Video Prompts All Tools","description":"Generate video prompts for ALL major AI video tools at once.\n\nUseful for comparing outputs across Runway, Veo, Kling, and Pika.\n\nRequires marketing access.","operationId":"generate_video_prompts_all_tools_marketing_generate_video_prompts_all_tools_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"topic","in":"query","required":true,"schema":{"type":"string","description":"Topic for video content","title":"Topic"},"description":"Topic for video content"},{"name":"concept","in":"query","required":false,"schema":{"type":"string","description":"Video concept type","default":"transformation","title":"Concept"},"description":"Video concept type"},{"name":"aspect_ratio","in":"query","required":false,"schema":{"type":"string","description":"Aspect ratio","default":"9:16","title":"Aspect Ratio"},"description":"Aspect ratio"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"AI model to use","default":"gpt-5-mini","title":"Model"},"description":"AI model to use"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/tiktok-video":{"post":{"tags":["marketing"],"summary":"Generate Tiktok Video Content","description":"Generate complete TikTok/Instagram Reels video content package.\n\nIncludes: video prompt, text overlays, caption with hashtags,\nsound suggestion, and posting strategy.\n\nRequires marketing access.","operationId":"generate_tiktok_video_content_marketing_generate_tiktok_video_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"topic","in":"query","required":true,"schema":{"type":"string","description":"Topic for TikTok/Reels video","title":"Topic"},"description":"Topic for TikTok/Reels video"},{"name":"video_style","in":"query","required":false,"schema":{"type":"string","description":"Style: transformation, tips, reveal, comparison","default":"transformation","title":"Video Style"},"description":"Style: transformation, tips, reveal, comparison"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"AI model to use","default":"gpt-5-mini","title":"Model"},"description":"AI model to use"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/app-demo-script":{"post":{"tags":["marketing"],"summary":"Generate App Demo Script","description":"Generate a script for recording a Yarda app demo video.\n\nReturns a timed script with screen actions, voiceover text,\ntext overlays, and posting strategy.\n\nRequires marketing access.","operationId":"generate_app_demo_script_marketing_generate_app_demo_script_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"feature","in":"query","required":false,"schema":{"type":"string","description":"Feature to demo: pro_mode, holiday_decorator, basic_generation, address_input","default":"pro_mode","title":"Feature"},"description":"Feature to demo: pro_mode, holiday_decorator, basic_generation, address_input"},{"name":"duration","in":"query","required":false,"schema":{"type":"integer","maximum":60,"minimum":15,"description":"Target duration in seconds","default":30,"title":"Duration"},"description":"Target duration in seconds"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"AI model to use","default":"gpt-5-mini","title":"Model"},"description":"AI model to use"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/reference/video-tools":{"get":{"tags":["marketing"],"summary":"Get Video Tools","description":"Get specifications for supported AI video generation tools.\n\nReturns tool capabilities, max durations, aspect ratios, and best use cases.","operationId":"get_video_tools_marketing_reference_video_tools_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/generate/image":{"post":{"tags":["marketing"],"summary":"Generate Image","description":"Generate an image using Pollinations.ai with Gemini fallback.\n\nFalls back to Gemini image generation when Pollinations.ai is unavailable.\nWhen Gemini is used, images are also uploaded to Vercel Blob for persistent storage.\n\nRequires marketing access.","operationId":"generate_image_marketing_generate_image_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateImageRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/generate/image-with-text":{"post":{"tags":["marketing"],"summary":"Generate Image With Text","description":"Generate an image with text overlay for social media.\n\nRequires marketing access.","operationId":"generate_image_with_text_marketing_generate_image_with_text_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateImageWithTextRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/images/history":{"get":{"tags":["marketing"],"summary":"Get Image History","description":"Get prompt/generation history.\n\nRequires marketing access.","operationId":"get_image_history_marketing_images_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/stats":{"get":{"tags":["marketing"],"summary":"Get Pipeline Stats","description":"Get pipeline statistics overview.\n\nRequires marketing access.","operationId":"get_pipeline_stats_marketing_pipeline_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineStatsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/pipeline/content":{"get":{"tags":["marketing"],"summary":"List Content","description":"List content items with optional filters.\n\nRequires marketing access.","operationId":"list_content_marketing_pipeline_content_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"platform","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by platform","title":"Platform"},"description":"Filter by platform"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["marketing"],"summary":"Add Content","description":"Add content to the pipeline.\n\nRequires marketing access.","operationId":"add_content_marketing_pipeline_content_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentItem"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/content/{item_id}":{"get":{"tags":["marketing"],"summary":"Get Content Item","description":"Get a specific content item.\n\nRequires marketing access.","operationId":"get_content_item_marketing_pipeline_content__item_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["marketing"],"summary":"Update Content","description":"Update a content item.\n\nRequires marketing access.","operationId":"update_content_marketing_pipeline_content__item_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["marketing"],"summary":"Delete Content","description":"Delete a content item.\n\nRequires marketing access.","operationId":"delete_content_marketing_pipeline_content__item_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/content/{item_id}/schedule":{"post":{"tags":["marketing"],"summary":"Schedule Content","description":"Schedule content for publication.\n\nRequires marketing access.","operationId":"schedule_content_marketing_pipeline_content__item_id__schedule_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleContentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/content/{item_id}/publish":{"post":{"tags":["marketing"],"summary":"Mark Published","description":"Mark content as published.\n\nRequires marketing access.","operationId":"mark_published_marketing_pipeline_content__item_id__publish_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Published URL","title":"Url"},"description":"Published URL"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/upload-image":{"post":{"tags":["marketing"],"summary":"Upload Marketing Image","description":"Upload an image to Vercel Blob storage for marketing content.","operationId":"upload_marketing_image_marketing_pipeline_upload_image_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_marketing_image_marketing_pipeline_upload_image_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/pipeline/content/{item_id}/publish/pinterest":{"post":{"tags":["marketing"],"summary":"Publish To Pinterest","description":"Publish content directly to Pinterest.\n\nCreates a pin on Pinterest using the content's title, body, and image.\nOn success, marks the content as published with the Pinterest URL.\n\nRequires marketing access and Pinterest API credentials.","operationId":"publish_to_pinterest_marketing_pipeline_content__item_id__publish_pinterest_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"board_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pinterest board ID (uses default if not provided)","title":"Board Id"},"description":"Pinterest board ID (uses default if not provided)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/content/{item_id}/publish/tiktok":{"post":{"tags":["marketing"],"summary":"Publish To Tiktok","description":"Publish content directly to TikTok.\n\nRequires a video_url on the content item (TikTok only supports video).\nOn success, marks the content as published.\n\nRequires marketing access and TikTok API credentials.","operationId":"publish_to_tiktok_marketing_pipeline_content__item_id__publish_tiktok_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/tiktok/status":{"get":{"tags":["marketing"],"summary":"Get Tiktok Status","description":"Check TikTok publisher configuration and connection status.\n\nReturns token validity, user info, and creator posting permissions.\n\nRequires marketing access.","operationId":"get_tiktok_status_marketing_publishers_tiktok_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/publishers/tiktok/publish-status/{publish_id}":{"get":{"tags":["marketing"],"summary":"Get Tiktok Publish Status","description":"Check the processing status of a TikTok video publish operation.\n\nAfter posting via the inbox API, TikTok processes the video asynchronously.\nUse this endpoint to poll the status. Possible statuses:\n- PROCESSING_UPLOAD: Video is being uploaded\n- PROCESSING_DOWNLOAD: Video is being processed\n- SEND_TO_USER_INBOX: Video has been sent to the creator's drafts\n- PUBLISH_COMPLETE: Video is published\n- FAILED: Upload or processing failed\n\nRequires marketing access.","operationId":"get_tiktok_publish_status_marketing_publishers_tiktok_publish_status__publish_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"publish_id","in":"path","required":true,"schema":{"type":"string","title":"Publish Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/pinterest/status":{"get":{"tags":["marketing"],"summary":"Get Pinterest Status","description":"Check Pinterest publisher configuration and connection status.\n\nReturns token validity, available boards, and configuration info.\n\nRequires marketing access.","operationId":"get_pinterest_status_marketing_publishers_pinterest_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/pipeline/content/{item_id}/publish/youtube":{"post":{"tags":["marketing"],"summary":"Publish To Youtube","description":"Publish a video content item to YouTube.\n\nRequires a video_url on the content item.\nOn success, marks the content as published.\n\nRequires marketing access and YouTube API credentials.","operationId":"publish_to_youtube_marketing_pipeline_content__item_id__publish_youtube_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/youtube/status":{"get":{"tags":["marketing"],"summary":"Get Youtube Status","description":"Check YouTube publisher configuration and connection status.\n\nRequires marketing access.","operationId":"get_youtube_status_marketing_publishers_youtube_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/pipeline/content/{item_id}/metrics":{"patch":{"tags":["marketing"],"summary":"Update Metrics","description":"Update content performance metrics.\n\nRequires marketing access.","operationId":"update_metrics_marketing_pipeline_content__item_id__metrics_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMetricsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/pipeline/calendar":{"get":{"tags":["marketing"],"summary":"Get Calendar","description":"Get calendar view of scheduled content.\n\nRequires marketing access.","operationId":"get_calendar_marketing_pipeline_calendar_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"year","in":"query","required":true,"schema":{"type":"integer","maximum":2030,"minimum":2020,"title":"Year"}},{"name":"month","in":"query","required":true,"schema":{"type":"integer","maximum":12,"minimum":1,"title":"Month"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/reference/platforms":{"get":{"tags":["marketing"],"summary":"Get Platforms","description":"Get platform specifications.\n\nRequires marketing access.","operationId":"get_platforms_marketing_reference_platforms_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/reference/pillars":{"get":{"tags":["marketing"],"summary":"Get Pillars","description":"Get content pillars for audience.\n\nRequires marketing access.","operationId":"get_pillars_marketing_reference_pillars_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"audience","in":"query","required":false,"schema":{"type":"string","description":"Target audience","default":"homeowner","title":"Audience"},"description":"Target audience"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/reference/topics":{"get":{"tags":["marketing"],"summary":"Get Topics","description":"Get topic ideas.\n\nRequires marketing access.","operationId":"get_topics_marketing_reference_topics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"pillar","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Content pillar","title":"Pillar"},"description":"Content pillar"},{"name":"audience","in":"query","required":false,"schema":{"type":"string","description":"Target audience","default":"homeowner","title":"Audience"},"description":"Target audience"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/reference/calendar-template":{"get":{"tags":["marketing"],"summary":"Get Calendar Template","description":"Generate a content calendar template.\n\nRequires marketing access.","operationId":"get_calendar_template_marketing_reference_calendar_template_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":12,"minimum":1,"default":4,"title":"Weeks"}},{"name":"posts_per_day","in":"query","required":false,"schema":{"type":"integer","maximum":5,"minimum":1,"default":2,"title":"Posts Per Day"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/review/content":{"post":{"tags":["marketing"],"summary":"Review Content Endpoint","description":"Review content and get detailed feedback with scores.\n\nReturns platform-specific and audience-specific scores along with\nissues, suggestions, and an overall verdict (approve/improve/reject).\n\nRequires marketing access.","operationId":"review_content_endpoint_marketing_review_content_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewContentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewResultResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/review/image":{"post":{"tags":["marketing"],"summary":"Review Image Endpoint","description":"Review an image using vision model.\n\nAnalyzes the image for visual appeal, composition, platform fit,\nand AI-specific issues (human faces, text overlays, artifacts).\n\nRequires marketing access.","operationId":"review_image_endpoint_marketing_review_image_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewImageRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageReviewResultResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/review/full":{"post":{"tags":["marketing"],"summary":"Full Review Endpoint","description":"Complete review of both text content AND image.\n\nCombines text review (70%) and image review (30%) for a combined score.\n\nRequires marketing access.","operationId":"full_review_endpoint_marketing_review_full_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FullReviewRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FullReviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/review/improve":{"post":{"tags":["marketing"],"summary":"Improve Content Endpoint","description":"Review and auto-improve content in one step.\n\nFirst reviews the content, then automatically improves it based on\nthe feedback. Returns both original and improved versions.\n\nRequires marketing access.","operationId":"improve_content_endpoint_marketing_review_improve_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImproveContentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImprovedContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/review/criteria":{"get":{"tags":["marketing"],"summary":"Get Review Criteria Endpoint","description":"Get all review criteria for UI display.\n\nReturns platform criteria, audience criteria, and score thresholds.\n\nRequires marketing access.","operationId":"get_review_criteria_endpoint_marketing_review_criteria_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/blog/publish":{"post":{"tags":["marketing"],"summary":"Publish Blog Post","description":"Publish a blog post to the Yarda blog (Supabase-backed).\n\nCreates a new blog post in the database with 'published' status.\nThe post will immediately appear on yarda.pro/blog.\n\nRequires marketing access.","operationId":"publish_blog_post_marketing_blog_publish_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"title","in":"query","required":true,"schema":{"type":"string","description":"Blog post title","title":"Title"},"description":"Blog post title"},{"name":"description","in":"query","required":true,"schema":{"type":"string","description":"Meta description","title":"Description"},"description":"Meta description"},{"name":"content","in":"query","required":true,"schema":{"type":"string","description":"Full markdown content","title":"Content"},"description":"Full markdown content"},{"name":"image_url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Featured image URL","title":"Image Url"},"description":"Featured image URL"},{"name":"image_prompt","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Image prompt used","title":"Image Prompt"},"description":"Image prompt used"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/blog/posts":{"get":{"tags":["marketing"],"summary":"List Blog Posts","description":"List all blog posts (for marketing dashboard).\n\nRequires marketing access.","operationId":"list_blog_posts_marketing_blog_posts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/video":{"post":{"tags":["marketing"],"summary":"Generate Video","description":"Generate an AI video using Atlas Cloud's Seedance API.\n\nText-to-video generation with configurable model, resolution, and duration.\nReturns video URL when complete (sync mode) or prediction ID (async mode).\n\nRequires marketing access.","operationId":"generate_video_marketing_generate_video_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"prompt","in":"query","required":true,"schema":{"type":"string","description":"Text prompt for video generation","title":"Prompt"},"description":"Text prompt for video generation"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"Model: seedance-1.5-pro or seedance-2.0","default":"seedance-1.5-pro","title":"Model"},"description":"Model: seedance-1.5-pro or seedance-2.0"},{"name":"aspect_ratio","in":"query","required":false,"schema":{"type":"string","description":"Aspect ratio: 16:9, 9:16, 1:1, 21:9","default":"16:9","title":"Aspect Ratio"},"description":"Aspect ratio: 16:9, 9:16, 1:1, 21:9"},{"name":"resolution","in":"query","required":false,"schema":{"type":"string","description":"Resolution: 480p, 720p, 1080p","default":"720p","title":"Resolution"},"description":"Resolution: 480p, 720p, 1080p"},{"name":"duration","in":"query","required":false,"schema":{"type":"integer","maximum":15,"minimum":4,"description":"Duration in seconds (4-15)","default":8,"title":"Duration"},"description":"Duration in seconds (4-15)"},{"name":"generate_audio","in":"query","required":false,"schema":{"type":"boolean","description":"Generate audio with video","default":true,"title":"Generate Audio"},"description":"Generate audio with video"},{"name":"wait","in":"query","required":false,"schema":{"type":"boolean","description":"Wait for result (sync) or return prediction ID (async)","default":true,"title":"Wait"},"description":"Wait for result (sync) or return prediction ID (async)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/video-from-image":{"post":{"tags":["marketing"],"summary":"Generate Video From Image","description":"Generate an AI video from an image + text prompt (image-to-video).\n\nThe image serves as the first frame; the prompt describes the motion.\nUseful for animating Yarda AI-generated landscape designs.\n\nRequires marketing access.","operationId":"generate_video_from_image_marketing_generate_video_from_image_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"prompt","in":"query","required":true,"schema":{"type":"string","description":"Text prompt describing desired video motion","title":"Prompt"},"description":"Text prompt describing desired video motion"},{"name":"image_url","in":"query","required":true,"schema":{"type":"string","description":"URL of the source image (first frame)","title":"Image Url"},"description":"URL of the source image (first frame)"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"Model: seedance-1.5-pro or seedance-2.0","default":"seedance-1.5-pro","title":"Model"},"description":"Model: seedance-1.5-pro or seedance-2.0"},{"name":"aspect_ratio","in":"query","required":false,"schema":{"type":"string","description":"Aspect ratio","default":"16:9","title":"Aspect Ratio"},"description":"Aspect ratio"},{"name":"resolution","in":"query","required":false,"schema":{"type":"string","description":"Resolution: 480p, 720p, 1080p","default":"720p","title":"Resolution"},"description":"Resolution: 480p, 720p, 1080p"},{"name":"duration","in":"query","required":false,"schema":{"type":"integer","maximum":15,"minimum":4,"description":"Duration in seconds (4-15)","default":8,"title":"Duration"},"description":"Duration in seconds (4-15)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/generate/landscape-video":{"post":{"tags":["marketing"],"summary":"Generate Landscape Video","description":"High-level landscape video generation.\n\nAutomatically builds a cinematic prompt using the VideoPromptBuilder\n(8-element framework) and generates the video via Atlas Cloud.\n\nRequires marketing access.","operationId":"generate_landscape_video_marketing_generate_landscape_video_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"subject","in":"query","required":false,"schema":{"type":"string","description":"Landscape subject: backyard, front_yard, patio, garden, pool, walkway, etc.","default":"backyard","title":"Subject"},"description":"Landscape subject: backyard, front_yard, patio, garden, pool, walkway, etc."},{"name":"concept","in":"query","required":false,"schema":{"type":"string","description":"Video concept: transformation, walkthrough, detail, seasonal","default":"transformation","title":"Concept"},"description":"Video concept: transformation, walkthrough, detail, seasonal"},{"name":"resolution","in":"query","required":false,"schema":{"type":"string","description":"Resolution: 480p, 720p, 1080p","default":"720p","title":"Resolution"},"description":"Resolution: 480p, 720p, 1080p"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"Model: seedance-1.5-pro or seedance-2.0","default":"seedance-1.5-pro","title":"Model"},"description":"Model: seedance-1.5-pro or seedance-2.0"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/video/status/{prediction_id}":{"get":{"tags":["marketing"],"summary":"Get Video Status","description":"Check the status of a video generation job.\n\nUse this when you submitted a video in async mode (wait=false).\n\nRequires marketing access.","operationId":"get_video_status_marketing_video_status__prediction_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"string","title":"Prediction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/video-cta/process":{"post":{"tags":["marketing"],"summary":"Process Video Cta","description":"Process a video by appending a branded CTA closing screen.\n\nUpload a video file and configure the closing screen appearance.\nReturns the processed video with the CTA screen appended.\n\nRequires marketing access. Max file size: 100MB.\nSupported formats: MP4, MOV, M4V.","operationId":"process_video_cta_marketing_video_cta_process_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_process_video_cta_marketing_video_cta_process_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/generate/hook-prompts":{"post":{"tags":["marketing"],"summary":"Generate Hook Prompts","description":"Generate hook video prompts optimized for Veo 3, Seedance 2.0, and Kling.\n\nThese are text prompts designed to be copy-pasted into external AI video\ntools. The actual video generation happens outside our app.\n\nEach prompt follows the 8-element framework (Subject, Action, Camera,\nScene, Lighting, Style, Audio, Constraints) and includes a caption\ntext overlay for use in Remotion compositions.\n\nSupports 14 hook psychology templates and 7 visual styles.","operationId":"generate_hook_prompts_marketing_generate_hook_prompts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateHookPromptsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateHookPromptsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/blog/posts":{"get":{"tags":["blog"],"summary":"Get Published Posts","description":"Get all published blog posts (public, no auth required).\n\nReturns posts sorted by published date, newest first.","operationId":"get_published_posts_blog_posts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/blog/posts/{slug}":{"get":{"tags":["blog"],"summary":"Get Post By Slug","description":"Get a single published blog post by slug (public, no auth required).\n\nAlso increments the view count.","operationId":"get_post_by_slug_blog_posts__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/backlog":{"post":{"tags":["backlog"],"summary":"Create backlog item","description":"Create a new backlog item.\n\n**Admin only** - requires admin role.","operationId":"create_backlog_item_backlog_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacklogItemCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacklogItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["backlog"],"summary":"List backlog items","description":"List all backlog items with optional filters.\n\n**Admin only** - requires admin role.\n\nQuery parameters:\n- status: Filter by status (proposed, approved, in_progress, completed, rejected, deferred)\n- priority: Filter by priority (critical, high, medium, low, nice_to_have)\n- category: Filter by category (enhancement, bug, tech_debt, performance, ux, documentation, camera_positioning)\n- tag: Filter by tag (items containing this tag)\n- limit: Maximum results (default: 100)\n- offset: Pagination offset (default: 0)","operationId":"list_backlog_items_backlog_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"priority","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BacklogItemResponse"},"title":"Response List Backlog Items Backlog Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/backlog/stats":{"get":{"tags":["backlog"],"summary":"Get backlog statistics","description":"Get backlog statistics and summary.\n\n**Admin only** - requires admin role.\n\nReturns counts by status, priority, and category.","operationId":"get_backlog_stats_backlog_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacklogStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/backlog/{item_id}":{"get":{"tags":["backlog"],"summary":"Get backlog item","description":"Get a single backlog item by ID.\n\n**Admin only** - requires admin role.","operationId":"get_backlog_item_backlog__item_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacklogItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["backlog"],"summary":"Update backlog item","description":"Update a backlog item.\n\n**Admin only** - requires admin role.","operationId":"update_backlog_item_backlog__item_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacklogItemUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacklogItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["backlog"],"summary":"Delete backlog item","description":"Delete a backlog item.\n\n**Admin only** - requires admin role.","operationId":"delete_backlog_item_backlog__item_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/runs":{"post":{"tags":["camera-tests"],"summary":"Create a test run","description":"Create a new test run configuration.\n\n**Admin only** - requires admin role.\n\nThis creates the test run but does NOT start it. Use the start endpoint to begin execution.","operationId":"create_test_run_camera_tests_runs_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["camera-tests"],"summary":"List test runs","description":"List all test runs with optional filters.\n\n**Admin only** - requires admin role.\n\nQuery parameters:\n- status: Filter by status (pending, running, completed, failed, cancelled)\n- test_type: Filter by type (address_batch, cul_de_sac, corner_lot, random_sample, regression)\n- limit: Maximum results (default: 50)\n- offset: Pagination offset (default: 0)","operationId":"list_test_runs_camera_tests_runs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"test_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestRunSummary"},"title":"Response List Test Runs Camera Tests Runs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/runs/{run_id}/start":{"post":{"tags":["camera-tests"],"summary":"Start a test run","description":"Start executing a test run in the background.\n\n**Admin only** - requires admin role.\n\nThis kicks off the batch testing process which:\n1. Fetches all addresses to test\n2. Calls the camera positioning API for each\n3. Stores results and quality metrics\n4. Updates aggregate statistics\n\nThe test runs in the background - poll the GET endpoint for progress.","operationId":"start_test_run_camera_tests_runs__run_id__start_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/runs/{run_id}":{"get":{"tags":["camera-tests"],"summary":"Get test run details","description":"Get detailed information about a test run.\n\n**Admin only** - requires admin role.","operationId":"get_test_run_camera_tests_runs__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/runs/{run_id}/results":{"get":{"tags":["camera-tests"],"summary":"Get test results","description":"Get individual test results for a run.\n\n**Admin only** - requires admin role.\n\nQuery parameters:\n- quality_grade: Filter by grade (A, B, C, D, F)\n- has_issues: Filter to results with/without issues\n- needs_review: Filter to results needing manual review\n- limit: Maximum results (default: 100)\n- offset: Pagination offset (default: 0)","operationId":"get_test_results_camera_tests_runs__run_id__results_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}},{"name":"quality_grade","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quality Grade"}},{"name":"has_issues","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Issues"}},{"name":"needs_review","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Needs Review"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestResultResponse"},"title":"Response Get Test Results Camera Tests Runs  Run Id  Results Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/results/{result_id}/review":{"post":{"tags":["camera-tests"],"summary":"Review a test result","description":"Submit a manual review for a test result.\n\n**Admin only** - requires admin role.\n\nMark whether the camera positioning is correct and add notes.","operationId":"review_test_result_camera_tests_results__result_id__review_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Result Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResultReview"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResultResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/addresses":{"post":{"tags":["camera-tests"],"summary":"Add test address","description":"Add a new address to the test pool.\n\n**Admin only** - requires admin role.\n\nIf the address already exists, it will be updated with any new information.","operationId":"add_test_address_camera_tests_addresses_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAddressCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAddressResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["camera-tests"],"summary":"List test addresses","description":"List addresses in the test pool.\n\n**Admin only** - requires admin role.\n\nQuery parameters:\n- address_type: Filter by type (standard, cul_de_sac, corner_lot, etc.)\n- region: Filter by geographic region\n- is_active: Filter by active status (default: true)\n- limit: Maximum results (default: 100)\n- offset: Pagination offset (default: 0)","operationId":"list_test_addresses_camera_tests_addresses_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"address_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Type"}},{"name":"region","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"}},{"name":"is_active","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":true,"title":"Is Active"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestAddressResponse"},"title":"Response List Test Addresses Camera Tests Addresses Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/addresses/bulk":{"post":{"tags":["camera-tests"],"summary":"Bulk add test addresses","description":"Add multiple addresses to the test pool.\n\n**Admin only** - requires admin role.\n\nMaximum 1000 addresses per request.","operationId":"add_test_addresses_bulk_camera_tests_addresses_bulk_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAddressBulkCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Add Test Addresses Bulk Camera Tests Addresses Bulk Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/camera-tests/addresses/count":{"get":{"tags":["camera-tests"],"summary":"Get address count","description":"Get count of active test addresses.\n\n**Admin only** - requires admin role.","operationId":"get_address_count_camera_tests_addresses_count_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"address_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Address Count Camera Tests Addresses Count Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/camera-tests/addresses/cleanup":{"delete":{"tags":["camera-tests"],"summary":"Delete unvetted addresses","description":"Delete addresses without valid real estate source attribution.\n\n**Admin only** - requires admin role.\n\nValid sources: redfin, zillow, homes.com, trulia, har.com, coldwellbanker,\nlakeoswegoreview, and other legitimate real estate sources.\n\nThis removes addresses that were added without proper vetting.","operationId":"cleanup_unvetted_addresses_camera_tests_addresses_cleanup_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Cleanup Unvetted Addresses Camera Tests Addresses Cleanup Delete"}}}}},"security":[{"HTTPBearer":[]}]}},"/camera-tests/stats":{"get":{"tags":["camera-tests"],"summary":"Get overall statistics","description":"Get overall camera test statistics.\n\n**Admin only** - requires admin role.\n\nReturns:\n- Total test runs\n- Total addresses tested\n- Address pool size\n- Average quality scores\n- Recent test runs","operationId":"get_overall_stats_camera_tests_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverallStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/upload":{"post":{"tags":["Upload"],"summary":"Upload File","description":"Upload a file to Vercel Blob storage.\n\nArgs:\n    file: The file to upload (image)\n    upload_type: Type of upload (profile_photo, cover_photo, etc.)\n    current_user: Authenticated user\n    storage: Blob storage service\n\nReturns:\n    {\"url\": \"https://blob.vercel-storage.com/...\"}\n\nRaises:\n    400: If file is not an image or exceeds size limit\n    401: If user is not authenticated","operationId":"upload_file_api_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_file_api_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/playground/screenshot-request":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Request Screenshot","description":"Request a screenshot capture via Chrome automation.\nReturns immediately with screenshot_id. Client polls for completion.","operationId":"request_screenshot_playground_screenshot_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenshotRequestModel"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenshotResponseModel"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/screenshot-queue":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Get Screenshot Queue","description":"Get all pending screenshot requests.\nUsed by Chrome automation agent to fetch work.","operationId":"get_screenshot_queue_playground_screenshot_queue_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response Get Screenshot Queue Playground Screenshot Queue Get"}}}},"404":{"description":"Not found"}}}},"/playground/screenshot-complete":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Mark Screenshot Complete","description":"Mark a screenshot as completed.\nCalled by Chrome automation agent after saving screenshot.","operationId":"mark_screenshot_complete_playground_screenshot_complete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenshotCompleteModel"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/screenshot-status/{screenshot_id}":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Get Screenshot Status","description":"Check status of a screenshot request.\nUsed by backend to poll for completion.","operationId":"get_screenshot_status_playground_screenshot_status__screenshot_id__get","parameters":[{"name":"screenshot_id","in":"path","required":true,"schema":{"type":"string","title":"Screenshot Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenshotResponseModel"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/camera-test":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Test Camera Positioning","description":"Test camera positioning for a single address.\n\nCalculates camera positions for front and back views based on property\nclassification. Optionally validates with VLM if images are provided.\n\nArgs:\n    request: CameraTestRequest with address and options\n\nReturns:\n    CameraTestResponse with calculated positions and optional validation","operationId":"test_camera_positioning_playground_camera_test_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CameraTestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CameraTestResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/camera-tune":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Run Adaptive Tuning","description":"Run the adaptive tuning loop for an address.\n\nExecutes the self-improvement loop: capture → validate → adjust → retry\nuntil quality threshold is met or max iterations reached.\n\nThis endpoint validates pre-captured images. For full capture+validate+adjust\nflow, the frontend must provide a capture_callback mechanism or the images\nmust be provided with each iteration.\n\nArgs:\n    request: CameraTuneRequest with address, images, and tuning options\n\nReturns:\n    CameraTuneResponse with final results and adjustment history","operationId":"run_adaptive_tuning_playground_camera_tune_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CameraTuneRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CameraTuneResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/batch-test":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Run Batch Test","description":"Run camera positioning tests on multiple addresses.\n\nProcesses addresses sequentially and returns aggregated results.\nOptionally validates each address with VLM if validate=True.\n\nArgs:\n    request: BatchTestRequest with list of addresses\n\nReturns:\n    BatchTestResponse with individual and aggregate results","operationId":"run_batch_test_playground_batch_test_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTestResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/validate-view":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Validate Captured View","description":"Validate a captured view with the local VLM.\n\nSends the image to Qwen2.5-VL for quality assessment and returns\nstructured scores for each quality dimension.\n\nQuality Dimensions (with weights):\n- orientation_score (30%): Is the intended side (FRONT/BACK) visible?\n- house_visibility (25%): Is the house fully visible in frame?\n- geometry_quality (20%): Is there good 3D geometry (not just terrain)?\n- property_isolation (15%): Is the target property distinguished?\n- camera_angle (10%): Is the camera angle appropriate?\n\nArgs:\n    request: ValidateViewRequest with base64 image and view type\n\nReturns:\n    ValidationResult with scores, issues, and recommendations","operationId":"validate_captured_view_playground_validate_view_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateViewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationResult"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/vlm-status":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Check Vlm Status","description":"Check if the local VLM endpoint is available.\n\nQueries the VLM endpoint (LM Studio) to verify it's running and\nreturns connection information including latency.\n\nReturns:\n    VLMStatusResponse with availability, model info, and latency","operationId":"check_vlm_status_playground_vlm_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VLMStatusResponse"}}}},"404":{"description":"Not found"}}}},"/playground/learned-params":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Get Learned Parameters","description":"Query learned parameters for a property type combination.\n\nLooks up the learning database by layout_type (primary), lot_size,\nand optionally triangle_count range.\n\nArgs:\n    layout_type: Primary property layout type\n    lot_size: Lot size category\n    triangle_count: Optional triangle count to match ranges\n\nReturns:\n    LearnedParameters if found, None otherwise","operationId":"get_learned_parameters_playground_learned_params_get","parameters":[{"name":"layout_type","in":"query","required":true,"schema":{"$ref":"#/components/schemas/LayoutType"}},{"name":"lot_size","in":"query","required":true,"schema":{"$ref":"#/components/schemas/LotSize"}},{"name":"triangle_count","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Triangle Count"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/LearnedParameters"},{"type":"null"}],"title":"Response Get Learned Parameters Playground Learned Params Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Playground - Camera Positioning"],"summary":"Save Learned Parameters","description":"Save successful camera parameters to the learning database.\n\nCreates or updates an entry indexed by layout_type, lot_size,\nand triangle_count range.\n\nArgs:\n    request: SaveLearnedParamsRequest with parameters to save\n\nReturns:\n    LearnedParameters with the saved record","operationId":"save_learned_parameters_playground_learned_params_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveLearnedParamsRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearnedParameters"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/learned-params/all":{"get":{"tags":["Playground - Camera Positioning"],"summary":"List All Learned Parameters","description":"List all entries in the learning database.\n\nSupports optional filtering by layout_type and pagination.\n\nArgs:\n    layout_type: Optional filter by layout type\n    limit: Maximum records to return (default 100)\n    offset: Records to skip for pagination\n\nReturns:\n    LearnedParamsListResponse with items and total count","operationId":"list_all_learned_parameters_playground_learned_params_all_get","parameters":[{"name":"layout_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/LayoutType"},{"type":"null"}],"title":"Layout Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearnedParamsListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/auto-tune-stream":{"post":{"tags":["Playground - Camera Positioning"],"summary":"Auto Tune Stream","description":"Stream automated camera tuning progress via Server-Sent Events.\n\nThis endpoint runs the full adaptive tuning pipeline and streams\nreal-time progress updates including images, scores, and adjustments.\n\nEvent types:\n- start: Tuning session started\n- vlm_status: VLM availability check result\n- address_start: Beginning to process an address\n- validation_result: VLM validation scores for front/back views\n- adjustment: Parameter adjustment made\n- address_complete: Address processing finished\n- progress: Overall progress update\n- complete: All addresses processed\n- error: An error occurred\n\nArgs:\n    config: AutoTuneConfig with mode, thresholds, etc.\n\nReturns:\n    StreamingResponse with SSE events","operationId":"auto_tune_stream_playground_auto_tune_stream_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTuneConfig"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/playground/learned-parameters":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Get Learned Parameters","description":"Get all learned camera parameters from the learning database.\n\nReturns parameters grouped by layout_type and lot_size, showing:\n- Optimal altitude, pitch values\n- Quality scores achieved\n- Sample count (how many addresses contributed to these params)\n- Most recent address that used these params\n\nUseful for seeing what the auto-tuner has learned.","operationId":"get_learned_parameters_playground_learned_parameters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/playground/address-pool-stats":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Get Address Pool Stats","description":"Get statistics about the address pool and usage.\n\nReturns:\n- Total addresses in pool\n- Breakdown by layout type and lot size\n- How many have been tuned\n- How many remain unused","operationId":"get_address_pool_stats_playground_address_pool_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/playground/unused-addresses":{"get":{"tags":["Playground - Camera Positioning"],"summary":"Get Unused Addresses","description":"Get addresses from the pool that haven't been tuned yet.\n\nArgs:\n    limit: Maximum number of addresses to return (default 20)\n\nReturns addresses ready for auto-tuning, prioritizing diversity\nacross layout types and lot sizes.","operationId":"get_unused_addresses_playground_unused_addresses_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/promo/info/{promo_code}":{"get":{"tags":["promo"],"summary":"Get Promo Info","description":"Get information about a promo code for landing pages.\n\nThis endpoint retrieves the Stripe promotion code details\nto display on landing pages.\n\nArgs:\n    promo_code: The promo code or hashed ID\n\nReturns:\n    Promo code details including discount info","operationId":"get_promo_info_promo_info__promo_code__get","parameters":[{"name":"promo_code","in":"path","required":true,"schema":{"type":"string","title":"Promo Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/promo/apply/{promo_code}":{"get":{"tags":["promo"],"summary":"Apply Promo And Checkout","description":"Apply a promo code and redirect to Stripe Checkout.\n\nThis endpoint:\n1. Validates the promo code exists on Stripe\n2. Creates a checkout session with the promo pre-applied\n3. Redirects the user to Stripe Checkout\n\nIf the user is not authenticated, redirects to login first with\nreturn URL preserved.\n\nArgs:\n    promo_code: The promo code to apply\n    plan: Subscription plan ID (default: monthly_pro)\n    user: Current user (optional - will redirect to login if not authenticated)\n\nReturns:\n    RedirectResponse to Stripe Checkout or login page","operationId":"apply_promo_and_checkout_promo_apply__promo_code__get","parameters":[{"name":"promo_code","in":"path","required":true,"schema":{"type":"string","title":"Promo Code"}},{"name":"plan","in":"query","required":false,"schema":{"type":"string","description":"Subscription plan ID","default":"monthly_pro","title":"Plan"},"description":"Subscription plan ID"},{"name":"json_response","in":"query","required":false,"schema":{"type":"boolean","description":"Return JSON instead of redirect","default":false,"title":"Json Response"},"description":"Return JSON instead of redirect"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/promo/hash/{code}":{"get":{"tags":["promo"],"summary":"Get Code Hash","description":"Get the URL hash for a promo code (admin/testing endpoint).\n\nThis is useful for generating the hashed URLs for marketing materials.\n\nArgs:\n    code: The promo code to hash\n\nReturns:\n    The hashed value and full promo URL","operationId":"get_code_hash_promo_hash__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/inpaint":{"post":{"tags":["Inpainting"],"summary":"Create Inpaint","description":"Create an inpainting edit for a design variant.\n\nThe mask should be a PNG image where:\n- WHITE pixels indicate areas to modify\n- BLACK pixels indicate areas to preserve exactly\n\nNo credits are deducted — inpainting uses gemini-2.5-flash-image\n(non-premium model), which is included with Pro subscription.","operationId":"create_inpaint_api_v1_inpaint_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_inpaint_api_v1_inpaint_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InpaintResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"404":{"description":"Variant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"500":{"description":"Generation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/inpaint/{edit_id}":{"get":{"tags":["Inpainting"],"summary":"Get Inpaint Status","description":"Get the status of an inpainting edit.\n\nUse this endpoint to poll for completion if the initial request\nreturns a 'processing' status.","operationId":"get_inpaint_status_api_v1_inpaint__edit_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"edit_id","in":"path","required":true,"schema":{"type":"string","title":"Edit Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__InpaintStatusResponse"}}}},"404":{"description":"Edit not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/inpaint/variant/{variant_id}":{"delete":{"tags":["Inpainting"],"summary":"Delete Variant","description":"Delete a generation variant.\n\nUsed for \"Save and Replace\" functionality - deletes the original\nvariant after an inpaint edit creates a new one.","operationId":"delete_variant_api_v1_inpaint_variant__variant_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"responses":{"200":{"description":"Variant deleted successfully","content":{"application/json":{"schema":{}}}},"404":{"description":"Variant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pin-annotate":{"post":{"tags":["Pin Annotation"],"summary":"Create Pin Annotation","description":"Create a pin-drop annotation edit for a design.\n\nUsers place numbered pins on the generated image with comments describing\nchanges. Both the clean original and annotated images are sent to Gemini,\nwhich interprets the pin positions visually and regenerates the design.\n\nNo credits are deducted — uses gemini-2.5-flash-image (non-premium).","operationId":"create_pin_annotation_api_v1_pin_annotate_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_pin_annotation_api_v1_pin_annotate_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PinAnnotateResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"404":{"description":"Variant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"500":{"description":"Generation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__inpaint__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/analytics/events":{"post":{"tags":["analytics"],"summary":"Log Funnel Event","description":"Log a funnel event from the frontend.\n\nNo authentication required for visit/lead events to minimize friction.\nLightweight endpoint for high-volume event ingestion.\n\nEvent types: visit, lead, signup, trial_start, payment","operationId":"log_funnel_event_analytics_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelEventRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/campaigns":{"get":{"tags":["analytics"],"summary":"Get Campaign Summary","description":"Get campaign performance summary.\n\nAggregates subscription data by UTM parameters to show:\n- Trial starts by campaign\n- Conversions by campaign\n- Revenue by campaign\n\nData comes from Stripe subscription metadata.\n\nRequires admin access.","operationId":"get_campaign_summary_analytics_campaigns_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/funnel":{"get":{"tags":["analytics"],"summary":"Get Conversion Funnel","description":"Get 5-stage conversion funnel from funnel_events table.\n\nStages:\n1. Visits - page loads\n2. Leads - address entered\n3. Signups - account created\n4. Trial Starts - trial subscription started\n5. Paid Conversions - payment completed\n\nReturns count per stage, conversion rate to next stage,\noverall conversion rate from top, and drop-off rate.\n\nSupports ?days=30 for lookback and ?campaign=X for filtering.\n\nRequires admin access.","operationId":"get_conversion_funnel_analytics_funnel_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"},{"name":"campaign","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by UTM campaign","title":"Campaign"},"description":"Filter by UTM campaign"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/funnel/daily":{"get":{"tags":["analytics"],"summary":"Get Daily Funnel","description":"Get daily funnel snapshots for trend analysis.\n\nReturns daily counts per funnel stage for the lookback period.\nSupports ?days=30 and ?campaign=X query params.\n\nRequires admin access.","operationId":"get_daily_funnel_analytics_funnel_daily_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"},{"name":"campaign","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by UTM campaign","title":"Campaign"},"description":"Filter by UTM campaign"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyFunnelSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/funnel/campaigns":{"get":{"tags":["analytics"],"summary":"Get Funnel Campaigns","description":"Get distinct campaigns from funnel_events for filter dropdown.\n\nReturns list of campaign names seen in the lookback period.\n\nRequires admin access.","operationId":"get_funnel_campaigns_analytics_funnel_campaigns_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":90,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/trials":{"get":{"tags":["analytics"],"summary":"Get Trial List","description":"Get list of trial subscriptions with UTM attribution.\n\nShows individual trials with:\n- Customer email\n- Trial start/end dates\n- UTM attribution\n- Conversion status\n\nRequires admin access.","operationId":"get_trial_list_analytics_trials_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status: trialing, active, canceled","title":"Status"},"description":"Filter by status: trialing, active, canceled"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrialList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/daily-signups":{"get":{"tags":["analytics"],"summary":"Get Daily Signups","description":"Get daily signup counts.\n\nReturns signup count per day for the specified period.\n\nRequires admin access.","operationId":"get_daily_signups_analytics_daily_signups_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"description":"Number of days to look back","default":30,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/freemium-conversion":{"get":{"tags":["analytics"],"summary":"Get Freemium Conversion","description":"Weekly freemium → paid conversion rate for GTM OKR KR2.3 reporting.\n\nTracks:\n- Freemium activations (trial_start events with type=freemium)\n- Paid conversions (payment events) per week\n- Conversion rate = (paid / freemium_activated) × 100\n\nUses the freemium_conversion_weekly DB view (migration 080).\nRequires admin access.","operationId":"get_freemium_conversion_analytics_freemium_conversion_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":52,"minimum":1,"description":"Number of weeks to look back","default":12,"title":"Weeks"},"description":"Number of weeks to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreemiumConversionSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analytics/weekly-report":{"get":{"tags":["analytics"],"summary":"Get Weekly Report","description":"Unified weekly report for Jerry's Monday tracker (YAR-329).\n\nSingle endpoint that returns:\n- This week vs last week metrics (signups, first generations, payments)\n- Week-over-week growth percentages\n- Cumulative totals (total users, total generations, paying customers)\n- Estimated MRR\n\nRequires admin access.","operationId":"get_weekly_report_analytics_weekly_report_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyReport"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/designer-pro/upload/drone":{"post":{"tags":["designer-pro"],"summary":"Upload Drone Photo","description":"Upload a drone photo for Designer Pro.\n\nSupports high-resolution aerial imagery up to 50MB.\nValidates image dimensions (min 1000x1000, max 10000x10000).\n\nArgs:\n    file: Drone photo file (JPEG, PNG, TIFF, or WebP)\n    current_user: Authenticated user\n    storage: Blob storage service\n\nReturns:\n    DroneUploadResponse with URL and image metadata\n\nRaises:\n    400: Invalid file type, size, or dimensions\n    401: User not authenticated","operationId":"upload_drone_photo_v1_designer_pro_upload_drone_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_drone_photo_v1_designer_pro_upload_drone_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DroneUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/designer-pro/export/dxf":{"post":{"tags":["designer-pro"],"summary":"Export Dxf","description":"Export a Pro Mode design as DXF file.\n\nGenerates a DXF 2018 (AC1032) file with layers:\n- YARDA-BOUNDARY: Property boundary polyline\n- YARDA-HARDSCAPE: Patios, decks, walkways\n- YARDA-SOFTSCAPE: Lawn, planting beds\n- YARDA-WATER: Pools, fountains\n- YARDA-STRUCTURES: Pergolas, gazebos\n- YARDA-FIRE: Fire pits, fireplaces\n- YARDA-DIMENSIONS: Measurement annotations\n- YARDA-LABELS: Feature labels\n\nScale: 1 unit = 1 foot\n\nArgs:\n    request: DXF export request with generation_id and options\n    current_user: Authenticated user\n    dxf_service: DXF export service\n\nReturns:\n    DXF file as downloadable attachment\n\nRaises:\n    404: Generation not found\n    401: User not authenticated or not owner","operationId":"export_dxf_v1_designer_pro_export_dxf_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DXFExportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/designer-pro/export/materials/{generation_id}":{"get":{"tags":["designer-pro"],"summary":"Export Materials Csv","description":"Export material schedule as CSV file.\n\nGenerates a CSV with columns:\n- Item Name\n- Category\n- Quantity\n- Unit\n- Unit Price\n- Material Cost\n- Labor Rate\n- Labor Cost\n- Total\n- Notes\n\nIncludes summary row at bottom with totals.\nUses UTF-8 BOM encoding for Excel compatibility.\n\nArgs:\n    generation_id: ID of the Pro Mode generation\n    current_user: Authenticated user\n\nReturns:\n    CSV file as downloadable attachment\n\nRaises:\n    404: Generation not found\n    401: User not authenticated or not owner","operationId":"export_materials_csv_v1_designer_pro_export_materials__generation_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/freemium/activate":{"post":{"tags":["freemium"],"summary":"Activate Freemium Trial","description":"Activate freemium trial for the current user.\n\nInstantly activates freemium trial (no Stripe checkout required).\nUser must not have already used freemium or have an active subscription.\n\nReturns:\n    FreemiumActivateResponse with success status","operationId":"activate_freemium_trial_freemium_activate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreemiumActivateResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/freemium/status":{"get":{"tags":["freemium"],"summary":"Get Freemium Status","description":"Get freemium status for the current user.\n\nYAR-210: Returns full status including session tracking:\n- Session designs remaining (0-3)\n- Locked address (if session started)\n- Base design ID (if session started)\n- Whether session is exhausted\n\nAlso returns:\n- Whether user can activate freemium\n- Whether user is on freemium trial\n- Allowed/locked styles and features\n- Options per style limit\n\nReturns:\n    FreemiumStatusResponse with full status","operationId":"get_freemium_status_freemium_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreemiumStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/chat/sessions":{"post":{"tags":["chat"],"summary":"Create a new chat session","description":"Create a new chat session.\n\n- Anonymous users: Provide a client-generated session_token\n- Authenticated users: User ID is automatically captured\n\nReturns the created session with its ID.","operationId":"create_session_chat_sessions_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSessionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSession"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}":{"get":{"tags":["chat"],"summary":"Get a chat session with messages","description":"Get a chat session with its full message history.\n\nSecurity:\n- Authenticated users can only access their own sessions\n- Anonymous users must provide matching X-Session-Token header","operationId":"get_session_chat_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"x-session-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Session-Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSession"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["chat"],"summary":"End a chat session","description":"End a chat session.\n\nSets the session status to 'ended' and records the end time.","operationId":"end_session_chat_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"x-session-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Session-Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/get-or-create":{"post":{"tags":["chat"],"summary":"Get existing session or create new one","description":"Get an existing session by token, or create a new one if not found.\n\nUseful for:\n- Restoring chat state after page refresh\n- Migrating anonymous sessions to logged-in users","operationId":"get_or_create_session_chat_sessions_get_or_create_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSessionCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSession"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/messages":{"post":{"tags":["chat"],"summary":"Send a message and receive AI response (SSE stream)","description":"Send a message and receive streaming AI response.\n\nReturns Server-Sent Events (SSE) with the following event types:\n- `start`: AI response is starting\n- `chunk`: Partial response text (stream these to show real-time typing)\n- `sources`: Knowledge base sources used in response\n- `done`: Complete response with message_id\n- `error`: Error occurred\n\nExample SSE events:\n```\ndata: {\"type\": \"start\"}\n\ndata: {\"type\": \"chunk\", \"content\": \"Hello! \"}\n\ndata: {\"type\": \"chunk\", \"content\": \"I can help you with that.\"}\n\ndata: {\"type\": \"sources\", \"sources\": [{\"title\": \"Getting Started\", \"url\": \"...\"}]}\n\ndata: {\"type\": \"done\", \"content\": \"Hello! I can help you with that.\", \"message_id\": \"...\"}\n```","operationId":"send_message_chat_sessions__session_id__messages_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"x-session-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Session-Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessageCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/support/tickets":{"post":{"tags":["support"],"summary":"Create a support ticket","description":"Create a new support ticket.\n\nIf chat_session_id is provided, the ticket will be linked to the chat\nand an AI-generated summary will be created.\n\n**Requires authentication.**","operationId":"create_ticket_support_tickets_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicketCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicket"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["support"],"summary":"Get user's support tickets","description":"Get current user's support tickets.\n\nQuery parameters:\n- status: Filter by ticket status (open, pending, resolved, closed)\n- limit: Max results (default: 20)\n- offset: Pagination offset\n\n**Requires authentication.**","operationId":"get_tickets_support_tickets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TicketStatus"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SupportTicketSummary"},"title":"Response Get Tickets Support Tickets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/support/tickets/{ticket_id}":{"get":{"tags":["support"],"summary":"Get a support ticket","description":"Get a support ticket with its full message history.\n\nAlso includes linked chat conversation if available.\n\n**Requires authentication.** Users can only view their own tickets.","operationId":"get_ticket_support_tickets__ticket_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicket"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/support/tickets/{ticket_id}/messages":{"post":{"tags":["support"],"summary":"Add a message to a ticket","description":"Add a message to a support ticket.\n\nUsers can only add messages to their own tickets.\nInternal notes are not allowed for regular users.\n\n**Requires authentication.**","operationId":"add_ticket_message_support_tickets__ticket_id__messages_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ticket_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Ticket Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessageCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pro-mode/sessions/{session_id}/configuration":{"put":{"tags":["design-engine"],"summary":"Set Configuration","description":"Set the design configuration for a session.\n\nSaves the user's style selections, feature selections, custom instructions,\nand precision settings (for Studio mode).\n\n**Authentication:** Required\n\n**Path Parameters:**\n- session_id: UUID of the session\n\n**Request Body:**\n- mode: Design mode (quick/studio)\n- style_selections: List of selected style IDs\n- feature_selections: List of selected feature IDs\n- custom_instructions: Optional custom instructions\n- precision_settings: Optional precision settings (Studio mode)\n\n**Response:**\n- session_id: Session UUID\n- configuration: Saved configuration\n- ready_to_generate: Whether configuration is valid for generation\n\n**Example:**\n```bash\ncurl -X PUT https://api.yarda.app/pro-mode/sessions/{id}/configuration \\\n  -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"mode\": \"quick\", \"style_selections\": [\"mediterranean\"], \"feature_selections\": [\"patio\", \"lawn_area\"]}'\n```","operationId":"set_configuration_pro_mode_sessions__session_id__configuration_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignConfigurationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignConfigurationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pro-mode/styles":{"get":{"tags":["design-engine"],"summary":"Get Styles","description":"Get available design styles.\n\nReturns all available landscape design styles with their descriptions,\nthumbnails, and recommended climate zones. If zone and state are provided,\nstyles are sorted by climate appropriateness with recommended styles first.\n\n**Authentication:** Not required\n\n**Query Parameters:**\n- zone (optional): USDA Plant Hardiness Zone (e.g., '9a', '7b')\n- state (optional): Two-letter US state code (e.g., 'az', 'ca')\n\n**Response:**\n- List of style options, sorted by recommendation if zone/state provided\n\n**Example:**\n```bash\ncurl https://api.yarda.app/pro-mode/styles\ncurl https://api.yarda.app/pro-mode/styles?zone=9a&state=az\n```","operationId":"get_styles_pro_mode_styles_get","parameters":[{"name":"zone","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zone"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StyleOption"},"title":"Response Get Styles Pro Mode Styles Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pro-mode/features":{"get":{"tags":["design-engine"],"summary":"Get Features","description":"Get available features.\n\nReturns all available landscape features, optionally filtered by category.\n\n**Authentication:** Not required\n\n**Query Parameters:**\n- category (optional): Filter by category (hardscape, softscape, water, fire, structure)\n\n**Response:**\n- List of feature options\n\n**Example:**\n```bash\ncurl https://api.yarda.app/pro-mode/features\ncurl https://api.yarda.app/pro-mode/features?category=water\n```","operationId":"get_features_pro_mode_features_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FeatureOption"},"title":"Response Get Features Pro Mode Features Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/referral/code":{"get":{"tags":["referral"],"summary":"Get Referral Code","description":"Get the current user's referral code.\n\nReturns the user's unique referral code and shareable URL.\n\nReturns:\n    ReferralCodeResponse with code and URL","operationId":"get_referral_code_referral_code_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralCodeResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/referral/stats":{"get":{"tags":["referral"],"summary":"Get Referral Stats","description":"Get referral statistics for dashboard.\n\nReturns the user's referral code, success counts, credits earned,\nannual limits, and recent referral activity.\n\nReturns:\n    ReferralStatsResponse with full statistics","operationId":"get_referral_stats_referral_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralStatsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/referral/validate/{code}":{"get":{"tags":["referral"],"summary":"Validate Referral Code","description":"Validate a referral code without applying it.\n\nThis endpoint can be called with or without authentication.\nIf authenticated, self-referral will be checked.\n\nArgs:\n    code: The referral code to validate\n\nReturns:\n    ValidateReferralResponse with validation status","operationId":"validate_referral_code_referral_validate__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/referral/apply":{"post":{"tags":["referral"],"summary":"Apply Referral Code","description":"Apply a referral code to the current user.\n\nLinks the user to the referrer. The referrer will earn 50 generation credits\nwhen this user subscribes to Pro ($99/month).\n\nCan only be done once per user. Once a referrer is set, it cannot be changed.\n\nArgs:\n    request: Contains the referral code to apply\n\nReturns:\n    ApplyReferralResponse with result","operationId":"apply_referral_code_referral_apply_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplyReferralRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplyReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/referral/utm-attribution":{"post":{"tags":["referral"],"summary":"Record Utm Attribution","description":"Record UTM-based referral attribution for the current user.\n\nCalled during signup when utm_source is pro-referral or homeowner-referral.\nIdempotent: subsequent calls for the same user are silently ignored.\n\nArgs:\n    request: UTM source and ref param\n\nReturns:\n    UTMAttributionResponse with result","operationId":"record_utm_attribution_referral_utm_attribution_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UTMAttributionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UTMAttributionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/boundary-corrections":{"post":{"tags":["Boundary Corrections"],"summary":"Submit Correction","description":"Submit a boundary polygon correction. Fire-and-forget from frontend.\nTriggers background visual reasoning analysis via Gemini.","operationId":"submit_correction_v1_boundary_corrections_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoundaryCorrectionRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoundaryCorrectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/boundary-corrections/stats":{"get":{"tags":["Boundary Corrections"],"summary":"Get Stats","description":"Get aggregate boundary correction statistics.","operationId":"get_stats_v1_boundary_corrections_stats_get","parameters":[{"name":"lot_shape","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Shape"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/boundary-corrections/recent":{"get":{"tags":["Boundary Corrections"],"summary":"List Recent","description":"List recent boundary corrections for dashboard.","operationId":"list_recent_v1_boundary_corrections_recent_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"lot_shape","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Shape"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/boundary-corrections/reasoning-stats":{"get":{"tags":["Boundary Corrections"],"summary":"Get Reasoning Stats","description":"Get aggregate visual reasoning statistics for the dashboard.","operationId":"get_reasoning_stats_v1_boundary_corrections_reasoning_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/boundary-corrections/batch-analyze":{"post":{"tags":["Boundary Corrections"],"summary":"Batch Analyze","description":"Re-analyze corrections where analysis failed or was never triggered.\nUseful for backfilling or retrying failures.","operationId":"batch_analyze_v1_boundary_corrections_batch_analyze_post","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/boundary-learning/rules":{"get":{"tags":["Boundary Learning"],"summary":"Get Rules","description":"Get the current active learned rules for the dashboard.","operationId":"get_rules_v1_boundary_learning_rules_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/boundary-learning/refresh":{"post":{"tags":["Boundary Learning"],"summary":"Refresh Rules","description":"Force recomputation of learned rules from correction data.","operationId":"refresh_rules_v1_boundary_learning_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/boundary-learning/rules/history":{"get":{"tags":["Boundary Learning"],"summary":"Rules History","description":"List past rule compilations for audit trail.","operationId":"rules_history_v1_boundary_learning_rules_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/status":{"get":{"tags":["publishers"],"summary":"Get All Publisher Status","description":"Get configuration status for all publishers.","operationId":"get_all_publisher_status_marketing_publishers_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/publishers/status/{platform}":{"get":{"tags":["publishers"],"summary":"Get Publisher Status","description":"Get detailed status for a specific publisher, including token verification.","operationId":"get_publisher_status_marketing_publishers_status__platform__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/instagram/{item_id}":{"post":{"tags":["publishers"],"summary":"Publish To Instagram","description":"Publish pipeline content to Instagram via Graph API.\n\nCreates an image post on the connected Instagram Business account.\nInstagram requires a two-step process: create media container, then publish.\nImages should ideally be 1:1 (square) for best engagement.\n\nRequires INSTAGRAM_ACCESS_TOKEN and INSTAGRAM_BUSINESS_ACCOUNT_ID.","operationId":"publish_to_instagram_marketing_publishers_instagram__item_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/facebook/{item_id}":{"post":{"tags":["publishers"],"summary":"Publish To Facebook","description":"Publish pipeline content to a Facebook Page.\n\nUses the Facebook Pages API (same Meta Graph API as Instagram).\nSupports image posts (photo + caption), text-only posts, and link posts.\n\nRequires FACEBOOK_PAGE_ACCESS_TOKEN and FACEBOOK_PAGE_ID.","operationId":"publish_to_facebook_marketing_publishers_facebook__item_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Facebook Page ID (uses default from env if not provided)","title":"Page Id"},"description":"Facebook Page ID (uses default from env if not provided)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/linkedin/{item_id}":{"post":{"tags":["publishers"],"summary":"Publish To Linkedin","description":"Publish pipeline content to LinkedIn Company Page.\n\nUses the LinkedIn Marketing API Posts endpoint.\nRequires LINKEDIN_ACCESS_TOKEN and LINKEDIN_ORGANIZATION_ID.","operationId":"publish_to_linkedin_marketing_publishers_linkedin__item_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/tiktok/refresh-token":{"post":{"tags":["publishers"],"summary":"Refresh Tiktok Token","description":"Manually refresh the TikTok access token using the stored refresh token.\n\nTikTok access tokens expire every ~6 hours. This endpoint forces a refresh\nand persists the new tokens in os.environ for the current process.\n\nReturns the new token expiry and whether the refresh succeeded.\nAuto-refresh also happens on 401 during normal API calls, but this endpoint\nis useful for proactive refreshes or debugging token issues.","operationId":"refresh_tiktok_token_marketing_publishers_tiktok_refresh_token_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/marketing/publishers/tiktok/{item_id}":{"post":{"tags":["publishers"],"summary":"Publish To Tiktok","description":"Publish pipeline content to TikTok via Inbox API (lands in creator drafts).\n\nRequires a video_url on the content item (TikTok only supports video).\nVideos are downloaded server-side and uploaded directly to TikTok via\nFILE_UPLOAD to avoid domain-ownership verification issues.\n\nRequires TIKTOK_ACCESS_TOKEN (+ refresh token env vars for auto-refresh).","operationId":"publish_to_tiktok_marketing_publishers_tiktok__item_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/youtube/{item_id}":{"post":{"tags":["publishers"],"summary":"Publish To Youtube Via Publishers","description":"Publish pipeline content to YouTube as a Short or regular video.\n\nRequires a video_url on the content item (YouTube requires video).\nVideos are downloaded server-side and uploaded via YouTube Data API v3\nresumable upload.\n\nFor Shorts: video must be vertical (9:16) and <= 60 seconds.\n#Shorts is automatically included in the description if not already present.\n\nRequires YOUTUBE_CLIENT_ID, YOUTUBE_CLIENT_SECRET, YOUTUBE_REFRESH_TOKEN.","operationId":"publish_to_youtube_via_publishers_marketing_publishers_youtube__item_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/nextdoor/{item_id}":{"post":{"tags":["publishers"],"summary":"Publish To Nextdoor","description":"Publish pipeline content to Nextdoor via the Publish API.\n\nCreates a post on the connected Nextdoor Business account.\nRequires NEXTDOOR_ACCESS_TOKEN and NEXTDOOR_PROFILE_ID.","operationId":"publish_to_nextdoor_marketing_publishers_nextdoor__item_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/publishers/nextdoor/{item_id}/format":{"post":{"tags":["publishers"],"summary":"Format For Nextdoor","description":"Format pipeline content for manual Nextdoor posting (copy-paste ready).\n\nUse this when Nextdoor API credentials are not configured.\nReturns pre-formatted text optimized for Nextdoor's neighborhood audience.","operationId":"format_for_nextdoor_marketing_publishers_nextdoor__item_id__format_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/influencers":{"get":{"tags":["outreach"],"summary":"List Influencers","operationId":"list_influencers_outreach_influencers_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"}},{"name":"platform","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"}},{"name":"tier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InfluencerResponse"},"title":"Response List Influencers Outreach Influencers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["outreach"],"summary":"Create Influencer","operationId":"create_influencer_outreach_influencers_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InfluencerCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InfluencerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/influencers/{influencer_id}":{"get":{"tags":["outreach"],"summary":"Get Influencer","operationId":"get_influencer_outreach_influencers__influencer_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"influencer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Influencer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InfluencerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["outreach"],"summary":"Update Influencer","operationId":"update_influencer_outreach_influencers__influencer_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"influencer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Influencer Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InfluencerUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InfluencerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["outreach"],"summary":"Delete Influencer","operationId":"delete_influencer_outreach_influencers__influencer_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"influencer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Influencer Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/influencers/{influencer_id}/actions":{"get":{"tags":["outreach"],"summary":"List Actions","operationId":"list_actions_outreach_influencers__influencer_id__actions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"influencer_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Influencer Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActionResponse"},"title":"Response List Actions Outreach Influencers  Influencer Id  Actions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/actions":{"post":{"tags":["outreach"],"summary":"Log Action","operationId":"log_action_outreach_actions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/outreach/campaigns":{"get":{"tags":["outreach"],"summary":"List Campaigns","operationId":"list_campaigns_outreach_campaigns_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CampaignResponse"},"title":"Response List Campaigns Outreach Campaigns Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["outreach"],"summary":"Create Campaign","operationId":"create_campaign_outreach_campaigns_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/campaigns/{campaign_id}":{"patch":{"tags":["outreach"],"summary":"Update Campaign","operationId":"update_campaign_outreach_campaigns__campaign_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/pipeline":{"get":{"tags":["outreach"],"summary":"Get Pipeline Summary","operationId":"get_pipeline_summary_outreach_pipeline_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PipelineStageSummary"},"type":"array","title":"Response Get Pipeline Summary Outreach Pipeline Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/outreach/sms/contacts":{"get":{"tags":["outreach"],"summary":"List Sms Contacts","operationId":"list_sms_contacts_outreach_sms_contacts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opted_out","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Opted Out"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SmsContactResponse"},"title":"Response List Sms Contacts Outreach Sms Contacts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/sms/opt-in":{"post":{"tags":["outreach"],"summary":"Sms Opt In","description":"Public endpoint — no auth required.\nCalled by the /sms-optin form to register consent.","operationId":"sms_opt_in_outreach_sms_opt_in_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsOptInRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsContactResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/outreach/sms/send":{"post":{"tags":["outreach"],"summary":"Send Sms","operationId":"send_sms_outreach_sms_send_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsSendRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Send Sms Outreach Sms Send Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/outreach/sms/send-bulk":{"post":{"tags":["outreach"],"summary":"Send Bulk Sms","description":"Send same message to multiple contacts. Skips opted-out or non-consenting.","operationId":"send_bulk_sms_outreach_sms_send_bulk_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsBulkSendRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Send Bulk Sms Outreach Sms Send Bulk Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/outreach/webhooks/twilio/status":{"post":{"tags":["outreach"],"summary":"Twilio Status Callback","description":"Twilio delivery status callback.","operationId":"twilio_status_callback_outreach_webhooks_twilio_status_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/outreach/webhooks/twilio/inbound":{"post":{"tags":["outreach"],"summary":"Twilio Inbound Sms","description":"Twilio inbound SMS webhook (STOP, HELP, replies).","operationId":"twilio_inbound_sms_outreach_webhooks_twilio_inbound_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/lead-discovery/discover/google-places":{"post":{"tags":["lead-discovery"],"summary":"Discover Google Places","description":"Trigger a Google Places discovery search.\n\nReturns immediately with status=processing. Discovery runs in the\nbackground so Railway's gateway timeout doesn't kill the work.","operationId":"discover_google_places_lead_discovery_discover_google_places_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoverRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/discover/yelp":{"post":{"tags":["lead-discovery"],"summary":"Discover Yelp","description":"Trigger a Yelp Fusion discovery search.\n\nReturns immediately with status=processing. Discovery runs in the\nbackground so Railway's gateway timeout doesn't kill the work.","operationId":"discover_yelp_lead_discovery_discover_yelp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoverRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/discover/market/{market_id}":{"post":{"tags":["lead-discovery"],"summary":"Discover Market","description":"Run discovery for all keywords in a target market.\n\nReturns immediately with status=processing. Discovery runs in the\nbackground so Railway's gateway timeout doesn't kill the work.","operationId":"discover_market_lead_discovery_discover_market__market_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"market_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Market Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/leads":{"get":{"tags":["lead-discovery"],"summary":"List Leads","description":"List discovered leads with filters.","operationId":"list_leads_lead_discovery_leads_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"}},{"name":"outreach_status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Outreach Status"}},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"has_phone","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Phone"}},{"name":"has_email","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Email"}},{"name":"min_rating","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Rating"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/src__models__lead_discovery__LeadResponse"},"title":"Response List Leads Lead Discovery Leads Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/leads/stats":{"get":{"tags":["lead-discovery"],"summary":"Get Lead Stats","description":"Get lead dashboard statistics.","operationId":"get_lead_stats_lead_discovery_leads_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/leads/{lead_id}":{"get":{"tags":["lead-discovery"],"summary":"Get Lead","description":"Get a single lead by ID.","operationId":"get_lead_lead_discovery_leads__lead_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__lead_discovery__LeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["lead-discovery"],"summary":"Update Lead","description":"Update a lead's type, channel, status, or notes.","operationId":"update_lead_lead_discovery_leads__lead_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__models__lead_discovery__LeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/leads/{lead_id}/enrich":{"post":{"tags":["lead-discovery"],"summary":"Enrich Lead","description":"Enrich a single lead by scraping its website for social handles.","operationId":"enrich_lead_lead_discovery_leads__lead_id__enrich_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/enrich/batch":{"post":{"tags":["lead-discovery"],"summary":"Enrich Batch","description":"Batch enrich leads that have websites but no social handles.","operationId":"enrich_batch_lead_discovery_enrich_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/enrich/all":{"post":{"tags":["lead-discovery"],"summary":"Enrich All","description":"Kick off background enrichment of ALL unenriched leads in batches of 50.","operationId":"enrich_all_lead_discovery_enrich_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/enrich/stats":{"get":{"tags":["lead-discovery"],"summary":"Get Enrichment Stats","description":"Get enrichment progress statistics.","operationId":"get_enrichment_stats_lead_discovery_enrich_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/leads/{lead_id}/sms":{"post":{"tags":["lead-discovery"],"summary":"Send Sms","description":"Send an SMS to a lead via Twilio.","operationId":"send_sms_lead_discovery_leads__lead_id__sms_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadSmsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/leads/{lead_id}/email":{"post":{"tags":["lead-discovery"],"summary":"Send Email","description":"Send an email to a lead via Resend.","operationId":"send_email_lead_discovery_leads__lead_id__email_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadEmailRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/leads/{lead_id}/dm":{"post":{"tags":["lead-discovery"],"summary":"Log Dm","description":"Log a DM action from browser automation.","operationId":"log_dm_lead_discovery_leads__lead_id__dm_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadDmLogRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/leads/{lead_id}/outreach-history":{"get":{"tags":["lead-discovery"],"summary":"Get Outreach History","description":"Get outreach action timeline for a lead.","operationId":"get_outreach_history_lead_discovery_leads__lead_id__outreach_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OutreachActionResponse"},"title":"Response Get Outreach History Lead Discovery Leads  Lead Id  Outreach History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/markets":{"get":{"tags":["lead-discovery"],"summary":"List Markets","description":"List target markets.","operationId":"list_markets_lead_discovery_markets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Active Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MarketResponse"},"title":"Response List Markets Lead Discovery Markets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["lead-discovery"],"summary":"Create Market","description":"Add a new target market.","operationId":"create_market_lead_discovery_markets_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/markets/{market_id}":{"patch":{"tags":["lead-discovery"],"summary":"Update Market","description":"Update a target market.","operationId":"update_market_lead_discovery_markets__market_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"market_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Market Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/refresh-all-markets":{"post":{"tags":["lead-discovery"],"summary":"Refresh All Markets","description":"Refresh all active markets that are older than max_age_days.\n\nReturns immediately with status=processing. Refresh runs in the\nbackground so Railway's gateway timeout doesn't kill the work.","operationId":"refresh_all_markets_lead_discovery_refresh_all_markets_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"max_age_days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":14,"title":"Max Age Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/batches":{"get":{"tags":["lead-discovery"],"summary":"List Batches","description":"List recent discovery batch runs.","operationId":"list_batches_lead_discovery_batches_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DiscoveryBatchResponse"},"title":"Response List Batches Lead Discovery Batches Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/templates/sms":{"get":{"tags":["lead-discovery"],"summary":"Get Sms Templates","description":"Get SMS outreach templates.","operationId":"get_sms_templates_lead_discovery_templates_sms_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OutreachTemplate"},"title":"Response Get Sms Templates Lead Discovery Templates Sms Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/templates/email":{"get":{"tags":["lead-discovery"],"summary":"Get Email Templates","description":"Get email outreach templates.","operationId":"get_email_templates_lead_discovery_templates_email_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OutreachTemplate"},"title":"Response Get Email Templates Lead Discovery Templates Email Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/dm-queue":{"get":{"tags":["lead-discovery"],"summary":"Get Dm Queue","description":"Get leads ready for Instagram DM outreach.","operationId":"get_dm_queue_lead_discovery_dm_queue_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"template_id","in":"query","required":false,"schema":{"type":"string","default":"intro_dm","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/dm-stats":{"get":{"tags":["lead-discovery"],"summary":"Get Dm Stats","description":"Get Instagram DM campaign statistics.","operationId":"get_dm_stats_lead_discovery_dm_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/templates/dm":{"get":{"tags":["lead-discovery"],"summary":"Get Dm Templates","description":"Get Instagram DM outreach templates.","operationId":"get_dm_templates_lead_discovery_templates_dm_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/dm-queue/{lead_id}/log-sent":{"post":{"tags":["lead-discovery"],"summary":"Log Dm Sent","description":"Log that a DM was manually sent to a lead via browser automation.","operationId":"log_dm_sent_lead_discovery_dm_queue__lead_id__log_sent_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}},{"name":"template_id","in":"query","required":false,"schema":{"type":"string","default":"intro_dm","title":"Template Id"}},{"name":"message","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/comment-queue":{"get":{"tags":["lead-discovery"],"summary":"Get Comment Queue","description":"Get leads ready for Instagram comment warm-up.","operationId":"get_comment_queue_lead_discovery_comment_queue_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"template_id","in":"query","required":false,"schema":{"type":"string","default":"great_work","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/comment-stats":{"get":{"tags":["lead-discovery"],"summary":"Get Comment Stats","description":"Get Instagram comment campaign statistics.","operationId":"get_comment_stats_lead_discovery_comment_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/templates/comment":{"get":{"tags":["lead-discovery"],"summary":"Get Comment Templates","description":"Get Instagram comment templates.","operationId":"get_comment_templates_lead_discovery_templates_comment_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/comment-queue/{lead_id}/log-sent":{"post":{"tags":["lead-discovery"],"summary":"Log Comment Sent","description":"Log that a comment was left on a lead's Instagram post.","operationId":"log_comment_sent_lead_discovery_comment_queue__lead_id__log_sent_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}},{"name":"template_id","in":"query","required":false,"schema":{"type":"string","default":"great_work","title":"Template Id"}},{"name":"message","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/canonical":{"get":{"tags":["lead-discovery"],"summary":"List Canonical Leads","description":"List canonical leads with filters.","operationId":"list_canonical_leads_lead_discovery_canonical_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"pipeline_stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pipeline Stage"}},{"name":"lead_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"}},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"min_score","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Score"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CanonicalLeadResponse"},"title":"Response List Canonical Leads Lead Discovery Canonical Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/canonical/stats":{"get":{"tags":["lead-discovery"],"summary":"Get Canonical Stats","description":"Get canonical lead counts by pipeline stage.","operationId":"get_canonical_stats_lead_discovery_canonical_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/canonical/{canonical_id}":{"get":{"tags":["lead-discovery"],"summary":"Get Canonical Lead","description":"Get a single canonical lead with source count.","operationId":"get_canonical_lead_lead_discovery_canonical__canonical_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanonicalLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["lead-discovery"],"summary":"Update Canonical Lead","description":"Update a canonical lead's pipeline stage, type, channel, or DNC flag.","operationId":"update_canonical_lead_lead_discovery_canonical__canonical_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanonicalLeadUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanonicalLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/canonical/{canonical_id}/sources":{"get":{"tags":["lead-discovery"],"summary":"Get Canonical Sources","description":"Get all discovered leads linked to a canonical lead.","operationId":"get_canonical_sources_lead_discovery_canonical__canonical_id__sources_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/src__models__lead_discovery__LeadResponse"},"title":"Response Get Canonical Sources Lead Discovery Canonical  Canonical Id  Sources Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/dedup/batch":{"post":{"tags":["lead-discovery"],"summary":"Run Dedup Batch","description":"Process unlinked discovered leads and create/link canonical leads.","operationId":"run_dedup_batch_lead_discovery_dedup_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DedupBatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/dedup/merge":{"post":{"tags":["lead-discovery"],"summary":"Merge Canonical Leads","description":"Merge two canonical leads (absorb into keep).","operationId":"merge_canonical_leads_lead_discovery_dedup_merge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeCanonicalRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/canonical/{canonical_id}/notes":{"post":{"tags":["lead-discovery"],"summary":"Add Note","description":"Add a note to a canonical lead.","operationId":"add_note_lead_discovery_canonical__canonical_id__notes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadNoteCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadNoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["lead-discovery"],"summary":"List Notes","description":"List notes for a canonical lead.","operationId":"list_notes_lead_discovery_canonical__canonical_id__notes_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LeadNoteResponse"},"title":"Response List Notes Lead Discovery Canonical  Canonical Id  Notes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/canonical/{canonical_id}/audit":{"get":{"tags":["lead-discovery"],"summary":"Get Audit Log","description":"Get audit trail for a canonical lead.","operationId":"get_audit_log_lead_discovery_canonical__canonical_id__audit_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditLogResponse"},"title":"Response Get Audit Log Lead Discovery Canonical  Canonical Id  Audit Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/canonical/{canonical_id}/preferences":{"get":{"tags":["lead-discovery"],"summary":"Get Contact Preferences","description":"Get contact preferences for a canonical lead.","operationId":"get_contact_preferences_lead_discovery_canonical__canonical_id__preferences_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["lead-discovery"],"summary":"Update Contact Preferences","description":"Update contact preferences for a canonical lead.","operationId":"update_contact_preferences_lead_discovery_canonical__canonical_id__preferences_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"canonical_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Canonical Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPreferencesUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/outreach/{action_id}/response":{"post":{"tags":["lead-discovery"],"summary":"Log Outreach Response","description":"Log a response to an outreach action and update lead status.","operationId":"log_outreach_response_lead_discovery_outreach__action_id__response_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"action_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Action Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutreachResponseLog"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/outreach/batch":{"post":{"tags":["lead-discovery"],"summary":"Run Batch Outreach","description":"Send outreach to a batch of enriched, uncontacted leads. Runs in background.","operationId":"run_batch_outreach_lead_discovery_outreach_batch_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"channel","in":"query","required":false,"schema":{"type":"string","pattern":"^(email|sms)$","default":"email","title":"Channel"}},{"name":"template_id","in":"query","required":false,"schema":{"type":"string","default":"cold_intro","title":"Template Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"min_score","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Min Score"}},{"name":"lead_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lead-discovery/backfill-scores":{"post":{"tags":["lead-discovery"],"summary":"Backfill Lead Scores","description":"Backfill qualification_score for enriched leads that were scored before scoring was wired.","operationId":"backfill_lead_scores_lead_discovery_backfill_scores_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/leads/bulk-action":{"post":{"tags":["lead-discovery"],"summary":"Bulk Lead Action","description":"Perform bulk actions on multiple leads.","operationId":"bulk_lead_action_lead_discovery_leads_bulk_action_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkLeadAction"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/seed-na-markets":{"post":{"tags":["lead-discovery"],"summary":"Seed Na Markets","description":"Bulk-insert North America metros into target_markets (idempotent).","operationId":"seed_na_markets_lead_discovery_seed_na_markets_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/run-na-campaign":{"post":{"tags":["lead-discovery"],"summary":"Run Na Campaign","description":"Trigger the daily NA Yelp lead discovery campaign.\n\nReturns immediately; campaign runs in background.","operationId":"run_na_campaign_lead_discovery_run_na_campaign_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/lead-discovery/campaign-status":{"get":{"tags":["lead-discovery"],"summary":"Get Campaign Status","description":"Get current campaign run status, tier breakdown, and overall progress.","operationId":"get_campaign_status_lead_discovery_campaign_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/agent/chat":{"post":{"tags":["agent"],"summary":"Send a message to the AI landscape design agent (SSE stream)","description":"Send a message to the AI landscape design agent and receive a streaming\nSSE response.\n\n## Authentication\nRequires a valid Bearer token in the Authorization header.\n\n## Request Body\n- **session_id** (optional): Existing session ID for multi-turn conversation.\n  If omitted, a new session is created and its ID is returned in the first event.\n- **message** (required): The user's chat message (1-4000 chars).\n- **attachments** (optional): Photo attachments with base64-encoded data.\n  Each attachment has: type (site_photo|inspiration_photo), base64, caption, fileName.\n\n## SSE Event Types\n\n```\ndata: {\"type\": \"session\", \"session_id\": \"uuid\", \"is_new\": true}\n\ndata: {\"type\": \"action\", \"action\": \"photo_received\", \"data\": {\"count\": 2, \"type\": \"inspiration\"}}\n\ndata: {\"type\": \"action\", \"action\": \"analyzing_photos\", \"data\": {\"count\": 2}}\n\ndata: {\"type\": \"chunk\", \"content\": \"I'd be happy to...\"}\n\ndata: {\"type\": \"action\", \"action\": \"geocoding\", \"data\": {\"address\": \"...\"}}\n\ndata: {\"type\": \"media\", \"media_type\": \"satellite\", \"url\": \"...\", \"label\": \"Satellite View\"}\n\ndata: {\"type\": \"progress\", \"step\": \"generating_plan\", \"progress\": 25, \"message\": \"...\"}\n\ndata: {\"type\": \"error\", \"error\": \"Something went wrong.\"}\n\ndata: {\"type\": \"done\"}\n```\n\n## Conversation Flow\n1. First call creates a session -- capture the `session_id` from the `session` event\n2. Subsequent calls include `session_id` to continue the conversation\n3. Agent extracts design intent and builds context across messages\n4. Photos are classified as site photos or inspiration photos and analyzed\n5. When ready, agent emits `action: start_generation` with full design context\n\nReturns:\n    StreamingResponse with SSE events (text/event-stream).","operationId":"agent_chat_v1_agent_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/agent/chat/upload":{"post":{"tags":["agent"],"summary":"Send a message with photo uploads to the agent (multipart, SSE stream)","description":"Send a message with photo file uploads to the agent.\n\nThis endpoint accepts multipart/form-data for direct file uploads\n(as opposed to the JSON endpoint which accepts base64-encoded data).\n\n## Form Fields\n- **message** (required): The user's chat message.\n- **session_id** (optional): Existing session ID.\n- **photo_types** (optional): Comma-separated list of types for each file\n  (site_photo or inspiration_photo).\n- **photo_captions** (optional): Comma-separated captions for each file.\n- **files** (optional): Up to 5 photo files (JPEG, PNG, WebP, max 10MB each).\n\nReturns:\n    StreamingResponse with SSE events (text/event-stream).","operationId":"agent_chat_upload_v1_agent_chat_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_agent_chat_upload_v1_agent_chat_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/agent/sessions":{"get":{"tags":["agent"],"summary":"List user's agent sessions","description":"List the current user's agent conversation sessions.\n\nReturns sessions ordered by most recently updated first.\nEach session includes address, status, message count, and timestamps.\n\nQuery parameters:\n- **limit**: Max sessions to return (1-100, default 20)\n- **offset**: Pagination offset (default 0)\n- **include_completed**: Include completed/abandoned sessions (default true)","operationId":"list_sessions_v1_agent_sessions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"include_completed","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Completed"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/sessions/{session_id}":{"get":{"tags":["agent"],"summary":"Get a session with its messages","description":"Get a specific session including all its messages.\n\nUsed to restore a previous conversation on page load or when\nselecting a session from the session list.\n\nReturns 404 if the session doesn't exist or belongs to another user.","operationId":"get_session_v1_agent_sessions__session_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["agent"],"summary":"Mark a session as completed","description":"Mark a session as completed (soft delete).\n\nThe session data is retained but the status changes to 'completed'.\nThis prevents it from being auto-recovered on page refresh.","operationId":"delete_session_v1_agent_sessions__session_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/a2a/v1/message:send":{"post":{"tags":["a2a"],"summary":"Send Message","operationId":"send_message_a2a_v1_message_send_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/A2ASendRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/a2a/v1/message:stream":{"post":{"tags":["a2a"],"summary":"Stream Message","operationId":"stream_message_a2a_v1_message_stream_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/A2ASendRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/a2a/v1/tasks/{task_id}":{"get":{"tags":["a2a"],"summary":"Get Task","operationId":"get_task_a2a_v1_tasks__task_id__get","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/a2a/v1/tasks/{task_id}:subscribe":{"post":{"tags":["a2a"],"summary":"Subscribe Task","operationId":"subscribe_task_a2a_v1_tasks__task_id__subscribe_post","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/A2ASubscribeRequest"},{"type":"null"}],"title":"Subscribe Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/keys/service-account":{"post":{"tags":["agent"],"summary":"Create an API key using pre-shared secret (service accounts)","description":"Create an API key for service account authentication using a pre-shared secret.\n\n    This endpoint validates the provided secret against the SERVICE_ACCOUNT_SECRET\n    environment variable. If valid, it returns an API key for the pre-configured\n    service account.\n\n    Use this endpoint when you have a pre-shared secret configured in Railway\n    and need programmatic API access without OAuth.","operationId":"create_service_account_api_key_api_agent_keys_service_account_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceAccountKeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAgentKeyResponse"}}}},"401":{"description":"Invalid pre-shared secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/property-info":{"post":{"tags":["agent"],"summary":"Get property information for AI agents","description":"Returns all property information needed by AI agents in a single call:\n    - Parsed address components (street, city, state, ZIP)\n    - Satellite image URL (uploaded to blob storage)\n    - Boundary polygon coordinates [[lat, lng], ...]\n    - Lot dimensions (width, depth, area in sq ft)\n    - Imagery date (when the satellite image was captured)\n\n    This endpoint is designed for AI agents that need to understand property\n    boundaries and dimensions for landscape design tasks.","operationId":"get_property_info_api_agent_property_info_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyInfoRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyInfoResponse"}}}},"400":{"description":"Invalid address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"404":{"description":"Property not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-openai-is-consequential":false}},"/api/agent/designs":{"post":{"tags":["agent"],"summary":"Create a landscape design generation","description":"Create a new landscape design generation for an AI agent.\n\n    This endpoint accepts a design request and processes it asynchronously.\n    Returns immediately with 202 Accepted and design_id. Poll GET /api/agent/designs/{id}\n    to check the status until status is 'completed' or 'failed'.\n\n    Required fields:\n    - address: Full property address\n    - style: Design style (e.g., modern_minimalist, california_native)\n    - yard_area: Area to design (front, back, side, full)\n\n    Optional fields:\n    - preferences: Object with features and budget_tier\n\n    Processing steps (run asynchronously):\n    1. Geocode address to get coordinates\n    2. Fetch satellite imagery\n    3. Detect property boundary polygon\n    4. Generate AI design renders\n    5. Estimate materials and costs","operationId":"create_design_api_agent_designs_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDesignRequest"}}}},"responses":{"202":{"description":"Design creation accepted - processing asynchronously","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDesignResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/designs/batch":{"post":{"tags":["agent"],"summary":"Create multiple landscape design generations in batch","description":"Create multiple landscape design generations for AI agents in a single call.\n\n    This endpoint accepts up to 20 design requests and processes them asynchronously.\n    Returns immediately with 202 Accepted and a list of design_ids with 'processing' status.\n    Poll GET /api/agent/designs/{id} for each design to check status until completed.\n\n    Each item requires:\n    - address: Full property address\n    - style: Design style (e.g., modern_minimalist, california_native)\n    - yard_area: Area to design (front, back, side, full)","operationId":"create_design_batch_api_agent_designs_batch_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDesignRequest"}}}},"responses":{"202":{"description":"Batch design creation accepted - processing asynchronously","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDesignResponse"}}}},"400":{"description":"Invalid request - max 20 items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/pricing":{"get":{"tags":["agent"],"summary":"Get agent API pricing tiers","description":"Get pricing tiers for agent API access.\n\n    Returns:\n    - Free tier: 5 designs/month\n    - Pro monthly: unlimited designs for $29/month\n    - Pro yearly: unlimited designs for $240/year\n\n    Also returns current usage for the authenticated API key.","operationId":"get_agent_pricing_api_agent_pricing_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentUsagePricingResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/checkout":{"post":{"tags":["agent"],"summary":"Create Stripe checkout session for agent subscription","description":"Create a Stripe checkout session to upgrade the agent API key to Pro tier.\n\n    Supported tiers:\n    - pro_monthly: $29/month\n    - pro_yearly: $240/year (2 months free)\n\n    Returns a Stripe checkout URL to redirect the user to for payment.","operationId":"create_checkout_session_api_agent_checkout_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSessionRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSessionResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"400":{"description":"Invalid tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/portal":{"post":{"tags":["agent"],"summary":"Get Stripe customer portal URL for subscription management","description":"Get a Stripe Customer Portal URL to manage the agent Pro subscription.\n\n    Allows users to:\n    - View subscription details and billing history\n    - Cancel or pause subscription\n    - Update payment method\n    - Change billing address\n\n    Requires an active Pro subscription.","operationId":"get_agent_customer_portal_api_agent_portal_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"400":{"description":"No subscription found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/designs/{design_id}":{"get":{"tags":["agent"],"summary":"Get design status and results","description":"Get the current status and results of a landscape design generation.\n\n    Returns the design with its current status:\n    - pending: Design request received, not yet processed\n    - processing: Generation in progress\n    - completed: Generation complete, results available\n    - failed: Generation failed","operationId":"get_design_api_agent_designs__design_id__get","parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDesignResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"404":{"description":"Design not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/quick-design":{"post":{"tags":["agent"],"summary":"Quick street-view front yard redesign — no boundary detection needed","description":"Fast front yard redesign from street view — designed for agent/GPT flows.\n\nTakes an address, fetches the street view, generates a redesigned front yard\nin one Gemini call (~15 seconds). No boundary detection, no 2D plan.\n\nReturns before/after URLs and a promo CTA to drive traffic to yarda.pro.","operationId":"agent_quick_design_api_agent_quick_design_post","parameters":[{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickDesignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/designs/{design_id}/estimate-materials":{"post":{"tags":["agent"],"summary":"Estimate Design Materials","description":"Estimate materials and costs for a landscape design.\n\nThis endpoint analyzes the design's render image to estimate\nmaterials, quantities, and total cost. Call this after getting\na completed design to show the user a cost breakdown.","operationId":"estimate_design_materials_api_agent_designs__design_id__estimate_materials_post","parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Material estimate for the design","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MaterialsEstimateResponse"}}}},"401":{"description":"Invalid or missing API key"},"404":{"description":"Design not found or no renders available"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/proposals":{"post":{"tags":["agent-v1"],"summary":"Create a proposal from an agent design","description":"Create a shareable landscape proposal from a completed agent design.\n\n    Requires a completed design_id from POST /v1/agent/designs.\n    The contractor_info is used to identify the contractor on the proposal.\n    On first call, a lightweight contractor profile is auto-created.\n    On subsequent calls with the same API key, the existing profile is reused.\n\n    Returns a shareable proposal URL (yarda.pro/p/{id}) that can be sent\n    to clients via any channel (SMS, email, chat).","operationId":"create_proposal_v1_agent_proposals_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProposalRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProposalResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"404":{"description":"Design not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-openai-is-consequential":true}},"/v1/agent/proposals/{proposal_id}/public":{"get":{"tags":["agent-v1"],"summary":"Get public proposal data","description":"Get proposal data for the public proposal page (/p/{id}).\n\n    No authentication required. Rate limited to 60 requests per minute per IP.\n\n    Returns contractor info, design images, material estimates, and\n    property address. Used by the frontend to render the shareable\n    proposal page with OpenGraph meta tags for social previews.","operationId":"get_public_proposal_v1_agent_proposals__proposal_id__public_get","parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Proposal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProposalResponse"}}}},"404":{"description":"Proposal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/designs/{design_id}/boundary":{"get":{"tags":["agent-v1"],"summary":"Get design boundary data for adjustment","description":"Get satellite image and boundary polygon for the /adjust page.\n\n    No authentication required. Rate limited to 60 requests per minute per IP.\n    Returns only boundary-related data — no renders, materials, or cost data.","operationId":"get_design_boundary_v1_agent_designs__design_id__boundary_get","parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoundaryResponse"}}}},"404":{"description":"Design not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/designs/{design_id}/preview":{"get":{"tags":["agent-v1"],"summary":"Get public design preview","description":"Public, no-auth endpoint for the /d/[designId] preview page.\n\n    Returns design status, satellite image, and watermarked render URL.\n    No materials, costs, or boundary data exposed.\n    Rate limited to 60 requests per minute per IP.","operationId":"get_design_preview_v1_agent_designs__design_id__preview_get","parameters":[{"name":"design_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Design Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignPreviewResponse"}}}},"404":{"description":"Design not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__agent_proposals_api__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys":{"get":{"tags":["api-keys"],"summary":"List API keys","description":"List all API keys for the authenticated user.\n\n    Returns key metadata only - not the actual keys (they are hashed).","operationId":"list_api_keys_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/APIKeyResponse"},"type":"array","title":"Response List Api Keys Api Keys Get"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__api_keys__ErrorResponse"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["api-keys"],"summary":"Create a new API key","description":"Create a new API key for programmatic access to Yarda's agent API.\n\n    The API key is returned only once in the response. Store it securely -\n    it cannot be retrieved later.\n\n    The key follows the format: `yarda_ak_` + 32 random hex characters","operationId":"create_api_key_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__api_keys__ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__api_keys__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke an API key","description":"Revoke an API key. This action is irreversible - the key will\n    no longer be valid for API requests.","operationId":"revoke_api_key_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__api_keys__ErrorResponse"}}}},"403":{"description":"Not authorized to revoke this key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__api_keys__ErrorResponse"}}}},"404":{"description":"API key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__endpoints__api_keys__ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/api-keys":{"get":{"tags":["agent-api-keys"],"summary":"List API keys","description":"List all API keys for the authenticated user.\n\nReturns metadata only, not the actual keys.","operationId":"list_agent_api_keys_api_agent_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/APIKeyResponse"},"type":"array","title":"Response List Agent Api Keys Api Agent Api Keys Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["agent-api-keys"],"summary":"Create a new API key","description":"Create a new API key for the authenticated user.\n\nReturns the full key only once - it cannot be retrieved later.","operationId":"create_agent_api_key_api_agent_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/agent/api-keys/{key_id}":{"delete":{"tags":["agent-api-keys"],"summary":"Revoke an API key","description":"Revoke an API key.\n\nSets revoked_at timestamp, making the key invalid immediately.","operationId":"revoke_agent_api_key_api_agent_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/v1/generations":{"post":{"summary":"Create Internal Generation","description":"Create a landscape generation for an external AI agent.\n\nThis endpoint is designed for MCP server use by external AI agents.\nIt accepts an internal API key for authentication and creates a generation\non behalf of the API key's associated system user.\n\nThe generation is created using the same pipeline as regular Pro Mode generations.\n\nArgs:\n    request: AgentDesignRequest with address, style, yard_area, preferences\n    background_tasks: FastAPI background tasks\n    x_internal_api_key: Internal API key for authentication\n\nReturns:\n    AgentDesignResponse with design_id, status, and initial data","operationId":"create_internal_generation_internal_v1_generations_post","parameters":[{"name":"X-Internal-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Internal-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDesignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent-pricing":{"get":{"summary":"Get Agent Pricing Info","description":"Get Yarda pricing information for AI agents.\n\nReturns simplified pricing structure for MCP server use.\n\nArgs:\n    x_api_key: Optional API key for authentication\n\nReturns:\n    AgentPricingResponse with pricing plans and rate limits","operationId":"get_agent_pricing_info_api_v1_agent_pricing_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPricingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pricing":{"get":{"summary":"Get Mcp Pricing","description":"Get Yarda pricing information in MCP-compatible format.\n\nReturns simplified pricing structure for the MCP server get_pricing tool.\nThis endpoint provides the free/pro plan format expected by MCP agents.\n\nArgs:\n    x_api_key: Optional API key for authentication\n\nReturns:\n    MCPPricingResponse with free and pro plan pricing","operationId":"get_mcp_pricing_api_v1_pricing_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPPricingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent/styles":{"get":{"summary":"Get Styles","description":"Get available landscape design styles for AI agents.\n\nArgs:\n    x_api_key: Optional API key for authentication\n\nReturns:\n    AgentStylesResponse with available styles","operationId":"get_styles_api_agent_styles_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentStylesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pricing":{"get":{"tags":["pricing"],"summary":"Get Pricing","description":"Get Yarda pricing information for free and pro plans.\n\nReturns pricing details including monthly/yearly prices, features,\nusage limits, and trial information.\n\nUsed by MCP get_pricing tool.","operationId":"get_pricing_v1_pricing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"}}}}}}},"/v1/analytics/generation-performance":{"get":{"tags":["generation-analytics"],"summary":"Get Generation Performance","description":"Average latency by call_type, model, and style.\n\nReturns p50, p95, and average latency for each combination.\nRequires admin access.","operationId":"get_generation_performance_v1_analytics_generation_performance_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"description":"Number of days to look back","default":7,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PerformanceSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/analytics/generation-volume":{"get":{"tags":["generation-analytics"],"summary":"Get Generation Volume","description":"Daily call counts by call_type.\n\nRequires admin access.","operationId":"get_generation_volume_v1_analytics_generation_volume_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"description":"Number of days to look back","default":7,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VolumeSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/analytics/error-rates":{"get":{"tags":["generation-analytics"],"summary":"Get Error Rates","description":"Error rate by call_type.\n\nRequires admin access.","operationId":"get_error_rates_v1_analytics_error_rates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"description":"Number of days to look back","default":7,"title":"Days"},"description":"Number of days to look back"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorRateSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/analytics/generation/{generation_id}/calls":{"get":{"tags":["generation-analytics"],"summary":"Get Generation Calls","description":"All AI pipeline calls for a specific generation.\n\nReturns calls ordered by sequence/timestamp.\nRequires admin access.","operationId":"get_generation_calls_v1_analytics_generation__generation_id__calls_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerationCallList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/csp-report":{"post":{"tags":["security"],"summary":"Receive Csp Report","description":"Receive CSP violation reports from browsers.\n\nBrowsers POST JSON with Content-Type: application/csp-report.\nWe log the violation details for monitoring.","operationId":"receive_csp_report_csp_report_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/analytics/roi":{"get":{"tags":["analytics"],"summary":"Get Roi Dashboard","description":"Aggregate ROI dashboard data from existing CRM tables.","operationId":"get_roi_dashboard_analytics_roi_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoiDashboardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/breaker-panel":{"get":{"tags":["breaker-panel"],"summary":"Get Panel","description":"Get breaker panel state.","operationId":"get_panel_api_breaker_panel_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PanelData"}}}}}},"put":{"tags":["breaker-panel"],"summary":"Save Panel","description":"Save breaker panel state.","operationId":"save_panel_api_breaker_panel_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PanelData"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health/deep":{"get":{"tags":["health"],"summary":"Health Deep","description":"Deep health check including webhook monitoring stats for the last 2 hours.\n\nNo auth required — intended for external monitoring tools (e.g. UptimeRobot, PagerDuty).\n\nReturns:\n- status: healthy / degraded / critical\n- webhook_failure_rate_pct: % of events that failed in the last 2h\n- webhook_gap_detected: True if zero events received in the last 2h\n- total_events_2h: total webhook events in the window","operationId":"health_deep_health_deep_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/services":{"get":{"tags":["health"],"summary":"Health Services","description":"Extended health check for all external services.\n\nNon-destructive: uses only free/metadata API calls.\nCost per call: ~$0.007 (geocoding $0.005, others free).","operationId":"health_services_health_services_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/skill-eval/results":{"get":{"tags":["skill-eval"],"summary":"List Eval Results","description":"List skill evaluation results with optional filtering.","operationId":"list_eval_results_admin_skill_eval_results_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"style","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"scored_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Scored Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/skill-eval/results/{generation_id}":{"get":{"tags":["skill-eval"],"summary":"Get Eval Result","description":"Get skill eval result for a specific generation — side-by-side comparison.","operationId":"get_eval_result_admin_skill_eval_results__generation_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"generation_id","in":"path","required":true,"schema":{"type":"string","title":"Generation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/skill-eval/results/{result_id}/score":{"patch":{"tags":["skill-eval"],"summary":"Score Eval Result","description":"Score a skill eval result (manual grading by CEO).","operationId":"score_eval_result_admin_skill_eval_results__result_id__score_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}},{"name":"realism","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Realism"}},{"name":"style_accuracy","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Style Accuracy"}},{"name":"composition","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Composition"}},{"name":"technical","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Technical"}},{"name":"property_respect","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Property Respect"}},{"name":"notes","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/skill-eval/summary":{"get":{"tags":["skill-eval"],"summary":"Eval Summary","description":"Summary stats: how skill prompts compare to production.","operationId":"eval_summary_admin_skill_eval_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/csat":{"post":{"tags":["csat"],"summary":"Submit Csat","description":"Submit a CSAT rating. Open to all users (authenticated or not).","operationId":"submit_csat_csat_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CSATSubmit"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CSATResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/csat/report":{"get":{"tags":["csat"],"summary":"Get Csat Report","description":"Get monthly CSAT averages. Admin only.","operationId":"get_csat_report_csat_report_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":6,"title":"Months"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CSATMonthlyReport"},"title":"Response Get Csat Report Csat Report Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","description":"Health check endpoint.","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Health check endpoint for monitoring.\n\nReturns:\n    Health status with database connection status","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"A2AMessage":{"properties":{"role":{"type":"string","title":"Role","default":"user"},"parts":{"items":{"$ref":"#/components/schemas/A2APart"},"type":"array","title":"Parts"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","title":"A2AMessage"},"A2APart":{"properties":{"kind":{"type":"string","title":"Kind","default":"text"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Data"}},"type":"object","title":"A2APart"},"A2ASendRequest":{"properties":{"message":{"anyOf":[{"$ref":"#/components/schemas/A2AMessage"},{"type":"null"}]},"skill":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skill"},"input":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Input"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","title":"A2ASendRequest"},"A2ASubscribeRequest":{"properties":{"push_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Push Url","description":"Optional URL to receive a POST callback when the task completes. The server will POST the full task result to this URL."}},"type":"object","title":"A2ASubscribeRequest"},"AIModel":{"type":"string","enum":["gpt-5-mini","gemini-3.0-flash"],"title":"AIModel","description":"Available AI models for content generation."},"APIKeyResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"key_hint":{"type":"string","title":"Key Hint"},"rate_limit":{"type":"integer","title":"Rate Limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","name","key_prefix","key_hint","rate_limit","created_at","last_used_at","revoked_at"],"title":"APIKeyResponse"},"APIKeyStats":{"properties":{"total":{"type":"integer","title":"Total"},"active_last_7_days":{"type":"integer","title":"Active Last 7 Days"}},"type":"object","required":["total","active_last_7_days"],"title":"APIKeyStats"},"ActionCreate":{"properties":{"influencer_id":{"type":"string","format":"uuid","title":"Influencer Id"},"action_type":{"type":"string","title":"Action Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"new_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Stage"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["influencer_id","action_type"],"title":"ActionCreate"},"ActionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"influencer_id":{"type":"string","format":"uuid","title":"Influencer Id"},"action_type":{"type":"string","title":"Action Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"old_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Stage"},"new_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Stage"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","influencer_id","action_type"],"title":"ActionResponse"},"AddressHistoryItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"design_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Url"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"map_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Map Style"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"generation_type":{"type":"string","title":"Generation Type","default":"standard"}},"type":"object","required":["id","created_at"],"title":"AddressHistoryItem","description":"Simplified generation item for address-based thumbnails"},"AddressHistoryResponse":{"properties":{"address":{"type":"string","title":"Address"},"generations":{"items":{"$ref":"#/components/schemas/AddressHistoryItem"},"type":"array","title":"Generations"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["address","generations","total"],"title":"AddressHistoryResponse","description":"Response for /history/by-address endpoint"},"AddressParsed":{"properties":{"street":{"type":"string","title":"Street"},"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"zip":{"type":"string","title":"Zip"}},"type":"object","required":["street","city","state","zip"],"title":"AddressParsed"},"AddressType":{"type":"string","enum":["standard","cul_de_sac","corner_lot","multi_family","rural","urban","hillside","flag_lot","through_lot","pie_shaped"],"title":"AddressType","description":"Address types for classification."},"AgentChatRequest":{"properties":{"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Existing session ID. If omitted, a new session is created."},"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message","description":"User's chat message."},"attachments":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Attachments","description":"Optional file attachments. Each dict has 'type' (site_photo|inspiration_photo), 'base64' (base64-encoded image data), 'caption', and 'fileName'."}},"type":"object","required":["message"],"title":"AgentChatRequest","description":"Request body for POST /v1/agent/chat (JSON mode)."},"AgentDesignRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Valid US address for the property"},"style":{"$ref":"#/components/schemas/src__models__agent_api_models__DesignStyle","description":"Design style to apply"},"yard_area":{"$ref":"#/components/schemas/src__models__agent_api_models__YardArea","description":"Area to design: front, back, side, full"},"preferences":{"anyOf":[{"$ref":"#/components/schemas/DesignPreferences"},{"type":"null"}],"description":"Optional design preferences"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url","description":"Optional URL to receive a POST callback when design generation completes. The request body will contain the full AgentDesignResponse."}},"type":"object","required":["address","style","yard_area"],"title":"AgentDesignRequest","description":"Request body for POST /api/agent/designs"},"AgentDesignResponse":{"properties":{"design_id":{"type":"string","title":"Design Id","description":"Unique design identifier (UUID)"},"status":{"$ref":"#/components/schemas/DesignStatus","description":"Design generation status"},"address":{"type":"string","title":"Address","description":"Property address"},"satellite_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Url","description":"URL of satellite imagery"},"boundary_polygon":{"anyOf":[{"$ref":"#/components/schemas/BoundaryPolygon"},{"type":"null"}],"description":"Property boundary polygon"},"renders":{"items":{"$ref":"#/components/schemas/DesignRender"},"type":"array","title":"Renders","description":"AI-generated design renders"},"materials":{"items":{"$ref":"#/components/schemas/src__models__agent_api_models__MaterialItem"},"type":"array","title":"Materials","description":"Materials with cost estimates"},"estimated_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Cost","description":"Total estimated cost in USD"},"style_applied":{"$ref":"#/components/schemas/src__models__agent_api_models__DesignStyle","description":"Design style that was applied"},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Design creation timestamp"}},"type":"object","required":["design_id","status","address","style_applied","created_at"],"title":"AgentDesignResponse","description":"Response body for POST /api/agent/designs and GET /api/agent/designs/{design_id}"},"AgentMetricsResponse":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"api_keys":{"$ref":"#/components/schemas/APIKeyStats"},"designs_by_origin_daily":{"items":{"$ref":"#/components/schemas/DesignsByOriginDay"},"type":"array","title":"Designs By Origin Daily"},"designs_total":{"additionalProperties":true,"type":"object","title":"Designs Total"},"top_consumers":{"items":{"$ref":"#/components/schemas/TopConsumer"},"type":"array","title":"Top Consumers"},"mcp_tool_stats":{"items":{"$ref":"#/components/schemas/MCPToolStat"},"type":"array","title":"Mcp Tool Stats"}},"type":"object","required":["period_days","api_keys","designs_by_origin_daily","designs_total","top_consumers","mcp_tool_stats"],"title":"AgentMetricsResponse"},"AgentPricingResponse":{"properties":{"effective_date":{"type":"string","title":"Effective Date","description":"Pricing effective date (YYYY-MM-DD)"},"currency":{"type":"string","title":"Currency","description":"Currency code","default":"USD"},"plans":{"items":{"$ref":"#/components/schemas/Plan"},"type":"array","title":"Plans","description":"Available pricing plans"},"rate_limits":{"$ref":"#/components/schemas/RateLimits","description":"Rate limit configurations"}},"type":"object","required":["effective_date","plans","rate_limits"],"title":"AgentPricingResponse","description":"Response body for GET /api/agent/pricing"},"AgentPricingTier":{"properties":{"tier":{"type":"string","title":"Tier","description":"Tier name: free, pro"},"designs_per_month":{"type":"integer","title":"Designs Per Month","description":"Number of designs allowed per month"},"price_cents":{"type":"integer","title":"Price Cents","description":"Price in cents (0 for free)"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"Features included in this tier"}},"type":"object","required":["tier","designs_per_month","price_cents","features"],"title":"AgentPricingTier","description":"Pricing tier for agent API"},"AgentStyleItem":{"properties":{"id":{"$ref":"#/components/schemas/src__models__agent_api_models__DesignStyle","description":"Style identifier"},"name":{"type":"string","title":"Name","description":"Display name, e.g., 'Modern Minimalist'"},"description":{"type":"string","title":"Description","description":"Style description"},"emoji":{"type":"string","title":"Emoji","description":"Emoji icon"},"example_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Example Image Url","description":"Example image URL"}},"type":"object","required":["id","name","description","emoji"],"title":"AgentStyleItem","description":"A design style with example"},"AgentStylesResponse":{"properties":{"styles":{"items":{"$ref":"#/components/schemas/AgentStyleItem"},"type":"array","title":"Styles","description":"Available design styles"}},"type":"object","required":["styles"],"title":"AgentStylesResponse","description":"Response body for GET /api/agent/styles"},"AgentUsagePricingResponse":{"properties":{"tiers":{"items":{"$ref":"#/components/schemas/AgentPricingTier"},"type":"array","title":"Tiers","description":"Available pricing tiers"},"current_tier":{"type":"string","title":"Current Tier","description":"Current tier for this API key"},"designs_used_this_month":{"type":"integer","title":"Designs Used This Month","description":"Number of designs used this month"},"designs_remaining":{"type":"integer","title":"Designs Remaining","description":"Number of designs remaining this month"}},"type":"object","required":["tiers","current_tier","designs_used_this_month","designs_remaining"],"title":"AgentUsagePricingResponse","description":"Response body for GET /api/agent/pricing - usage-based pricing"},"AlignCoordinatesRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Full property address including house number"},"lat":{"type":"number","title":"Lat","description":"Current latitude from geocoding"},"lng":{"type":"number","title":"Lng","description":"Current longitude from geocoding"},"zoom":{"type":"integer","title":"Zoom","description":"Satellite image zoom level","default":20}},"type":"object","required":["address","lat","lng"],"title":"AlignCoordinatesRequest","description":"Request to align coordinates using AI vision analysis"},"AlignCoordinatesResponse":{"properties":{"originalLat":{"type":"number","title":"Originallat"},"originalLng":{"type":"number","title":"Originallng"},"correctedLat":{"type":"number","title":"Correctedlat"},"correctedLng":{"type":"number","title":"Correctedlng"},"offsetNorthFt":{"type":"number","title":"Offsetnorthft","description":"Offset in feet (positive=north)"},"offsetEastFt":{"type":"number","title":"Offseteastft","description":"Offset in feet (positive=east)"},"confidence":{"type":"string","title":"Confidence","description":"high, medium, or low"},"reasoning":{"type":"string","title":"Reasoning","description":"AI explanation of the alignment"}},"type":"object","required":["originalLat","originalLng","correctedLat","correctedLng","offsetNorthFt","offsetEastFt","confidence","reasoning"],"title":"AlignCoordinatesResponse","description":"Response with corrected coordinates"},"AnalyzeInspirationRequest":{"properties":{"photos":{"items":{"$ref":"#/components/schemas/InspirationPhotoItem"},"type":"array","maxItems":3,"minItems":1,"title":"Photos","description":"1-3 inspiration photos with captions"}},"type":"object","required":["photos"],"title":"AnalyzeInspirationRequest","description":"Request to analyze inspiration photos and extract design direction (YAR-95)."},"AnalyzeInspirationResponse":{"properties":{"summary":{"type":"string","title":"Summary","description":"Human-readable analysis summary","default":""},"takeaways":{"items":{"$ref":"#/components/schemas/InspirationTakeaway"},"type":"array","title":"Takeaways","description":"5-7 selectable design takeaways","default":[]}},"type":"object","title":"AnalyzeInspirationResponse","description":"AI analysis results from inspiration photos (YAR-95)."},"AnalyzePropertyRequest":{"properties":{"satellite_2d_base64":{"type":"string","title":"Satellite 2D Base64","description":"Base64-encoded satellite image"},"address":{"type":"string","title":"Address","description":"Property address","default":""},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"{lat, lng}"},"street_edge":{"type":"string","title":"Street Edge","description":"Street edge direction","default":"BOTTOM"},"boundary_vertices":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Boundary Vertices","description":"Polygon vertices [{x, y}] normalized 0-1"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features","description":"User-selected features (may be empty at Step 2)","default":[]}},"type":"object","required":["satellite_2d_base64"],"title":"AnalyzePropertyRequest","description":"Request for standalone property analysis (Call 1 prefetch)."},"AnalyzeReferenceDesignRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded design image"},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description","description":"Layout from generation"},"site_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Site Analysis","description":"Site analysis from generation"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features","description":"Known feature names"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"}},"type":"object","required":["image_base64"],"title":"AnalyzeReferenceDesignRequest","description":"Request to analyze a reference design image."},"AnalyzeReferenceDesignResponse":{"properties":{"elements":{"items":{"$ref":"#/components/schemas/DesignAnalysisElement"},"type":"array","title":"Elements"},"recommendedViewpoint":{"anyOf":[{"$ref":"#/components/schemas/RecommendedViewpoint"},{"type":"null"}]},"analysisNotes":{"type":"string","title":"Analysisnotes","default":""}},"type":"object","title":"AnalyzeReferenceDesignResponse","description":"Response with design analysis results."},"AnalyzeShotRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded screenshot from 3D viewer"},"view_type":{"type":"string","title":"View Type","description":"Type of view: 'front' or 'backyard'","default":"backyard"},"current_camera":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Current Camera","description":"Current camera params for adjustment calculation"}},"type":"object","required":["image_base64"],"title":"AnalyzeShotRequest","description":"Request to analyze a 3D view screenshot."},"AnalyzeShotResponse":{"properties":{"marker":{"$ref":"#/components/schemas/MarkerPositionResponse"},"canvas_width":{"type":"integer","title":"Canvas Width"},"canvas_height":{"type":"integer","title":"Canvas Height"},"offset_x_percent":{"type":"number","title":"Offset X Percent"},"offset_y_percent":{"type":"number","title":"Offset Y Percent"},"sky_percent":{"type":"number","title":"Sky Percent"},"vegetation_percent":{"type":"number","title":"Vegetation Percent"},"building_percent":{"type":"number","title":"Building Percent"},"property_fill_percent":{"type":"number","title":"Property Fill Percent"},"is_acceptable":{"type":"boolean","title":"Is Acceptable"},"recommended_pan_x":{"type":"number","title":"Recommended Pan X"},"recommended_pan_y":{"type":"number","title":"Recommended Pan Y"},"recommended_altitude_change":{"type":"number","title":"Recommended Altitude Change"},"notes":{"type":"string","title":"Notes"}},"type":"object","required":["marker","canvas_width","canvas_height","offset_x_percent","offset_y_percent","sky_percent","vegetation_percent","building_percent","property_fill_percent","is_acceptable","recommended_pan_x","recommended_pan_y","recommended_altitude_change","notes"],"title":"AnalyzeShotResponse","description":"Shot analysis results with adjustment recommendations."},"AnalyzeSiteRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded image to analyze"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"}},"type":"object","required":["image_base64"],"title":"AnalyzeSiteRequest","description":"Request to analyze site features"},"ApplyReferralRequest":{"properties":{"code":{"type":"string","maxLength":12,"minLength":6,"title":"Code","description":"Referral code to apply"}},"type":"object","required":["code"],"title":"ApplyReferralRequest","description":"Request to apply a referral code to current user."},"ApplyReferralResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether the code was applied successfully"},"message":{"type":"string","title":"Message","description":"Result message"}},"type":"object","required":["success","message"],"title":"ApplyReferralResponse","description":"Response after applying a referral code."},"AreaRequest":{"properties":{"area":{"$ref":"#/components/schemas/src__models__generation__YardArea","description":"Type of yard area to generate"},"style":{"$ref":"#/components/schemas/src__models__generation__DesignStyle","description":"Design style for this area"},"custom_prompt":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Custom Prompt","description":"Optional custom prompt for this area (max 500 characters)"},"preservation_strength":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Preservation Strength","description":"Control transformation intensity: 0.0-0.4 = dramatic, 0.4-0.6 = balanced, 0.6-1.0 = subtle","default":0.5}},"type":"object","required":["area","style"],"title":"AreaRequest","description":"Request model for individual yard area within multi-area generation"},"AreaStatus":{"type":"string","enum":["not_started","pending","processing","completed","failed"],"title":"AreaStatus","description":"Status of individual area within multi-area generation"},"AreaStatusResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Unique identifier for this area"},"area":{"$ref":"#/components/schemas/YardArea-Output","description":"Type of yard area"},"style":{"$ref":"#/components/schemas/src__models__generation__DesignStyle","description":"Design style applied"},"status":{"$ref":"#/components/schemas/AreaStatus","description":"Current status of this area"},"progress":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Progress","description":"Progress percentage (0-100)"},"current_stage":{"anyOf":[{"$ref":"#/components/schemas/ProcessingStage"},{"type":"null"}],"description":"Current processing stage"},"status_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Message","description":"User-facing progress message"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url","description":"Generated design image URL (single)"},"image_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Image Urls","description":"Generated design image URLs (array for multi-angle support)"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message","description":"Error message if failed"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At","description":"Completion timestamp"}},"type":"object","required":["id","area","style","status","progress"],"title":"AreaStatusResponse","description":"Progress tracking for individual area within multi-area generation"},"Audience":{"type":"string","enum":["homeowner","service_provider"],"title":"Audience","description":"Target audience for content."},"AuditLogResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"canonical_lead_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Canonical Lead Id"},"action":{"type":"string","title":"Action"},"field_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Name"},"old_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Value"},"new_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Value"},"performed_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Performed By"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","action"],"title":"AuditLogResponse","description":"Audit log entry."},"AutoReloadConfigResponse":{"properties":{"auto_reload_enabled":{"type":"boolean","title":"Auto Reload Enabled","description":"Auto-reload enabled"},"auto_reload_threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Reload Threshold","description":"Balance threshold (1-100)"},"auto_reload_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Reload Amount","description":"Reload amount (min 10)"},"auto_reload_failure_count":{"type":"integer","title":"Auto Reload Failure Count","description":"Consecutive failure count","default":0},"last_reload_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Reload At","description":"Last reload timestamp (for throttling)"}},"type":"object","required":["auto_reload_enabled"],"title":"AutoReloadConfigResponse","description":"Response with current auto-reload configuration.\n\nRequirements:\n- FR-034 to FR-042: All auto-reload configuration fields","example":{"auto_reload_amount":100,"auto_reload_enabled":true,"auto_reload_failure_count":0,"auto_reload_threshold":20,"last_reload_at":"2025-01-20T14:45:00Z"}},"AutoTuneConfig":{"properties":{"mode":{"type":"string","title":"Mode","default":"standard"},"max_addresses":{"type":"integer","title":"Max Addresses","default":20},"quality_threshold":{"type":"number","title":"Quality Threshold","default":7.0},"max_iterations":{"type":"integer","title":"Max Iterations","default":3},"capture_images":{"type":"boolean","title":"Capture Images","default":true}},"type":"object","title":"AutoTuneConfig","description":"Configuration for automated tuning."},"BackgroundStyle":{"type":"string","enum":["gradient","solid","blur","none"],"title":"BackgroundStyle","description":"Background styles for text overlays."},"BacklogCategory":{"type":"string","enum":["enhancement","bug","tech_debt","performance","ux","documentation","camera_positioning"],"title":"BacklogCategory","description":"Backlog item categories."},"BacklogItemCreate":{"properties":{"title":{"type":"string","maxLength":200,"minLength":1,"title":"Title","description":"Brief title"},"description":{"type":"string","maxLength":5000,"minLength":1,"title":"Description","description":"Detailed description"},"category":{"$ref":"#/components/schemas/BacklogCategory","description":"Item category"},"priority":{"$ref":"#/components/schemas/BacklogPriority","description":"Priority level","default":"medium"},"related_feedback_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Related Feedback Id","description":"Link to user feedback"},"related_file_path":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Related File Path","description":"Related file path"},"related_line_numbers":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Related Line Numbers","description":"Line numbers e.g. '100-150'"},"estimated_effort":{"anyOf":[{"$ref":"#/components/schemas/EffortSize"},{"type":"null"}],"description":"Effort estimate (t-shirt size)"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags","description":"Tags for filtering","default":[]},"implementation_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Implementation Notes","description":"Technical implementation notes"},"acceptance_criteria":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acceptance Criteria","description":"Definition of done"}},"type":"object","required":["title","description","category"],"title":"BacklogItemCreate","description":"Request model for creating a backlog item."},"BacklogItemResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"category":{"type":"string","title":"Category"},"priority":{"type":"string","title":"Priority"},"status":{"type":"string","title":"Status"},"related_feedback_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Related Feedback Id"},"related_file_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Related File Path"},"related_line_numbers":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Related Line Numbers"},"estimated_effort":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Estimated Effort"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"completed_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Completed By"},"implementation_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Implementation Notes"},"acceptance_criteria":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acceptance Criteria"}},"type":"object","required":["id","title","description","category","priority","status","related_feedback_id","related_file_path","related_line_numbers","estimated_effort","tags","created_by","created_at","updated_at","completed_at","completed_by","implementation_notes","acceptance_criteria"],"title":"BacklogItemResponse","description":"Response model for backlog item."},"BacklogItemUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string","maxLength":5000,"minLength":1},{"type":"null"}],"title":"Description"},"category":{"anyOf":[{"$ref":"#/components/schemas/BacklogCategory"},{"type":"null"}]},"priority":{"anyOf":[{"$ref":"#/components/schemas/BacklogPriority"},{"type":"null"}]},"status":{"anyOf":[{"$ref":"#/components/schemas/BacklogStatus"},{"type":"null"}]},"estimated_effort":{"anyOf":[{"$ref":"#/components/schemas/EffortSize"},{"type":"null"}]},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"implementation_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Implementation Notes"},"acceptance_criteria":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acceptance Criteria"}},"type":"object","title":"BacklogItemUpdate","description":"Request model for updating a backlog item."},"BacklogPriority":{"type":"string","enum":["critical","high","medium","low","nice_to_have"],"title":"BacklogPriority","description":"Backlog priority levels."},"BacklogStats":{"properties":{"total":{"type":"integer","title":"Total"},"by_status":{"additionalProperties":true,"type":"object","title":"By Status"},"by_priority":{"additionalProperties":true,"type":"object","title":"By Priority"},"by_category":{"additionalProperties":true,"type":"object","title":"By Category"}},"type":"object","required":["total","by_status","by_priority","by_category"],"title":"BacklogStats","description":"Statistics for backlog overview."},"BacklogStatus":{"type":"string","enum":["proposed","approved","in_progress","completed","rejected","deferred"],"title":"BacklogStatus","description":"Backlog item status."},"BatchDesignItem":{"properties":{"address":{"type":"string","title":"Address","description":"Valid US address for the property"},"style":{"$ref":"#/components/schemas/src__models__agent_api_models__DesignStyle","description":"Design style to apply"},"yard_area":{"$ref":"#/components/schemas/src__models__agent_api_models__YardArea","description":"Area to design: front, back, side, full"}},"type":"object","required":["address","style","yard_area"],"title":"BatchDesignItem","description":"Single item in a batch design request"},"BatchDesignItemResponse":{"properties":{"design_id":{"type":"string","title":"Design Id","description":"Unique design identifier (UUID)"},"status":{"$ref":"#/components/schemas/DesignStatus","description":"Design generation status"},"address":{"type":"string","title":"Address","description":"Property address"}},"type":"object","required":["design_id","status","address"],"title":"BatchDesignItemResponse","description":"Response for a single item in a batch design request"},"BatchDesignRequest":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/BatchDesignItem"},"type":"array","maxItems":20,"minItems":1,"title":"Designs","description":"List of design requests (max 20 items)"}},"type":"object","required":["designs"],"title":"BatchDesignRequest","description":"Request body for POST /api/agent/designs/batch"},"BatchDesignResponse":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/BatchDesignItemResponse"},"type":"array","title":"Designs","description":"List of design responses"}},"type":"object","required":["designs"],"title":"BatchDesignResponse","description":"Response body for POST /api/agent/designs/batch"},"BatchTestRequest":{"properties":{"addresses":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Addresses","description":"List of addresses to test"},"validate":{"type":"boolean","title":"Validate","description":"Whether to validate with VLM","default":true},"save_successful":{"type":"boolean","title":"Save Successful","description":"Save successful params to learning DB","default":true}},"type":"object","required":["addresses"],"title":"BatchTestRequest","description":"Request model for batch testing."},"BatchTestResponse":{"properties":{"total":{"type":"integer","title":"Total"},"successful":{"type":"integer","title":"Successful"},"failed":{"type":"integer","title":"Failed"},"skipped":{"type":"integer","title":"Skipped"},"avg_front_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Front Score"},"avg_back_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Back Score"},"results":{"items":{"$ref":"#/components/schemas/CameraTestResponse"},"type":"array","title":"Results"}},"type":"object","required":["total","successful","failed","skipped"],"title":"BatchTestResponse","description":"Response model for batch test results."},"BidPackContents":{"properties":{"materials":{"items":{"$ref":"#/components/schemas/src__marketplace__models__pro_engine__MaterialItem"},"type":"array","title":"Materials"},"labor_hours":{"$ref":"#/components/schemas/LaborEstimate"},"equipment":{"items":{"type":"string"},"type":"array","title":"Equipment"}},"type":"object","title":"BidPackContents","description":"Complete bid pack contents."},"BidPackRequest":{"properties":{"project_id":{"type":"string","title":"Project Id"},"estimate_id":{"type":"string","title":"Estimate Id"},"style_code":{"type":"string","title":"Style Code"},"area_type":{"type":"string","title":"Area Type"}},"type":"object","required":["project_id","estimate_id","style_code","area_type"],"title":"BidPackRequest","description":"Request to generate bid pack."},"BidPackResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"estimate_id":{"type":"string","format":"uuid","title":"Estimate Id"},"style_code":{"type":"string","title":"Style Code"},"area_type":{"type":"string","title":"Area Type"},"contents":{"$ref":"#/components/schemas/BidPackContents"},"total_materials_count":{"type":"integer","title":"Total Materials Count"},"estimated_labor_hours":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Estimated Labor Hours"},"version":{"type":"integer","title":"Version"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","project_id","estimate_id","style_code","area_type","contents","total_materials_count","version","created_at","updated_at"],"title":"BidPackResponse","description":"Full bid pack response."},"BlogPostResponse":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"content":{"type":"string","title":"Content"},"image_prompt":{"type":"string","title":"Image Prompt"},"social_posts":{"items":{"$ref":"#/components/schemas/SocialPostFromBlog"},"type":"array","title":"Social Posts"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["title","description","content","image_prompt"],"title":"BlogPostResponse","description":"Response containing a generated blog post with companion social posts."},"Body_agent_chat_upload_v1_agent_chat_upload_post":{"properties":{"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"photo_types":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Types","description":"Comma-separated photo types matching each file (site_photo|inspiration_photo)"},"photo_captions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Captions","description":"Comma-separated captions matching each uploaded file"},"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files","default":[]}},"type":"object","required":["message"],"title":"Body_agent_chat_upload_v1_agent_chat_upload_post"},"Body_create_generation_v1_generations__post":{"properties":{"address":{"type":"string","title":"Address"},"area":{"type":"string","title":"Area"},"style":{"type":"string","title":"Style"},"custom_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Prompt"},"image":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Image"}},"type":"object","required":["address","area","style"],"title":"Body_create_generation_v1_generations__post"},"Body_create_inpaint_api_v1_inpaint_post":{"properties":{"source_variant_id":{"type":"string","title":"Source Variant Id","description":"UUID of the variant to edit"},"prompt":{"type":"string","maxLength":500,"minLength":1,"title":"Prompt","description":"Description of the desired change"},"mask":{"type":"string","format":"binary","title":"Mask","description":"PNG mask image (white=edit, black=preserve)"}},"type":"object","required":["source_variant_id","prompt","mask"],"title":"Body_create_inpaint_api_v1_inpaint_post"},"Body_create_multi_area_generation_with_photo_v1_generations_multi_with_photo_post":{"properties":{"data":{"type":"string","title":"Data"},"backyard_photo":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Backyard Photo"}},"type":"object","required":["data"],"title":"Body_create_multi_area_generation_with_photo_v1_generations_multi_with_photo_post"},"Body_create_pin_annotation_api_v1_pin_annotate_post":{"properties":{"source_variant_id":{"type":"string","title":"Source Variant Id","description":"UUID of the variant to edit"},"annotated_image":{"type":"string","format":"binary","title":"Annotated Image","description":"PNG image with pin markers rendered on it"},"original_image":{"type":"string","format":"binary","title":"Original Image","description":"Clean original PNG image (no annotations)"},"pins_json":{"type":"string","title":"Pins Json","description":"JSON array of pin annotations [{number, x, y, comment}]"}},"type":"object","required":["source_variant_id","annotated_image","original_image","pins_json"],"title":"Body_create_pin_annotation_api_v1_pin_annotate_post"},"Body_generate_from_upload_v1_pro_mode_generate_from_upload_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"style":{"type":"string","title":"Style","default":"Modern Minimalist"},"features":{"type":"string","title":"Features","default":""},"skip_cad_enhance":{"type":"boolean","title":"Skip Cad Enhance","default":false},"use_flash_model":{"type":"boolean","title":"Use Flash Model","default":false},"is_3d_tiles":{"type":"boolean","title":"Is 3D Tiles","default":false},"map_style":{"type":"string","title":"Map Style","default":"Colorful"},"ai_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Model"}},"type":"object","required":["file"],"title":"Body_generate_from_upload_v1_pro_mode_generate_from_upload_post"},"Body_get_satellite_image_v1_pro_mode_satellite_image_post":{"properties":{"address":{"type":"string","title":"Address"},"zoom":{"type":"integer","title":"Zoom","default":20},"size":{"type":"string","title":"Size","default":"640x640"}},"type":"object","required":["address"],"title":"Body_get_satellite_image_v1_pro_mode_satellite_image_post"},"Body_process_video_cta_marketing_video_cta_process_post":{"properties":{"video":{"type":"string","format":"binary","title":"Video","description":"Video file (MP4/MOV, max 100MB)"},"cta_text":{"type":"string","title":"Cta Text","description":"CTA headline text","default":"Transform Your Yard Today"},"cta_url":{"type":"string","title":"Cta Url","description":"CTA URL to display","default":"yarda.pro"},"duration":{"type":"integer","maximum":5.0,"minimum":3.0,"title":"Duration","description":"Closing screen duration in seconds","default":4},"bg_color":{"type":"string","title":"Bg Color","description":"Background color (hex)","default":"#1F2937"},"text_color":{"type":"string","title":"Text Color","description":"Text color (hex)","default":"#FFFFFF"},"accent_color":{"type":"string","title":"Accent Color","description":"Accent/URL color (hex)","default":"#2D8B5D"},"logo":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Logo","description":"Optional logo image (PNG/JPG)"}},"type":"object","required":["video"],"title":"Body_process_video_cta_marketing_video_cta_process_post"},"Body_upload_drone_photo_v1_designer_pro_upload_drone_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_drone_photo_v1_designer_pro_upload_drone_post"},"Body_upload_file_api_upload_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"upload_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Upload Type"}},"type":"object","required":["file"],"title":"Body_upload_file_api_upload_post"},"Body_upload_marketing_image_marketing_pipeline_upload_image_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_marketing_image_marketing_pipeline_upload_image_post"},"BoundaryCorrectionRequest":{"properties":{"address":{"type":"string","maxLength":500,"minLength":1,"title":"Address"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates"},"original_vertices":{"items":{"$ref":"#/components/schemas/PolygonVertex"},"type":"array","minItems":3,"title":"Original Vertices"},"corrected_vertices":{"items":{"$ref":"#/components/schemas/PolygonVertex"},"type":"array","minItems":3,"title":"Corrected Vertices"},"lot_shape":{"type":"string","title":"Lot Shape","default":"rectangular"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","default":0.0},"street_edge":{"type":"string","title":"Street Edge","default":"bottom"}},"type":"object","required":["address","original_vertices","corrected_vertices"],"title":"BoundaryCorrectionRequest"},"BoundaryCorrectionResponse":{"properties":{"id":{"type":"string","title":"Id"},"mean_displacement":{"type":"number","title":"Mean Displacement"},"max_displacement":{"type":"number","title":"Max Displacement"},"vertex_count_delta":{"type":"integer","title":"Vertex Count Delta"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","mean_displacement","max_displacement","vertex_count_delta","created_at"],"title":"BoundaryCorrectionResponse"},"BoundaryPoint":{"properties":{"x":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X","description":"Normalized X coordinate (0-1)"},"y":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y","description":"Normalized Y coordinate (0-1)"}},"type":"object","required":["x","y"],"title":"BoundaryPoint","description":"A single point in a boundary polygon (normalized 0-1 coordinates)."},"BoundaryPolygon":{"properties":{"type":{"type":"string","title":"Type","default":"Polygon"},"coordinates":{"items":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"array","title":"Coordinates","description":"GeoJSON coordinates array [[[lng, lat], ...]]"}},"type":"object","required":["coordinates"],"title":"BoundaryPolygon","description":"GeoJSON Polygon representing property boundary"},"BoundaryResponse":{"properties":{"design_id":{"type":"string","title":"Design Id"},"address":{"type":"string","title":"Address"},"satellite_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Url"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates"},"normalized_polygon":{"anyOf":[{"items":{"additionalProperties":{"type":"number"},"type":"object"},"type":"array"},{"type":"null"}],"title":"Normalized Polygon"},"street_edge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Edge"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"status":{"type":"string","title":"Status"}},"type":"object","required":["design_id","address","status"],"title":"BoundaryResponse","description":"Public boundary data for the /adjust/[designId] page."},"BudgetStatusResponse":{"properties":{"daily":{"additionalProperties":true,"type":"object","title":"Daily"},"monthly":{"additionalProperties":true,"type":"object","title":"Monthly"},"per_user_daily_limit_usd":{"type":"number","title":"Per User Daily Limit Usd"},"hard_block_enabled":{"type":"boolean","title":"Hard Block Enabled"},"alert_threshold_pct":{"type":"number","title":"Alert Threshold Pct"}},"type":"object","required":["daily","monthly","per_user_daily_limit_usd","hard_block_enabled","alert_threshold_pct"],"title":"BudgetStatusResponse","description":"Current budget status."},"BudgetTier":{"type":"string","enum":["budget","mid_range","premium"],"title":"BudgetTier","description":"Budget tier options"},"BulkLeadAction":{"properties":{"lead_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Lead Ids"},"action":{"type":"string","title":"Action"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"type":"object","required":["lead_ids","action"],"title":"BulkLeadAction","description":"Bulk action on multiple leads."},"BusinessInfoRequest":{"properties":{"url":{"type":"string","title":"Url","description":"Facebook page URL or business website URL"}},"type":"object","required":["url"],"title":"BusinessInfoRequest","description":"Request body for business info extraction."},"BusinessInfoResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"source":{"type":"string","title":"Source","description":"Source type: 'facebook' or 'website'"},"url":{"type":"string","title":"Url"},"business_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"services":{"items":{"type":"string"},"type":"array","title":"Services"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["success","source","url"],"title":"BusinessInfoResponse","description":"Response with extracted business information."},"BusinessLocationResponse":{"properties":{"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"zip_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip Code"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"default_travel_radius_miles":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Default Travel Radius Miles"}},"type":"object","title":"BusinessLocationResponse","description":"Business location details for contractor."},"BusinessLocationUpdateRequest":{"properties":{"address":{"type":"string","maxLength":500,"minLength":5,"title":"Address"},"city":{"type":"string","maxLength":100,"minLength":2,"title":"City"},"state":{"type":"string","maxLength":2,"minLength":2,"title":"State"},"zip_code":{"type":"string","maxLength":10,"minLength":5,"title":"Zip Code"},"lat":{"anyOf":[{"type":"number","maximum":90.0,"minimum":-90.0},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number","maximum":180.0,"minimum":-180.0},{"type":"null"}],"title":"Lng"},"default_travel_radius_miles":{"type":"number","maximum":500.0,"minimum":1.0,"title":"Default Travel Radius Miles","default":25.0}},"type":"object","required":["address","city","state","zip_code"],"title":"BusinessLocationUpdateRequest","description":"Request to set/update contractor's business location."},"CADGenerationRequest":{"properties":{"place_id":{"type":"string","title":"Place Id","description":"Google Place ID for validation"},"address":{"type":"string","title":"Address","description":"Property address for display"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat","description":"Latitude for satellite fetch"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng","description":"Longitude for satellite fetch"},"style":{"type":"string","title":"Style","description":"Design style","default":"modern_minimalist"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"Features to include (pool, patio, etc.)","default":[]}},"type":"object","required":["place_id","address"],"title":"CADGenerationRequest","description":"Request for Property Pass 2D CAD site plan generation"},"CSATMonthlyReport":{"properties":{"month":{"type":"string","title":"Month"},"count":{"type":"integer","title":"Count"},"average_rating":{"type":"number","title":"Average Rating"},"distribution":{"additionalProperties":true,"type":"object","title":"Distribution"}},"type":"object","required":["month","count","average_rating","distribution"],"title":"CSATMonthlyReport"},"CSATResponse":{"properties":{"id":{"type":"string","title":"Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["id","message"],"title":"CSATResponse"},"CSATSubmit":{"properties":{"rating":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Rating","description":"1-5 star rating"},"comment":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Comment"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"context":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Context","description":"Where CSAT was shown"}},"type":"object","required":["rating"],"title":"CSATSubmit"},"CalculateBackyardCameraRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Full property address"},"lat":{"type":"number","title":"Lat","description":"Property latitude from geocoding"},"lng":{"type":"number","title":"Lng","description":"Property longitude from geocoding"},"distance_meters":{"type":"number","title":"Distance Meters","description":"Distance from house center to camera (default 45m, ~148ft)","default":45},"altitude_meters":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Altitude Meters","description":"Camera altitude in meters. If None, auto-calculates based on distance"},"pitch":{"type":"number","title":"Pitch","description":"Camera pitch in degrees (default -40 for good backyard view)","default":-40},"auto_altitude":{"type":"boolean","title":"Auto Altitude","description":"If True, calculate optimal altitude based on distance. If False, use altitude_meters","default":true},"satelliteImageBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satelliteimagebase64","description":"Base64-encoded satellite image for AI-based orientation detection (Tier 2 fallback)"},"forceSatelliteAnalysis":{"type":"boolean","title":"Forcesatelliteanalysis","description":"Skip Street View, use satellite analysis directly","default":false}},"type":"object","required":["address","lat","lng"],"title":"CalculateBackyardCameraRequest","description":"Request to calculate optimal backyard camera position using the TIERED orientation detection system.\n\nTIERED DETECTION ALGORITHM (in order of preference):\n1. TIER 1 - Street View Metadata (FREE, <100ms): Best accuracy when available\n2. TIER 2 - Gemini 3 Flash Satellite Analysis (~2-3s): AI vision to detect driveway/front door\n3. TIER 3 - Default South-facing assumption: Fallback when other methods fail\n\nEach tier provides a confidence level (high/medium/low) so the frontend can decide\nwhether to show a warning or allow manual adjustment."},"CalculateBackyardCameraResponse":{"properties":{"propertyLat":{"type":"number","title":"Propertylat","description":"Property latitude (geocoded house location)"},"propertyLng":{"type":"number","title":"Propertylng","description":"Property longitude (geocoded house location)"},"cameraLat":{"type":"number","title":"Cameralat","description":"Backyard view camera latitude"},"cameraLng":{"type":"number","title":"Cameralng","description":"Backyard view camera longitude"},"cameraHeading":{"type":"number","title":"Cameraheading","description":"Backyard view camera heading"},"cameraPitch":{"type":"number","title":"Camerapitch","description":"Camera pitch angle"},"cameraAltitude":{"type":"number","title":"Cameraaltitude","description":"Camera altitude in meters"},"houseHeading":{"type":"number","title":"Househeading","description":"Direction house front faces (from Street View)"},"headingSource":{"type":"string","title":"Headingsource","description":"How house heading was determined"},"offsetNorthFt":{"type":"number","title":"Offsetnorthft","description":"Equivalent offset in feet (for UI display)"},"offsetEastFt":{"type":"number","title":"Offseteastft","description":"Equivalent offset in feet (for UI display)"},"frontView":{"anyOf":[{"$ref":"#/components/schemas/src__api__endpoints__pro_mode__CameraPosition"},{"type":"null"}],"description":"Front view camera: positioned on street side, looking toward backyard"},"backyardView":{"anyOf":[{"$ref":"#/components/schemas/src__api__endpoints__pro_mode__CameraPosition"},{"type":"null"}],"description":"Backyard view camera: positioned on backyard side, looking toward street"},"sideFrontView":{"anyOf":[{"$ref":"#/components/schemas/src__api__endpoints__pro_mode__CameraPosition"},{"type":"null"}],"description":"Side front view camera: positioned on secondary street side (corner lots only)"},"confidence":{"type":"string","title":"Confidence","description":"Confidence level: high (Street View), medium (road estimate), low (default)"},"reasoning":{"type":"string","title":"Reasoning","description":"Explanation of how camera position was calculated"},"lotSize":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lotsize","description":"Detected lot size category: SMALL, MEDIUM, LARGE, or ESTATE"},"lotSizeConfidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lotsizeconfidence","description":"Confidence in lot size detection: high, medium, low"}},"type":"object","required":["propertyLat","propertyLng","cameraLat","cameraLng","cameraHeading","cameraPitch","cameraAltitude","houseHeading","headingSource","offsetNorthFt","offsetEastFt","confidence","reasoning"],"title":"CalculateBackyardCameraResponse","description":"Response with TWO camera positions for comprehensive property visualization:\n\n1. Front View: Camera on STREET side, looking toward backyard\n   - Shows house front facade\n   - Backyard visible in the distance behind house\n   - Good for context and house orientation\n\n2. Backyard View: Camera on BACKYARD side, looking toward street\n   - Shows backyard in foreground\n   - House visible with street beyond\n   - Primary view for landscape design"},"CameraAdjustments":{"properties":{"moveNorthFt":{"type":"number","title":"Movenorthft","description":"Feet to move north (negative=south)","default":0},"moveEastFt":{"type":"number","title":"Moveeastft","description":"Feet to move east (negative=west)","default":0},"headingChangeDeg":{"type":"number","title":"Headingchangedeg","description":"Degrees to rotate heading","default":0},"altitudeChangeM":{"type":"number","title":"Altitudechangem","description":"Meters to adjust altitude","default":0},"pitchChangeDeg":{"type":"number","title":"Pitchchangedeg","description":"Degrees to adjust pitch","default":0}},"type":"object","title":"CameraAdjustments","description":"Suggested camera adjustments"},"CameraParams":{"properties":{"heading":{"type":"number","title":"Heading","description":"Compass heading in degrees (0-360)"},"pitch":{"type":"number","title":"Pitch","description":"Camera pitch in degrees (negative = looking down)","default":-40},"altitude":{"type":"number","title":"Altitude","description":"Camera altitude in meters","default":25},"offsetN":{"type":"number","title":"Offsetn","description":"North offset in feet from geocoded point","default":0},"offsetE":{"type":"number","title":"Offsete","description":"East offset in feet from geocoded point","default":0}},"type":"object","required":["heading"],"title":"CameraParams","description":"Camera parameters for 3D tiles view"},"CameraTestRequest":{"properties":{"address":{"type":"string","minLength":1,"title":"Address","description":"Full property address"},"capture_views":{"type":"boolean","title":"Capture Views","description":"Whether to capture actual 3D views","default":false},"validate":{"type":"boolean","title":"Validate","description":"Whether to validate with VLM","default":false},"config_overrides":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Config Overrides","description":"Override default camera parameters"}},"type":"object","required":["address"],"title":"CameraTestRequest","description":"Request model for single address camera test."},"CameraTestResponse":{"properties":{"address":{"type":"string","title":"Address"},"property_classification":{"$ref":"#/components/schemas/PropertyClassification"},"front_camera":{"$ref":"#/components/schemas/src__models__adaptive_camera__CameraPosition"},"back_camera":{"$ref":"#/components/schemas/src__models__adaptive_camera__CameraPosition"},"front_validation":{"anyOf":[{"$ref":"#/components/schemas/ValidationResult"},{"type":"null"}]},"back_validation":{"anyOf":[{"$ref":"#/components/schemas/ValidationResult"},{"type":"null"}]},"used_learned_params":{"type":"boolean","title":"Used Learned Params","default":false},"learned_params_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Learned Params Source"}},"type":"object","required":["address","property_classification","front_camera","back_camera"],"title":"CameraTestResponse","description":"Response model for camera test."},"CameraTuneRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Property address"},"front_image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Front Image Base64","description":"Base64-encoded front view image"},"back_image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Back Image Base64","description":"Base64-encoded back view image"},"layout_type":{"anyOf":[{"$ref":"#/components/schemas/LayoutType"},{"type":"null"}],"description":"Property layout type (corner_lot, cul_de_sac, etc.)"},"lot_size":{"anyOf":[{"$ref":"#/components/schemas/LotSize"},{"type":"null"}],"description":"Lot size category"},"triangle_count":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Triangle Count","description":"3D tile triangle count for coverage assessment"},"terrain_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Terrain Type","description":"Terrain type (flat, gentle_slope, steep_slope)"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude","description":"Property center latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude","description":"Property center longitude"},"front_heading":{"anyOf":[{"type":"number","maximum":360.0,"minimum":0.0},{"type":"null"}],"title":"Front Heading","description":"Heading angle for front view (degrees)"},"initial_altitude":{"anyOf":[{"type":"number","maximum":200.0,"minimum":20.0},{"type":"null"}],"title":"Initial Altitude","description":"Initial camera altitude in meters"},"initial_pitch":{"anyOf":[{"type":"number","maximum":-10.0,"minimum":-70.0},{"type":"null"}],"title":"Initial Pitch","description":"Initial camera pitch in degrees"},"max_iterations":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Max Iterations","description":"Maximum retry attempts","default":3},"quality_threshold":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Quality Threshold","description":"Minimum acceptable quality score","default":7.0},"save_on_success":{"type":"boolean","title":"Save On Success","description":"Save successful params to learning DB","default":true}},"type":"object","required":["address"],"title":"CameraTuneRequest","description":"Request model for adaptive tuning loop."},"CameraTuneResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether quality threshold was met"},"outcome":{"$ref":"#/components/schemas/CaptureOutcome"},"iterations_used":{"type":"integer","title":"Iterations Used"},"final_front_camera":{"anyOf":[{"$ref":"#/components/schemas/src__models__adaptive_camera__CameraPosition"},{"type":"null"}]},"final_back_camera":{"anyOf":[{"$ref":"#/components/schemas/src__models__adaptive_camera__CameraPosition"},{"type":"null"}]},"final_front_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Final Front Score"},"final_back_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Final Back Score"},"iteration_history":{"items":{"$ref":"#/components/schemas/TuningIterationSummary"},"type":"array","title":"Iteration History"},"saved_to_learning_db":{"type":"boolean","title":"Saved To Learning Db","default":false},"flagged_for_review":{"type":"boolean","title":"Flagged For Review","default":false},"review_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Reason"},"total_duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Duration Ms"}},"type":"object","required":["success","outcome","iterations_used"],"title":"CameraTuneResponse","description":"Response model for tuning results."},"CampaignCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"budget_cents":{"type":"integer","title":"Budget Cents","default":0},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date"}},"type":"object","required":["name"],"title":"CampaignCreate"},"CampaignMetrics":{"properties":{"campaign":{"type":"string","title":"Campaign"},"source":{"type":"string","title":"Source"},"medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Medium"},"visits":{"type":"integer","title":"Visits","default":0},"signups":{"type":"integer","title":"Signups","default":0},"trial_starts":{"type":"integer","title":"Trial Starts","default":0},"conversions":{"type":"integer","title":"Conversions","default":0},"revenue_cents":{"type":"integer","title":"Revenue Cents","default":0},"conversion_rate":{"type":"number","title":"Conversion Rate","default":0.0}},"type":"object","required":["campaign","source"],"title":"CampaignMetrics","description":"Metrics for a single campaign."},"CampaignResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"status":{"type":"string","title":"Status"},"budget_cents":{"type":"integer","title":"Budget Cents","default":0},"spent_cents":{"type":"integer","title":"Spent Cents","default":0},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","name","status"],"title":"CampaignResponse"},"CampaignRun":{"properties":{"campaign_date":{"type":"string","title":"Campaign Date"},"status":{"type":"string","title":"Status"},"markets_targeted":{"type":"integer","title":"Markets Targeted"},"markets_completed":{"type":"integer","title":"Markets Completed"},"markets_failed":{"type":"integer","title":"Markets Failed"},"yelp_api_calls_used":{"type":"integer","title":"Yelp Api Calls Used"},"new_leads_found":{"type":"integer","title":"New Leads Found"}},"type":"object","required":["campaign_date","status","markets_targeted","markets_completed","markets_failed","yelp_api_calls_used","new_leads_found"],"title":"CampaignRun"},"CampaignSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"total_visits":{"type":"integer","title":"Total Visits"},"total_signups":{"type":"integer","title":"Total Signups"},"total_trial_starts":{"type":"integer","title":"Total Trial Starts"},"total_conversions":{"type":"integer","title":"Total Conversions"},"total_revenue_cents":{"type":"integer","title":"Total Revenue Cents"},"campaigns":{"items":{"$ref":"#/components/schemas/CampaignMetrics"},"type":"array","title":"Campaigns"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","total_visits","total_signups","total_trial_starts","total_conversions","total_revenue_cents","campaigns","generated_at"],"title":"CampaignSummary","description":"Campaign performance summary."},"CampaignUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"budget_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Budget Cents"},"spent_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Spent Cents"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date"}},"type":"object","title":"CampaignUpdate"},"CancelSubscriptionRequest":{"properties":{"cancel_immediately":{"type":"boolean","title":"Cancel Immediately","description":"If true, cancel immediately. If false, cancel at period end.","default":false}},"type":"object","title":"CancelSubscriptionRequest","description":"Request to cancel subscription.\n\nSubscription will remain active until end of current period."},"CancelSubscriptionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"}},"type":"object","required":["success","message","cancel_at_period_end"],"title":"CancelSubscriptionResponse","description":"Response after canceling subscription."},"CanonicalLeadResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"business_name":{"type":"string","title":"Business Name"},"phone_e164":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone E164"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"website_normalized":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website Normalized"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"zip_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip Code"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"best_rating":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Rating"},"total_review_count":{"type":"integer","title":"Total Review Count","default":0},"lead_type":{"type":"string","title":"Lead Type","default":"general"},"lead_score":{"type":"integer","title":"Lead Score","default":0},"pipeline_stage":{"type":"string","title":"Pipeline Stage","default":"prospect"},"preferred_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Channel"},"do_not_contact":{"type":"boolean","title":"Do Not Contact","default":false},"instagram_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instagram Handle"},"facebook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Facebook Url"},"houzz_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Houzz Url"},"yelp_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yelp Url"},"nextdoor_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextdoor Url"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"},"last_outreach_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Outreach At"},"outreach_count":{"type":"integer","title":"Outreach Count","default":0},"source_count":{"type":"integer","title":"Source Count","default":0},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","business_name"],"title":"CanonicalLeadResponse","description":"Canonical (deduplicated) lead response."},"CanonicalLeadUpdate":{"properties":{"pipeline_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pipeline Stage"},"lead_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"},"preferred_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Channel"},"do_not_contact":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Do Not Contact"}},"type":"object","title":"CanonicalLeadUpdate","description":"Update a canonical lead."},"CaptureOutcome":{"type":"string","enum":["success","fixed","failed","escalated","skipped"],"title":"CaptureOutcome","description":"Result of a capture attempt in the self-improvement loop."},"ChannelStats":{"properties":{"channel":{"type":"string","title":"Channel"},"total_sent":{"type":"integer","title":"Total Sent"},"delivered":{"type":"integer","title":"Delivered"},"responded":{"type":"integer","title":"Responded"},"response_rate":{"type":"number","title":"Response Rate"}},"type":"object","required":["channel","total_sent","delivered","responded","response_rate"],"title":"ChannelStats"},"ChatMessage":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"session_id":{"type":"string","format":"uuid","title":"Session Id"},"role":{"$ref":"#/components/schemas/ChatRole"},"content":{"type":"string","title":"Content"},"sources":{"items":{"$ref":"#/components/schemas/ChatMessageSource"},"type":"array","title":"Sources","default":[]},"tokens_used":{"type":"integer","title":"Tokens Used","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","session_id","role","content","created_at"],"title":"ChatMessage","description":"A single message in a chat conversation."},"ChatMessageCreate":{"properties":{"content":{"type":"string","maxLength":2000,"minLength":1,"title":"Content","description":"Message content from user"}},"type":"object","required":["content"],"title":"ChatMessageCreate","description":"Request model for sending a message in a chat session."},"ChatMessageSource":{"properties":{"title":{"type":"string","title":"Title"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"snippet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snippet"}},"type":"object","required":["title"],"title":"ChatMessageSource","description":"Knowledge base source referenced in AI response."},"ChatRole":{"type":"string","enum":["user","assistant","system"],"title":"ChatRole","description":"Role of message sender in chat."},"ChatSession":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"session_token":{"type":"string","title":"Session Token"},"status":{"$ref":"#/components/schemas/ChatSessionStatus"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Messages","default":[]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","default":{}},"started_at":{"type":"string","format":"date-time","title":"Started At"},"last_activity_at":{"type":"string","format":"date-time","title":"Last Activity At"},"ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ended At"}},"type":"object","required":["id","user_id","session_token","status","started_at","last_activity_at"],"title":"ChatSession","description":"A chat session with full message history."},"ChatSessionCreate":{"properties":{"session_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Token","description":"Client-generated session token for anonymous users"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Additional context (user agent, page URL, etc.)"}},"type":"object","title":"ChatSessionCreate","description":"Request model for creating a new chat session."},"ChatSessionStatus":{"type":"string","enum":["active","ended"],"title":"ChatSessionStatus","description":"Status of a chat session."},"CheckoutSessionRequest":{"properties":{"tier":{"type":"string","enum":["pro_monthly","pro_yearly"],"title":"Tier","description":"Tier to purchase: pro_monthly, pro_yearly"},"success_url":{"type":"string","title":"Success Url","description":"URL to redirect after successful payment"},"cancel_url":{"type":"string","title":"Cancel Url","description":"URL to redirect after cancelled payment"}},"type":"object","required":["tier","success_url","cancel_url"],"title":"CheckoutSessionRequest","description":"Request to create a Stripe checkout session for agent payment"},"CheckoutSessionResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url","description":"Stripe checkout session URL"},"session_id":{"type":"string","title":"Session Id","description":"Stripe session ID"}},"type":"object","required":["checkout_url","session_id"],"title":"CheckoutSessionResponse","description":"Response with Stripe checkout session URL"},"ClientDesign":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"generation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Id"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","title","created_at"],"title":"ClientDesign","description":"Designer Pro design linked to a client."},"ClientListResponse":{"properties":{"clients":{"items":{"$ref":"#/components/schemas/ClientResponse"},"type":"array","title":"Clients"},"stats":{"$ref":"#/components/schemas/ClientStats"},"pagination":{"$ref":"#/components/schemas/ClientPagination"}},"type":"object","required":["clients","stats","pagination"],"title":"ClientListResponse","description":"Response from GET /clients endpoint."},"ClientPagination":{"properties":{"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["limit","offset","has_more"],"title":"ClientPagination","description":"Pagination info for client list."},"ClientProposal":{"properties":{"id":{"type":"string","title":"Id"},"status":{"$ref":"#/components/schemas/ProposalStatus"},"total_price":{"type":"number","title":"Total Price"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"can_edit":{"type":"boolean","title":"Can Edit","description":"True if status allows editing (pending or viewed)","default":true}},"type":"object","required":["id","status","total_price","created_at"],"title":"ClientProposal","description":"Proposal for a client's project."},"ClientResponse":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id"},"lead_id":{"type":"string","title":"Lead Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"phone":{"type":"string","title":"Phone"},"address":{"type":"string","title":"Address"},"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"image_urls":{"items":{"type":"string"},"type":"array","title":"Image Urls"},"generated_areas":{"items":{"type":"string"},"type":"array","title":"Generated Areas"},"generation_prompts":{"items":{"$ref":"#/components/schemas/GenerationPrompt"},"type":"array","title":"Generation Prompts"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"stage":{"$ref":"#/components/schemas/ClientStage"},"distribution_status":{"$ref":"#/components/schemas/DistributionStatus"},"is_new":{"type":"boolean","title":"Is New","description":"True if status = 'pending' (for badge count)","default":false},"viewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Viewed At"},"distributed_at":{"type":"string","format":"date-time","title":"Distributed At"},"designs":{"items":{"$ref":"#/components/schemas/ClientDesign"},"type":"array","title":"Designs"},"proposals":{"items":{"$ref":"#/components/schemas/ClientProposal"},"type":"array","title":"Proposals"},"design_count":{"type":"integer","title":"Design Count","default":0},"can_view_full":{"type":"boolean","title":"Can View Full","description":"True if partner can see unredacted info (Pro or already viewed)","default":false}},"type":"object","required":["distribution_id","lead_id","name","email","phone","address","city","state","stage","distribution_status","distributed_at"],"title":"ClientResponse","description":"Full client response combining lead and proposal data.\n\nContact info is redacted for free-tier partners unless already viewed."},"ClientStage":{"type":"string","enum":["1-new","2-design","3-proposal-sent","4-proposal-accepted"],"title":"ClientStage","description":"Pipeline opportunity stages."},"ClientStats":{"properties":{"total":{"type":"integer","title":"Total","description":"Total number of clients","default":0},"new":{"type":"integer","title":"New","description":"Count of stage 1-new (for badge display)","default":0},"design":{"type":"integer","title":"Design","description":"Count of stage 2-design","default":0},"proposal_sent":{"type":"integer","title":"Proposal Sent","description":"Count of stage 3-proposal-sent","default":0},"won":{"type":"integer","title":"Won","description":"Count of stage 4-proposal-accepted","default":0}},"type":"object","title":"ClientStats","description":"Client statistics for badge display."},"CompleteSignupResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"contractor_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contractor Id"},"is_new_partner":{"type":"boolean","title":"Is New Partner","default":false}},"type":"object","required":["success","message"],"title":"CompleteSignupResponse","description":"Response for completing partner signup after magic link verification."},"CompletionEvidence":{"properties":{"type":{"type":"string","title":"Type","description":"photo, document, note"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"},"uploaded_at":{"type":"string","format":"date-time","title":"Uploaded At"}},"type":"object","required":["type"],"title":"CompletionEvidence","description":"Evidence of milestone completion."},"ConfigureAutoReloadRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","description":"Enable or disable auto-reload"},"threshold":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Threshold","description":"Balance threshold to trigger reload (1-100)"},"amount":{"anyOf":[{"type":"integer","minimum":10.0},{"type":"null"}],"title":"Amount","description":"Amount of tokens to reload (minimum 10)"}},"type":"object","required":["enabled"],"title":"ConfigureAutoReloadRequest","description":"Request to configure auto-reload settings.\n\nRequirements:\n- FR-034: Enable auto-reload with threshold (1-100) and amount (min 10)","example":{"amount":100,"enabled":true,"threshold":20}},"ContactPreferencesResponse":{"properties":{"canonical_lead_id":{"type":"string","format":"uuid","title":"Canonical Lead Id"},"max_contacts_per_month":{"type":"integer","title":"Max Contacts Per Month","default":3},"preferred_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Time"},"opted_out":{"type":"boolean","title":"Opted Out","default":false},"opted_out_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Opted Out At"},"opt_out_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Opt Out Reason"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["canonical_lead_id"],"title":"ContactPreferencesResponse","description":"Lead contact preferences."},"ContactPreferencesUpdate":{"properties":{"max_contacts_per_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Contacts Per Month"},"preferred_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Time"},"opted_out":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Opted Out"},"opt_out_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Opt Out Reason"}},"type":"object","title":"ContactPreferencesUpdate","description":"Update contact preferences."},"ContentItem":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"title":{"type":"string","title":"Title","default":""},"body":{"type":"string","title":"Body","default":""},"platform":{"$ref":"#/components/schemas/Platform"},"content_type":{"$ref":"#/components/schemas/ContentType"},"status":{"$ref":"#/components/schemas/ContentStatus","default":"draft"},"audience":{"type":"string","title":"Audience","default":"homeowner"},"hook":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hook"},"hashtags":{"items":{"type":"string"},"type":"array","title":"Hashtags"},"call_to_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call To Action"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"image_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Prompt"},"scheduled_for":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled For"},"published_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published At"},"published_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published Url"},"campaign_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id"},"variant_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Of"},"adaptation_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Adaptation Version"},"platform_specific":{"additionalProperties":true,"type":"object","title":"Platform Specific"},"ai_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Model"},"generation_params":{"additionalProperties":true,"type":"object","title":"Generation Params"},"review_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Review Score"},"review_verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Verdict"},"review_feedback":{"additionalProperties":true,"type":"object","title":"Review Feedback"},"reviewed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewed At"},"reviewed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewed By"},"metrics":{"additionalProperties":{"type":"integer"},"type":"object","title":"Metrics"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["platform","content_type"],"title":"ContentItem","description":"A content item in the pipeline with full metadata (Supabase schema)."},"ContentListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ContentItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"ContentListResponse","description":"Response containing multiple content items."},"ContentPiece":{"properties":{"platform":{"$ref":"#/components/schemas/Platform"},"content_type":{"$ref":"#/components/schemas/ContentType"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"body":{"type":"string","title":"Body","default":""},"hashtags":{"items":{"type":"string"},"type":"array","title":"Hashtags"},"call_to_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call To Action"},"image_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Prompt"},"hook":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hook"},"scheduled_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Date"},"topic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic"},"platform_specific":{"additionalProperties":{"type":"string"},"type":"object","title":"Platform Specific"},"variant_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Of"}},"type":"object","required":["platform","content_type"],"title":"ContentPiece","description":"A generated piece of content (not yet in pipeline)."},"ContentResponse":{"properties":{"content":{"$ref":"#/components/schemas/ContentItem"}},"type":"object","required":["content"],"title":"ContentResponse","description":"Response containing a content item."},"ContentStatus":{"type":"string","enum":["ideation","draft","review","approved","scheduled","published","analyzing","archived"],"title":"ContentStatus","description":"Pipeline status for content items."},"ContentType":{"type":"string","enum":["social_post","post","reel_script","reel","blog_post","email","thread","pin","idea_pin","carousel","article","video_script","educational","listicle","problem_solution"],"title":"ContentType","description":"Types of content that can be generated."},"ContractorCreateRequest":{"properties":{"business_name":{"type":"string","maxLength":200,"minLength":2,"title":"Business Name"},"contact_name":{"type":"string","maxLength":100,"minLength":2,"title":"Contact Name"},"contact_email":{"type":"string","maxLength":255,"title":"Contact Email"},"contact_phone":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Contact Phone"},"business_license":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Business License"},"license_state":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"License State"},"years_in_business":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Years In Business"},"website_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Website Url"},"bio":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Bio"},"specializations":{"items":{"$ref":"#/components/schemas/Specialization"},"type":"array","title":"Specializations"}},"type":"object","required":["business_name","contact_name","contact_email"],"title":"ContractorCreateRequest","description":"Request to create a contractor profile (links to existing user)."},"ContractorInfo":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name","description":"Contact person name"},"company":{"type":"string","maxLength":200,"minLength":1,"title":"Company","description":"Business/company name"},"phone":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Phone","description":"Contact phone number"},"email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Email","description":"Contact email"}},"type":"object","required":["name","company"],"title":"ContractorInfo","description":"Contractor identity for proposal creation."},"ContractorPublicResponse":{"properties":{"id":{"type":"string","title":"Id"},"business_name":{"type":"string","title":"Business Name"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"profile_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Photo Url"},"cover_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Photo Url"},"specializations":{"items":{"type":"string"},"type":"array","title":"Specializations"},"verification_status":{"$ref":"#/components/schemas/ContractorVerificationStatus"},"yarda_rank":{"type":"integer","title":"Yarda Rank"},"completed_jobs_count":{"type":"integer","title":"Completed Jobs Count"},"years_in_business":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Years In Business"},"website_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website Url"}},"type":"object","required":["id","business_name","verification_status","yarda_rank","completed_jobs_count"],"title":"ContractorPublicResponse","description":"Public contractor profile (for homeowner browsing).\n\nContact info is NOT included - only revealed after bid acceptance."},"ContractorResponse":{"properties":{"id":{"type":"string","title":"Id"},"user_id":{"type":"string","title":"User Id"},"business_name":{"type":"string","title":"Business Name"},"contact_name":{"type":"string","title":"Contact Name"},"contact_email":{"type":"string","title":"Contact Email"},"contact_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact Phone"},"business_license":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business License"},"license_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License State"},"years_in_business":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Years In Business"},"website_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website Url"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"profile_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Photo Url"},"cover_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Photo Url"},"specializations":{"items":{"type":"string"},"type":"array","title":"Specializations"},"verification_status":{"$ref":"#/components/schemas/ContractorVerificationStatus"},"yarda_rank":{"type":"integer","title":"Yarda Rank"},"completed_jobs_count":{"type":"integer","title":"Completed Jobs Count"},"total_bids_count":{"type":"integer","title":"Total Bids Count","default":0},"accepted_bids_count":{"type":"integer","title":"Accepted Bids Count","default":0},"email_notifications_enabled":{"type":"boolean","title":"Email Notifications Enabled","default":true},"is_active":{"type":"boolean","title":"Is Active"},"service_areas":{"items":{"$ref":"#/components/schemas/ServiceAreaResponse"},"type":"array","title":"Service Areas"},"business_location":{"anyOf":[{"$ref":"#/components/schemas/BusinessLocationResponse"},{"type":"null"}]},"onboarding_completed":{"type":"boolean","title":"Onboarding Completed","default":false},"onboarding_completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Onboarding Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","user_id","business_name","contact_name","contact_email","verification_status","yarda_rank","completed_jobs_count","is_active","created_at","updated_at"],"title":"ContractorResponse","description":"Full contractor profile response (for contractor's own view)."},"ContractorSummary":{"properties":{"id":{"type":"string","title":"Id"},"business_name":{"type":"string","title":"Business Name"},"contact_email":{"type":"string","title":"Contact Email"},"verification_status":{"type":"string","title":"Verification Status"},"yarda_rank":{"type":"integer","title":"Yarda Rank"},"completed_jobs_count":{"type":"integer","title":"Completed Jobs Count"},"total_bids_count":{"type":"integer","title":"Total Bids Count"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","business_name","contact_email","verification_status","yarda_rank","completed_jobs_count","total_bids_count","is_active","created_at"],"title":"ContractorSummary","description":"Summary info for a contractor"},"ContractorUpdateRequest":{"properties":{"business_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":2},{"type":"null"}],"title":"Business Name"},"contact_name":{"anyOf":[{"type":"string","maxLength":100,"minLength":2},{"type":"null"}],"title":"Contact Name"},"contact_phone":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Contact Phone"},"contact_email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Contact Email"},"website_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Website Url"},"bio":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Bio"},"specializations":{"anyOf":[{"items":{"$ref":"#/components/schemas/Specialization"},"type":"array"},{"type":"null"}],"title":"Specializations"},"email_notifications_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Notifications Enabled"},"profile_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Photo Url"},"cover_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Photo Url"},"years_in_business":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Years In Business"},"business_license":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Business License"},"license_state":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"License State"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"ContractorUpdateRequest","description":"Request to update contractor profile."},"ContractorVerificationStatus":{"type":"string","enum":["unverified","pending","verified","suspended"],"title":"ContractorVerificationStatus","description":"Contractor verification status levels."},"CostSummaryResponse":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"},"total_images":{"type":"integer","title":"Total Images"},"total_calls":{"type":"integer","title":"Total Calls"},"by_date":{"additionalProperties":true,"type":"object","title":"By Date"},"by_model":{"additionalProperties":true,"type":"object","title":"By Model"}},"type":"object","required":["period_days","total_cost_usd","total_images","total_calls","by_date","by_model"],"title":"CostSummaryResponse","description":"Cost summary for a time period."},"CreateAPIKeyRequest":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","description":"Human-readable name for this API key","default":"Default"},"rate_limit":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Rate Limit","description":"Maximum requests per minute allowed for this API key","default":100}},"type":"object","title":"CreateAPIKeyRequest"},"CreateAPIKeyResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"key":{"type":"string","title":"Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"key_hint":{"type":"string","title":"Key Hint"},"rate_limit":{"type":"integer","title":"Rate Limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"message":{"type":"string","title":"Message","default":"Save this key securely - it will not be shown again"}},"type":"object","required":["id","name","key","key_prefix","key_hint","rate_limit","created_at"],"title":"CreateAPIKeyResponse"},"CreateAgentKeyResponse":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"name":{"type":"string","title":"Name"},"key":{"type":"string","title":"Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"key_hint":{"type":"string","title":"Key Hint"},"rate_limit":{"type":"integer","title":"Rate Limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","email","name","key","key_prefix","key_hint","rate_limit","created_at"],"title":"CreateAgentKeyResponse"},"CreateCheckoutSessionRequest":{"properties":{"package_id":{"type":"string","title":"Package Id","description":"Token package ID (Stripe product ID or legacy format)"},"stripe_price_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Price Id","description":"Stripe price ID (preferred)"}},"type":"object","required":["package_id"],"title":"CreateCheckoutSessionRequest","description":"Request to create Stripe checkout session.","example":{"package_id":"prod_TSJTQXgPdNLHev","stripe_price_id":"price_1SVyWBBNX8WkBQaWrtAiiNUX"}},"CreateCheckoutSessionResponse":{"properties":{"session_id":{"type":"string","title":"Session Id","description":"Stripe checkout session ID"},"url":{"type":"string","title":"Url","description":"Checkout URL to redirect user"}},"type":"object","required":["session_id","url"],"title":"CreateCheckoutSessionResponse","description":"Response with Stripe checkout session URL.","example":{"session_id":"cs_test_1234567890abcdef","url":"https://checkout.stripe.com/pay/cs_test_1234567890abcdef"}},"CreateClientRequest":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","description":"Client's full name"},"email":{"type":"string","title":"Email","description":"Client's email address"},"phone":{"type":"string","maxLength":20,"minLength":10,"title":"Phone","description":"Client's phone number"},"address":{"type":"string","minLength":5,"title":"Address","description":"Full street address"},"city":{"type":"string","maxLength":100,"minLength":1,"title":"City","description":"City name"},"state":{"type":"string","maxLength":2,"minLength":2,"title":"State","description":"Two-letter state code (e.g., CA)"},"zip_code":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Zip Code","description":"ZIP code"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Notes about the project or client"},"stage":{"$ref":"#/components/schemas/ClientStage","description":"Initial pipeline stage","default":"1-new"}},"type":"object","required":["name","email","phone","address","city","state"],"title":"CreateClientRequest","description":"Request to manually create a client."},"CreateDirectRequest":{"properties":{"pro_mode_generation_ids":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Pro Mode Generation Ids","description":"At least one Pro Mode design is required"},"message":{"type":"string","minLength":10,"title":"Message","description":"Intro message to homeowner"},"address":{"type":"string","minLength":1,"title":"Address","description":"Property street address"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City","description":"City name"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State","description":"State code"},"zip_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip Code","description":"ZIP code"},"customer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Customer Name","description":"Customer name"},"customer_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Customer Email","description":"Customer email"},"customer_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Customer Phone","description":"Customer phone"},"distribution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Distribution Id","description":"Existing lead distribution ID (auto-created if not provided)"},"price_range_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Range Min","description":"Minimum price estimate"},"price_range_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Range Max","description":"Maximum price estimate"},"line_items":{"anyOf":[{"items":{"$ref":"#/components/schemas/LineItemCreate"},"type":"array"},{"type":"null"}],"title":"Line Items","description":"Itemized pricing breakdown"},"design_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Design Notes","description":"Notes about the design"},"estimated_duration_days":{"anyOf":[{"type":"integer","maximum":365.0,"minimum":1.0},{"type":"null"}],"title":"Estimated Duration Days","description":"Estimated project duration"}},"type":"object","required":["pro_mode_generation_ids","message","address"],"title":"CreateDirectRequest","description":"Request model for creating a proposal directly (auto-creates lead if needed)."},"CreateFromLeadRequest":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id","description":"Lead distribution ID to convert"},"pro_mode_generation_ids":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Pro Mode Generation Ids","description":"At least one Pro Mode design is required"},"message":{"type":"string","minLength":10,"title":"Message","description":"Intro message to homeowner"},"price_range_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Range Min","description":"Minimum price estimate"},"price_range_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Range Max","description":"Maximum price estimate"},"line_items":{"anyOf":[{"items":{"$ref":"#/components/schemas/LineItemCreate"},"type":"array"},{"type":"null"}],"title":"Line Items","description":"Itemized pricing breakdown"},"design_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Design Notes","description":"Notes about the design"},"estimated_duration_days":{"anyOf":[{"type":"integer","maximum":365.0,"minimum":1.0},{"type":"null"}],"title":"Estimated Duration Days","description":"Estimated project duration"}},"type":"object","required":["distribution_id","pro_mode_generation_ids","message"],"title":"CreateFromLeadRequest","description":"Request model for creating a proposal from a lead distribution."},"CreateFromLeadResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"contractor_id":{"type":"string","title":"Contractor Id"},"status":{"type":"string","title":"Status"},"lead_distribution_id":{"type":"string","title":"Lead Distribution Id"},"created_at":{"type":"string","title":"Created At"},"message":{"type":"string","title":"Message"}},"type":"object","required":["id","project_id","contractor_id","status","lead_distribution_id","created_at","message"],"title":"CreateFromLeadResponse","description":"Response model for lead conversion."},"CreateGenerationRequest":{"properties":{"address":{"type":"string","maxLength":200,"minLength":5,"title":"Address","description":"Full property address for imagery retrieval"},"areas":{"items":{"$ref":"#/components/schemas/AreaRequest"},"type":"array","maxItems":5,"minItems":1,"title":"Areas","description":"List of yard areas to generate (1-5 areas)"},"place_id":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Place Id","description":"Google Place ID for property pass lookup (optional, will be geocoded if not provided)"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"Pre-resolved coordinates {lat, lng} from frontend Google Places autocomplete. Skips Geocoding API when provided."},"generation_mode":{"$ref":"#/components/schemas/GenerationMode","description":"Generation strategy to use (single_call or two_stage)","default":"single_call"}},"type":"object","required":["address","areas"],"title":"CreateGenerationRequest","description":"Request model for creating multi-area generation\n\nSupports both single-area and multi-area generation requests.\nPayment method is determined by backend based on user's subscription/token/trial status."},"CreateLeadRequest":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"phone":{"type":"string","title":"Phone"},"address":{"type":"string","title":"Address"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"generated_areas":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Generated Areas"},"image_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Image Urls"}},"type":"object","required":["name","email","phone","address"],"title":"CreateLeadRequest","description":"Request body for creating a new lead."},"CreateProposalRequest":{"properties":{"design_id":{"type":"string","title":"Design Id","description":"ID of the completed agent design"},"contractor_info":{"$ref":"#/components/schemas/ContractorInfo","description":"Contractor identity"},"markup_percentage":{"anyOf":[{"type":"number","maximum":200.0,"minimum":0.0},{"type":"null"}],"title":"Markup Percentage","description":"Markup percentage on material costs (0-200)"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes","description":"Additional notes about the proposal"}},"type":"object","required":["design_id","contractor_info"],"title":"CreateProposalRequest","description":"Request to create a proposal from an agent design."},"CreateProposalResponse":{"properties":{"proposal_id":{"type":"string","title":"Proposal Id"},"proposal_url":{"type":"string","title":"Proposal Url"},"contractor":{"additionalProperties":true,"type":"object","title":"Contractor"},"address":{"type":"string","title":"Address"},"total_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost"},"line_items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Line Items"},"design_images":{"items":{"type":"string"},"type":"array","title":"Design Images"},"satellite_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Url"},"status":{"type":"string","title":"Status"}},"type":"object","required":["proposal_id","proposal_url","contractor","address","status"],"title":"CreateProposalResponse","description":"Response from proposal creation."},"CreateSubscriptionRequest":{"properties":{"plan_id":{"type":"string","title":"Plan Id","description":"Plan to subscribe to (e.g., 'monthly_pro', 'pro_plus')"},"success_url":{"type":"string","title":"Success Url","description":"URL to redirect on successful subscription"},"cancel_url":{"type":"string","title":"Cancel Url","description":"URL to redirect if user cancels"},"utm":{"anyOf":[{"$ref":"#/components/schemas/UTMParams"},{"type":"null"}],"description":"UTM parameters for attribution tracking (YAR-123)"},"promo_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Code","description":"Coupon code to auto-apply (e.g., 'BETA_FLEET_1MO')"}},"type":"object","required":["plan_id","success_url","cancel_url"],"title":"CreateSubscriptionRequest","description":"Request to create a new subscription checkout session.\n\nUsed when user initiates subscription purchase."},"CreateSubscriptionResponse":{"properties":{"session_id":{"type":"string","title":"Session Id","description":"Stripe Checkout Session ID"},"url":{"type":"string","title":"Url","description":"Stripe Checkout URL to redirect user"}},"type":"object","required":["session_id","url"],"title":"CreateSubscriptionResponse","description":"Response after creating subscription checkout session.\n\nContains Stripe session ID and redirect URL."},"CreditType":{"type":"string","enum":["pro_quota","trial","token","holiday"],"title":"CreditType"},"CriteriaScores":{"properties":{"backWallVisibility":{"type":"integer","title":"Backwallvisibility"},"backyardCoverage":{"type":"integer","title":"Backyardcoverage"},"propertyCentering":{"type":"integer","title":"Propertycentering"},"obstructionFree":{"type":"integer","title":"Obstructionfree"},"viewingAngle":{"type":"integer","title":"Viewingangle"}},"type":"object","required":["backWallVisibility","backyardCoverage","propertyCentering","obstructionFree","viewingAngle"],"title":"CriteriaScores","description":"Individual quality criteria scores"},"CustomerPortalRequest":{"properties":{"return_url":{"type":"string","maxLength":2000,"minLength":1,"title":"Return Url","description":"URL to return to after visiting the customer portal"}},"type":"object","required":["return_url"],"title":"CustomerPortalRequest","description":"Request to get Stripe customer portal URL"},"CustomerPortalResponse":{"properties":{"url":{"type":"string","title":"Url","description":"Stripe Customer Portal URL"}},"type":"object","required":["url"],"title":"CustomerPortalResponse","description":"Response with Stripe Customer Portal URL.\n\nCustomer portal allows users to manage their subscription, payment methods, etc."},"DXFExportRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id"},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description"},"include_dimensions":{"type":"boolean","title":"Include Dimensions","default":true},"include_labels":{"type":"boolean","title":"Include Labels","default":true}},"type":"object","required":["generation_id"],"title":"DXFExportRequest","description":"Request for DXF export."},"DailyActivity":{"properties":{"date":{"type":"string","title":"Date"},"sent":{"type":"integer","title":"Sent"},"responded":{"type":"integer","title":"Responded"}},"type":"object","required":["date","sent","responded"],"title":"DailyActivity"},"DailyFunnelRow":{"properties":{"date":{"type":"string","title":"Date"},"visits":{"type":"integer","title":"Visits","default":0},"leads":{"type":"integer","title":"Leads","default":0},"signups":{"type":"integer","title":"Signups","default":0},"trial_starts":{"type":"integer","title":"Trial Starts","default":0},"payments":{"type":"integer","title":"Payments","default":0}},"type":"object","required":["date"],"title":"DailyFunnelRow","description":"One day's funnel counts."},"DailyFunnelSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign"},"daily":{"items":{"$ref":"#/components/schemas/DailyFunnelRow"},"type":"array","title":"Daily"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","daily","generated_at"],"title":"DailyFunnelSummary","description":"Daily funnel snapshots for trend analysis."},"DailyVolume":{"properties":{"date":{"type":"string","title":"Date"},"call_type":{"type":"string","title":"Call Type"},"call_count":{"type":"integer","title":"Call Count"}},"type":"object","required":["date","call_type","call_count"],"title":"DailyVolume"},"Day3EmailResponse":{"properties":{"eligible":{"type":"integer","title":"Eligible"},"sent":{"type":"integer","title":"Sent"},"failed":{"type":"integer","title":"Failed"},"message":{"type":"string","title":"Message"}},"type":"object","required":["eligible","sent","failed","message"],"title":"Day3EmailResponse","description":"Response from Day 3 email batch job."},"DedupBatchRequest":{"properties":{"limit":{"type":"integer","title":"Limit","default":200}},"type":"object","title":"DedupBatchRequest","description":"Trigger dedup batch processing."},"DesignAnalysisElement":{"properties":{"name":{"type":"string","title":"Name","description":"Element name (e.g., Pool, Lawn)"},"material":{"type":"string","title":"Material","description":"Material description (e.g., Bermuda Grass)","default":""},"widthFt":{"type":"number","title":"Widthft","description":"Width in feet","default":0},"depthFt":{"type":"number","title":"Depthft","description":"Depth/length in feet","default":0},"areaSqft":{"type":"number","title":"Areasqft","description":"Area in square feet","default":0},"icon":{"type":"string","title":"Icon","description":"Icon identifier for frontend","default":"default"}},"type":"object","required":["name"],"title":"DesignAnalysisElement","description":"A single design element with dimensions."},"DesignConfigurationRequest":{"properties":{"mode":{"$ref":"#/components/schemas/DesignMode"},"style_selections":{"items":{"type":"string"},"type":"array","title":"Style Selections"},"feature_selections":{"items":{"type":"string"},"type":"array","title":"Feature Selections"},"custom_instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Instructions"},"precision_settings":{"anyOf":[{"$ref":"#/components/schemas/PrecisionSettings"},{"type":"null"}]}},"type":"object","required":["mode"],"title":"DesignConfigurationRequest","description":"Request to set design configuration"},"DesignConfigurationResponse":{"properties":{"session_id":{"type":"string","format":"uuid","title":"Session Id"},"configuration":{"$ref":"#/components/schemas/DesignConfigurationRequest"},"ready_to_generate":{"type":"boolean","title":"Ready To Generate"}},"type":"object","required":["session_id","configuration","ready_to_generate"],"title":"DesignConfigurationResponse","description":"Response after setting configuration"},"DesignMode":{"type":"string","enum":["quick","studio"],"title":"DesignMode","description":"Design mode selection"},"DesignPreferences":{"properties":{"features":{"anyOf":[{"items":{"$ref":"#/components/schemas/FeatureType"},"type":"array"},{"type":"null"}],"title":"Features","description":"Optional features to include: pool, fire_pit, outdoor_kitchen, pergola, retaining_wall, vegetable_garden, playground"},"budget_tier":{"anyOf":[{"$ref":"#/components/schemas/BudgetTier"},{"type":"null"}],"description":"Budget tier: budget, mid_range, premium"}},"type":"object","title":"DesignPreferences","description":"User preferences for design generation"},"DesignPreviewResponse":{"properties":{"design_id":{"type":"string","title":"Design Id"},"status":{"type":"string","title":"Status"},"address":{"type":"string","title":"Address"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"satellite_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Url"},"render_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Render Url"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["design_id","status","address"],"title":"DesignPreviewResponse","description":"Public design preview data for the /d/[designId] page."},"DesignRender":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the render image"},"view":{"$ref":"#/components/schemas/RenderView","description":"View perspective: aerial, front, back, side"},"area":{"$ref":"#/components/schemas/RenderArea","description":"Area rendered: full, front_yard, backyard, side_yard"}},"type":"object","required":["url","view","area"],"title":"DesignRender","description":"A design render image"},"DesignStatus":{"type":"string","enum":["pending","processing","completed","failed"],"title":"DesignStatus","description":"Status of a design generation"},"DesignSummary":{"properties":{"id":{"type":"string","title":"Id","description":"Generation UUID"},"result_url":{"type":"string","title":"Result Url","description":"Vercel Blob URL for the design image"},"generation_type":{"type":"string","enum":["pro_2d_site_plan","pro_3d_render"],"title":"Generation Type","description":"Type of Pro Mode generation"},"pro_mode_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Pro Mode Metadata","description":"Style, features, layout description from Pro Mode"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","result_url","generation_type","created_at"],"title":"DesignSummary","description":"Summary of a Pro Mode design attached to a proposal.\n\nPopulated from the generations table when fetching proposals."},"DesignToCADRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded rendered design image"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"},"cad_style":{"type":"string","title":"Cad Style","description":"CAD style: '2D' for flat top-down or 'Oblique' for 3D axonometric","default":"2D"},"satellite_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Base64","description":"Optional: Base64-encoded satellite image - for CAD 2D, generates fresh from satellite instead of converting"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style","description":"Design style for direct generation from satellite"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features","description":"Features for direct generation from satellite"},"street_edge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Edge","description":"Street edge for direct generation (TOP/BOTTOM/LEFT/RIGHT)"},"layout_description":{"anyOf":[{"$ref":"#/components/schemas/LayoutDescriptionModel"},{"type":"null"}],"description":"Original layout description - ensures features, dimensions, and positions match during conversion"}},"type":"object","required":["image_base64"],"title":"DesignToCADRequest","description":"Request to convert a rendered landscape design to professional CAD drawing"},"DesignToCADResponse":{"properties":{"cadBase64":{"type":"string","title":"Cadbase64","description":"Base64-encoded CAD drawing"}},"type":"object","required":["cadBase64"],"title":"DesignToCADResponse","description":"Response with professional CAD-style drawing"},"DesignsByOriginDay":{"properties":{"date":{"type":"string","title":"Date"},"agent":{"type":"integer","title":"Agent"},"web":{"type":"integer","title":"Web"}},"type":"object","required":["date","agent","web"],"title":"DesignsByOriginDay"},"DetectAllFeaturePositionsRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded generated design image"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"List of feature names to detect (e.g., ['Pool', 'Patio', 'Fire Pit'])"},"mime_type":{"type":"string","title":"Mime Type","description":"Image MIME type","default":"image/png"}},"type":"object","required":["image_base64","features"],"title":"DetectAllFeaturePositionsRequest","description":"Request to detect positions of ALL features in a generated image"},"DetectAllFeaturePositionsResponse":{"properties":{"features":{"items":{"$ref":"#/components/schemas/FeaturePositionItem"},"type":"array","title":"Features","description":"List of feature positions"}},"type":"object","required":["features"],"title":"DetectAllFeaturePositionsResponse","description":"Response with detected positions for ALL features"},"DetectBoundaryPolygonRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Property address"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"Property coordinates {lat, lng}"},"satellite_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Base64","description":"Pre-fetched satellite image as base64 (skips fetch if provided)"}},"type":"object","required":["address"],"title":"DetectBoundaryPolygonRequest","description":"Request to detect property boundary polygon vertices from satellite image."},"DetectFeaturePositionsRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded generated design image"},"key_feature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Feature","description":"Name of main feature to detect (e.g., 'pool', 'pergola')"},"mime_type":{"type":"string","title":"Mime Type","description":"Image MIME type","default":"image/png"}},"type":"object","required":["image_base64"],"title":"DetectFeaturePositionsRequest","description":"Request to detect feature positions in a generated image"},"DetectFeaturePositionsResponse":{"properties":{"frontYard":{"$ref":"#/components/schemas/FeaturePosition","description":"Position of front yard area"},"backyard":{"$ref":"#/components/schemas/FeaturePosition","description":"Position of backyard area"},"keyFeature":{"anyOf":[{"$ref":"#/components/schemas/FeaturePosition"},{"type":"null"}],"description":"Position of key feature"}},"type":"object","required":["frontYard","backyard"],"title":"DetectFeaturePositionsResponse","description":"Response with detected feature positions for viewpoint dots"},"DetectFootprintRequest":{"properties":{"generation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Id","description":"UUID of a saved Pro Mode generation (satellite image fetched server-side)"},"satellite_image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Base64","description":"Base64-encoded satellite image (JPEG/PNG)"},"satellite_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Url","description":"Public URL of the satellite image (used when base64 not provided)"},"address":{"type":"string","title":"Address","description":"Property address (aids disambiguation)","default":""},"property_boundary":{"anyOf":[{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},{"type":"null"}],"title":"Property Boundary","description":"Optional property boundary polygon: [[x, z], ...] in meters relative to center"}},"type":"object","title":"DetectFootprintRequest","description":"Request to detect the building footprint from satellite imagery."},"DetectFootprintResponse":{"properties":{"polygon":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Polygon","description":"Building footprint vertices: [[x, z], ...] in meters relative to property center"},"confidence":{"type":"number","title":"Confidence","description":"Detection confidence 0-1"},"building_type":{"type":"string","title":"Building Type","description":"residential | commercial | mixed"},"estimatedAreaM2":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimatedaream2"},"floorsVisible":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Floorsvisible"},"reasoning":{"type":"string","title":"Reasoning","default":""}},"type":"object","required":["polygon","confidence","building_type"],"title":"DetectFootprintResponse","description":"Response with detected building footprint polygon."},"DetectionConfidence":{"type":"string","enum":["high","medium","low"],"title":"DetectionConfidence","description":"Confidence level of property detection/classification."},"DimensionDataResponse":{"properties":{"has_dimensions":{"type":"boolean","title":"Has Dimensions","description":"Whether dimension data is available"},"lot_dimensions":{"anyOf":[{"$ref":"#/components/schemas/src__marketplace__models__partner_project__LotDimensions"},{"type":"null"}]},"house_footprint":{"anyOf":[{"$ref":"#/components/schemas/HouseFootprint"},{"type":"null"}]},"features":{"items":{"$ref":"#/components/schemas/FeatureDimension"},"type":"array","title":"Features"},"property_boundary":{"anyOf":[{"$ref":"#/components/schemas/PropertyBoundary"},{"type":"null"}]}},"type":"object","required":["has_dimensions"],"title":"DimensionDataResponse","description":"Parsed dimension data for overlay rendering.\n\nExtracted from site_analysis.dimensions in the generation record."},"DiscoverRequest":{"properties":{"location":{"type":"string","title":"Location"},"keyword":{"type":"string","title":"Keyword","default":"landscaping"},"radius_miles":{"type":"integer","title":"Radius Miles","default":25},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"}},"type":"object","required":["location"],"title":"DiscoverRequest","description":"Trigger a discovery search."},"DiscoveryBatchResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"location":{"type":"string","title":"Location"},"keyword":{"type":"string","title":"Keyword"},"radius_miles":{"type":"integer","title":"Radius Miles"},"source":{"type":"string","title":"Source"},"total_found":{"type":"integer","title":"Total Found","default":0},"new_leads":{"type":"integer","title":"New Leads","default":0},"duplicates_skipped":{"type":"integer","title":"Duplicates Skipped","default":0},"status":{"type":"string","title":"Status","default":"completed"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","location","keyword","radius_miles","source"],"title":"DiscoveryBatchResponse","description":"Discovery batch run summary."},"DistributionStatus":{"type":"string","enum":["pending","viewed","accepted","rejected","expired"],"title":"DistributionStatus","description":"Lead distribution status."},"DrivewayConfig":{"type":"string","enum":["center","side","circular","shared","rear","not_visible"],"title":"DrivewayConfig","description":"Driveway position/style relative to house."},"DroneUploadResponse":{"properties":{"url":{"type":"string","title":"Url"},"width":{"type":"integer","title":"Width"},"height":{"type":"integer","title":"Height"},"size_bytes":{"type":"integer","title":"Size Bytes"}},"type":"object","required":["url","width","height","size_bytes"],"title":"DroneUploadResponse","description":"Response from drone photo upload."},"EffortSize":{"type":"string","enum":["xs","s","m","l","xl"],"title":"EffortSize","description":"T-shirt sizing for effort estimation."},"EnhanceImageRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded satellite image"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"}},"type":"object","required":["image_base64"],"title":"EnhanceImageRequest","description":"Request to enhance satellite image to CAD style"},"EnhanceImageResponse":{"properties":{"enhancedBase64":{"type":"string","title":"Enhancedbase64"}},"type":"object","required":["enhancedBase64"],"title":"EnhanceImageResponse","description":"Response with enhanced CAD-style image"},"EnrichBatchRequest":{"properties":{"limit":{"type":"integer","title":"Limit","default":50},"lead_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"}},"type":"object","title":"EnrichBatchRequest","description":"Batch enrich leads that have websites but no social handles."},"ErrorRate":{"properties":{"call_type":{"type":"string","title":"Call Type"},"total_calls":{"type":"integer","title":"Total Calls"},"error_count":{"type":"integer","title":"Error Count"},"error_rate_pct":{"type":"number","title":"Error Rate Pct"}},"type":"object","required":["call_type","total_calls","error_count","error_rate_pct"],"title":"ErrorRate"},"ErrorRateSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"rates":{"items":{"$ref":"#/components/schemas/ErrorRate"},"type":"array","title":"Rates"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","rates","generated_at"],"title":"ErrorRateSummary"},"EscrowPaymentResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"milestone_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Milestone Id"},"proposal_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Proposal Id"},"homeowner_user_id":{"type":"string","format":"uuid","title":"Homeowner User Id"},"contractor_user_id":{"type":"string","format":"uuid","title":"Contractor User Id"},"stripe_payment_intent_id":{"type":"string","title":"Stripe Payment Intent Id"},"stripe_transfer_group":{"type":"string","title":"Stripe Transfer Group"},"stripe_charge_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Charge Id"},"stripe_transfer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Transfer Id"},"amount_cents":{"type":"integer","title":"Amount Cents"},"platform_fee_cents":{"type":"integer","title":"Platform Fee Cents"},"contractor_payout_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Contractor Payout Cents"},"status":{"$ref":"#/components/schemas/EscrowPaymentStatus"},"captured_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Captured At"},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At"},"refunded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Refunded At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","project_id","milestone_id","proposal_id","homeowner_user_id","contractor_user_id","stripe_payment_intent_id","stripe_transfer_group","stripe_charge_id","stripe_transfer_id","amount_cents","platform_fee_cents","contractor_payout_cents","status","captured_at","released_at","refunded_at","created_at","updated_at"],"title":"EscrowPaymentResponse","description":"Full escrow payment response."},"EscrowPaymentStatus":{"type":"string","enum":["held","released","refunded","partial_release","disputed"],"title":"EscrowPaymentStatus","description":"Escrow payment status."},"EstimateCreateRequest":{"properties":{"proposal_id":{"type":"string","format":"uuid","title":"Proposal Id","description":"The proposal this estimate is for"},"labor_items":{"items":{"$ref":"#/components/schemas/LaborItem-Input"},"type":"array","title":"Labor Items"},"material_items":{"items":{"$ref":"#/components/schemas/MaterialItem-Input"},"type":"array","title":"Material Items"},"markup_percentage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"}],"title":"Markup Percentage","description":"Markup percentage (0-100)","default":"0"},"tax_percentage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"}],"title":"Tax Percentage","description":"Tax percentage (0-100) applied to subtotal + markup","default":"0"},"waste_factor_percentage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"}],"title":"Waste Factor Percentage","description":"Waste factor percentage (0-100) for materials","default":"0"},"contractor_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Contractor Notes"},"validity_days":{"type":"integer","maximum":365.0,"minimum":1.0,"title":"Validity Days","default":30}},"type":"object","required":["proposal_id"],"title":"EstimateCreateRequest","description":"Request body for creating a new estimate."},"EstimateListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"proposal_id":{"type":"string","format":"uuid","title":"Proposal Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"version":{"type":"integer","title":"Version"},"total_estimate_cents":{"type":"integer","title":"Total Estimate Cents"},"total_formatted":{"type":"string","title":"Total Formatted"},"status":{"$ref":"#/components/schemas/EstimateStatus"},"item_count":{"type":"integer","title":"Item Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"submitted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Submitted At"}},"type":"object","required":["id","proposal_id","project_id","version","total_estimate_cents","total_formatted","status","item_count","created_at"],"title":"EstimateListItem","description":"Simplified estimate for list views."},"EstimateMaterialsRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded generated design image"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features","description":"List of known features in the design"},"property_dimensions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Property Dimensions","description":"Property measurements (lot_width, lot_depth in feet)"},"mime_type":{"type":"string","title":"Mime Type","description":"Image MIME type","default":"image/png"}},"type":"object","required":["image_base64"],"title":"EstimateMaterialsRequest","description":"Request to estimate materials from a landscape design image"},"EstimateMaterialsResponse":{"properties":{"materials":{"items":{"$ref":"#/components/schemas/src__api__endpoints__pro_mode__MaterialItem"},"type":"array","title":"Materials","description":"List of materials with pricing"},"summary":{"$ref":"#/components/schemas/MaterialSummary","description":"Cost summary"},"analysisNotes":{"type":"string","title":"Analysisnotes","description":"AI analysis notes"}},"type":"object","required":["materials","summary","analysisNotes"],"title":"EstimateMaterialsResponse","description":"Response with material estimates and pricing"},"EstimateRequest":{"properties":{"project_id":{"type":"string","title":"Project Id"},"generation_id":{"type":"string","title":"Generation Id"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"}},"type":"object","required":["project_id","generation_id","latitude","longitude"],"title":"EstimateRequest","description":"Request to generate property estimate."},"EstimateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"proposal_id":{"type":"string","format":"uuid","title":"Proposal Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"contractor_id":{"type":"string","format":"uuid","title":"Contractor Id"},"version":{"type":"integer","title":"Version","default":1},"labor_items":{"items":{"$ref":"#/components/schemas/LaborItem-Output"},"type":"array","title":"Labor Items"},"material_items":{"items":{"$ref":"#/components/schemas/src__marketplace__models__estimate__MaterialItem-Output"},"type":"array","title":"Material Items"},"total_labor_cents":{"type":"integer","title":"Total Labor Cents"},"total_material_cents":{"type":"integer","title":"Total Material Cents"},"markup_percentage":{"type":"string","title":"Markup Percentage"},"markup_amount_cents":{"type":"integer","title":"Markup Amount Cents"},"tax_percentage":{"type":"string","title":"Tax Percentage","default":"0"},"tax_amount_cents":{"type":"integer","title":"Tax Amount Cents","default":0},"waste_factor_percentage":{"type":"string","title":"Waste Factor Percentage","default":"0"},"waste_amount_cents":{"type":"integer","title":"Waste Amount Cents","default":0},"total_estimate_cents":{"type":"integer","title":"Total Estimate Cents"},"status":{"$ref":"#/components/schemas/EstimateStatus"},"contractor_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contractor Notes"},"validity_days":{"type":"integer","title":"Validity Days"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"submitted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Submitted At"},"responded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Responded At"}},"type":"object","required":["id","proposal_id","project_id","contractor_id","labor_items","material_items","total_labor_cents","total_material_cents","markup_percentage","markup_amount_cents","total_estimate_cents","status","validity_days","created_at","updated_at"],"title":"EstimateResponse","description":"Full estimate response with all details.","example":{"contractor_id":"123e4567-e89b-12d3-a456-426614174003","contractor_notes":"Price valid for 30 days","created_at":"2025-12-11T10:00:00Z","id":"123e4567-e89b-12d3-a456-426614174000","labor_items":[{"category":"Hardscape","description":"Paver patio installation","hourly_rate_cents":7500,"hours":24,"subtotal_cents":180000}],"markup_amount_cents":54000,"markup_percentage":15,"material_items":[{"name":"Travertine Pavers","quantity":400,"subtotal_cents":180000,"unit":"sqft","unit_price_cents":450}],"project_id":"123e4567-e89b-12d3-a456-426614174002","proposal_id":"123e4567-e89b-12d3-a456-426614174001","status":"submitted","submitted_at":"2025-12-11T12:00:00Z","total_estimate_cents":414000,"total_labor_cents":180000,"total_material_cents":180000,"updated_at":"2025-12-11T10:00:00Z","validity_days":30,"version":1}},"EstimateStatus":{"type":"string","enum":["draft","submitted","accepted","rejected","superseded"],"title":"EstimateStatus","description":"Status of a contractor estimate."},"EstimateUpdateRequest":{"properties":{"labor_items":{"anyOf":[{"items":{"$ref":"#/components/schemas/LaborItem-Input"},"type":"array"},{"type":"null"}],"title":"Labor Items"},"material_items":{"anyOf":[{"items":{"$ref":"#/components/schemas/MaterialItem-Input"},"type":"array"},{"type":"null"}],"title":"Material Items"},"markup_percentage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Markup Percentage"},"tax_percentage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Tax Percentage"},"waste_factor_percentage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Waste Factor Percentage"},"contractor_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Contractor Notes"},"validity_days":{"anyOf":[{"type":"integer","maximum":365.0,"minimum":1.0},{"type":"null"}],"title":"Validity Days"}},"type":"object","title":"EstimateUpdateRequest","description":"Request body for updating an existing draft estimate."},"FeatureDimension":{"properties":{"type":{"type":"string","title":"Type","description":"Feature type: pool, patio, deck, etc."},"label":{"type":"string","title":"Label","description":"Display label for the dimension marker"},"dimensions":{"$ref":"#/components/schemas/FeatureDimensionSize"},"position":{"$ref":"#/components/schemas/Position","description":"Relative position of feature center in the image"}},"type":"object","required":["type","label","dimensions","position"],"title":"FeatureDimension","description":"Dimension information for a specific landscape feature."},"FeatureDimensionSize":{"properties":{"width_ft":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Width Ft"},"length_ft":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Length Ft"},"radius_ft":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Radius Ft","description":"For circular features"},"area_sqft":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Area Sqft"}},"type":"object","title":"FeatureDimensionSize","description":"Dimensions for a landscape feature (flexible based on shape)."},"FeatureOption":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"icon":{"type":"string","title":"Icon"},"category":{"type":"string","title":"Category"},"estimated_cost":{"type":"number","title":"Estimated Cost"}},"type":"object","required":["id","name","icon","category","estimated_cost"],"title":"FeatureOption","description":"Available feature option"},"FeaturePosition":{"properties":{"x":{"type":"number","maximum":100.0,"minimum":0.0,"title":"X","description":"X position (0=left, 100=right)"},"y":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Y","description":"Y position (0=top, 100=bottom)"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"Detection confidence"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Feature name (for key_feature)"}},"type":"object","required":["x","y","confidence"],"title":"FeaturePosition","description":"Position of a feature in the image (as percentages)"},"FeaturePositionItem":{"properties":{"featureName":{"type":"string","title":"Featurename","description":"Name of the feature"},"xPercent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Xpercent","description":"X position (0=left, 100=right)"},"yPercent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Ypercent","description":"Y position (0=top, 100=bottom)"},"zone":{"type":"string","title":"Zone","description":"Zone: 'backyard' or 'front_yard'"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"Detection confidence"}},"type":"object","required":["featureName","xPercent","yPercent","zone","confidence"],"title":"FeaturePositionItem","description":"Position of a single feature"},"FeatureType":{"type":"string","enum":["pool","fire_pit","outdoor_kitchen","pergola","retaining_wall","vegetable_garden","playground"],"title":"FeatureType","description":"Optional features for design"},"FeedbackCreate":{"properties":{"message":{"type":"string","maxLength":5000,"minLength":1,"title":"Message","description":"Feedback message"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email","description":"User email (optional if logged in)"},"page_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Page Url","description":"Current page URL"}},"type":"object","required":["message"],"title":"FeedbackCreate","description":"Request model for creating feedback."},"FeedbackOptInResponse":{"properties":{"feedback_opt_in":{"type":"boolean","title":"Feedback Opt In","description":"Whether user has opted in to see the feedback button"}},"type":"object","required":["feedback_opt_in"],"title":"FeedbackOptInResponse","description":"Response with user's feedback opt-in status"},"FeedbackResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"message":{"type":"string","title":"Message"},"page_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page Url"},"status":{"type":"string","title":"Status"},"admin_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Admin Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"reviewed_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Reviewed By"}},"type":"object","required":["id","user_id","email","message","page_url","status","admin_notes","created_at","reviewed_at","reviewed_by"],"title":"FeedbackResponse","description":"Response model for feedback."},"FeedbackUpdate":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"Feedback status"},"admin_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Admin Notes","description":"Admin notes"}},"type":"object","title":"FeedbackUpdate","description":"Request model for updating feedback (admin only)."},"FencingType":{"type":"string","enum":["auto","cedar","wood_privacy","vinyl","chain_link","metal","wrought_iron","living_wall","hedge","none"],"title":"FencingType","description":"Fencing and border types."},"FloorplanRoomModel":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type"},"polygon":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Polygon"},"areaM2":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aream2"},"hasWindows":{"type":"boolean","title":"Haswindows","default":false}},"type":"object","required":["name","type","polygon"],"title":"FloorplanRoomModel","description":"A single room in the generated floor plan."},"FloorplanWallModel":{"properties":{"start":{"items":{"type":"number"},"type":"array","title":"Start"},"end":{"items":{"type":"number"},"type":"array","title":"End"}},"type":"object","required":["start","end"],"title":"FloorplanWallModel","description":"An interior wall segment."},"FreemiumActivateResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether activation succeeded"},"message":{"type":"string","title":"Message","description":"Status message"},"is_freemium":{"type":"boolean","title":"Is Freemium","description":"Whether now on freemium","default":false},"status":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Status","description":"Full freemium status after activation"}},"type":"object","required":["success","message"],"title":"FreemiumActivateResponse","description":"Response after activating freemium trial."},"FreemiumConversionRow":{"properties":{"week_start":{"type":"string","title":"Week Start"},"freemium_activations":{"type":"integer","title":"Freemium Activations","default":0},"paid_conversions":{"type":"integer","title":"Paid Conversions","default":0},"conversion_rate_pct":{"type":"number","title":"Conversion Rate Pct","default":0.0}},"type":"object","required":["week_start"],"title":"FreemiumConversionRow","description":"Weekly freemium activation vs paid conversion metrics."},"FreemiumConversionSummary":{"properties":{"period_weeks":{"type":"integer","title":"Period Weeks"},"total_freemium_activations":{"type":"integer","title":"Total Freemium Activations"},"total_paid_conversions":{"type":"integer","title":"Total Paid Conversions"},"overall_conversion_rate_pct":{"type":"number","title":"Overall Conversion Rate Pct"},"weekly":{"items":{"$ref":"#/components/schemas/FreemiumConversionRow"},"type":"array","title":"Weekly"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_weeks","total_freemium_activations","total_paid_conversions","overall_conversion_rate_pct","weekly","generated_at"],"title":"FreemiumConversionSummary","description":"Weekly freemium→paid conversion rate for GTM reporting."},"FreemiumStatusResponse":{"properties":{"is_freemium_user":{"type":"boolean","title":"Is Freemium User","description":"Whether user is on freemium trial"},"session_designs_remaining":{"type":"integer","title":"Session Designs Remaining","description":"Designs left in session (0-3)"},"session_designs_used":{"type":"integer","title":"Session Designs Used","description":"Designs used in session"},"session_designs_limit":{"type":"integer","title":"Session Designs Limit","description":"Max designs per session","default":3},"locked_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Locked Address","description":"Address locked for this session"},"base_design_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Design Id","description":"UUID of first design in session"},"is_session_exhausted":{"type":"boolean","title":"Is Session Exhausted","description":"Whether session is exhausted"},"can_activate":{"type":"boolean","title":"Can Activate","description":"Whether user can activate freemium"},"is_freemium":{"type":"boolean","title":"Is Freemium","description":"Whether user is on freemium trial (alias)"},"freemium_trial_used":{"type":"boolean","title":"Freemium Trial Used","description":"Whether freemium was ever used"},"generations_remaining":{"type":"integer","title":"Generations Remaining","description":"Remaining free generations (alias)"},"generations_used":{"type":"integer","title":"Generations Used","description":"Generations used (alias)"},"is_exhausted":{"type":"boolean","title":"Is Exhausted","description":"Whether exhausted (alias)"},"allowed_styles":{"items":{"type":"string"},"type":"array","title":"Allowed Styles","description":"Styles available in free trial"},"allowed_features":{"items":{"type":"string"},"type":"array","title":"Allowed Features","description":"Features available in free trial"},"locked_styles":{"items":{"type":"string"},"type":"array","title":"Locked Styles","description":"Styles locked in free trial"},"locked_features":{"items":{"type":"string"},"type":"array","title":"Locked Features","description":"Features locked in free trial"},"options_per_style":{"type":"integer","title":"Options Per Style","description":"Max options per style"}},"type":"object","required":["is_freemium_user","session_designs_remaining","session_designs_used","is_session_exhausted","can_activate","is_freemium","freemium_trial_used","generations_remaining","generations_used","is_exhausted","allowed_styles","allowed_features","locked_styles","locked_features","options_per_style"],"title":"FreemiumStatusResponse","description":"Full freemium status response with YAR-210 session tracking.\n\nSession-based fields:\n- is_freemium_user: Whether user is on freemium trial\n- session_designs_remaining: Designs left in session (0-3)\n- session_designs_used: Designs used in session\n- session_designs_limit: Max designs per session (3)\n- locked_address: Address locked for this session (or null)\n- base_design_id: UUID of first design (or null)\n- is_session_exhausted: Whether session is exhausted"},"FullReviewRequest":{"properties":{"content":{"additionalProperties":true,"type":"object","title":"Content","description":"Content dict with title, body, hook, etc."},"platform":{"type":"string","title":"Platform","description":"Target platform"},"audience":{"type":"string","title":"Audience","description":"Target audience","default":"homeowner"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url","description":"Optional URL to generated image"}},"type":"object","required":["content","platform"],"title":"FullReviewRequest","description":"Request for full content and image review."},"FullReviewResponse":{"properties":{"text_review":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Text Review"},"image_review":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Image Review"},"combined_score":{"type":"number","title":"Combined Score"},"combined_verdict":{"type":"string","title":"Combined Verdict"}},"type":"object","required":["text_review","image_review","combined_score","combined_verdict"],"title":"FullReviewResponse","description":"Response from full content and image review."},"FunnelEventRequest":{"properties":{"event_type":{"type":"string","enum":["visit","lead","signup","trial_start","payment","generation_limit_hit","upgrade_modal_shown","upgrade_cta_clicked","payment_started"],"title":"Event Type"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["event_type"],"title":"FunnelEventRequest","description":"Request body for logging a funnel event."},"FunnelSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign"},"stages":{"items":{"$ref":"#/components/schemas/src__api__endpoints__analytics__FunnelStage"},"type":"array","title":"Stages"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","stages","generated_at"],"title":"FunnelSummary","description":"Trial conversion funnel."},"G3PCreditPack":{"properties":{"pack_id":{"type":"string","title":"Pack Id","description":"Unique pack identifier (e.g., 'starter_10')"},"name":{"type":"string","title":"Name","description":"Human-readable pack name"},"credits":{"type":"integer","title":"Credits","description":"Number of G3P credits in pack"},"price_usd":{"type":"string","title":"Price Usd","description":"Price in USD"},"price_cents":{"type":"integer","title":"Price Cents","description":"Price in cents"},"price_per_credit":{"type":"string","title":"Price Per Credit","description":"Price per G3P credit in USD"},"savings_percent":{"type":"integer","title":"Savings Percent","description":"Savings compared to base price","default":0},"stripe_price_id":{"type":"string","title":"Stripe Price Id","description":"Stripe Price ID for checkout","default":""},"is_popular":{"type":"boolean","title":"Is Popular","description":"Whether to highlight as popular","default":false}},"type":"object","required":["pack_id","name","credits","price_usd","price_cents","price_per_credit"],"title":"G3PCreditPack","description":"G3P credit pack definition for purchasing additional Gemini 3 Pro generations.\n\nEach G3P credit = 1 Pro Mode generation using Gemini 3 Pro (~$0.14 cost).\nNamed \"G3P\" to distinguish from regular homeowner credits."},"G3PCreditPurchaseRequest":{"properties":{"pack_id":{"type":"string","title":"Pack Id","description":"G3P credit pack to purchase"},"success_url":{"type":"string","title":"Success Url","description":"URL to redirect on success"},"cancel_url":{"type":"string","title":"Cancel Url","description":"URL to redirect on cancel"}},"type":"object","required":["pack_id","success_url","cancel_url"],"title":"G3PCreditPurchaseRequest","description":"Request to purchase G3P credits."},"G3PCreditPurchaseResponse":{"properties":{"session_id":{"type":"string","title":"Session Id","description":"Stripe Checkout Session ID"},"url":{"type":"string","title":"Url","description":"Stripe Checkout URL"},"pack":{"$ref":"#/components/schemas/G3PCreditPack","description":"G3P credit pack being purchased"}},"type":"object","required":["session_id","url","pack"],"title":"G3PCreditPurchaseResponse","description":"Response after creating G3P credit checkout session."},"GenerateBlogRequest":{"properties":{"topic":{"type":"string","title":"Topic"},"style":{"type":"string","title":"Style","default":"educational"},"design_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Style"},"word_count":{"type":"integer","maximum":3000.0,"minimum":300.0,"title":"Word Count","default":800}},"type":"object","required":["topic"],"title":"GenerateBlogRequest","description":"Request to generate a blog post."},"GenerateContentRequest":{"properties":{"platform":{"$ref":"#/components/schemas/Platform"},"topic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic"},"content_type":{"anyOf":[{"$ref":"#/components/schemas/ContentType"},{"type":"null"}]},"audience":{"$ref":"#/components/schemas/Audience","default":"homeowner"},"pillar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pillar"},"design_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Style"},"count":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Count","default":1},"model":{"anyOf":[{"$ref":"#/components/schemas/AIModel"},{"type":"null"}],"description":"AI model to use for generation","default":"gpt-5-mini"}},"type":"object","required":["platform"],"title":"GenerateContentRequest","description":"Request to generate content."},"GenerateFloorplanRequest":{"properties":{"footprint":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Footprint","description":"Building footprint polygon: [[x, z], ...] in meters relative to property center"},"building_type":{"type":"string","title":"Building Type","description":"Building type: residential | commercial | mixed","default":"residential"},"num_floors":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Num Floors","description":"Floor number to generate (1 = ground floor)","default":1},"style_hint":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Style Hint","description":"Optional layout style hint (e.g. 'open plan', 'traditional')"}},"type":"object","required":["footprint"],"title":"GenerateFloorplanRequest","description":"Request to generate a floor plan from a building footprint."},"GenerateFloorplanResponse":{"properties":{"interiorWalls":{"items":{"$ref":"#/components/schemas/FloorplanWallModel"},"type":"array","title":"Interiorwalls"},"rooms":{"items":{"$ref":"#/components/schemas/FloorplanRoomModel"},"type":"array","title":"Rooms"},"totalAreaM2":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Totalaream2"},"numRooms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numrooms"}},"type":"object","required":["interiorWalls","rooms"],"title":"GenerateFloorplanResponse","description":"Response with generated floor plan."},"GenerateHighAngle3DRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"ID of the existing 2D plan generation"}},"type":"object","required":["generation_id"],"title":"GenerateHighAngle3DRequest","description":"Request to generate a high-angle 3D bird's-eye perspective."},"GenerateHighAngle3DResponse":{"properties":{"image_url":{"type":"string","title":"Image Url"},"layout":{"additionalProperties":true,"type":"object","title":"Layout","default":{}},"generation_id":{"type":"string","title":"Generation Id"},"credits_remaining":{"type":"integer","title":"Credits Remaining","default":0}},"type":"object","required":["image_url","generation_id"],"title":"GenerateHighAngle3DResponse","description":"Response from high-angle 3D generation."},"GenerateHookPromptsRequest":{"properties":{"topic":{"type":"string","title":"Topic","description":"Landscaping topic","default":"backyard transformation"},"template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template","description":"Hook template (e.g. transformation, pain_point). Auto-selects if omitted."},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style","description":"Visual style (e.g. dramatic_transformation, aerial_reveal). Defaults to dramatic_transformation."},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool","description":"Video tool (veo_3, seedance, kling). Generates for all if omitted."},"count":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Count","description":"Number of hook batches to generate","default":3},"season":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Season","description":"Season (spring, summer, fall, winter)"}},"type":"object","title":"GenerateHookPromptsRequest","description":"Request to generate hook video prompts."},"GenerateHookPromptsResponse":{"properties":{"prompts":{"items":{"$ref":"#/components/schemas/HookPromptResponse"},"type":"array","title":"Prompts"},"recommended_tool":{"type":"string","title":"Recommended Tool"},"recommendation_reason":{"type":"string","title":"Recommendation Reason"},"topic":{"type":"string","title":"Topic"}},"type":"object","required":["prompts","recommended_tool","recommendation_reason","topic"],"title":"GenerateHookPromptsResponse","description":"Response containing generated hook prompts."},"GenerateImageRequest":{"properties":{"prompt":{"type":"string","title":"Prompt"},"width":{"type":"integer","maximum":2048.0,"minimum":256.0,"title":"Width","default":1024},"height":{"type":"integer","maximum":2048.0,"minimum":256.0,"title":"Height","default":1024},"platform":{"anyOf":[{"$ref":"#/components/schemas/Platform"},{"type":"null"}]},"style":{"type":"string","title":"Style","default":"photography"}},"type":"object","required":["prompt"],"title":"GenerateImageRequest","description":"Request to generate an image."},"GenerateImageWithTextRequest":{"properties":{"prompt":{"type":"string","title":"Prompt"},"text":{"type":"string","title":"Text"},"platform":{"$ref":"#/components/schemas/Platform","default":"instagram"},"text_type":{"type":"string","title":"Text Type","default":"hook"},"position":{"$ref":"#/components/schemas/TextPosition","default":"center"},"style":{"$ref":"#/components/schemas/TextOverlayStyle","default":"bold"},"text_color":{"type":"string","title":"Text Color","default":"#FFFFFF"},"background_style":{"$ref":"#/components/schemas/BackgroundStyle","default":"gradient"},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Width"},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Height"}},"type":"object","required":["prompt","text"],"title":"GenerateImageWithTextRequest","description":"Request to generate an image with text overlay."},"GenerateLinkedInRequest":{"properties":{"topic":{"type":"string","title":"Topic"},"post_style":{"type":"string","title":"Post Style","default":"insight"},"audience":{"$ref":"#/components/schemas/Audience","default":"service_provider"}},"type":"object","required":["topic"],"title":"GenerateLinkedInRequest","description":"Request to generate LinkedIn content for service providers."},"GenerateMarketingAssetsRequest":{"properties":{"generation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Id"},"satellite_base64":{"anyOf":[{"type":"string","maxLength":20000000},{"type":"null"}],"title":"Satellite Base64"},"oblique_front_base64":{"anyOf":[{"type":"string","maxLength":20000000},{"type":"null"}],"title":"Oblique Front Base64"},"oblique_back_base64":{"anyOf":[{"type":"string","maxLength":20000000},{"type":"null"}],"title":"Oblique Back Base64"},"platforms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Platforms"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"}},"type":"object","title":"GenerateMarketingAssetsRequest"},"GeneratePlanRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Property address"},"style":{"type":"string","title":"Style","description":"Design style","default":"Modern Minimalist"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"Features to include","default":[]},"street_edge":{"type":"string","title":"Street Edge","description":"Which edge has the street (TOP/BOTTOM/LEFT/RIGHT)","default":"BOTTOM"},"street_edge_user_set":{"type":"boolean","title":"Street Edge User Set","description":"When True, street_edge was explicitly set by user and overrides AI detection","default":false},"custom_prompt":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Custom Prompt","description":"Custom prompt additions from user"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"Pre-resolved lat/lng from frontend Places API"},"place_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place Id","description":"Google Places place_id for improved accuracy"},"generation_mode":{"type":"string","title":"Generation Mode","description":"Generation mode: two_stage, single_call_thinking, or mask_based","default":"two_stage"},"tiles_3d_screenshot_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tiles 3D Screenshot Base64","description":"Base64 screenshot from 3D tiles viewer (backyard perspective)"},"tiles_3d_camera":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tiles 3D Camera","description":"Camera params: {heading, pitch, altitude, lat, lng}"},"map_style":{"type":"string","title":"Map Style","description":"Output style: Colorful, CAD Oblique, or CAD 2D","default":"Colorful"},"ai_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Model","description":"AI model override (default: gemini-3.1-flash-image-preview)"},"quality_mode":{"type":"string","title":"Quality Mode","description":"Quality mode: 'premium' (high thinking) or 'fast' (low thinking)","default":"premium"},"polygon_vertices":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Polygon Vertices","description":"Refined boundary polygon vertices: [{x: 0-1, y: 0-1}, ...] from detect-boundary-polygon endpoint"}},"type":"object","required":["address"],"title":"GeneratePlanRequest","description":"Request for full 2D landscape plan generation"},"GeneratePlanResponse":{"properties":{"originalBase64":{"type":"string","title":"Originalbase64","description":"Enhanced base plan"},"designBase64":{"type":"string","title":"Designbase64","description":"Final design overlay (backyard view for oblique)"},"cad2DBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cad2Dbase64","description":"Separate CAD 2D variant (when CAD Oblique is primary)"},"siteAnalysis":{"$ref":"#/components/schemas/SiteAnalysisResponse"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates"},"layoutDescription":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layoutdescription","description":"Structured layout for 3D coherence"},"frontYardDesignBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frontyarddesignbase64","description":"Front yard oblique design (generated from front yard 3D tiles shot)"},"frontYardLayoutDescription":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Frontyardlayoutdescription","description":"Front yard layout for feature consistency"}},"type":"object","required":["originalBase64","designBase64","siteAnalysis"],"title":"GeneratePlanResponse","description":"Response with generated 2D plan - supports dual-shot generation (front + back)"},"GenerateWalkthroughRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"ID of the existing generation"},"viewpoints":{"items":{"type":"string"},"type":"array","title":"Viewpoints","description":"Specific viewpoint IDs to generate (empty = all)","default":[]},"layoutDescription":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layoutdescription","description":"Layout JSON from 2D generation for feature-specific viewpoints"},"referenceImageBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referenceimagebase64","description":"Base64 of the primary 3D view for consistency"}},"type":"object","required":["generation_id"],"title":"GenerateWalkthroughRequest","description":"Request to generate a walkthrough with multiple viewpoints."},"GeneratedContentResponse":{"properties":{"pieces":{"items":{"$ref":"#/components/schemas/ContentPiece"},"type":"array","title":"Pieces"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["pieces"],"title":"GeneratedContentResponse","description":"Response containing generated content (not yet saved)."},"GenerationCall":{"properties":{"id":{"type":"string","title":"Id"},"call_type":{"type":"string","title":"Call Type"},"call_sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Call Sequence"},"model_used":{"type":"string","title":"Model Used"},"latency_ms":{"type":"integer","title":"Latency Ms"},"status":{"type":"string","title":"Status"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"prompt_preview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Preview"},"input_image_count":{"type":"integer","title":"Input Image Count","default":0},"output_image_size_kb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Output Image Size Kb"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","call_type","model_used","latency_ms","status","created_at"],"title":"GenerationCall"},"GenerationCallList":{"properties":{"generation_id":{"type":"string","title":"Generation Id"},"calls":{"items":{"$ref":"#/components/schemas/GenerationCall"},"type":"array","title":"Calls"}},"type":"object","required":["generation_id","calls"],"title":"GenerationCallList"},"GenerationDetailResponse":{"properties":{"id":{"type":"string","title":"Id"},"address":{"type":"string","title":"Address"},"design_url":{"type":"string","title":"Design Url"},"satellite_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Url"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"features":{"items":{"type":"string"},"type":"array","title":"Features"},"custom_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Prompt"},"site_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Site Analysis"},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates"},"created_at":{"type":"string","title":"Created At"},"is_favorite":{"type":"boolean","title":"Is Favorite","default":false},"renderings":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Renderings","description":"3D renderings for this design"},"variants":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Variants","description":"Design variants (CAD conversions)"},"inpaint_variants":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Inpaint Variants","description":"Inpaint edit variants"},"child_edits":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Child Edits","description":"Child generations created by inpaint/pin edits"},"is_reference_design":{"type":"boolean","title":"Is Reference Design","description":"True if this is the reference design","default":false},"reference_generation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Generation Id","description":"UUID of parent reference design"},"reference_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reference Version","description":"Version number for reference designs"},"linked_variants":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Linked Variants","description":"Variants linked to this reference"},"design_assets":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Design Assets","description":"All design assets (unified view)"},"street_view_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street View Url","description":"Street View image URL"},"tiles_backyard_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tiles Backyard Url","description":"Backyard 3D tiles screenshot URL"},"tiles_front_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tiles Front Url","description":"Front yard 3D tiles screenshot URL"}},"type":"object","required":["id","address","design_url","created_at"],"title":"GenerationDetailResponse","description":"Full details of a single Pro Mode generation"},"GenerationHistoryItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"place_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place Id"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"generation_type":{"type":"string","title":"Generation Type","default":"standard"},"status":{"type":"string","title":"Status"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"is_favorite":{"type":"boolean","title":"Is Favorite","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features"},"rendering_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rendering Count"}},"type":"object","required":["id","status","created_at"],"title":"GenerationHistoryItem","description":"Individual generation item in history list"},"GenerationHistoryResponse":{"properties":{"generations":{"items":{"$ref":"#/components/schemas/GenerationHistoryItem"},"type":"array","title":"Generations"},"projects":{"items":{"$ref":"#/components/schemas/src__models__generation__ProjectSummary"},"type":"array","title":"Projects"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["generations","projects","total","page","page_size","has_more"],"title":"GenerationHistoryResponse","description":"Response model for /history endpoint"},"GenerationMode":{"type":"string","enum":["single_call","two_stage"],"title":"GenerationMode","description":"Generation strategy/mode\n\n- SINGLE_CALL: Uses Gemini 3 Pro (or specified model) in one pass\n- TWO_STAGE: Uses Gemini 2.5 Flash in two passes (Draw Boundary -> Generate Plan)"},"GenerationPrompt":{"properties":{"area":{"type":"string","title":"Area","description":"Generation area (front_yard, backyard, etc.)"},"prompt":{"type":"string","title":"Prompt","description":"User's prompt text"}},"type":"object","required":["area","prompt"],"title":"GenerationPrompt","description":"Prompt used during AI generation."},"GenerationStatus":{"type":"string","enum":["pending","processing","completed","partial","partial_failed","failed"],"title":"GenerationStatus","description":"Status of landscape generation (multi-area request)"},"GetInitialCameraPositionRequest":{"properties":{"street_edge":{"type":"string","title":"Street Edge","description":"Which edge has the street: TOP, BOTTOM, LEFT, RIGHT"}},"type":"object","required":["street_edge"],"title":"GetInitialCameraPositionRequest","description":"Request to get recommended initial camera position"},"GetInitialCameraPositionResponse":{"properties":{"heading":{"type":"number","title":"Heading"},"pitch":{"type":"number","title":"Pitch"},"altitude":{"type":"number","title":"Altitude"},"offsetN":{"type":"number","title":"Offsetn"},"offsetE":{"type":"number","title":"Offsete"},"description":{"type":"string","title":"Description"}},"type":"object","required":["heading","pitch","altitude","offsetN","offsetE","description"],"title":"GetInitialCameraPositionResponse","description":"Response with recommended initial camera position"},"GoogleDocExportRequest":{"properties":{"google_access_token":{"type":"string","title":"Google Access Token","description":"Google OAuth access token with drive.file scope"}},"type":"object","required":["google_access_token"],"title":"GoogleDocExportRequest","description":"Request body for Google Docs export."},"GoogleDocExportResponse":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the created Google Doc"},"message":{"type":"string","title":"Message","default":"Google Doc created successfully"}},"type":"object","required":["url"],"title":"GoogleDocExportResponse","description":"Response containing the created Google Doc URL."},"GoogleReviewImportRequest":{"properties":{"google_access_token":{"type":"string","title":"Google Access Token"},"location_id":{"type":"string","title":"Location Id"}},"type":"object","required":["google_access_token","location_id"],"title":"GoogleReviewImportRequest","description":"Request to import reviews from Google Business Profile"},"GrantCreditsRequest":{"properties":{"email":{"type":"string","title":"Email"},"credit_type":{"$ref":"#/components/schemas/CreditType"},"amount":{"type":"integer","title":"Amount"}},"type":"object","required":["email","credit_type","amount"],"title":"GrantCreditsRequest"},"GroundCoverType":{"type":"string","enum":["auto","natural_grass","bluegrass","bermuda","fescue","zoysia","artificial_turf","gravel","mulch","decomposed_granite","none"],"title":"GroundCoverType","description":"Ground cover material types."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"timestamp":{"type":"string","title":"Timestamp"},"budget_status":{"type":"string","title":"Budget Status"},"daily_spend_usd":{"type":"number","title":"Daily Spend Usd"},"monthly_spend_usd":{"type":"number","title":"Monthly Spend Usd"}},"type":"object","required":["status","timestamp","budget_status","daily_spend_usd","monthly_spend_usd"],"title":"HealthResponse","description":"System health check."},"HookPromptResponse":{"properties":{"tool":{"type":"string","title":"Tool"},"prompt":{"type":"string","title":"Prompt"},"hook_template":{"type":"string","title":"Hook Template"},"style":{"type":"string","title":"Style"},"caption_text":{"type":"string","title":"Caption Text"},"caption_highlight_words":{"items":{"type":"string"},"type":"array","title":"Caption Highlight Words"},"duration_seconds":{"type":"integer","title":"Duration Seconds"},"aspect_ratio":{"type":"string","title":"Aspect Ratio"},"subject":{"type":"string","title":"Subject"},"action":{"type":"string","title":"Action"},"camera":{"type":"string","title":"Camera"},"scene":{"type":"string","title":"Scene"},"lighting":{"type":"string","title":"Lighting"},"visual_style":{"type":"string","title":"Visual Style"},"audio":{"type":"string","title":"Audio"},"constraints":{"type":"string","title":"Constraints"},"landscaping_category":{"type":"string","title":"Landscaping Category"},"season":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Season"},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","required":["tool","prompt","hook_template","style","caption_text","caption_highlight_words","duration_seconds","aspect_ratio","subject","action","camera","scene","lighting","visual_style","audio","constraints","landscaping_category"],"title":"HookPromptResponse","description":"A single hook prompt in the response."},"HooksResponse":{"properties":{"hooks":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Hooks"},"topic":{"type":"string","title":"Topic"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["hooks","topic","count"],"title":"HooksResponse","description":"Response containing generated hooks."},"HouseFootprint":{"properties":{"width_ft":{"type":"number","exclusiveMinimum":0.0,"title":"Width Ft"},"depth_ft":{"type":"number","exclusiveMinimum":0.0,"title":"Depth Ft"},"position":{"$ref":"#/components/schemas/Position","description":"Relative position of house center in the image"}},"type":"object","required":["width_ft","depth_ft","position"],"title":"HouseFootprint","description":"House dimensions and position from site analysis."},"ImageGenerationResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"blob_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blob Url"},"local_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Local Path"},"prompt":{"type":"string","title":"Prompt"},"enhanced_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enhanced Prompt"},"width":{"type":"integer","title":"Width"},"height":{"type":"integer","title":"Height"},"backend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Backend"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["success","prompt","width","height"],"title":"ImageGenerationResponse","description":"Response from image generation."},"ImageReviewResultResponse":{"properties":{"image_url":{"type":"string","title":"Image Url"},"platform":{"type":"string","title":"Platform"},"visual_appeal":{"type":"number","title":"Visual Appeal"},"composition":{"type":"number","title":"Composition"},"relevance_to_topic":{"type":"number","title":"Relevance To Topic"},"platform_fit":{"type":"number","title":"Platform Fit"},"emotional_impact":{"type":"number","title":"Emotional Impact"},"overall_score":{"type":"number","title":"Overall Score"},"verdict":{"type":"string","title":"Verdict"},"has_humans":{"type":"boolean","title":"Has Humans"},"has_text_overlays":{"type":"boolean","title":"Has Text Overlays"},"has_artifacts":{"type":"boolean","title":"Has Artifacts"},"strengths":{"items":{"type":"string"},"type":"array","title":"Strengths"},"issues":{"items":{"type":"string"},"type":"array","title":"Issues"},"suggestions":{"items":{"type":"string"},"type":"array","title":"Suggestions"},"reviewer_model":{"type":"string","title":"Reviewer Model"},"review_timestamp":{"type":"string","title":"Review Timestamp"}},"type":"object","required":["image_url","platform","visual_appeal","composition","relevance_to_topic","platform_fit","emotional_impact","overall_score","verdict","has_humans","has_text_overlays","has_artifacts","strengths","issues","suggestions","reviewer_model","review_timestamp"],"title":"ImageReviewResultResponse","description":"Response from image review."},"ImportedReview":{"properties":{"source_platform":{"type":"string","enum":["google","yelp","manual"],"title":"Source Platform"},"external_review_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Review Id"},"external_location_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Location Id"},"reviewer_name":{"type":"string","title":"Reviewer Name"},"reviewer_photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Photo Url"},"rating":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Rating"},"review_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Text"},"review_date":{"type":"string","format":"date-time","title":"Review Date"},"response_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Text"},"response_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Response Date"},"is_visible":{"type":"boolean","title":"Is Visible","default":true},"is_flagged":{"type":"boolean","title":"Is Flagged","default":false},"flag_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flag Reason"},"id":{"type":"string","format":"uuid","title":"Id"},"contractor_id":{"type":"string","format":"uuid","title":"Contractor Id"},"imported_at":{"type":"string","format":"date-time","title":"Imported At"},"last_synced_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Synced At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["source_platform","reviewer_name","rating","review_date","id","contractor_id","imported_at","created_at","updated_at"],"title":"ImportedReview","description":"Complete review model returned from API"},"ImportedReviewUpdate":{"properties":{"is_visible":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Visible"},"response_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Text"},"is_flagged":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Flagged"},"flag_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flag Reason"}},"type":"object","title":"ImportedReviewUpdate","description":"Model for updating a review"},"ImproveContentRequest":{"properties":{"content":{"additionalProperties":true,"type":"object","title":"Content","description":"Content to improve"},"platform":{"type":"string","title":"Platform","description":"Target platform"},"audience":{"type":"string","title":"Audience","description":"Target audience","default":"homeowner"}},"type":"object","required":["content","platform"],"title":"ImproveContentRequest","description":"Request to auto-improve content."},"ImprovedContentResponse":{"properties":{"original":{"additionalProperties":true,"type":"object","title":"Original"},"improved":{"additionalProperties":true,"type":"object","title":"Improved"},"review_score":{"type":"number","title":"Review Score"},"review_verdict":{"type":"string","title":"Review Verdict"}},"type":"object","required":["original","improved","review_score","review_verdict"],"title":"ImprovedContentResponse","description":"Response with improved content."},"InfluencerCreate":{"properties":{"handle":{"type":"string","title":"Handle"},"platform":{"type":"string","title":"Platform"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"profile_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"tier":{"type":"string","title":"Tier","default":"tier3"},"followers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Followers"},"engagement_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Engagement Rate"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"},"contact_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact Method"},"compensation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compensation Type"},"compensation_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Compensation Amount"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"}},"type":"object","required":["handle","platform"],"title":"InfluencerCreate"},"InfluencerResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"handle":{"type":"string","title":"Handle"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"platform":{"type":"string","title":"Platform"},"profile_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"tier":{"type":"string","title":"Tier"},"followers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Followers"},"engagement_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Engagement Rate"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"},"contact_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact Method"},"pipeline_stage":{"type":"string","title":"Pipeline Stage"},"qualification_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Qualification Score"},"compensation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compensation Type"},"compensation_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Compensation Amount"},"compensation_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compensation Notes"},"next_follow_up_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Next Follow Up Date"},"last_contacted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Contacted At"},"tags":{"items":{},"type":"array","title":"Tags"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","handle","platform","tier","pipeline_stage"],"title":"InfluencerResponse"},"InfluencerUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"followers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Followers"},"engagement_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Engagement Rate"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"},"pipeline_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pipeline Stage"},"compensation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compensation Type"},"compensation_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Compensation Amount"},"compensation_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compensation Notes"},"next_follow_up_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Next Follow Up Date"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"}},"type":"object","title":"InfluencerUpdate"},"InpaintResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether the operation completed successfully"},"editId":{"type":"string","format":"uuid","title":"Editid","description":"UUID of the inpaint edit record"},"status":{"$ref":"#/components/schemas/InpaintStatus","description":"Current status of the edit"},"resultVariantId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resultvariantid","description":"ID of the new variant (e.g., 'inpaint-xxx' string in pro_mode_metadata.variants)"},"resultImageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resultimageurl","description":"URL to the inpainted image (if completed)"},"llmUnderstanding":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llmunderstanding","description":"LLM's interpretation of the edit request"},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Errormessage","description":"Error details (if failed)"}},"type":"object","required":["success","editId","status"],"title":"InpaintResponse","description":"Response model for inpainting endpoint."},"InpaintStatus":{"type":"string","enum":["pending","processing","completed","failed"],"title":"InpaintStatus","description":"Status of an inpainting edit operation."},"InspirationPhotoItem":{"properties":{"base64":{"type":"string","maxLength":7500000,"title":"Base64","description":"Base64-encoded image (JPEG/PNG/WebP, max ~5MB)"},"caption":{"type":"string","maxLength":150,"title":"Caption","description":"What the user likes about this photo"}},"type":"object","required":["base64","caption"],"title":"InspirationPhotoItem","description":"A single user-uploaded inspiration photo with caption (YAR-95)."},"InspirationTakeaway":{"properties":{"id":{"type":"string","title":"Id","description":"Unique ID (t1-t7)"},"label":{"type":"string","title":"Label","description":"Short 2-5 word label"},"description":{"type":"string","title":"Description","description":"One sentence describing this element"},"category":{"type":"string","title":"Category","description":"style | feature | material | mood"}},"type":"object","required":["id","label","description","category"],"title":"InspirationTakeaway","description":"A single selectable design takeaway from inspiration photo analysis."},"InternalNoteCreate":{"properties":{"content":{"type":"string","title":"Content"}},"type":"object","required":["content"],"title":"InternalNoteCreate","description":"Create internal note."},"LLMCallDetail":{"properties":{"call_id":{"type":"string","title":"Call Id"},"timestamp":{"type":"string","title":"Timestamp"},"call_type":{"type":"string","title":"Call Type"},"model":{"type":"string","title":"Model"},"prompt_text":{"type":"string","title":"Prompt Text"},"prompt_length":{"type":"integer","title":"Prompt Length"},"input_images":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Input Images"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"view_angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"View Angle"},"custom_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Prompt"},"response_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Text"},"response_text_length":{"type":"integer","title":"Response Text Length","default":0},"output_image_size_kb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Output Image Size Kb"},"parsed_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Parsed Json"},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description"},"duration_ms":{"type":"integer","title":"Duration Ms","default":0},"status":{"type":"string","title":"Status"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","default":{}}},"type":"object","required":["call_id","timestamp","call_type","model","prompt_text","prompt_length","input_images","status"],"title":"LLMCallDetail","description":"Full details of an LLM call."},"LLMCallSummary":{"properties":{"call_id":{"type":"string","title":"Call Id"},"timestamp":{"type":"string","title":"Timestamp"},"call_type":{"type":"string","title":"Call Type"},"model":{"type":"string","title":"Model"},"status":{"type":"string","title":"Status"},"duration_ms":{"type":"integer","title":"Duration Ms"},"prompt_length":{"type":"integer","title":"Prompt Length"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"}},"type":"object","required":["call_id","timestamp","call_type","model","status","duration_ms","prompt_length"],"title":"LLMCallSummary","description":"Summary of an LLM call."},"LLMStatsResponse":{"properties":{"total_calls":{"type":"integer","title":"Total Calls"},"by_type":{"additionalProperties":true,"type":"object","title":"By Type"},"by_status":{"additionalProperties":true,"type":"object","title":"By Status"},"avg_duration_ms":{"type":"integer","title":"Avg Duration Ms"},"total_prompt_chars":{"type":"integer","title":"Total Prompt Chars"},"unique_addresses":{"type":"integer","title":"Unique Addresses"},"date_range":{"type":"string","title":"Date Range"}},"type":"object","required":["total_calls","by_type","by_status","avg_duration_ms","total_prompt_chars","unique_addresses","date_range"],"title":"LLMStatsResponse","description":"Statistics response."},"LaborEstimate":{"properties":{"hardscape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardscape"},"planting":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Planting"},"irrigation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Irrigation"},"lighting":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lighting"},"demolition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Demolition"},"grading":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grading"}},"type":"object","title":"LaborEstimate","description":"Labor hours by category."},"LaborItem-Input":{"properties":{"category":{"type":"string","maxLength":100,"minLength":1,"title":"Category"},"description":{"type":"string","maxLength":500,"minLength":1,"title":"Description"},"hours":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"}],"title":"Hours"},"hourly_rate_cents":{"type":"integer","minimum":0.0,"title":"Hourly Rate Cents","description":"Rate per hour in cents"},"subtotal_cents":{"type":"integer","title":"Subtotal Cents","description":"Calculated: hours * hourly_rate_cents","default":0}},"type":"object","required":["category","description","hours","hourly_rate_cents"],"title":"LaborItem","description":"A single labor line item in an estimate.","example":{"category":"Hardscape","description":"Paver patio installation (400 sqft)","hourly_rate_cents":7500,"hours":24.0,"subtotal_cents":180000}},"LaborItem-Output":{"properties":{"category":{"type":"string","maxLength":100,"minLength":1,"title":"Category"},"description":{"type":"string","maxLength":500,"minLength":1,"title":"Description"},"hours":{"type":"string","title":"Hours"},"hourly_rate_cents":{"type":"integer","minimum":0.0,"title":"Hourly Rate Cents","description":"Rate per hour in cents"},"subtotal_cents":{"type":"integer","title":"Subtotal Cents","description":"Calculated: hours * hourly_rate_cents","default":0}},"type":"object","required":["category","description","hours","hourly_rate_cents"],"title":"LaborItem","description":"A single labor line item in an estimate.","example":{"category":"Hardscape","description":"Paver patio installation (400 sqft)","hourly_rate_cents":7500,"hours":24.0,"subtotal_cents":180000}},"LatencyBreakdown":{"properties":{"call_type":{"type":"string","title":"Call Type"},"model_used":{"type":"string","title":"Model Used"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"avg_latency_ms":{"type":"number","title":"Avg Latency Ms"},"p50_latency_ms":{"type":"number","title":"P50 Latency Ms"},"p95_latency_ms":{"type":"number","title":"P95 Latency Ms"},"total_calls":{"type":"integer","title":"Total Calls"}},"type":"object","required":["call_type","model_used","avg_latency_ms","p50_latency_ms","p95_latency_ms","total_calls"],"title":"LatencyBreakdown"},"LayoutDescriptionModel":{"properties":{"features":{"anyOf":[{"items":{"$ref":"#/components/schemas/LayoutFeature"},"type":"array"},{"type":"null"}],"title":"Features"},"orientation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Orientation"},"backyard_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Backyard Description"},"front_yard_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Front Yard Description"},"approach":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Approach"},"viewing_angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Viewing Angle"},"street_edge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Edge"},"sources_used":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sources Used"}},"type":"object","title":"LayoutDescriptionModel","description":"Layout description from original generation - ensures feature consistency across map styles"},"LayoutFeature":{"properties":{"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"relative_to_house":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relative To House"},"typical_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Typical Size"},"adjacent_to":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Adjacent To"},"position_in_view":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position In View"},"center_x_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Center X Percent"},"center_y_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Center Y Percent"}},"type":"object","required":["name"],"title":"LayoutFeature","description":"Single feature from layout description - used for consistency across map styles"},"LayoutType":{"type":"string","enum":["standard","corner_lot","cul_de_sac","flag_lot","through_lot","pie_shaped","hillside","irregular"],"title":"LayoutType","description":"Primary property layout classification.\n\nThis is the PRIMARY KEY for the learning database - layout type has the most\nsignificant impact on camera positioning requirements."},"LeadDeleteResponse":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["distribution_id","message"],"title":"LeadDeleteResponse","description":"Response body for lead deletion."},"LeadDetails":{"properties":{"project_title":{"type":"string","title":"Project Title","description":"Title from the marketplace project brief"},"homeowner_name":{"type":"string","title":"Homeowner Name","description":"First name + initial of homeowner"},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the lead was created"}},"type":"object","required":["project_title","homeowner_name","created_at"],"title":"LeadDetails","description":"Summary information about a matched lead."},"LeadDmLogRequest":{"properties":{"channel":{"type":"string","title":"Channel"},"content":{"type":"string","title":"Content"},"status":{"type":"string","title":"Status","default":"sent"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["channel","content"],"title":"LeadDmLogRequest","description":"Log a DM action from browser automation."},"LeadEmailRequest":{"properties":{"subject":{"type":"string","title":"Subject"},"body":{"type":"string","title":"Body"},"template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"}},"type":"object","required":["subject","body"],"title":"LeadEmailRequest","description":"Send email to a discovered lead."},"LeadFullResponse":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id"},"lead_id":{"type":"string","title":"Lead Id"},"lead_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead City"},"lead_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead State"},"generated_areas":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Generated Areas"},"image_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Image Urls"},"lead_name":{"type":"string","title":"Lead Name"},"lead_email":{"type":"string","title":"Lead Email"},"lead_phone":{"type":"string","title":"Lead Phone"},"lead_address":{"type":"string","title":"Lead Address"},"lead_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Notes"},"distance_miles":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance Miles"},"match_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Match Score"},"status":{"type":"string","title":"Status"},"stage":{"type":"string","title":"Stage"},"design_count":{"type":"integer","title":"Design Count","default":0},"proposal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proposal Id"},"distributed_at":{"type":"string","format":"date-time","title":"Distributed At"},"viewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Viewed At"},"responded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Responded At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"is_pro_subscriber":{"type":"boolean","title":"Is Pro Subscriber"},"can_view_full":{"type":"boolean","title":"Can View Full"}},"type":"object","required":["distribution_id","lead_id","lead_city","lead_state","generated_areas","image_urls","lead_name","lead_email","lead_phone","lead_address","lead_notes","distance_miles","match_score","status","stage","distributed_at","viewed_at","responded_at","expires_at","is_pro_subscriber","can_view_full"],"title":"LeadFullResponse","description":"Full lead view for Pro partners."},"LeadListResponse":{"properties":{"leads":{"items":{"anyOf":[{"$ref":"#/components/schemas/LeadPeekResponse"},{"$ref":"#/components/schemas/LeadFullResponse"}]},"type":"array","title":"Leads"},"total_count":{"type":"integer","title":"Total Count"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["leads","total_count","has_more"],"title":"LeadListResponse","description":"Response for lead inbox listing."},"LeadMatchResponse":{"properties":{"has_match":{"type":"boolean","title":"Has Match","description":"Whether a pending lead was found for this address"},"lead_distribution_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Lead Distribution Id","description":"ID of the matched lead distribution"},"project_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Project Id","description":"ID of the marketplace project for the lead"},"has_existing_proposal":{"type":"boolean","title":"Has Existing Proposal","description":"Whether the contractor already submitted a proposal for this lead","default":false},"match_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Match Type","description":"How the match was made: 'place_id' or 'address_fuzzy'"},"lead_details":{"anyOf":[{"$ref":"#/components/schemas/LeadDetails"},{"type":"null"}],"description":"Summary info about the matched lead (if found)"}},"type":"object","required":["has_match"],"title":"LeadMatchResponse","description":"Response when checking if an address matches a pending lead.\n\nUsed in Pro Mode completion to auto-detect leads that match\nthe address being designed."},"LeadNoteCreate":{"properties":{"content":{"type":"string","title":"Content"}},"type":"object","required":["content"],"title":"LeadNoteCreate","description":"Add a note to a canonical lead."},"LeadNoteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"canonical_lead_id":{"type":"string","format":"uuid","title":"Canonical Lead Id"},"content":{"type":"string","title":"Content"},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","canonical_lead_id","content"],"title":"LeadNoteResponse","description":"Lead note response."},"LeadPeekResponse":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id"},"lead_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead City"},"lead_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead State"},"generated_areas":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Generated Areas"},"image_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Image Urls"},"lead_name":{"type":"string","title":"Lead Name"},"lead_email":{"type":"string","title":"Lead Email"},"lead_phone":{"type":"string","title":"Lead Phone"},"lead_address":{"type":"string","title":"Lead Address"},"distance_miles":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance Miles"},"match_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Match Score"},"status":{"type":"string","title":"Status"},"stage":{"type":"string","title":"Stage"},"design_count":{"type":"integer","title":"Design Count","default":0},"proposal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proposal Id"},"distributed_at":{"type":"string","format":"date-time","title":"Distributed At"},"is_pro_subscriber":{"type":"boolean","title":"Is Pro Subscriber"},"can_view_full":{"type":"boolean","title":"Can View Full"}},"type":"object","required":["distribution_id","lead_city","lead_state","generated_areas","image_urls","lead_name","lead_email","lead_phone","lead_address","distance_miles","match_score","status","stage","distributed_at","is_pro_subscriber","can_view_full"],"title":"LeadPeekResponse","description":"Redacted lead view for free partners (peek only)."},"LeadResponseRequest":{"properties":{"response":{"type":"string","title":"Response"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["response"],"title":"LeadResponseRequest","description":"Request to accept or reject a lead."},"LeadSmsRequest":{"properties":{"body":{"type":"string","title":"Body"},"template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"}},"type":"object","required":["body"],"title":"LeadSmsRequest","description":"Send SMS to a discovered lead."},"LeadStageUpdateRequest":{"properties":{"stage":{"type":"string","title":"Stage"}},"type":"object","required":["stage"],"title":"LeadStageUpdateRequest","description":"Request body for updating a lead's CRM stage."},"LeadStageUpdateResponse":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id"},"stage":{"type":"string","title":"Stage"},"message":{"type":"string","title":"Message"}},"type":"object","required":["distribution_id","stage","message"],"title":"LeadStageUpdateResponse","description":"Response body for stage update."},"LeadStatsResponse":{"properties":{"pending":{"type":"integer","title":"Pending"},"viewed":{"type":"integer","title":"Viewed"},"accepted":{"type":"integer","title":"Accepted"},"rejected":{"type":"integer","title":"Rejected"},"expired":{"type":"integer","title":"Expired"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["pending","viewed","accepted","rejected","expired","total"],"title":"LeadStatsResponse","description":"Lead distribution statistics for a contractor."},"LeadUpdate":{"properties":{"lead_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"},"preferred_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Channel"},"outreach_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Outreach Status"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"LeadUpdate","description":"Update a discovered lead."},"LeadUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"LeadUpdateRequest","description":"Request body for updating a lead."},"LeadUpdateResponse":{"properties":{"lead_id":{"type":"string","title":"Lead Id"},"distribution_id":{"type":"string","title":"Distribution Id"},"message":{"type":"string","title":"Message"},"updated_fields":{"items":{"type":"string"},"type":"array","title":"Updated Fields"}},"type":"object","required":["lead_id","distribution_id","message","updated_fields"],"title":"LeadUpdateResponse","description":"Response body for lead update."},"LearnedParameters":{"properties":{"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id","description":"Unique identifier"},"layout_type":{"$ref":"#/components/schemas/LayoutType","description":"Property layout type (primary index)"},"lot_size":{"$ref":"#/components/schemas/LotSize","description":"Lot size category"},"triangle_count_min":{"type":"integer","minimum":0.0,"title":"Triangle Count Min","description":"Minimum triangle count for this config","default":0},"triangle_count_max":{"type":"integer","minimum":0.0,"title":"Triangle Count Max","description":"Maximum triangle count for this config","default":999999999},"altitude":{"type":"number","exclusiveMinimum":0.0,"title":"Altitude","description":"Camera altitude in meters"},"front_offset":{"type":"number","exclusiveMinimum":0.0,"title":"Front Offset","description":"Front view offset distance in meters"},"back_offset":{"type":"number","exclusiveMinimum":0.0,"title":"Back Offset","description":"Back view offset distance in meters"},"front_pitch":{"type":"number","maximum":0.0,"minimum":-90.0,"title":"Front Pitch","description":"Front view pitch in degrees"},"back_pitch":{"type":"number","maximum":0.0,"minimum":-90.0,"title":"Back Pitch","description":"Back view pitch in degrees"},"front_quality_score":{"anyOf":[{"type":"number","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Front Quality Score","description":"Average front view quality score"},"back_quality_score":{"anyOf":[{"type":"number","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Back Quality Score","description":"Average back view quality score"},"orientation_correct":{"type":"boolean","title":"Orientation Correct","description":"True if orientation was correct","default":true},"sample_count":{"type":"integer","minimum":1.0,"title":"Sample Count","description":"Number of properties this is based on","default":1},"address_sample":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Sample","description":"Example address (for reference)"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region","description":"Geographic region (informational, not used for lookup)"},"iterations_needed":{"type":"integer","minimum":0.0,"title":"Iterations Needed","description":"Average iterations to achieve success (0 = fixed on first try)","default":1},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"When this record was created"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"When this record was last updated"}},"type":"object","required":["layout_type","lot_size","altitude","front_offset","back_offset","front_pitch","back_pitch"],"title":"LearnedParameters","description":"Learned camera parameters for a property type combination.\n\nStored in the learning database and used as starting points for similar\nproperties. Indexed by layout_type (primary), lot_size, and triangle_count_range."},"LearnedParamsListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/LearnedParameters"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"LearnedParamsListResponse","description":"Response model for listing learned parameters."},"LineItem":{"properties":{"id":{"type":"string","title":"Id","description":"UUID for React key and identification"},"description":{"type":"string","maxLength":500,"minLength":1,"title":"Description","description":"Description of the line item (e.g., 'Paver installation - front walkway')"},"quantity":{"type":"string","title":"Quantity","description":"Quantity (e.g., 500 for sq ft, 1 for each, 40 for hours)"},"unit":{"type":"string","maxLength":50,"minLength":1,"title":"Unit","description":"Unit of measure (e.g., 'sq ft', 'each', 'hours')"},"unit_price":{"type":"string","title":"Unit Price","description":"Price per unit in dollars (e.g., 8.00)"},"category":{"anyOf":[{"$ref":"#/components/schemas/LineItemCategory"},{"type":"null"}],"description":"Optional category for grouping (materials, labor, other)"},"total":{"type":"string","title":"Total","description":"Auto-calculated: quantity * unit_price.","readOnly":true}},"type":"object","required":["id","description","quantity","unit","unit_price","total"],"title":"LineItem","description":"Individual cost component within a proposal's pricing breakdown.\n\nExample line items:\n- \"Paver installation - front walkway\" | 500 sq ft @ $8.00 = $4,000\n- \"Irrigation system\" | 1 each @ $2,500.00 = $2,500\n- \"Project management\" | 40 hours @ $75.00 = $3,000"},"LineItemCategory":{"type":"string","enum":["materials","labor","other"],"title":"LineItemCategory","description":"Category for line items in a proposal."},"LineItemCreate":{"properties":{"id":{"type":"string","title":"Id","description":"UUID for React key"},"description":{"type":"string","maxLength":500,"minLength":1,"title":"Description"},"quantity":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string"}],"title":"Quantity"},"unit":{"type":"string","maxLength":50,"minLength":1,"title":"Unit"},"unit_price":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"}],"title":"Unit Price"},"total":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}],"title":"Total","description":"Optional - will be recalculated"},"category":{"anyOf":[{"$ref":"#/components/schemas/LineItemCategory"},{"type":"null"}]}},"type":"object","required":["id","description","quantity","unit","unit_price"],"title":"LineItemCreate","description":"Line item in request body (total is optional, will be calculated)."},"LinkDesignRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id"}},"type":"object","required":["generation_id"],"title":"LinkDesignRequest","description":"Request to link a generation to a lead."},"LinkDesignResponse":{"properties":{"distribution_id":{"type":"string","title":"Distribution Id"},"generation_id":{"type":"string","title":"Generation Id"},"stage":{"type":"string","title":"Stage"},"design_count":{"type":"integer","title":"Design Count"},"message":{"type":"string","title":"Message"}},"type":"object","required":["distribution_id","generation_id","stage","design_count","message"],"title":"LinkDesignResponse","description":"Response after linking a design to a lead."},"LoadEditorSceneResponse":{"properties":{"generationId":{"type":"string","title":"Generationid"},"scene":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Scene","description":"Editor scene JSON, or null if not yet saved"}},"type":"object","required":["generationId"],"title":"LoadEditorSceneResponse","description":"Response with the loaded editor scene."},"LoginRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest","description":"Request model for user login."},"LoginResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"user":{"$ref":"#/components/schemas/User"}},"type":"object","required":["access_token","user"],"title":"LoginResponse","description":"Response model for successful login."},"LotSize":{"type":"string","enum":["SMALL","MEDIUM","LARGE","ESTATE"],"title":"LotSize","description":"Lot size classification.\n\nMatches existing CAMERA_PARAMS_BY_LOT_SIZE in pro_mode.py for consistency."},"MCPPricingFeature":{"properties":{"name":{"type":"string","title":"Name","description":"Feature name"},"included":{"type":"boolean","title":"Included","description":"Whether feature is included"},"limit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Limit","description":"Limit if applicable"}},"type":"object","required":["name","included"],"title":"MCPPricingFeature","description":"Feature in MCP pricing response"},"MCPPricingLimits":{"properties":{"designs_per_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Designs Per Month","description":"Designs per month limit"},"generations_per_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Generations Per Month","description":"Generations per month limit"}},"type":"object","title":"MCPPricingLimits","description":"Limits in MCP pricing response"},"MCPPricingPlan":{"properties":{"plan":{"type":"string","title":"Plan","description":"Plan identifier (free/pro)"},"price_monthly":{"type":"number","title":"Price Monthly","description":"Monthly price in USD"},"price_yearly":{"type":"number","title":"Price Yearly","description":"Yearly price in USD"},"features":{"items":{"$ref":"#/components/schemas/MCPPricingFeature"},"type":"array","title":"Features","description":"List of features"},"limits":{"anyOf":[{"$ref":"#/components/schemas/MCPPricingLimits"},{"type":"null"}],"description":"Plan limits"},"trial_info":{"anyOf":[{"$ref":"#/components/schemas/MCPTrialInfo"},{"type":"null"}],"description":"Trial information"}},"type":"object","required":["plan","price_monthly","price_yearly","features"],"title":"MCPPricingPlan","description":"Single pricing plan in MCP format"},"MCPPricingResponse":{"properties":{"free":{"$ref":"#/components/schemas/MCPPricingPlan","description":"Free plan pricing"},"pro":{"$ref":"#/components/schemas/MCPPricingPlan","description":"Pro plan pricing"}},"type":"object","required":["free","pro"],"title":"MCPPricingResponse","description":"MCP-compatible pricing response for get_pricing tool"},"MCPToolStat":{"properties":{"tool_name":{"type":"string","title":"Tool Name"},"total_invocations":{"type":"integer","title":"Total Invocations"},"success_count":{"type":"integer","title":"Success Count"},"error_count":{"type":"integer","title":"Error Count"},"avg_response_time_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Response Time Ms"}},"type":"object","required":["tool_name","total_invocations","success_count","error_count"],"title":"MCPToolStat"},"MCPTrialInfo":{"properties":{"days":{"type":"integer","title":"Days","description":"Trial days","default":7},"designs_included":{"type":"integer","title":"Designs Included","description":"Designs included in trial","default":3}},"type":"object","title":"MCPTrialInfo","description":"Trial info in MCP pricing response"},"ManualLeadCreateRequest":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"phone":{"type":"string","title":"Phone"},"address":{"type":"string","title":"Address"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"budget_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Budget Min"},"budget_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Budget Max"}},"type":"object","required":["name","email","phone","address"],"title":"ManualLeadCreateRequest"},"ManualLeadResponse":{"properties":{"lead_id":{"type":"string","title":"Lead Id"},"distribution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Distribution Id"},"parsed_details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Parsed Details"},"message":{"type":"string","title":"Message"}},"type":"object","required":["lead_id","distribution_id","parsed_details","message"],"title":"ManualLeadResponse"},"ManualReviewCreate":{"properties":{"reviewer_name":{"type":"string","title":"Reviewer Name"},"rating":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Rating"},"review_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Text"},"review_date":{"type":"string","format":"date-time","title":"Review Date"}},"type":"object","required":["reviewer_name","rating","review_date"],"title":"ManualReviewCreate","description":"Model for creating a manual review entry"},"MarkerPositionResponse":{"properties":{"x":{"type":"integer","title":"X"},"y":{"type":"integer","title":"Y"},"found":{"type":"boolean","title":"Found"},"confidence":{"type":"number","title":"Confidence"}},"type":"object","required":["x","y","found","confidence"],"title":"MarkerPositionResponse","description":"Position of the property marker in the image."},"MarketCreate":{"properties":{"name":{"type":"string","title":"Name"},"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"radius_miles":{"type":"integer","title":"Radius Miles","default":25},"median_home_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Home Price"},"price_percentile":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Percentile"},"tier":{"type":"integer","title":"Tier","default":3},"country":{"type":"string","title":"Country","default":"US"},"population":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Population"},"keywords":{"items":{"type":"string"},"type":"array","title":"Keywords"}},"type":"object","required":["name","city","state","latitude","longitude"],"title":"MarketCreate","description":"Add a target market."},"MarketResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"radius_miles":{"type":"integer","title":"Radius Miles"},"median_home_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Home Price"},"price_percentile":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Percentile"},"tier":{"type":"integer","title":"Tier","default":3},"country":{"type":"string","title":"Country","default":"US"},"population":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Population"},"is_active":{"type":"boolean","title":"Is Active","default":true},"keywords":{"items":{},"type":"array","title":"Keywords"},"last_scraped_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Scraped At"},"yelp_scraped_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Yelp Scraped At"},"yelp_api_calls_used":{"type":"integer","title":"Yelp Api Calls Used","default":0},"total_leads":{"type":"integer","title":"Total Leads","default":0},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","name","city","state","latitude","longitude","radius_miles"],"title":"MarketResponse","description":"Target market response."},"MarketUpdate":{"properties":{"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"radius_miles":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Radius Miles"},"keywords":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Keywords"},"median_home_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Home Price"},"price_percentile":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Percentile"}},"type":"object","title":"MarketUpdate","description":"Update a target market."},"MarketingAssetResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"assets":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Assets"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["success"],"title":"MarketingAssetResponse"},"MarketplaceMetrics":{"properties":{"total_projects":{"type":"integer","title":"Total Projects"},"open_projects":{"type":"integer","title":"Open Projects"},"completed_projects":{"type":"integer","title":"Completed Projects"},"cancelled_projects":{"type":"integer","title":"Cancelled Projects"},"total_proposals":{"type":"integer","title":"Total Proposals"},"accepted_proposals":{"type":"integer","title":"Accepted Proposals"},"pending_proposals":{"type":"integer","title":"Pending Proposals"},"total_contractors":{"type":"integer","title":"Total Contractors"},"verified_contractors":{"type":"integer","title":"Verified Contractors"},"active_contractors":{"type":"integer","title":"Active Contractors"},"acceptance_rate":{"type":"number","title":"Acceptance Rate"},"avg_proposals_per_project":{"type":"number","title":"Avg Proposals Per Project"},"avg_project_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Project Value"}},"type":"object","required":["total_projects","open_projects","completed_projects","cancelled_projects","total_proposals","accepted_proposals","pending_proposals","total_contractors","verified_contractors","active_contractors","acceptance_rate","avg_proposals_per_project"],"title":"MarketplaceMetrics","description":"High-level marketplace metrics"},"MarketplaceProjectStatus":{"type":"string","enum":["open","reviewing","proposal_accepted","in_progress","completed","cancelled","expired"],"title":"MarketplaceProjectStatus","description":"Project status in the marketplace lifecycle."},"MarketplaceProposalStatus":{"type":"string","enum":["pending","viewed","accepted","rejected","withdrawn"],"title":"MarketplaceProposalStatus","description":"Proposal status in the marketplace lifecycle."},"MaterialCostDetail":{"properties":{"name":{"type":"string","title":"Name","description":"Material name, e.g., 'Patio Pavers'"},"quantity":{"type":"number","title":"Quantity","description":"Quantity needed"},"unit":{"type":"string","title":"Unit","description":"Unit of measurement: sq ft, linear ft, unit"},"estimated_cost":{"type":"number","title":"Estimated Cost","description":"Estimated total cost in USD"}},"type":"object","required":["name","quantity","unit","estimated_cost"],"title":"MaterialCostDetail","description":"A material item with cost breakdown for ChatGPT GPT action"},"MaterialItem-Input":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"unit":{"type":"string","maxLength":50,"minLength":1,"title":"Unit"},"quantity":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"}],"title":"Quantity"},"unit_price_cents":{"type":"integer","minimum":0.0,"title":"Unit Price Cents","description":"Price per unit in cents"},"subtotal_cents":{"type":"integer","title":"Subtotal Cents","description":"Calculated: quantity * unit_price_cents","default":0}},"type":"object","required":["name","unit","quantity","unit_price_cents"],"title":"MaterialItem","description":"A single material line item in an estimate.","example":{"name":"Travertine Pavers - French Pattern","quantity":420.0,"subtotal_cents":189000,"unit":"sqft","unit_price_cents":450}},"MaterialPreferences":{"properties":{"ground_cover":{"$ref":"#/components/schemas/GroundCoverType","description":"Preferred ground cover material","default":"auto"},"patio_surface":{"$ref":"#/components/schemas/PatioSurfaceType","description":"Preferred patio/hardscape surface","default":"auto"},"fencing":{"$ref":"#/components/schemas/FencingType","description":"Preferred fencing type","default":"auto"},"grass_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grass Type","description":"Specific grass variety (e.g., Bermuda, Bluegrass)"},"paver_pattern":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Paver Pattern","description":"Paver pattern (e.g., herringbone, running_bond)"},"fence_height":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fence Height","description":"Fence height preference (e.g., 6ft, 4ft)"}},"type":"object","title":"MaterialPreferences","description":"User's material preferences selected before generation.\nThese guide the AI in generating designs with specific materials."},"MaterialSummary":{"properties":{"totalMaterials":{"type":"number","title":"Totalmaterials","description":"Total materials cost"},"totalLabor":{"type":"number","title":"Totallabor","description":"Total labor cost"},"grandTotal":{"type":"number","title":"Grandtotal","description":"Combined total"},"priceRangeLow":{"type":"number","title":"Pricerangelow","description":"Low estimate (-10%)"},"priceRangeHigh":{"type":"number","title":"Pricerangehigh","description":"High estimate (+10%)"}},"type":"object","required":["totalMaterials","totalLabor","grandTotal","priceRangeLow","priceRangeHigh"],"title":"MaterialSummary","description":"Summary of material estimation totals"},"MaterialUnit":{"type":"string","enum":["sqft","linear_ft","unit"],"title":"MaterialUnit","description":"Unit types for materials"},"MaterialsEstimateResponse":{"properties":{"materials":{"items":{"$ref":"#/components/schemas/MaterialCostDetail"},"type":"array","title":"Materials","description":"List of materials with quantities and costs"},"estimated_cost":{"type":"number","title":"Estimated Cost","description":"Total estimated cost in USD"}},"type":"object","required":["materials","estimated_cost"],"title":"MaterialsEstimateResponse","description":"Response for estimateMaterials action"},"MergeCanonicalRequest":{"properties":{"keep_id":{"type":"string","format":"uuid","title":"Keep Id"},"absorb_id":{"type":"string","format":"uuid","title":"Absorb Id"}},"type":"object","required":["keep_id","absorb_id"],"title":"MergeCanonicalRequest","description":"Merge two canonical leads."},"MetroAreaResponse":{"properties":{"code":{"type":"string","title":"Code"},"name":{"type":"string","title":"Name"},"state_codes":{"items":{"type":"string"},"type":"array","title":"State Codes"},"cities_count":{"type":"integer","title":"Cities Count"},"approximate_radius_miles":{"type":"integer","title":"Approximate Radius Miles"},"population_estimate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Population Estimate"}},"type":"object","required":["code","name","state_codes","cities_count","approximate_radius_miles"],"title":"MetroAreaResponse","description":"Metro area definition for frontend selection."},"MigrationResponse":{"properties":{"migrated":{"type":"integer","title":"Migrated"},"skipped":{"type":"integer","title":"Skipped"},"message":{"type":"string","title":"Message"}},"type":"object","required":["migrated","skipped","message"],"title":"MigrationResponse","description":"Response for migration endpoints."},"MilestoneComplete":{"properties":{"evidence":{"items":{"$ref":"#/components/schemas/CompletionEvidence"},"type":"array","title":"Evidence"}},"type":"object","title":"MilestoneComplete","description":"Request to mark milestone as completed."},"MilestoneDispute":{"properties":{"reason":{"type":"string","maxLength":2000,"minLength":20,"title":"Reason"}},"type":"object","required":["reason"],"title":"MilestoneDispute","description":"Request to dispute a milestone."},"MilestoneListResponse":{"properties":{"milestones":{"items":{"$ref":"#/components/schemas/MilestoneResponse"},"type":"array","title":"Milestones"},"total_amount_cents":{"type":"integer","title":"Total Amount Cents"},"approved_amount_cents":{"type":"integer","title":"Approved Amount Cents"},"completion_percent":{"type":"string","title":"Completion Percent"}},"type":"object","required":["milestones","total_amount_cents","approved_amount_cents","completion_percent"],"title":"MilestoneListResponse","description":"List of milestones for a project."},"MilestoneResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"proposal_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Proposal Id"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sequence_order":{"type":"integer","title":"Sequence Order"},"amount_cents":{"type":"integer","title":"Amount Cents"},"percentage_of_total":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Percentage Of Total"},"status":{"$ref":"#/components/schemas/MilestoneStatus"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"approved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Approved At"},"completion_evidence":{"items":{"$ref":"#/components/schemas/CompletionEvidence"},"type":"array","title":"Completion Evidence"},"disputed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Disputed At"},"dispute_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dispute Reason"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","project_id","proposal_id","title","description","sequence_order","amount_cents","percentage_of_total","status","started_at","completed_at","approved_at","disputed_at","dispute_reason","created_at","updated_at"],"title":"MilestoneResponse","description":"Full milestone response."},"MilestoneStatus":{"type":"string","enum":["pending","in_progress","completed","approved","disputed","cancelled"],"title":"MilestoneStatus","description":"Milestone completion status."},"MultiAreaGenerationResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Unique generation request ID"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id","description":"User who created this generation"},"status":{"$ref":"#/components/schemas/GenerationStatus","description":"Overall generation status"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address","description":"Property address (user input)"},"geocoded_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocoded Address","description":"Formatted address from Google Maps (what was actually used for image retrieval)"},"geocoding_accuracy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocoding Accuracy","description":"Geocoding accuracy level (ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER, APPROXIMATE)"},"total_cost":{"type":"integer","minimum":1.0,"title":"Total Cost","description":"Total cost in credits/tokens"},"payment_method":{"$ref":"#/components/schemas/PaymentType","description":"Payment method used (trial/token/subscription)"},"credits_remaining":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Credits Remaining","description":"Remaining credits after deduction: {'trial': N, 'token': N, 'holiday': N}"},"areas":{"items":{"$ref":"#/components/schemas/AreaStatusResponse"},"type":"array","title":"Areas","description":"Status for each requested area"},"source_images":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Source Images","description":"Source images (Street View/Satellite)"},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Request creation timestamp"},"start_processing_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Start Processing At","description":"When processing started"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At","description":"When all areas completed (or request failed)"},"estimated_completion":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Completion","description":"Estimated completion time (for pending/processing status)"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At","description":"When this generation expires and will be deleted. NULL = never expires (subscription). For trial: creation time, for token: 7 days after creation."},"retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retention Days","description":"Days remaining before automatic deletion. NULL = permanent (subscription)."},"retention_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retention Message","description":"User-friendly message: 'Saved for 7 days' or 'Saved permanently (Subscription)' or 'Not saved (Trial)'"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message","description":"Overall error message (for failed status)"},"hardiness_zone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardiness Zone","description":"USDA Plant Hardiness Zone (e.g., '7a') for plant recommendations"},"hardiness_zone_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardiness Zone Description","description":"Temperature range description (e.g., '0 to 5°F minimum')"},"property_insights":{"anyOf":[{"$ref":"#/components/schemas/PropertyInsights"},{"type":"null"}],"description":"Progressive property metadata for enhanced waiting experience (YAR-345)"}},"type":"object","required":["id","status","total_cost","payment_method","areas","created_at"],"title":"MultiAreaGenerationResponse","description":"Response model for multi-area generation request\n\nIncludes overall status, per-area progress tracking, and retention policy info.\n\nRetention Policy Info:\n- expires_at: When this generation will be deleted (NULL = never expires for subscriptions)\n- retention_days: Days remaining before deletion (NULL = permanent for subscriptions)\n- retention_message: User-friendly message about how long the generation will be kept"},"MultiSourceFusionRequest":{"properties":{"tiles_3d_screenshot_base64":{"type":"string","title":"Tiles 3D Screenshot Base64","description":"Base64-encoded 3D tiles screenshot (backyard perspective)"},"satellite_2d_base64":{"type":"string","title":"Satellite 2D Base64","description":"Base64-encoded 2D satellite image (top-down)"},"street_view_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street View Base64","description":"Base64-encoded Street View image (front of house)"},"front_yard_tiles_3d_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Front Yard Tiles 3D Base64","description":"Base64-encoded 3D tiles screenshot (front yard perspective) - for dual-shot generation"},"style":{"type":"string","title":"Style","description":"Design style","default":"Modern Minimalist"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"Features to include","default":[]},"street_edge":{"type":"string","title":"Street Edge","description":"Which edge has the street (TOP/BOTTOM/LEFT/RIGHT)","default":"BOTTOM"},"street_edge_user_set":{"type":"boolean","title":"Street Edge User Set","description":"When True, street_edge was explicitly set by user and overrides AI detection","default":false},"camera_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Camera Params","description":"Camera parameters from 3D view {heading, pitch, altitude}"},"custom_prompt":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Custom Prompt","description":"Custom instructions from user"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"Property coordinates {lat, lng}"},"map_style":{"type":"string","title":"Map Style","description":"Output style: Colorful, CAD Oblique, or CAD 2D","default":"Colorful"},"ai_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Model","description":"AI model override (default: gemini-3.1-flash-image-preview)"},"quality_mode":{"type":"string","title":"Quality Mode","description":"Quality mode: 'premium' (high thinking) or 'fast' (low thinking)","default":"premium"},"address":{"type":"string","title":"Address","description":"Property address (helps identify correct house for cul-de-sacs)","default":""},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description","description":"Layout from Step 2 generation (for CAD 2D feature preservation)"},"material_preferences":{"anyOf":[{"$ref":"#/components/schemas/MaterialPreferences"},{"type":"null"}],"description":"User's material preferences for ground cover, patio surface, and fencing"},"boundary_corners":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Boundary Corners","description":"Property boundary corners from Step 2: [{id: 'front-left'|'front-right'|'back-left'|'back-right', lat: number, lng: number}]"},"polygon_vertices":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Polygon Vertices","description":"Refined boundary polygon vertices: [{x: 0-1, y: 0-1}, ...] from detect-boundary-polygon endpoint"},"property_dimensions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Property Dimensions","description":"Property dimensions from DimensionCalculator for accurate scale labels in CAD 2D output"},"focus_area":{"type":"string","title":"Focus Area","description":"Focus area: 'front_yard', 'backyard', or 'both'","default":"both"},"use_public_view":{"type":"boolean","title":"Use Public View","description":"When True, use Street View (ground-level) as reference for front yard generation","default":false},"prefetchedAnalysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Prefetchedanalysis","description":"Prefetched property analysis JSON from /analyze-property endpoint"},"skipObliques":{"type":"boolean","title":"Skipobliques","description":"When True, skip Calls 3/4 (oblique renderings) and return the 2D plan immediately","default":false},"sitePlanBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Siteplanbase64","description":"Pre-generated 2D site plan base64 from Phase 1 — skips Call 2 and plan credit deduction"},"inspiration_photos":{"anyOf":[{"items":{"$ref":"#/components/schemas/InspirationPhotoItem"},"type":"array","maxItems":5},{"type":"null"}],"title":"Inspiration Photos","description":"Up to 5 user-uploaded inspiration photos with captions guiding AI style"},"front_yard_instructions":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Front Yard Instructions"},"backyard_instructions":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Backyard Instructions"},"backTriangleCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Backtrianglecount","description":"Triangle count from backyard 3D tile capture. When <40000 (terrain-only), satellite image supplements the reference."},"resumePipelineId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resumepipelineid","description":"Pipeline ID from a previous failed generation to resume from last checkpoint"},"prompt_source":{"type":"string","const":"skill","title":"Prompt Source","description":"Prompt source: only 'skill' is supported (Method A/B toggle removed)","default":"skill"}},"type":"object","required":["tiles_3d_screenshot_base64","satellite_2d_base64"],"title":"MultiSourceFusionRequest","description":"Request for multi-source fusion generation (3D tiles + 2D satellite + Street View)"},"MyDesignsResponse":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/ProModeGenerationSummary"},"type":"array","title":"Designs"},"total_count":{"type":"integer","title":"Total Count","description":"Total number of designs"},"has_more":{"type":"boolean","title":"Has More","description":"Whether more pages exist","default":false}},"type":"object","required":["total_count"],"title":"MyDesignsResponse","description":"Response with user's Pro Mode generation history"},"NotificationPreferenceRequest":{"properties":{"preference":{"type":"string","title":"Preference"}},"type":"object","required":["preference"],"title":"NotificationPreferenceRequest","description":"Request to update notification preference."},"OnboardingNudgeResponse":{"properties":{"eligible":{"type":"integer","title":"Eligible"},"sent":{"type":"integer","title":"Sent"},"failed":{"type":"integer","title":"Failed"},"message":{"type":"string","title":"Message"}},"type":"object","required":["eligible","sent","failed","message"],"title":"OnboardingNudgeResponse","description":"Response from onboarding nudge batch job."},"OnboardingSequenceResponse":{"properties":{"tutorial_eligible":{"type":"integer","title":"Tutorial Eligible"},"tutorial_sent":{"type":"integer","title":"Tutorial Sent"},"tutorial_failed":{"type":"integer","title":"Tutorial Failed"},"social_proof_eligible":{"type":"integer","title":"Social Proof Eligible"},"social_proof_sent":{"type":"integer","title":"Social Proof Sent"},"social_proof_failed":{"type":"integer","title":"Social Proof Failed"},"trial_reminder_eligible":{"type":"integer","title":"Trial Reminder Eligible"},"trial_reminder_sent":{"type":"integer","title":"Trial Reminder Sent"},"trial_reminder_failed":{"type":"integer","title":"Trial Reminder Failed"},"trial_expired_eligible":{"type":"integer","title":"Trial Expired Eligible"},"trial_expired_sent":{"type":"integer","title":"Trial Expired Sent"},"trial_expired_failed":{"type":"integer","title":"Trial Expired Failed"},"total_sent":{"type":"integer","title":"Total Sent"},"total_failed":{"type":"integer","title":"Total Failed"},"message":{"type":"string","title":"Message"}},"type":"object","required":["tutorial_eligible","tutorial_sent","tutorial_failed","social_proof_eligible","social_proof_sent","social_proof_failed","trial_reminder_eligible","trial_reminder_sent","trial_reminder_failed","trial_expired_eligible","trial_expired_sent","trial_expired_failed","total_sent","total_failed","message"],"title":"OnboardingSequenceResponse","description":"Response from onboarding sequence batch job."},"OptimizeBackyardCameraRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded screenshot from CesiumJS 3D Tiles"},"address":{"type":"string","title":"Address","description":"Property address"},"street_edge":{"type":"string","title":"Street Edge","description":"Which edge has the street: TOP, BOTTOM, LEFT, RIGHT"},"current_params":{"$ref":"#/components/schemas/CameraParams","description":"Current camera parameters"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"}},"type":"object","required":["image_base64","address","street_edge","current_params"],"title":"OptimizeBackyardCameraRequest","description":"Request to evaluate and optimize camera position for backyard view"},"OptimizeBackyardCameraResponse":{"properties":{"qualityScore":{"type":"integer","title":"Qualityscore","description":"Overall quality score 1-10"},"criteriaScores":{"$ref":"#/components/schemas/CriteriaScores"},"observations":{"$ref":"#/components/schemas/ShotObservations"},"isAcceptable":{"type":"boolean","title":"Isacceptable","description":"True if score >= 7"},"adjustments":{"$ref":"#/components/schemas/CameraAdjustments"},"reasoning":{"type":"string","title":"Reasoning","description":"AI explanation of issues and recommended adjustments"},"confidence":{"type":"string","title":"Confidence","description":"Confidence level: high, medium, low"},"suggestedParams":{"anyOf":[{"$ref":"#/components/schemas/CameraParams"},{"type":"null"}],"description":"New camera params with adjustments applied"}},"type":"object","required":["qualityScore","criteriaScores","observations","isAcceptable","adjustments","reasoning","confidence"],"title":"OptimizeBackyardCameraResponse","description":"Response with quality evaluation and adjustment suggestions"},"OutreachActionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"lead_id":{"type":"string","format":"uuid","title":"Lead Id"},"canonical_lead_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Canonical Lead Id"},"channel":{"type":"string","title":"Channel"},"action_type":{"type":"string","title":"Action Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"},"status":{"type":"string","title":"Status","default":"sent"},"response_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Text"},"response_sentiment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Sentiment"},"responded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Responded At"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","lead_id","channel","action_type"],"title":"OutreachActionResponse","description":"Outreach action log entry."},"OutreachResponseLog":{"properties":{"response_text":{"type":"string","title":"Response Text"},"response_sentiment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Sentiment"}},"type":"object","required":["response_text"],"title":"OutreachResponseLog","description":"Log a response to an outreach action."},"OutreachTemplate":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"channel":{"type":"string","title":"Channel"},"target_type":{"type":"string","title":"Target Type"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"body":{"type":"string","title":"Body"},"placeholders":{"items":{"type":"string"},"type":"array","title":"Placeholders"}},"type":"object","required":["id","name","channel","target_type","body"],"title":"OutreachTemplate","description":"Outreach message template."},"OverallStats":{"properties":{"total_test_runs":{"type":"integer","title":"Total Test Runs"},"total_addresses_tested":{"type":"integer","title":"Total Addresses Tested"},"total_addresses_in_pool":{"type":"integer","title":"Total Addresses In Pool"},"avg_front_quality_all_time":{"type":"number","title":"Avg Front Quality All Time"},"avg_back_quality_all_time":{"type":"number","title":"Avg Back Quality All Time"},"recent_runs":{"items":{"$ref":"#/components/schemas/TestRunSummary"},"type":"array","title":"Recent Runs"}},"type":"object","required":["total_test_runs","total_addresses_tested","total_addresses_in_pool","avg_front_quality_all_time","avg_back_quality_all_time","recent_runs"],"title":"OverallStats","description":"Overall camera test statistics."},"PanelData":{"properties":{"data":{"additionalProperties":true,"type":"object","title":"Data"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["data"],"title":"PanelData"},"PartnerDesignCreate":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"ID of the generation to save"},"lead_distribution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Distribution Id","description":"Optional lead to link this design to"},"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["generation_id"],"title":"PartnerDesignCreate","description":"Request to save a design."},"PartnerDesignListResponse":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/PartnerDesignResponse"},"type":"array","title":"Designs"},"total_count":{"type":"integer","title":"Total Count"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["designs","total_count","has_more"],"title":"PartnerDesignListResponse","description":"Response for listing designs."},"PartnerDesignResponse":{"properties":{"id":{"type":"string","title":"Id"},"partner_id":{"type":"string","title":"Partner Id"},"generation_id":{"type":"string","title":"Generation Id"},"lead_distribution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Distribution Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"is_favorite":{"type":"boolean","title":"Is Favorite"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"lead_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Name"},"lead_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead City"},"lead_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Stage"}},"type":"object","required":["id","partner_id","generation_id","lead_distribution_id","title","notes","is_favorite","created_at","updated_at"],"title":"PartnerDesignResponse","description":"Response for a saved design."},"PartnerDesignUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"is_favorite":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Favorite"},"lead_distribution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Distribution Id","description":"Link/unlink to a lead"}},"type":"object","title":"PartnerDesignUpdate","description":"Request to update a saved design."},"PartnerProjectResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"contractor_id":{"type":"string","format":"uuid","title":"Contractor Id"},"normalized_address":{"type":"string","title":"Normalized Address","description":"Lowercase, standardized address for duplicate detection"},"display_address":{"type":"string","title":"Display Address","description":"Original user-entered address format"},"place_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place Id"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State Code"},"zip_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip Code"},"generation_count":{"type":"integer","title":"Generation Count","description":"Total number of Pro Mode generations for this address","default":0},"proposal_count":{"type":"integer","title":"Proposal Count","description":"Total number of proposals using designs from this project","default":0},"last_generation_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Generation At","description":"When the most recent generation was created"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","contractor_id","normalized_address","display_address","created_at","updated_at"],"title":"PartnerProjectResponse","description":"Partner project response with aggregated counts.\n\nRepresents a property address with all associated Pro Mode generations."},"PartnerProjectWithDesigns":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"contractor_id":{"type":"string","format":"uuid","title":"Contractor Id"},"normalized_address":{"type":"string","title":"Normalized Address","description":"Lowercase, standardized address for duplicate detection"},"display_address":{"type":"string","title":"Display Address","description":"Original user-entered address format"},"place_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place Id"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State Code"},"zip_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip Code"},"generation_count":{"type":"integer","title":"Generation Count","description":"Total number of Pro Mode generations for this address","default":0},"proposal_count":{"type":"integer","title":"Proposal Count","description":"Total number of proposals using designs from this project","default":0},"last_generation_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Generation At","description":"When the most recent generation was created"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"recent_designs":{"items":{"$ref":"#/components/schemas/DesignSummary"},"type":"array","title":"Recent Designs","description":"Most recent 10 designs for this project"}},"type":"object","required":["id","contractor_id","normalized_address","display_address","created_at","updated_at"],"title":"PartnerProjectWithDesigns","description":"Partner project with recent designs included.\n\nUsed for the project detail view, showing the 10 most recent designs."},"PartnerProjectsListResponse":{"properties":{"projects":{"items":{"$ref":"#/components/schemas/PartnerProjectResponse"},"type":"array","title":"Projects"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["projects","total","page","limit","has_more"],"title":"PartnerProjectsListResponse","description":"Paginated list of partner projects."},"PartnerSignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email","description":"Partner's email address"},"business_name":{"type":"string","maxLength":200,"minLength":2,"title":"Business Name","description":"Business name"},"contact_name":{"type":"string","maxLength":100,"minLength":2,"title":"Contact Name","description":"Contact person's name"},"contact_phone":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Contact Phone","description":"Contact phone number"},"specializations":{"items":{"type":"string"},"type":"array","title":"Specializations","description":"Service specializations"},"headquarters_zip":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Headquarters Zip","description":"Headquarters ZIP code"},"headquarters_state":{"anyOf":[{"type":"string","maxLength":2},{"type":"null"}],"title":"Headquarters State","description":"Headquarters state code"},"website_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Website Url","description":"Business website URL"},"bio":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Bio","description":"Business description"},"years_in_business":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Years In Business","description":"Years in business"},"agreed_to_disclaimers":{"type":"boolean","title":"Agreed To Disclaimers","description":"User agreed to disclaimers"},"agreed_to_terms":{"type":"boolean","title":"Agreed To Terms","description":"User agreed to terms of service"}},"type":"object","required":["email","business_name","contact_name","agreed_to_disclaimers","agreed_to_terms"],"title":"PartnerSignupRequest","description":"Request body for partner signup (unauthenticated)."},"PartnerSignupResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"is_existing_user":{"type":"boolean","title":"Is Existing User","default":false},"email":{"type":"string","title":"Email"}},"type":"object","required":["success","message","email"],"title":"PartnerSignupResponse","description":"Response for partner signup initiation."},"PatioSurfaceType":{"type":"string","enum":["auto","travertine","flagstone","paver_stone","brick","concrete","stamped_concrete","composite_deck","wood_deck","slate","none"],"title":"PatioSurfaceType","description":"Patio and walkway surface types."},"PaymentDashboard":{"properties":{"token_purchases":{"$ref":"#/components/schemas/TokenPurchaseSummary"},"subscriptions":{"items":{"$ref":"#/components/schemas/SubscriptionSummary"},"type":"array","title":"Subscriptions"},"token_balances":{"items":{"$ref":"#/components/schemas/TokenBalance"},"type":"array","title":"Token Balances"},"recent_transactions":{"items":{"$ref":"#/components/schemas/RecentTransaction"},"type":"array","title":"Recent Transactions"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["token_purchases","subscriptions","token_balances","recent_transactions","generated_at"],"title":"PaymentDashboard","description":"Complete payment visibility dashboard."},"PaymentStatusResponse":{"properties":{"active_payment_method":{"type":"string","title":"Active Payment Method","description":"Currently active payment method (hierarchy: subscription > trial > token > none)","examples":["subscription","trial","token","none"]},"trial_remaining":{"type":"integer","minimum":0.0,"title":"Trial Remaining","description":"Trial credits remaining (3 on registration)"},"trial_used":{"type":"integer","minimum":0.0,"title":"Trial Used","description":"Trial credits used"},"token_balance":{"type":"integer","minimum":0.0,"title":"Token Balance","description":"Purchased tokens available"},"subscription_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Tier","description":"Subscription tier (e.g. 'monthly_pro')","examples":["monthly_pro",null]},"subscription_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Status","description":"Subscription status (active/past_due/cancelled)","examples":["active","past_due",null]},"can_generate":{"type":"boolean","title":"Can Generate","description":"Whether user has any payment method available"}},"type":"object","required":["active_payment_method","trial_remaining","trial_used","token_balance","can_generate"],"title":"PaymentStatusResponse","description":"User's current payment capabilities for generation flow.\n\nFeature: 004-generation-flow\nEndpoint: GET /v1/users/payment-status\nRequirements: FR-007 (payment hierarchy), FR-019 (payment display)"},"PaymentType":{"type":"string","enum":["trial","token","subscription","property_pass"],"title":"PaymentType","description":"Payment method for generation"},"PerformanceSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"breakdowns":{"items":{"$ref":"#/components/schemas/LatencyBreakdown"},"type":"array","title":"Breakdowns"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","breakdowns","generated_at"],"title":"PerformanceSummary"},"PinAnnotateResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether the operation completed successfully"},"editId":{"type":"string","format":"uuid","title":"Editid","description":"UUID of the edit record"},"status":{"type":"string","title":"Status","description":"Current status: completed or failed"},"resultImageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resultimageurl","description":"URL to the regenerated image"},"resultVariantId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resultvariantid","description":"UUID of the newly created generation/variant"},"llmUnderstanding":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llmunderstanding","description":"LLM's interpretation of the pin annotations"},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Errormessage","description":"Error details if failed"}},"type":"object","required":["success","editId","status"],"title":"PinAnnotateResponse","description":"Response model for pin annotation endpoint."},"PipelineStage":{"properties":{"stage":{"type":"string","title":"Stage"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["stage","count"],"title":"PipelineStage"},"PipelineStageSummary":{"properties":{"stage":{"type":"string","title":"Stage"},"influencer_count":{"type":"integer","title":"Influencer Count"},"tier1_count":{"type":"integer","title":"Tier1 Count","default":0},"tier2_count":{"type":"integer","title":"Tier2 Count","default":0},"tier3_count":{"type":"integer","title":"Tier3 Count","default":0}},"type":"object","required":["stage","influencer_count"],"title":"PipelineStageSummary"},"PipelineStatsResponse":{"properties":{"by_status":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Status"},"by_platform":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Platform"},"upcoming_7_days":{"type":"integer","title":"Upcoming 7 Days"},"total_content":{"type":"integer","title":"Total Content"},"performance":{"additionalProperties":{"type":"integer"},"type":"object","title":"Performance"}},"type":"object","required":["by_status","by_platform","upcoming_7_days","total_content","performance"],"title":"PipelineStatsResponse","description":"Response containing pipeline statistics."},"Plan":{"properties":{"plan_id":{"type":"string","title":"Plan Id","description":"Plan identifier, e.g., 'g3p_credits_starter'"},"name":{"type":"string","title":"Name","description":"Plan display name"},"credits":{"type":"integer","title":"Credits","description":"Number of design credits"},"price_cents":{"type":"integer","title":"Price Cents","description":"Price in cents"},"price_per_credit":{"type":"number","title":"Price Per Credit","description":"Cost per credit in USD"}},"type":"object","required":["plan_id","name","credits","price_cents","price_per_credit"],"title":"Plan","description":"Pricing plan details"},"PlanToRenderRequest":{"properties":{"plan_base64":{"type":"string","title":"Plan Base64","description":"Base64-encoded 2D landscape plan (PDF or image)"},"plan_mime_type":{"type":"string","title":"Plan Mime Type","description":"MIME type: application/pdf, image/png, image/jpeg, image/heic"},"plan_filename":{"type":"string","title":"Plan Filename","description":"Original filename","default":"plan"},"house_photo_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"House Photo Base64","description":"Optional base64-encoded house exterior photo"},"house_photo_mime_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"House Photo Mime Type","description":"House photo MIME type"},"num_renders":{"type":"integer","maximum":12.0,"minimum":4.0,"title":"Num Renders","description":"Number of renders to generate (4-12)","default":8}},"type":"object","required":["plan_base64","plan_mime_type"],"title":"PlanToRenderRequest","description":"Request for Plan-to-Render feature"},"Platform":{"type":"string","enum":["pinterest","instagram","tiktok","youtube","reddit","nextdoor","facebook","linkedin","blog","email"],"title":"Platform","description":"Supported social media platforms."},"PolygonVertex":{"properties":{"x":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X"},"y":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y"}},"type":"object","required":["x","y"],"title":"PolygonVertex"},"PortfolioProjectCreateRequest":{"properties":{"title":{"type":"string","maxLength":200,"minLength":5,"title":"Title","description":"Project title"},"description":{"type":"string","minLength":20,"title":"Description","description":"Detailed project description"},"project_type":{"type":"string","maxLength":100,"title":"Project Type","description":"Type of project (e.g., 'Front Yard Renovation')"},"city":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"City"},"state_code":{"anyOf":[{"type":"string","maxLength":2},{"type":"null"}],"title":"State Code"},"before_images":{"items":{"type":"string"},"type":"array","title":"Before Images","description":"Array of before image URLs"},"after_images":{"items":{"type":"string"},"type":"array","title":"After Images","description":"Array of after image URLs"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"completion_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Completion Date"},"duration_days":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Duration Days","description":"Project duration in days"},"project_cost_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Project Cost Min","description":"Minimum project cost in dollars"},"project_cost_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Project Cost Max","description":"Maximum project cost in dollars"},"client_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Client Name","description":"Client name (can be anonymous)"},"testimonial":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Testimonial"},"rating":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Rating","description":"Client rating (1-5 stars)"},"is_featured":{"type":"boolean","title":"Is Featured","description":"Feature on contractor profile","default":false},"is_public":{"type":"boolean","title":"Is Public","description":"Public visibility","default":true},"display_order":{"type":"integer","title":"Display Order","description":"Manual ordering (higher = shown first)","default":0}},"type":"object","required":["title","description","project_type"],"title":"PortfolioProjectCreateRequest","description":"Request to create a new portfolio project"},"PortfolioProjectPublicResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"project_type":{"type":"string","title":"Project Type"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State Code"},"before_images":{"items":{"type":"string"},"type":"array","title":"Before Images"},"after_images":{"items":{"type":"string"},"type":"array","title":"After Images"},"completion_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Completion Date"},"duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Days"},"project_cost_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Project Cost Min"},"project_cost_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Project Cost Max"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"testimonial":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Testimonial"},"rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating"},"is_featured":{"type":"boolean","title":"Is Featured"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","title","description","project_type","is_featured","created_at"],"title":"PortfolioProjectPublicResponse","description":"Public view of a portfolio project (for homeowners)"},"PortfolioProjectResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"contractor_id":{"type":"string","format":"uuid","title":"Contractor Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"project_type":{"type":"string","title":"Project Type"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State Code"},"before_images":{"items":{"type":"string"},"type":"array","title":"Before Images"},"after_images":{"items":{"type":"string"},"type":"array","title":"After Images"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"completion_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Completion Date"},"duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Days"},"project_cost_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Project Cost Min"},"project_cost_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Project Cost Max"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"testimonial":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Testimonial"},"rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating"},"is_featured":{"type":"boolean","title":"Is Featured"},"is_public":{"type":"boolean","title":"Is Public"},"display_order":{"type":"integer","title":"Display Order"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","contractor_id","title","description","project_type","is_featured","is_public","display_order","created_at","updated_at"],"title":"PortfolioProjectResponse","description":"Response model for a portfolio project"},"PortfolioProjectUpdateRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200,"minLength":5},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string","minLength":20},{"type":"null"}],"title":"Description"},"project_type":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Project Type"},"city":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"City"},"state_code":{"anyOf":[{"type":"string","maxLength":2},{"type":"null"}],"title":"State Code"},"before_images":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Before Images"},"after_images":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"After Images"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"completion_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Completion Date"},"duration_days":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Duration Days"},"project_cost_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Project Cost Min"},"project_cost_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Project Cost Max"},"client_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Client Name"},"testimonial":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Testimonial"},"rating":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Rating"},"is_featured":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Featured"},"is_public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"},"display_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Display Order"}},"type":"object","title":"PortfolioProjectUpdateRequest","description":"Request to update an existing portfolio project"},"PortfolioStatsResponse":{"properties":{"total_projects":{"type":"integer","title":"Total Projects"},"average_rating":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Average Rating"},"featured_count":{"type":"integer","title":"Featured Count"},"total_images":{"type":"integer","title":"Total Images"}},"type":"object","required":["total_projects","featured_count","total_images"],"title":"PortfolioStatsResponse","description":"Portfolio statistics for a contractor"},"Position":{"properties":{"x":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X"},"y":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y"}},"type":"object","required":["x","y"],"title":"Position","description":"Relative position within the design image (0-1 normalized)."},"PrecisionSettings":{"properties":{"boundary_accuracy":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Boundary Accuracy"},"scale_calibration":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scale Calibration"}},"type":"object","title":"PrecisionSettings","description":"Precision settings for architects"},"PrequalificationData":{"properties":{"timeline":{"type":"string","title":"Timeline","description":"When they want to start: asap, 1-3months, 3-6months, exploring"},"access_restrictions":{"items":{"type":"string"},"type":"array","title":"Access Restrictions","description":"Access restrictions: no-restrictions, gate-code, pets, hoa-approval, other"},"hardscape_needs":{"items":{"type":"string"},"type":"array","title":"Hardscape Needs","description":"Hardscape needs: none, patio, walkway, retaining-wall, driveway, multiple"}},"type":"object","required":["timeline"],"title":"PrequalificationData","description":"Pre-qualification data collected from homeowner."},"Pricing":{"properties":{"plan":{"type":"string","title":"Plan","description":"Plan type: 'free' or 'pro'"},"price_monthly":{"type":"number","title":"Price Monthly","description":"Monthly price in USD"},"price_yearly":{"type":"number","title":"Price Yearly","description":"Yearly price in USD"},"features":{"items":{"$ref":"#/components/schemas/PricingFeature"},"type":"array","title":"Features","description":"List of plan features"},"limits":{"anyOf":[{"$ref":"#/components/schemas/PricingLimits"},{"type":"null"}],"description":"Usage limits"},"trial_info":{"anyOf":[{"$ref":"#/components/schemas/PricingTrialInfo"},{"type":"null"}],"description":"Trial information"}},"type":"object","required":["plan","price_monthly","price_yearly","features"],"title":"Pricing"},"PricingFeature":{"properties":{"name":{"type":"string","title":"Name","description":"Feature name"},"included":{"type":"boolean","title":"Included","description":"Whether feature is included in plan"},"limit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Limit","description":"Limit if applicable"}},"type":"object","required":["name","included"],"title":"PricingFeature"},"PricingLimits":{"properties":{"designs_per_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Designs Per Month","description":"Monthly design limit"},"generations_per_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Generations Per Month","description":"Monthly generation limit"}},"type":"object","title":"PricingLimits"},"PricingResponse":{"properties":{"free":{"$ref":"#/components/schemas/Pricing","description":"Free plan details"},"pro":{"$ref":"#/components/schemas/Pricing","description":"Pro plan details"}},"type":"object","required":["free","pro"],"title":"PricingResponse"},"PricingTrialInfo":{"properties":{"days":{"type":"integer","title":"Days","description":"Trial period in days"},"designs_included":{"type":"integer","title":"Designs Included","description":"Designs included in trial"}},"type":"object","required":["days","designs_included"],"title":"PricingTrialInfo"},"ProModeGenerationSummary":{"properties":{"id":{"type":"string","title":"Id","description":"Generation UUID"},"address":{"type":"string","title":"Address","description":"Property address"},"design_url":{"type":"string","title":"Design Url","description":"URL of the design image"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url","description":"Thumbnail URL for gallery"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style","description":"Design style used"},"created_at":{"type":"string","title":"Created At","description":"ISO timestamp of creation"},"is_favorite":{"type":"boolean","title":"Is Favorite","description":"Whether user favorited this","default":false},"rendering_count":{"type":"integer","title":"Rendering Count","description":"Number of 3D renderings","default":0},"is_reference_design":{"type":"boolean","title":"Is Reference Design","description":"True if this is the reference design for this address","default":false},"reference_generation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Generation Id","description":"UUID of parent reference design (if this is a variant)"},"reference_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reference Version","description":"Version number for reference designs"},"variant_count":{"type":"integer","title":"Variant Count","description":"Number of variants linked to this reference design","default":0}},"type":"object","required":["id","address","design_url","created_at"],"title":"ProModeGenerationSummary","description":"Summary of a Pro Mode generation for history listing"},"ProModePreferencesResponse":{"properties":{"design_mode":{"type":"string","title":"Design Mode","description":"Design mode preference: quick (fast proposals) or studio (full creative control)","default":"quick"},"design_mode_set_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Design Mode Set At","description":"Timestamp when design mode was last changed"},"has_seen_mode_explainer":{"type":"boolean","title":"Has Seen Mode Explainer","description":"Whether user has seen the first-time mode explainer modal","default":false}},"type":"object","title":"ProModePreferencesResponse","description":"Response with user's Pro Mode preferences"},"ProUsageStatus":{"properties":{"has_pro_access":{"type":"boolean","title":"Has Pro Access","description":"Whether user has active Pro subscription"},"subscription_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Tier","description":"Current subscription tier"},"subscription_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Status","description":"Subscription status"},"quota_used":{"type":"integer","title":"Quota Used","description":"Pro generations used this billing period","default":0},"quota_total":{"type":"integer","title":"Quota Total","description":"Total monthly quota","default":0},"quota_remaining":{"type":"integer","title":"Quota Remaining","description":"Quota remaining this period","default":0},"quota_resets_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Quota Resets At","description":"When quota resets"},"g3p_credits_available":{"type":"integer","title":"G3P Credits Available","description":"G3P credits available","default":0},"total_generations_available":{"type":"integer","title":"Total Generations Available","description":"Total generations available (quota + G3P credits)","default":0},"can_generate":{"type":"boolean","title":"Can Generate","description":"Whether user can generate right now","default":false},"is_freemium":{"type":"boolean","title":"Is Freemium","description":"Whether user is on freemium trial","default":false},"freemium_generations_remaining":{"type":"integer","title":"Freemium Generations Remaining","description":"Freemium generations remaining","default":0},"freemium_trial_used":{"type":"boolean","title":"Freemium Trial Used","description":"Whether freemium trial has been used","default":false}},"type":"object","required":["has_pro_access"],"title":"ProUsageStatus","description":"Current Pro Mode usage status for a user.\n\nReturns quota and G3P credit information for UI display."},"ProcessingStage":{"type":"string","enum":["queued","retrieving_imagery","analyzing_property","generating_design","applying_style","finalizing","complete"],"title":"ProcessingStage","description":"Detailed progress tracking for area generation"},"ProjectBrief":{"properties":{"title":{"type":"string","maxLength":200,"title":"Title","description":"e.g., 'Front Yard Renovation - Modern Minimalist Style'"},"scope_summary":{"type":"string","maxLength":1000,"title":"Scope Summary","description":"2-3 sentence overview of the project scope"},"areas":{"items":{"$ref":"#/components/schemas/ProjectBriefArea"},"type":"array","title":"Areas","description":"Areas and styles selected by homeowner"},"address":{"type":"string","title":"Address","description":"Full property address"},"custom_prompts":{"items":{"type":"string"},"type":"array","title":"Custom Prompts","description":"Any custom requirements from homeowner"},"material_suggestions":{"items":{"type":"string"},"type":"array","title":"Material Suggestions","description":"AI-suggested materials based on style"},"estimated_sqft":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Sqft","description":"Estimated square footage (future feature)"},"ai_confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Ai Confidence","description":"AI confidence in the brief accuracy","default":0.85}},"type":"object","required":["title","scope_summary","address"],"title":"ProjectBrief","description":"AI-generated project brief for contractors.\n\nGenerated when homeowner clicks \"Get Build Estimates\" using\nGemini to create contractor-friendly summaries."},"ProjectBriefArea":{"properties":{"area_type":{"type":"string","title":"Area Type"},"style":{"type":"string","title":"Style"},"custom_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Prompt"}},"type":"object","required":["area_type","style"],"title":"ProjectBriefArea","description":"Individual area in project brief."},"ProjectContractorListResponse":{"properties":{"projects":{"items":{"$ref":"#/components/schemas/ProjectContractorViewResponse"},"type":"array","title":"Projects"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["projects","total","page","limit","has_more"],"title":"ProjectContractorListResponse","description":"Paginated project list for contractors."},"ProjectContractorViewResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_brief":{"$ref":"#/components/schemas/ProjectBrief"},"full_address":{"type":"string","title":"Full Address"},"city":{"type":"string","title":"City"},"state_code":{"type":"string","title":"State Code"},"zip_code":{"type":"string","title":"Zip Code"},"status":{"$ref":"#/components/schemas/MarketplaceProjectStatus"},"proposals_close_at":{"type":"string","format":"date-time","title":"Proposals Close At"},"proposal_count":{"type":"integer","title":"Proposal Count"},"ai_design_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Design Image Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","project_brief","full_address","city","state_code","zip_code","status","proposals_close_at","proposal_count","created_at"],"title":"ProjectContractorViewResponse","description":"Project view for contractors (pre-proposal info).\n\nShows address and AI image but NO homeowner contact info.\nContact info is only exchanged after proposal acceptance."},"ProjectCreateRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"UUID of completed AI generation"},"consent_given":{"type":"boolean","title":"Consent Given","description":"User must consent to share contact info with contractors (CCPA compliance)"},"consent_timestamp":{"type":"string","title":"Consent Timestamp","description":"ISO timestamp when user gave consent"},"additional_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Additional Notes","description":"Optional additional notes from homeowner"},"prequalification":{"anyOf":[{"$ref":"#/components/schemas/PrequalificationData"},{"type":"null"}],"description":"Pre-qualification data: timeline, access restrictions, hardscape needs"}},"type":"object","required":["generation_id","consent_given","consent_timestamp"],"title":"ProjectCreateRequest","description":"Request to create a marketplace project from a generation.\n\nCalled when homeowner clicks \"Get Build Estimates\" on a\ncompleted AI generation."},"ProjectDesignsListResponse":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/DesignSummary"},"type":"array","title":"Designs"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["designs","total","page","limit","has_more"],"title":"ProjectDesignsListResponse","description":"Paginated list of designs for a specific project."},"ProjectListResponse":{"properties":{"projects":{"items":{"$ref":"#/components/schemas/ProjectResponse"},"type":"array","title":"Projects"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["projects","total","page","limit","has_more"],"title":"ProjectListResponse","description":"Paginated project list response."},"ProjectPaymentSummary":{"properties":{"project_id":{"type":"string","format":"uuid","title":"Project Id"},"total_contract_cents":{"type":"integer","title":"Total Contract Cents"},"held_in_escrow_cents":{"type":"integer","title":"Held In Escrow Cents"},"released_to_contractor_cents":{"type":"integer","title":"Released To Contractor Cents"},"refunded_cents":{"type":"integer","title":"Refunded Cents"},"pending_approval_cents":{"type":"integer","title":"Pending Approval Cents"},"milestones":{"items":{"$ref":"#/components/schemas/MilestoneResponse"},"type":"array","title":"Milestones"},"payments":{"items":{"$ref":"#/components/schemas/EscrowPaymentResponse"},"type":"array","title":"Payments"}},"type":"object","required":["project_id","total_contract_cents","held_in_escrow_cents","released_to_contractor_cents","refunded_cents","pending_approval_cents","milestones","payments"],"title":"ProjectPaymentSummary","description":"Summary of all payments for a project."},"ProjectResponse":{"properties":{"id":{"type":"string","title":"Id"},"homeowner_user_id":{"type":"string","title":"Homeowner User Id"},"generation_id":{"type":"string","title":"Generation Id"},"project_brief":{"$ref":"#/components/schemas/ProjectBrief"},"full_address":{"type":"string","title":"Full Address"},"city":{"type":"string","title":"City"},"state_code":{"type":"string","title":"State Code"},"zip_code":{"type":"string","title":"Zip Code"},"status":{"$ref":"#/components/schemas/MarketplaceProjectStatus"},"proposals_open_at":{"type":"string","format":"date-time","title":"Proposals Open At"},"proposals_close_at":{"type":"string","format":"date-time","title":"Proposals Close At"},"view_count":{"type":"integer","title":"View Count"},"proposal_count":{"type":"integer","title":"Proposal Count"},"accepted_proposal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accepted Proposal Id"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","homeowner_user_id","generation_id","project_brief","full_address","city","state_code","zip_code","status","proposals_open_at","proposals_close_at","view_count","proposal_count","created_at","updated_at"],"title":"ProjectResponse","description":"Full project response for homeowner."},"PromoCodeInfo":{"properties":{"code":{"type":"string","title":"Code","description":"The promo code"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Code description"},"duration_days":{"type":"integer","title":"Duration Days","description":"Days of Pro access granted"},"is_valid":{"type":"boolean","title":"Is Valid","description":"Whether the code can be redeemed"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message","description":"Why code is invalid"}},"type":"object","required":["code","duration_days","is_valid"],"title":"PromoCodeInfo","description":"Public information about a promo code.\n\nReturned when validating a code (before redemption)."},"PropertyBoundary":{"properties":{"coordinates":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Coordinates","description":"List of [x, y] points defining the property boundary (0-1 normalized)"},"perimeter_ft":{"type":"number","exclusiveMinimum":0.0,"title":"Perimeter Ft"}},"type":"object","required":["coordinates","perimeter_ft"],"title":"PropertyBoundary","description":"Property boundary coordinates for overlay rendering."},"PropertyClassification":{"properties":{"layout_type":{"$ref":"#/components/schemas/LayoutType","description":"Primary layout type (most important for camera positioning)"},"lot_size":{"$ref":"#/components/schemas/LotSize","description":"Estimated lot size category"},"terrain_type":{"$ref":"#/components/schemas/TerrainType","description":"Terrain slope classification","default":"flat"},"driveway_config":{"$ref":"#/components/schemas/DrivewayConfig","description":"Detected driveway position","default":"not_visible"},"is_corner_lot":{"type":"boolean","title":"Is Corner Lot","description":"True if streets on 2+ sides","default":false},"is_cul_de_sac":{"type":"boolean","title":"Is Cul De Sac","description":"True if on curved/circular street","default":false},"detection_confidence":{"$ref":"#/components/schemas/DetectionConfidence","description":"Confidence in classification accuracy","default":"medium"},"detection_source":{"type":"string","title":"Detection Source","description":"Source of classification (gemini, street_view, fallback)","default":"gemini"}},"type":"object","required":["layout_type","lot_size"],"title":"PropertyClassification","description":"Complete property classification result.\n\nUsed to determine camera positioning strategy based on detected property\ncharacteristics. Layout type is the most important factor."},"PropertyEstimateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"generation_id":{"type":"string","format":"uuid","title":"Generation Id"},"measurements":{"$ref":"#/components/schemas/PropertyMeasurements"},"segment_masks":{"additionalProperties":true,"type":"object","title":"Segment Masks"},"solar_api_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Solar Api Confidence"},"samgeo_model_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Samgeo Model Version"},"calibration_source":{"type":"string","title":"Calibration Source","default":"solar_api"},"is_verified":{"type":"boolean","title":"Is Verified","default":false},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","project_id","generation_id","measurements","created_at","updated_at"],"title":"PropertyEstimateResponse","description":"Full property estimate response."},"PropertyInfoRequest":{"properties":{"address":{"type":"string","maxLength":500,"minLength":5,"title":"Address","description":"Full street address including city, state, and ZIP"}},"type":"object","required":["address"],"title":"PropertyInfoRequest"},"PropertyInfoResponse":{"properties":{"address_parsed":{"$ref":"#/components/schemas/AddressParsed"},"satellite_image_url":{"type":"string","title":"Satellite Image Url"},"street_view_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street View Image Url"},"boundary_polygon":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Boundary Polygon"},"lot_dimensions":{"$ref":"#/components/schemas/src__api__endpoints__agent_api__LotDimensions"},"imagery_date":{"type":"string","title":"Imagery Date"},"hardiness_zone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardiness Zone","description":"USDA Plant Hardiness Zone (e.g., '7a', '9b'). Used for climate-appropriate style recommendations."}},"type":"object","required":["address_parsed","satellite_image_url","boundary_polygon","lot_dimensions","imagery_date"],"title":"PropertyInfoResponse"},"PropertyInsights":{"properties":{"heading":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Heading","description":"House facing direction in degrees (0-360)"},"heading_cardinal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Heading Cardinal","description":"Cardinal direction house faces: N, NE, E, SE, S, SW, W, NW"},"lot_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Type","description":"RECTANGLE, WEDGE, CORNER, FLAG, IRREGULAR"},"street_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Type","description":"GRID, CUL_DE_SAC, CURVILINEAR, RURAL"},"street_edge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Edge","description":"TOP, BOTTOM, LEFT, RIGHT"},"lot_size_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lot Size Sqft","description":"Total lot area in square feet"},"lot_size_classification":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Size Classification","description":"SMALL (<5000), MEDIUM (5000-10000), LARGE (10000-20000), ESTATE (>20000)"},"front_yard_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Yard Sqft","description":"Front yard area in sq ft"},"backyard_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backyard Sqft","description":"Backyard area in sq ft"},"side_yard_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Side Yard Sqft","description":"Side yard area in sq ft"},"front_yard_depth_ft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Yard Depth Ft","description":"Front yard depth in feet"},"backyard_depth_ft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backyard Depth Ft","description":"Backyard depth in feet"},"backyard_width_ft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backyard Width Ft","description":"Backyard width in feet"},"detected_features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Detected Features","description":"Existing features spotted: e.g. ['2 Trees', 'Patio', 'Fence']"},"boundary_polygon":{"anyOf":[{"items":{"$ref":"#/components/schemas/BoundaryPoint"},"type":"array"},{"type":"null"}],"title":"Boundary Polygon","description":"Normalized 0-1 coordinate polygon for SVG overlay on satellite image"},"hardiness_zone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardiness Zone","description":"USDA Plant Hardiness Zone (e.g. '7a')"},"hardiness_zone_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardiness Zone Description","description":"Temperature range description (e.g. '0 to 5°F minimum')"},"plan_preview_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Preview Url","description":"B&W 2D plan image URL available before full generation completes"}},"type":"object","title":"PropertyInsights","description":"Property metadata surfaced during generation for the waiting experience.\n\nFields are progressively populated as each pipeline stage completes:\n- After Street View metadata fetch: heading, heading_cardinal\n- After Call 0 (boundary): boundary_polygon, lot_type, street_type, street_edge\n- After Call 1 (analysis): yard dimensions, lot_size, detected_features\n- After Call 2 (2D plan): plan_preview_url"},"PropertyMeasurements":{"properties":{"lot_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Area Sqft"},"building_footprint_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Building Footprint Sqft"},"roof_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Roof Area Sqft"},"driveway_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Driveway Area Sqft"},"lawn_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lawn Area Sqft"},"hardscape_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardscape Area Sqft"},"pool_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pool Area Sqft"},"garden_bed_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Garden Bed Area Sqft"},"patio_area_sqft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Patio Area Sqft"},"fence_linear_ft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fence Linear Ft"},"walkway_linear_ft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Walkway Linear Ft"},"edging_linear_ft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Edging Linear Ft"}},"type":"object","title":"PropertyMeasurements","description":"Property area and linear measurements from SAMGeo + Solar API."},"PropertyPassCheckResponse":{"properties":{"has_active_pass":{"type":"boolean","title":"Has Active Pass"},"pass_details":{"anyOf":[{"$ref":"#/components/schemas/PropertyPassResponse"},{"type":"null"}]},"place_id":{"type":"string","title":"Place Id"},"formatted_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formatted Address"}},"type":"object","required":["has_active_pass","place_id"],"title":"PropertyPassCheckResponse","description":"Response for checking if user has active pass for address."},"PropertyPassCheckoutRequest":{"properties":{"place_id":{"type":"string","title":"Place Id","description":"Google Place ID"},"formatted_address":{"type":"string","title":"Formatted Address","description":"Human-readable address"}},"type":"object","required":["place_id","formatted_address"],"title":"PropertyPassCheckoutRequest","description":"Request to create checkout session for property pass."},"PropertyPassCheckoutResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"},"session_id":{"type":"string","title":"Session Id"},"place_id":{"type":"string","title":"Place Id"},"formatted_address":{"type":"string","title":"Formatted Address"},"price_cents":{"type":"integer","title":"Price Cents","default":999},"duration_hours":{"type":"integer","title":"Duration Hours","default":120}},"type":"object","required":["checkout_url","session_id","place_id","formatted_address"],"title":"PropertyPassCheckoutResponse","description":"Response from creating checkout session."},"PropertyPassListResponse":{"properties":{"active_passes":{"items":{"$ref":"#/components/schemas/PropertyPassResponse"},"type":"array","title":"Active Passes"},"expired_passes":{"items":{"$ref":"#/components/schemas/PropertyPassResponse"},"type":"array","title":"Expired Passes"},"total_active":{"type":"integer","title":"Total Active"},"total_expired":{"type":"integer","title":"Total Expired"}},"type":"object","required":["active_passes","expired_passes","total_active","total_expired"],"title":"PropertyPassListResponse","description":"Response for listing user's property passes."},"PropertyPassResponse":{"properties":{"place_id":{"type":"string","title":"Place Id","description":"Google Place ID for address matching"},"formatted_address":{"type":"string","title":"Formatted Address","description":"Human-readable address"},"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"purchased_at":{"type":"string","format":"date-time","title":"Purchased At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"price_paid_cents":{"type":"integer","title":"Price Paid Cents","default":999},"grant_type":{"type":"string","title":"Grant Type","default":"stripe_purchase"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_active":{"type":"boolean","title":"Is Active","description":"Check if pass is currently active.","readOnly":true},"hours_remaining":{"type":"number","title":"Hours Remaining","description":"Hours remaining on pass.","readOnly":true},"days_remaining":{"type":"number","title":"Days Remaining","description":"Days remaining on pass.","readOnly":true}},"type":"object","required":["place_id","formatted_address","id","user_id","purchased_at","expires_at","created_at","is_active","hours_remaining","days_remaining"],"title":"PropertyPassResponse","description":"Response model for property pass."},"ProposalCreateRequest":{"properties":{"project_id":{"type":"string","title":"Project Id","description":"UUID of the project to submit proposal for"},"price_range_min":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Price Range Min","description":"[Legacy] Minimum estimate in dollars"},"price_range_max":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Price Range Max","description":"[Legacy] Maximum estimate in dollars"},"pro_mode_generation_ids":{"items":{"type":"string"},"type":"array","title":"Pro Mode Generation Ids","description":"UUIDs of Pro Mode designs to include in proposal (max 3)"},"line_items":{"items":{"$ref":"#/components/schemas/LineItemCreate"},"type":"array","title":"Line Items","description":"Itemized pricing breakdown"},"design_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Design Notes","description":"Contractor's explanation of design choices and approach"},"estimated_duration_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Estimated Duration Days","description":"Estimated project duration in days"},"message":{"type":"string","maxLength":2000,"minLength":50,"title":"Message","description":"Pitch message to homeowner (min 50 chars)"}},"type":"object","required":["project_id","message"],"title":"ProposalCreateRequest","description":"Request to submit a proposal on a project.\n\nSupports two modes:\n1. Legacy: price_range_min/max with message\n2. Pro Mode: pro_mode_generation_ids + line_items + message\n\nAt least one pricing method must be provided."},"ProposalResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"contractor_id":{"type":"string","title":"Contractor Id"},"price_range_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Range Min"},"price_range_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Range Max"},"pro_mode_generation_ids":{"items":{"type":"string"},"type":"array","title":"Pro Mode Generation Ids"},"line_items":{"items":{"$ref":"#/components/schemas/LineItem"},"type":"array","title":"Line Items"},"total_price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Total Price"},"design_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Notes"},"estimated_duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Duration Days"},"message":{"type":"string","title":"Message"},"status":{"$ref":"#/components/schemas/MarketplaceProposalStatus"},"viewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Viewed At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"rejected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Rejected At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","project_id","contractor_id","message","status","created_at","updated_at"],"title":"ProposalResponse","description":"Full proposal response."},"ProposalStatus":{"type":"string","enum":["pending","viewed","accepted","rejected","withdrawn"],"title":"ProposalStatus","description":"Proposal status values."},"ProposalSummary":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"contractor_business_name":{"type":"string","title":"Contractor Business Name"},"contractor_email":{"type":"string","title":"Contractor Email"},"price_range_min":{"type":"integer","title":"Price Range Min"},"price_range_max":{"type":"integer","title":"Price Range Max"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","project_id","contractor_business_name","contractor_email","price_range_min","price_range_max","status","created_at"],"title":"ProposalSummary","description":"Summary info for a proposal"},"ProposalUpdateRequest":{"properties":{"price_range_min":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Price Range Min"},"price_range_max":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Price Range Max"},"estimated_duration_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Estimated Duration Days"},"message":{"anyOf":[{"type":"string","maxLength":2000,"minLength":50},{"type":"null"}],"title":"Message"},"pro_mode_generation_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Pro Mode Generation Ids","description":"Updated list of Pro Mode design UUIDs"},"line_items":{"anyOf":[{"items":{"$ref":"#/components/schemas/LineItemCreate"},"type":"array"},{"type":"null"}],"title":"Line Items","description":"Updated line items"},"design_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Design Notes","description":"Updated design notes"}},"type":"object","title":"ProposalUpdateRequest","description":"Request to update a pending proposal."},"ProposalWithContractorResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"price_range_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Range Min"},"price_range_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Range Max"},"pro_mode_generation_ids":{"items":{"type":"string"},"type":"array","title":"Pro Mode Generation Ids"},"line_items":{"items":{"$ref":"#/components/schemas/LineItem"},"type":"array","title":"Line Items"},"total_price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Total Price"},"design_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Notes"},"estimated_duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Duration Days"},"message":{"type":"string","title":"Message"},"status":{"$ref":"#/components/schemas/MarketplaceProposalStatus"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"contractor":{"$ref":"#/components/schemas/ContractorPublicResponse"}},"type":"object","required":["id","project_id","message","status","created_at","contractor"],"title":"ProposalWithContractorResponse","description":"Proposal with contractor public info (for homeowner viewing proposals).\n\nIncludes public contractor profile but NOT contact info."},"ProxyMapRequest":{"properties":{"url":{"type":"string","title":"Url","description":"Full Google Maps Static API URL"}},"type":"object","required":["url"],"title":"ProxyMapRequest","description":"Request to proxy a Google Maps Static API image"},"ProxyMapResponse":{"properties":{"image_base64":{"type":"string","title":"Image Base64"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"}},"type":"object","required":["image_base64"],"title":"ProxyMapResponse","description":"Response with base64-encoded satellite image"},"PublicProposalResponse":{"properties":{"id":{"type":"string","title":"Id"},"address":{"type":"string","title":"Address"},"total_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Price"},"line_items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Line Items"},"design_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Notes"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"estimated_duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Duration Days"},"status":{"type":"string","title":"Status"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"contractor":{"additionalProperties":true,"type":"object","title":"Contractor"},"design_images":{"items":{"type":"string"},"type":"array","title":"Design Images"},"agent_design_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Design Id"},"satellite_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Url"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"}},"type":"object","required":["id","address","status","contractor"],"title":"PublicProposalResponse","description":"Public proposal data for /p/[id] page rendering."},"PublicReview":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"source_platform":{"type":"string","enum":["google","yelp","manual"],"title":"Source Platform"},"reviewer_name":{"type":"string","title":"Reviewer Name"},"rating":{"type":"integer","title":"Rating"},"review_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Text"},"review_date":{"type":"string","format":"date-time","title":"Review Date"},"response_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Text"}},"type":"object","required":["id","source_platform","reviewer_name","rating","review_date"],"title":"PublicReview","description":"Public-facing review model (visible reviews only)"},"PublicReviewListResponse":{"properties":{"reviews":{"items":{"$ref":"#/components/schemas/PublicReview"},"type":"array","title":"Reviews"},"average_rating":{"type":"number","title":"Average Rating"},"total_count":{"type":"integer","title":"Total Count"}},"type":"object","required":["reviews","average_rating","total_count"],"title":"PublicReviewListResponse","description":"Response for public review list endpoint"},"QuickDesignRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Full US property address"},"style":{"type":"string","title":"Style","description":"Design style: mediterranean, modern_minimalist, cottage_garden, japanese_zen, desert_xeriscape, tropical_resort","default":"mediterranean"}},"type":"object","required":["address"],"title":"QuickDesignRequest","description":"Request for quick street-view-based front yard redesign.\nNo boundary detection, no 2D plan — just a fast visual transformation.\nDesigned for ChatGPT GPT, MCP, and Google AI Mode agent flows."},"QuickDesignResponse":{"properties":{"design_id":{"type":"string","title":"Design Id","description":"Unique design ID"},"address":{"type":"string","title":"Address"},"style":{"type":"string","title":"Style"},"street_view_url":{"type":"string","title":"Street View Url","description":"Original street view image URL"},"satellite_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Url","description":"Satellite overview (display only)"},"design_url":{"type":"string","title":"Design Url","description":"AI-redesigned front yard image URL"},"promo":{"additionalProperties":true,"type":"object","title":"Promo","description":"CTA to promote full app"}},"type":"object","required":["design_id","address","style","street_view_url","design_url","promo"],"title":"QuickDesignResponse","description":"Response with street view before/after and promo CTA."},"RateLimitTier":{"properties":{"designs_per_day":{"type":"integer","title":"Designs Per Day","description":"Maximum designs per day"},"designs_per_minute":{"type":"integer","title":"Designs Per Minute","description":"Maximum designs per minute (burst)"}},"type":"object","required":["designs_per_day","designs_per_minute"],"title":"RateLimitTier","description":"Rate limit configuration"},"RateLimits":{"properties":{"default":{"$ref":"#/components/schemas/RateLimitTier","description":"Default tier rate limits"},"enterprise":{"$ref":"#/components/schemas/RateLimitTier","description":"Enterprise tier rate limits"}},"type":"object","required":["default","enterprise"],"title":"RateLimits","description":"All rate limit configurations"},"RatingDistribution":{"properties":{"1":{"type":"integer","title":"1","default":0},"2":{"type":"integer","title":"2","default":0},"3":{"type":"integer","title":"3","default":0},"4":{"type":"integer","title":"4","default":0},"5":{"type":"integer","title":"5","default":0}},"type":"object","title":"RatingDistribution","description":"Distribution of ratings 1-5"},"RecentTransaction":{"properties":{"type":{"type":"string","title":"Type"},"amount":{"type":"integer","title":"Amount"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"email":{"type":"string","title":"Email"},"balance_after":{"type":"integer","title":"Balance After"},"stripe_payment_intent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Payment Intent Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["type","amount","email","balance_after","created_at"],"title":"RecentTransaction"},"RecommendedViewpoint":{"properties":{"xPercent":{"type":"number","title":"Xpercent","description":"X position 0-100"},"yPercent":{"type":"number","title":"Ypercent","description":"Y position 0-100"},"description":{"type":"string","title":"Description","description":"Why this viewpoint was chosen","default":""}},"type":"object","required":["xPercent","yPercent"],"title":"RecommendedViewpoint","description":"Recommended 3D camera viewpoint position."},"RedeemPromoCodeRequest":{"properties":{"code":{"type":"string","maxLength":50,"minLength":3,"title":"Code","description":"Promo code to redeem"}},"type":"object","required":["code"],"title":"RedeemPromoCodeRequest","description":"Request to redeem a promo code."},"RedeemPromoCodeResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"subscription_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Tier"},"subscription_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Status"},"period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Period End"},"duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Days"}},"type":"object","required":["success","message"],"title":"RedeemPromoCodeResponse","description":"Response after successfully redeeming a promo code."},"ReferralCodeResponse":{"properties":{"referral_code":{"type":"string","title":"Referral Code","description":"User's unique referral code"},"referral_url":{"type":"string","title":"Referral Url","description":"Full shareable URL: https://yarda.pro/r/{code}"}},"type":"object","required":["referral_code","referral_url"],"title":"ReferralCodeResponse","description":"Response containing user's referral code and shareable URL."},"ReferralRecord":{"properties":{"email":{"type":"string","title":"Email","description":"Masked email of referred user (e.g., j***@gmail.com)"},"status":{"type":"string","title":"Status","description":"Referral status: pending, converted, rewarded"},"referred_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred At","description":"When user signed up with code"},"converted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Converted At","description":"When user made first purchase"},"credits_earned":{"type":"integer","title":"Credits Earned","description":"Credits earned from this referral","default":0}},"type":"object","required":["email","status"],"title":"ReferralRecord","description":"Individual referral record for dashboard display."},"ReferralStatsResponse":{"properties":{"referral_code":{"type":"string","title":"Referral Code","description":"User's unique referral code"},"referral_url":{"type":"string","title":"Referral Url","description":"Full shareable URL"},"successful_referrals":{"type":"integer","title":"Successful Referrals","description":"Number of successful (rewarded) referrals","default":0},"pending_referrals":{"type":"integer","title":"Pending Referrals","description":"Number of pending referrals","default":0},"total_credits_earned":{"type":"integer","title":"Total Credits Earned","description":"Total G3P credits earned from referrals","default":0},"annual_limit":{"type":"integer","title":"Annual Limit","description":"Maximum referrals per year","default":10},"annual_remaining":{"type":"integer","title":"Annual Remaining","description":"Remaining referrals this year","default":10},"annual_used":{"type":"integer","title":"Annual Used","description":"Referrals used this year","default":0},"recent_referrals":{"items":{"$ref":"#/components/schemas/ReferralRecord"},"type":"array","title":"Recent Referrals","description":"Recent referral activity (last 10)"}},"type":"object","required":["referral_code","referral_url"],"title":"ReferralStatsResponse","description":"Full referral statistics for dashboard."},"RefineDesignRequest":{"properties":{"session_id":{"type":"string","title":"Session Id","description":"Session ID from the original generation"},"instruction":{"type":"string","maxLength":2000,"minLength":3,"title":"Instruction","description":"Natural language instruction describing what to change"}},"type":"object","required":["session_id","instruction"],"title":"RefineDesignRequest","description":"Request to refine an existing design using NB2 multi-turn editing."},"RefineDesignResponse":{"properties":{"refinedImageBase64":{"type":"string","title":"Refinedimagebase64","description":"Base64-encoded refined design image"},"sessionId":{"type":"string","title":"Sessionid"},"instruction":{"type":"string","title":"Instruction"},"modelUsed":{"type":"string","title":"Modelused"}},"type":"object","required":["refinedImageBase64","sessionId","instruction","modelUsed"],"title":"RefineDesignResponse","description":"Response with the refined design image."},"RegenerateObliqueRequest":{"properties":{"generation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Id","description":"Legacy — no longer required"},"view_type":{"type":"string","title":"View Type","description":"'front' or 'back'"},"plan_image_base64":{"type":"string","title":"Plan Image Base64","description":"Base64-encoded updated 2D plan image"},"reference_image_base64":{"type":"string","title":"Reference Image Base64","description":"Base64-encoded 3D reference image for camera angle"},"style":{"type":"string","title":"Style","description":"Design style","default":"Modern Minimalist"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"Landscape features"},"analysis_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Analysis Json","description":"Site analysis from Call 1"},"layout_description":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description","description":"Plan layout from Call 2"},"street_edge":{"type":"string","title":"Street Edge","description":"Street edge direction","default":"BOTTOM"},"custom_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Prompt","description":"User custom prompt"},"material_preferences":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Material Preferences","description":"Material preferences"}},"type":"object","required":["view_type","plan_image_base64","reference_image_base64"],"title":"RegenerateObliqueRequest","description":"Request to regenerate a single oblique view from an updated 2D plan."},"RegenerateObliqueResponse":{"properties":{"oblique_image_base64":{"type":"string","title":"Oblique Image Base64"},"oblique_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oblique Image Url"},"view_type":{"type":"string","title":"View Type"},"credits_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits Remaining"}},"type":"object","required":["oblique_image_base64","view_type"],"title":"RegenerateObliqueResponse","description":"Response from oblique regeneration."},"RenderArea":{"type":"string","enum":["full","front_yard","backyard","side_yard"],"title":"RenderArea","description":"Render area types"},"RenderGroundLevelRequest":{"properties":{"designImageBase64":{"type":"string","title":"Designimagebase64","description":"Base64-encoded 2D design plan"},"style":{"type":"string","title":"Style","default":"Modern Minimalist"},"features":{"items":{"type":"string"},"type":"array","title":"Features","default":[]},"view_angle":{"type":"string","title":"View Angle","description":"Perspective: front_yard, backyard, pool_area, patio, side_yard","default":"front_yard"},"mime_type":{"type":"string","title":"Mime Type","default":"image/png"},"layoutDescription":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layoutdescription","description":"Structured layout from 2D generation for coherence"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"Lat/lng for Street View (front_yard only)"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address","description":"Address for Street View fallback"},"street_edge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Edge","description":"Which edge has the street (TOP/BOTTOM/LEFT/RIGHT)"},"primaryFeature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primaryfeature","description":"Feature that must be prominently visible from this viewpoint"},"satelliteImageBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satelliteimagebase64","description":"Base64-encoded satellite image for spatial analysis"},"referenceRenderingBase64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referencerenderingbase64","description":"Previously generated rendering to maintain consistency across views"},"use_public_view":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Use Public View","description":"Whether to use Street View (true) or front oblique (false) for front_yard"},"front_oblique_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Front Oblique Base64","description":"Front oblique rendering to use instead of Street View"}},"type":"object","required":["designImageBase64"],"title":"RenderGroundLevelRequest","description":"Request for ground-level 3D rendering"},"RenderGroundLevelResponse":{"properties":{"renderingBase64":{"type":"string","title":"Renderingbase64"}},"type":"object","required":["renderingBase64"],"title":"RenderGroundLevelResponse","description":"Response with photorealistic ground-level rendering"},"RenderView":{"type":"string","enum":["aerial","front","back","side"],"title":"RenderView","description":"Render view types"},"ReviewContentRequest":{"properties":{"content":{"additionalProperties":true,"type":"object","title":"Content","description":"Content dict with title, body, hook, etc."},"platform":{"type":"string","title":"Platform","description":"Target platform (pinterest, instagram, tiktok, linkedin, blog, facebook)"},"audience":{"type":"string","title":"Audience","description":"Target audience (homeowner, service_provider)","default":"homeowner"},"content_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Content Id","description":"Optional content ID from pipeline"},"model":{"anyOf":[{"$ref":"#/components/schemas/AIModel"},{"type":"null"}],"description":"AI model to use for review (defaults to same as generation)"}},"type":"object","required":["content","platform"],"title":"ReviewContentRequest","description":"Request to review content."},"ReviewImageRequest":{"properties":{"image_url":{"type":"string","title":"Image Url","description":"URL to the image to review"},"platform":{"type":"string","title":"Platform","description":"Target platform"},"content_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Content Context","description":"Optional content context for relevance checking"}},"type":"object","required":["image_url","platform"],"title":"ReviewImageRequest","description":"Request to review an image."},"ReviewImportResult":{"properties":{"imported_count":{"type":"integer","title":"Imported Count"},"skipped_count":{"type":"integer","title":"Skipped Count"},"errors":{"items":{"type":"string"},"type":"array","title":"Errors"},"reviews":{"items":{"$ref":"#/components/schemas/ImportedReview"},"type":"array","title":"Reviews"}},"type":"object","required":["imported_count","skipped_count","errors","reviews"],"title":"ReviewImportResult","description":"Result of a review import operation"},"ReviewListResponse":{"properties":{"reviews":{"items":{"$ref":"#/components/schemas/ImportedReview"},"type":"array","title":"Reviews"},"total":{"type":"integer","title":"Total"},"stats":{"$ref":"#/components/schemas/ReviewStats"}},"type":"object","required":["reviews","total","stats"],"title":"ReviewListResponse","description":"Response for review list endpoint"},"ReviewResultResponse":{"properties":{"content_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Content Id"},"platform":{"type":"string","title":"Platform"},"audience":{"type":"string","title":"Audience"},"platform_scores":{"additionalProperties":{"type":"number"},"type":"object","title":"Platform Scores"},"audience_scores":{"additionalProperties":{"type":"number"},"type":"object","title":"Audience Scores"},"platform_feedback":{"additionalProperties":{"type":"string"},"type":"object","title":"Platform Feedback"},"audience_feedback":{"additionalProperties":{"type":"string"},"type":"object","title":"Audience Feedback"},"overall_score":{"type":"number","title":"Overall Score"},"verdict":{"type":"string","title":"Verdict"},"issues":{"items":{"type":"string"},"type":"array","title":"Issues"},"suggestions":{"items":{"type":"string"},"type":"array","title":"Suggestions"},"overall_assessment":{"type":"string","title":"Overall Assessment"},"reviewer_model":{"type":"string","title":"Reviewer Model"},"review_timestamp":{"type":"string","title":"Review Timestamp"}},"type":"object","required":["content_id","platform","audience","platform_scores","audience_scores","platform_feedback","audience_feedback","overall_score","verdict","issues","suggestions","overall_assessment","reviewer_model","review_timestamp"],"title":"ReviewResultResponse","description":"Response from content review."},"ReviewStats":{"properties":{"average_rating":{"type":"number","title":"Average Rating"},"total_reviews":{"type":"integer","title":"Total Reviews"},"visible_reviews":{"type":"integer","title":"Visible Reviews"},"rating_distribution":{"$ref":"#/components/schemas/RatingDistribution"},"sources":{"additionalProperties":{"type":"integer"},"type":"object","title":"Sources"}},"type":"object","required":["average_rating","total_reviews","visible_reviews","rating_distribution","sources"],"title":"ReviewStats","description":"Review statistics for a contractor"},"RoiDashboardResponse":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"total_leads":{"type":"integer","title":"Total Leads"},"total_enriched":{"type":"integer","title":"Total Enriched"},"total_contacted":{"type":"integer","title":"Total Contacted"},"total_responded":{"type":"integer","title":"Total Responded"},"total_converted":{"type":"integer","title":"Total Converted"},"total_outreach_actions":{"type":"integer","title":"Total Outreach Actions"},"overall_response_rate":{"type":"number","title":"Overall Response Rate"},"overall_conversion_rate":{"type":"number","title":"Overall Conversion Rate"},"outreach_funnel":{"items":{"$ref":"#/components/schemas/src__api__endpoints__roi_dashboard__FunnelStage"},"type":"array","title":"Outreach Funnel"},"channel_effectiveness":{"items":{"$ref":"#/components/schemas/ChannelStats"},"type":"array","title":"Channel Effectiveness"},"campaign_runs":{"items":{"$ref":"#/components/schemas/CampaignRun"},"type":"array","title":"Campaign Runs"},"campaign_overall":{"additionalProperties":true,"type":"object","title":"Campaign Overall"},"pipeline_stages":{"items":{"$ref":"#/components/schemas/PipelineStage"},"type":"array","title":"Pipeline Stages"},"daily_activity":{"items":{"$ref":"#/components/schemas/DailyActivity"},"type":"array","title":"Daily Activity"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","total_leads","total_enriched","total_contacted","total_responded","total_converted","total_outreach_actions","overall_response_rate","overall_conversion_rate","outreach_funnel","channel_effectiveness","campaign_runs","campaign_overall","pipeline_stages","daily_activity","generated_at"],"title":"RoiDashboardResponse"},"SaveDesignVariantRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"UUID of the parent generation"},"variant_id":{"type":"string","title":"Variant Id","description":"Unique variant ID (e.g., 'variant-oblique-1234567')"},"map_style":{"type":"string","title":"Map Style","description":"Design style: 'Colorful', 'CAD Oblique', or 'CAD 2D'"},"design_image_base64":{"type":"string","title":"Design Image Base64","description":"Base64-encoded variant image"},"is_primary":{"type":"boolean","title":"Is Primary","description":"Whether this is the reference design","default":false}},"type":"object","required":["generation_id","variant_id","map_style","design_image_base64"],"title":"SaveDesignVariantRequest","description":"Request to save a design variant (CAD conversion) to an existing generation"},"SaveDesignVariantResponse":{"properties":{"variant_id":{"type":"string","title":"Variant Id","description":"ID of the saved variant"},"variant_url":{"type":"string","title":"Variant Url","description":"URL of the uploaded variant image"},"message":{"type":"string","title":"Message","default":"Variant saved successfully"}},"type":"object","required":["variant_id","variant_url"],"title":"SaveDesignVariantResponse","description":"Response after saving a design variant"},"SaveEditorSceneRequest":{"properties":{"scene":{"additionalProperties":true,"type":"object","title":"Scene","description":"Arbitrary JSON representing the full editor state"}},"type":"object","required":["scene"],"title":"SaveEditorSceneRequest","description":"Request to save an editor scene for a generation."},"SaveEditorSceneResponse":{"properties":{"generationId":{"type":"string","title":"Generationid"},"message":{"type":"string","title":"Message","default":"Scene saved successfully"}},"type":"object","required":["generationId"],"title":"SaveEditorSceneResponse","description":"Response after saving an editor scene."},"SaveLearnedParamsRequest":{"properties":{"layout_type":{"$ref":"#/components/schemas/LayoutType"},"lot_size":{"$ref":"#/components/schemas/LotSize"},"triangle_count_min":{"type":"integer","minimum":0.0,"title":"Triangle Count Min","default":0},"triangle_count_max":{"type":"integer","minimum":0.0,"title":"Triangle Count Max","default":999999999},"altitude":{"type":"number","exclusiveMinimum":0.0,"title":"Altitude"},"front_offset":{"type":"number","exclusiveMinimum":0.0,"title":"Front Offset"},"back_offset":{"type":"number","exclusiveMinimum":0.0,"title":"Back Offset"},"front_pitch":{"type":"number","maximum":0.0,"minimum":-90.0,"title":"Front Pitch"},"back_pitch":{"type":"number","maximum":0.0,"minimum":-90.0,"title":"Back Pitch"},"front_quality_score":{"anyOf":[{"type":"number","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Front Quality Score"},"back_quality_score":{"anyOf":[{"type":"number","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Back Quality Score"},"address_sample":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Sample"}},"type":"object","required":["layout_type","lot_size","altitude","front_offset","back_offset","front_pitch","back_pitch"],"title":"SaveLearnedParamsRequest","description":"Request model for saving learned parameters."},"SaveProModeGenerationRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Property address"},"place_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place Id","description":"Google Places place_id"},"style":{"type":"string","title":"Style","description":"Design style used"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"Features included in design","default":[]},"custom_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Prompt","description":"User's custom prompt"},"design_image_base64":{"type":"string","title":"Design Image Base64","description":"Base64-encoded design image"},"satellite_image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Satellite Image Base64","description":"Base64-encoded satellite image"},"site_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Site Analysis","description":"Site analysis results"},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description","description":"AI-generated layout description"},"coordinates":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Coordinates","description":"Property coordinates {lat, lng}"},"lead_distribution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Distribution Id","description":"Lead distribution ID if created from a lead"},"street_view_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street View Url","description":"Google Street View URL for the property"},"tiles_backyard_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tiles Backyard Base64","description":"Base64-encoded backyard 3D tiles screenshot"},"tiles_front_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tiles Front Base64","description":"Base64-encoded front yard 3D tiles screenshot"},"boundary_corners":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Boundary Corners","description":"Boundary polygon vertices for satellite overlay"},"oblique_front_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oblique Front Base64","description":"Base64-encoded front 3D oblique rendering"},"oblique_back_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oblique Back Base64","description":"Base64-encoded back 3D oblique rendering"}},"type":"object","required":["address","style","design_image_base64"],"title":"SaveProModeGenerationRequest","description":"Request to save a Pro Mode 2D generation to history"},"SaveProModeGenerationResponse":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"UUID of the saved generation"},"message":{"type":"string","title":"Message","default":"Generation saved successfully"}},"type":"object","required":["generation_id"],"title":"SaveProModeGenerationResponse","description":"Response after saving a Pro Mode generation"},"SaveProModeRenderingRequest":{"properties":{"generation_id":{"type":"string","title":"Generation Id","description":"UUID of the parent 2D generation"},"view_angle":{"type":"string","title":"View Angle","description":"View angle: front_yard, backyard, pool_area, patio, side_yard"},"rendering_image_base64":{"type":"string","title":"Rendering Image Base64","description":"Base64-encoded rendering image"},"primary_feature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Feature","description":"Primary feature in this view"},"street_edge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street Edge","description":"Street edge orientation"},"layout_description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Layout Description","description":"Layout description from 2D plan"}},"type":"object","required":["generation_id","view_angle","rendering_image_base64"],"title":"SaveProModeRenderingRequest","description":"Request to save a Pro Mode 3D rendering to history"},"SaveProModeRenderingResponse":{"properties":{"rendering_id":{"type":"string","title":"Rendering Id","description":"UUID of the saved rendering"},"message":{"type":"string","title":"Message","default":"Rendering saved successfully"}},"type":"object","required":["rendering_id"],"title":"SaveProModeRenderingResponse","description":"Response after saving a Pro Mode rendering"},"ScheduleContentRequest":{"properties":{"date":{"type":"string","title":"Date"},"time":{"type":"string","title":"Time","default":"10:00"}},"type":"object","required":["date"],"title":"ScheduleContentRequest","description":"Request to schedule content."},"ScreenshotCompleteModel":{"properties":{"screenshot_id":{"type":"string","title":"Screenshot Id"},"filepath":{"type":"string","title":"Filepath"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["screenshot_id","filepath","success"],"title":"ScreenshotCompleteModel"},"ScreenshotRequestModel":{"properties":{"lat":{"type":"number","title":"Lat"},"lng":{"type":"number","title":"Lng"},"heading":{"type":"number","title":"Heading"},"pitch":{"type":"number","title":"Pitch"},"altitude":{"type":"number","title":"Altitude"},"view_type":{"type":"string","title":"View Type"},"address":{"type":"string","title":"Address"},"prop_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prop Lat"},"prop_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prop Lng"}},"type":"object","required":["lat","lng","heading","pitch","altitude","view_type","address"],"title":"ScreenshotRequestModel"},"ScreenshotResponseModel":{"properties":{"screenshot_id":{"type":"string","title":"Screenshot Id"},"status":{"type":"string","title":"Status"},"filepath":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filepath"}},"type":"object","required":["screenshot_id","status"],"title":"ScreenshotResponseModel"},"SendNeighborDesignRequest":{"properties":{"neighbor_email":{"type":"string","title":"Neighbor Email","description":"Neighbor's email address"},"neighbor_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Neighbor Name","description":"Neighbor's name (optional)"},"sender_name":{"type":"string","title":"Sender Name","description":"Name of the person sending the design"},"address":{"type":"string","title":"Address","description":"Property address for the design"},"design_url":{"type":"string","title":"Design Url","description":"URL to view the design"},"design_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Design Image Url","description":"URL of the design image to embed"}},"type":"object","required":["neighbor_email","sender_name","address","design_url"],"title":"SendNeighborDesignRequest","description":"Request body for sending a design to a neighbor."},"SendNeighborDesignResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"SendNeighborDesignResponse","description":"Response for send-neighbor-design endpoint."},"SenderType":{"type":"string","enum":["user","agent","system"],"title":"SenderType","description":"Type of sender for ticket messages."},"ServiceAccountKeyRequest":{"properties":{"secret":{"type":"string","title":"Secret","description":"Pre-shared secret for service account authentication"},"name":{"type":"string","maxLength":255,"title":"Name","description":"Human-readable name for this API key","default":"Service Account"}},"type":"object","required":["secret"],"title":"ServiceAccountKeyRequest"},"ServiceAreaCreateRequest":{"properties":{"area_type":{"$ref":"#/components/schemas/ServiceAreaType"},"area_value":{"type":"string","maxLength":100,"minLength":2,"title":"Area Value"},"state_code":{"type":"string","maxLength":2,"minLength":2,"title":"State Code"},"metro_area_code":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Metro Area Code"},"county_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"County Name"},"travel_radius_miles":{"anyOf":[{"type":"number","maximum":500.0,"minimum":1.0},{"type":"null"}],"title":"Travel Radius Miles"},"is_include":{"type":"boolean","title":"Is Include","default":true},"notes":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Notes"}},"type":"object","required":["area_type","area_value","state_code"],"title":"ServiceAreaCreateRequest","description":"Request to add a service area."},"ServiceAreaResponse":{"properties":{"id":{"type":"string","title":"Id"},"area_type":{"$ref":"#/components/schemas/ServiceAreaType"},"area_value":{"type":"string","title":"Area Value"},"state_code":{"type":"string","title":"State Code"},"is_active":{"type":"boolean","title":"Is Active"},"metro_area_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metro Area Code"},"county_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Name"},"travel_radius_miles":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Travel Radius Miles"},"is_include":{"type":"boolean","title":"Is Include","default":true},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["id","area_type","area_value","state_code","is_active"],"title":"ServiceAreaResponse","description":"Service area in response."},"ServiceAreaType":{"type":"string","enum":["zip_code","city","radius","metro_area","county"],"title":"ServiceAreaType","description":"Type of service area coverage."},"ShotObservations":{"properties":{"backWallVisiblePct":{"type":"integer","title":"Backwallvisiblepct"},"backyardVisiblePct":{"type":"integer","title":"Backyardvisiblepct"},"isTargetCentered":{"type":"boolean","title":"Istargetcentered"},"visibleFeatures":{"items":{"type":"string"},"type":"array","title":"Visiblefeatures","default":[]},"blockingElements":{"items":{"type":"string"},"type":"array","title":"Blockingelements","default":[]}},"type":"object","required":["backWallVisiblePct","backyardVisiblePct","isTargetCentered"],"title":"ShotObservations","description":"Observations about the current shot"},"ShowcaseDesign":{"properties":{"id":{"type":"string","title":"Id"},"image_url":{"type":"string","title":"Image Url"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"generation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generation Type"}},"type":"object","required":["id","image_url"],"title":"ShowcaseDesign","description":"A single showcase design for the public gallery carousel."},"ShowcaseResponse":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/ShowcaseDesign"},"type":"array","title":"Designs"}},"type":"object","title":"ShowcaseResponse","description":"Response with showcase designs from demo accounts."},"SignupAttributionRequest":{"properties":{"utm_source":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Utm Campaign"},"referrer":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Referrer"}},"type":"object","title":"SignupAttributionRequest","description":"Request to store UTM attribution captured at signup."},"SignupAttributionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"stored":{"type":"boolean","title":"Stored","description":"True if attribution was stored; False if already set (first-touch preserved)"}},"type":"object","required":["success","stored"],"title":"SignupAttributionResponse","description":"Response after storing signup attribution."},"SimpleBalanceResponse":{"properties":{"trial":{"type":"integer","title":"Trial","description":"Trial credits remaining"},"token":{"type":"integer","title":"Token","description":"Token balance"}},"type":"object","required":["trial","token"],"title":"SimpleBalanceResponse","description":"Lightweight balance response with just the numbers.\n\nFor use cases where only current balances are needed without metadata.\nUsed internally or for performance-critical endpoints."},"SiteAnalysisResponse":{"properties":{"pixelsPerFoot":{"type":"number","title":"Pixelsperfoot"},"lotType":{"type":"string","title":"Lottype"},"streetType":{"type":"string","title":"Streettype"},"streetEdge":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Streetedge"},"clockPosition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clockposition"},"notes":{"type":"string","title":"Notes"},"yardEstimates":{"anyOf":[{"$ref":"#/components/schemas/YardEstimates"},{"type":"null"}]},"hardinessZone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardinesszone","description":"USDA Plant Hardiness Zone (e.g., '7a')"},"hardinessZoneDescription":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hardinesszonedescription","description":"Temperature range (e.g., '0 to 5°F')"}},"type":"object","required":["pixelsPerFoot","lotType","streetType","notes"],"title":"SiteAnalysisResponse","description":"Site analysis results from vision model"},"SmsBulkSendRequest":{"properties":{"contact_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Contact Ids"},"body":{"type":"string","title":"Body"},"consent_type":{"type":"string","title":"Consent Type","default":"transactional"},"campaign_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Campaign Id"}},"type":"object","required":["contact_ids","body"],"title":"SmsBulkSendRequest","description":"Admin sends an SMS to multiple contacts."},"SmsContactResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"phone":{"type":"string","title":"Phone"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name","default":""},"email":{"type":"string","title":"Email","default":""},"company":{"type":"string","title":"Company","default":""},"consent_transactional":{"type":"boolean","title":"Consent Transactional"},"consent_marketing":{"type":"boolean","title":"Consent Marketing"},"opted_out":{"type":"boolean","title":"Opted Out"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","phone","first_name","consent_transactional","consent_marketing","opted_out"],"title":"SmsContactResponse"},"SmsOptInRequest":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name","default":""},"phone":{"type":"string","title":"Phone"},"email":{"type":"string","title":"Email","default":""},"company":{"type":"string","title":"Company","default":""},"consent_transactional":{"type":"boolean","title":"Consent Transactional"},"consent_marketing":{"type":"boolean","title":"Consent Marketing","default":false}},"type":"object","required":["first_name","phone","consent_transactional"],"title":"SmsOptInRequest","description":"Inbound from the sms-optin form."},"SmsSendRequest":{"properties":{"contact_id":{"type":"string","format":"uuid","title":"Contact Id"},"body":{"type":"string","title":"Body"},"consent_type":{"type":"string","title":"Consent Type","default":"transactional"},"campaign_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Campaign Id"}},"type":"object","required":["contact_id","body"],"title":"SmsSendRequest","description":"Admin sends an SMS to a contact."},"SocialPostFromBlog":{"properties":{"platform":{"type":"string","title":"Platform"},"content_type":{"type":"string","title":"Content Type"},"hook":{"type":"string","title":"Hook"},"body":{"type":"string","title":"Body"},"hashtags":{"items":{"type":"string"},"type":"array","title":"Hashtags"},"call_to_action":{"type":"string","title":"Call To Action"},"image_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Prompt"}},"type":"object","required":["platform","content_type","hook","body","call_to_action"],"title":"SocialPostFromBlog","description":"A social media post generated from a blog post."},"SocialShareConfirmRequest":{"properties":{"place_id":{"type":"string","title":"Place Id","description":"Google Place ID"},"formatted_address":{"type":"string","title":"Formatted Address","description":"Human-readable address"}},"type":"object","required":["place_id","formatted_address"],"title":"SocialShareConfirmRequest","description":"Request to confirm social share and grant free property pass."},"SocialShareConfirmResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"pass_details":{"$ref":"#/components/schemas/PropertyPassResponse"},"message":{"type":"string","title":"Message"},"days_granted":{"type":"integer","title":"Days Granted","default":5}},"type":"object","required":["success","pass_details","message"],"title":"SocialShareConfirmResponse","description":"Response after confirming social share."},"Specialization":{"type":"string","enum":["hardscape","softscape","irrigation","lighting","pools","fencing","outdoor_living","xeriscaping","lawn_care","tree_service","water_features","design","maintenance"],"title":"Specialization","description":"Contractor specialization areas."},"StorageQuotaResponse":{"properties":{"storage_used_bytes":{"type":"integer","title":"Storage Used Bytes","description":"Total bytes used by user's designs"},"storage_limit_bytes":{"type":"integer","title":"Storage Limit Bytes","description":"Maximum storage allowed (1TB for Pro)"},"storage_used_formatted":{"type":"string","title":"Storage Used Formatted","description":"Human-readable storage used (e.g., '2.5 GB')"},"storage_limit_formatted":{"type":"string","title":"Storage Limit Formatted","description":"Human-readable storage limit (e.g., '1 TB')"},"percentage_used":{"type":"number","title":"Percentage Used","description":"Percentage of storage used (0-100)"},"is_near_limit":{"type":"boolean","title":"Is Near Limit","description":"True if usage exceeds 80%"},"is_over_limit":{"type":"boolean","title":"Is Over Limit","description":"True if usage exceeds limit"},"grace_period_active":{"type":"boolean","title":"Grace Period Active","description":"True if user is in post-cancellation grace period"},"grace_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Grace Period End","description":"When grace period ends (if active)"},"days_until_deletion":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Until Deletion","description":"Days until designs are deleted (if in grace)"}},"type":"object","required":["storage_used_bytes","storage_limit_bytes","storage_used_formatted","storage_limit_formatted","percentage_used","is_near_limit","is_over_limit","grace_period_active"],"title":"StorageQuotaResponse","description":"Response with user's storage quota and usage"},"StripeAccountStatus":{"type":"string","enum":["not_connected","pending","active","restricted","disabled"],"title":"StripeAccountStatus","description":"Contractor Stripe Connect account status."},"StripeAccountStatusResponse":{"properties":{"stripe_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Account Id"},"status":{"$ref":"#/components/schemas/StripeAccountStatus"},"onboarding_complete":{"type":"boolean","title":"Onboarding Complete"},"connected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Connected At"},"payouts_enabled":{"type":"boolean","title":"Payouts Enabled","default":false},"charges_enabled":{"type":"boolean","title":"Charges Enabled","default":false}},"type":"object","required":["stripe_account_id","status","onboarding_complete","connected_at"],"title":"StripeAccountStatusResponse","description":"Contractor's Stripe Connect account status."},"StripeOnboardingRequest":{"properties":{"refresh_url":{"type":"string","title":"Refresh Url","description":"URL to return to if onboarding incomplete"},"return_url":{"type":"string","title":"Return Url","description":"URL to return to after onboarding"}},"type":"object","required":["refresh_url","return_url"],"title":"StripeOnboardingRequest","description":"Request to start Stripe Connect onboarding."},"StripeOnboardingResponse":{"properties":{"onboarding_url":{"type":"string","title":"Onboarding Url"},"stripe_account_id":{"type":"string","title":"Stripe Account Id"}},"type":"object","required":["onboarding_url","stripe_account_id"],"title":"StripeOnboardingResponse","description":"Response with Stripe onboarding link."},"StyleOption":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"thumbnail_url":{"type":"string","title":"Thumbnail Url"},"climate_zones":{"items":{"type":"string"},"type":"array","title":"Climate Zones"},"recommended_for_zone":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Recommended For Zone"},"recommendation_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Recommendation Rank"}},"type":"object","required":["id","name","description","thumbnail_url"],"title":"StyleOption","description":"Available design style option"},"SubscriptionPlan":{"properties":{"plan_id":{"type":"string","title":"Plan Id","description":"Unique plan identifier (e.g., 'monthly_pro')"},"name":{"type":"string","title":"Name","description":"Human-readable plan name"},"description":{"type":"string","title":"Description","description":"Plan description"},"price_monthly":{"type":"string","title":"Price Monthly","description":"Monthly price in USD"},"price_cents":{"type":"integer","title":"Price Cents","description":"Monthly price in cents"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"List of plan features"},"stripe_price_id":{"type":"string","title":"Stripe Price Id","description":"Stripe Price ID for checkout"},"is_popular":{"type":"boolean","title":"Is Popular","description":"Whether to highlight as popular","default":false},"pro_generations_quota":{"type":"integer","title":"Pro Generations Quota","description":"Monthly Pro Mode G3 Pro generations included","default":0}},"type":"object","required":["plan_id","name","description","price_monthly","price_cents","features","stripe_price_id"],"title":"SubscriptionPlan","description":"Subscription plan definition.\n\nRepresents an available subscription tier with pricing and features."},"SubscriptionStatus":{"properties":{"is_active":{"type":"boolean","title":"Is Active","description":"Whether subscription is currently active"},"plan":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionPlan"},{"type":"null"}],"description":"Current subscription plan"},"current_period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period Start","description":"Current billing period start"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End","description":"Current billing period end"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","description":"Whether subscription will cancel at period end","default":false},"status":{"type":"string","title":"Status","description":"Subscription status: inactive, active, past_due, cancelled"}},"type":"object","required":["is_active","status"],"title":"SubscriptionStatus","description":"Current subscription status for a user.\n\nReturned when querying user's subscription state."},"SubscriptionSummary":{"properties":{"tier":{"type":"string","title":"Tier"},"status":{"type":"string","title":"Status"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["tier","status","count"],"title":"SubscriptionSummary"},"SupportAnalytics":{"properties":{"open_tickets":{"type":"integer","title":"Open Tickets","default":0},"pending_tickets":{"type":"integer","title":"Pending Tickets","default":0},"resolved_tickets":{"type":"integer","title":"Resolved Tickets","default":0},"closed_tickets":{"type":"integer","title":"Closed Tickets","default":0},"urgent_tickets":{"type":"integer","title":"Urgent Tickets","default":0},"high_priority_tickets":{"type":"integer","title":"High Priority Tickets","default":0},"avg_first_response_hours":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg First Response Hours"},"avg_resolution_hours":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Resolution Hours"},"total_tickets":{"type":"integer","title":"Total Tickets","default":0},"period_days":{"type":"integer","title":"Period Days","default":30}},"type":"object","title":"SupportAnalytics","description":"Support ticket analytics for admin dashboard."},"SupportTicket":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"ticket_number":{"type":"string","title":"Ticket Number"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email"},"user_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Name"},"chat_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Chat Session Id"},"status":{"$ref":"#/components/schemas/TicketStatus"},"priority":{"$ref":"#/components/schemas/TicketPriority"},"subject":{"type":"string","title":"Subject"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"assigned_to":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Assigned To"},"assigned_to_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To Name"},"messages":{"items":{"$ref":"#/components/schemas/TicketMessage"},"type":"array","title":"Messages","default":[]},"chat_messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Chat Messages","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"},"first_response_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Response At"}},"type":"object","required":["id","ticket_number","user_id","chat_session_id","status","priority","subject","created_at","updated_at"],"title":"SupportTicket","description":"A support ticket with full message history."},"SupportTicketCreate":{"properties":{"subject":{"type":"string","maxLength":200,"minLength":1,"title":"Subject","description":"Brief description of the issue"},"chat_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Chat Session Id","description":"Link to originating chat session"},"priority":{"$ref":"#/components/schemas/TicketPriority","description":"Initial priority level","default":"medium"}},"type":"object","required":["subject"],"title":"SupportTicketCreate","description":"Request model for creating a support ticket from chat."},"SupportTicketSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"ticket_number":{"type":"string","title":"Ticket Number"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email"},"user_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Name"},"status":{"$ref":"#/components/schemas/TicketStatus"},"priority":{"$ref":"#/components/schemas/TicketPriority"},"subject":{"type":"string","title":"Subject"},"message_count":{"type":"integer","title":"Message Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","ticket_number","user_id","status","priority","subject","created_at","updated_at"],"title":"SupportTicketSummary","description":"Summary view of a ticket (for list views)."},"TerrainType":{"type":"string","enum":["flat","gentle_slope","steep_slope"],"title":"TerrainType","description":"Terrain slope classification for hillside properties."},"TestAddressBulkCreate":{"properties":{"addresses":{"items":{"$ref":"#/components/schemas/TestAddressCreate"},"type":"array","maxItems":1000,"minItems":1,"title":"Addresses"}},"type":"object","required":["addresses"],"title":"TestAddressBulkCreate","description":"Request model for bulk adding test addresses."},"TestAddressCreate":{"properties":{"address":{"type":"string","maxLength":500,"minLength":1,"title":"Address","description":"Full address"},"lat":{"anyOf":[{"type":"number","maximum":90.0,"minimum":-90.0},{"type":"null"}],"title":"Lat","description":"Latitude"},"lng":{"anyOf":[{"type":"number","maximum":180.0,"minimum":-180.0},{"type":"null"}],"title":"Lng","description":"Longitude"},"address_type":{"anyOf":[{"$ref":"#/components/schemas/AddressType"},{"type":"null"}],"description":"Address classification"},"region":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Region","description":"Geographic region"},"state":{"anyOf":[{"type":"string","maxLength":2},{"type":"null"}],"title":"State","description":"US state code"},"expected_lot_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Lot Size","description":"Expected lot size for validation"},"expected_house_heading":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expected House Heading","description":"Expected heading for validation"},"source":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Source","description":"Where this address came from"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Additional notes"}},"type":"object","required":["address"],"title":"TestAddressCreate","description":"Request model for adding a test address."},"TestAddressResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"address":{"type":"string","title":"Address"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"address_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Type"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"expected_lot_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Lot Size"},"expected_house_heading":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expected House Heading"},"last_test_run_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Last Test Run Id"},"last_front_quality_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Front Quality Grade"},"last_back_quality_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Back Quality Grade"},"total_test_count":{"type":"integer","title":"Total Test Count"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","address","lat","lng","address_type","region","state","expected_lot_size","expected_house_heading","last_test_run_id","last_front_quality_grade","last_back_quality_grade","total_test_count","source","notes","is_active","created_at"],"title":"TestAddressResponse","description":"Response model for test address."},"TestResultResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_id":{"type":"string","format":"uuid","title":"Run Id"},"address":{"type":"string","title":"Address"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"is_cul_de_sac":{"type":"boolean","title":"Is Cul De Sac"},"is_corner_lot":{"type":"boolean","title":"Is Corner Lot"},"lot_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Size"},"lot_size_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lot Size Confidence"},"house_heading":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"House Heading"},"heading_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Heading Source"},"heading_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Heading Confidence"},"front_camera_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Camera Lat"},"front_camera_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Camera Lng"},"front_heading":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Heading"},"front_pitch":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Pitch"},"front_altitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Altitude"},"front_triangle_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Front Triangle Count"},"front_quality_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Front Quality Score"},"front_quality_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Front Quality Grade"},"front_screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Front Screenshot Url"},"back_camera_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Back Camera Lat"},"back_camera_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Back Camera Lng"},"back_heading":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Back Heading"},"back_pitch":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Back Pitch"},"back_altitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Back Altitude"},"back_triangle_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Back Triangle Count"},"back_quality_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Back Quality Score"},"back_quality_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Back Quality Grade"},"back_screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Back Screenshot Url"},"issues":{"items":{"type":"string"},"type":"array","title":"Issues"},"api_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Api Latency Ms"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"manually_reviewed":{"type":"boolean","title":"Manually Reviewed"},"reviewer_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Notes"},"is_correct":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Correct"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"reviewed_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Reviewed By"}},"type":"object","required":["id","run_id","address","lat","lng","is_cul_de_sac","is_corner_lot","lot_size","lot_size_confidence","house_heading","heading_source","heading_confidence","front_camera_lat","front_camera_lng","front_heading","front_pitch","front_altitude","front_triangle_count","front_quality_score","front_quality_grade","front_screenshot_url","back_camera_lat","back_camera_lng","back_heading","back_pitch","back_altitude","back_triangle_count","back_quality_score","back_quality_grade","back_screenshot_url","issues","api_latency_ms","created_at","manually_reviewed","reviewer_notes","is_correct","reviewed_at","reviewed_by"],"title":"TestResultResponse","description":"Response model for individual test result."},"TestResultReview":{"properties":{"is_correct":{"type":"boolean","title":"Is Correct","description":"Whether the camera positioning is correct"},"reviewer_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Notes","description":"Notes about the review"},"issues":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Issues","description":"Issues identified during review"}},"type":"object","required":["is_correct"],"title":"TestResultReview","description":"Request model for reviewing a test result."},"TestRunCreate":{"properties":{"run_name":{"type":"string","maxLength":200,"minLength":1,"title":"Run Name","description":"Name for this test run"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Description of what this test is for"},"test_type":{"$ref":"#/components/schemas/TestType","description":"Type of test","default":"address_batch"},"address_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array"},{"type":"null"}],"title":"Address Ids","description":"Specific address IDs to test (if not provided, tests all active)"},"address_types":{"anyOf":[{"items":{"$ref":"#/components/schemas/AddressType"},"type":"array"},{"type":"null"}],"title":"Address Types","description":"Filter by address types"},"limit":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Limit","description":"Maximum addresses to test"},"config_overrides":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Config Overrides","description":"Override default camera config"}},"type":"object","required":["run_name"],"title":"TestRunCreate","description":"Request model for creating a test run."},"TestRunResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_name":{"type":"string","title":"Run Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"test_type":{"type":"string","title":"Test Type"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"total_addresses":{"type":"integer","title":"Total Addresses"},"completed_addresses":{"type":"integer","title":"Completed Addresses"},"failed_addresses":{"type":"integer","title":"Failed Addresses"},"avg_front_quality_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Front Quality Score"},"avg_back_quality_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Back Quality Score"},"avg_triangle_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Triangle Count"},"grade_a_count":{"type":"integer","title":"Grade A Count"},"grade_b_count":{"type":"integer","title":"Grade B Count"},"grade_c_count":{"type":"integer","title":"Grade C Count"},"grade_d_count":{"type":"integer","title":"Grade D Count"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["id","run_name","description","test_type","config","total_addresses","completed_addresses","failed_addresses","avg_front_quality_score","avg_back_quality_score","avg_triangle_count","grade_a_count","grade_b_count","grade_c_count","grade_d_count","status","created_at","started_at","completed_at","created_by","error_message"],"title":"TestRunResponse","description":"Response model for test run."},"TestRunSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_name":{"type":"string","title":"Run Name"},"test_type":{"type":"string","title":"Test Type"},"status":{"type":"string","title":"Status"},"total_addresses":{"type":"integer","title":"Total Addresses"},"completed_addresses":{"type":"integer","title":"Completed Addresses"},"avg_front_quality_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Front Quality Score"},"avg_back_quality_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Back Quality Score"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","run_name","test_type","status","total_addresses","completed_addresses","avg_front_quality_score","avg_back_quality_score","created_at"],"title":"TestRunSummary","description":"Summary of a test run for list views."},"TestType":{"type":"string","enum":["address_batch","cul_de_sac","corner_lot","random_sample","regression"],"title":"TestType","description":"Types of test runs."},"TextOverlayStyle":{"type":"string","enum":["bold","elegant","playful","minimal"],"title":"TextOverlayStyle","description":"Text overlay styles for images."},"TextPosition":{"type":"string","enum":["top","center","bottom"],"title":"TextPosition","description":"Text position on images."},"TicketAssignment":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"}},"type":"object","required":["agent_id"],"title":"TicketAssignment","description":"Assign ticket to agent."},"TicketMessage":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"ticket_id":{"type":"string","format":"uuid","title":"Ticket Id"},"sender_type":{"$ref":"#/components/schemas/SenderType"},"sender_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Sender Id"},"sender_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sender Name"},"content":{"type":"string","title":"Content"},"is_internal":{"type":"boolean","title":"Is Internal","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","ticket_id","sender_type","sender_id","content","created_at"],"title":"TicketMessage","description":"A message on a support ticket."},"TicketMessageCreate":{"properties":{"content":{"type":"string","maxLength":5000,"minLength":1,"title":"Content","description":"Message content"},"is_internal":{"type":"boolean","title":"Is Internal","description":"Internal note (visible only to agents)","default":false}},"type":"object","required":["content"],"title":"TicketMessageCreate","description":"Request model for adding a message to a ticket."},"TicketPriority":{"type":"string","enum":["low","medium","high","urgent"],"title":"TicketPriority","description":"Priority level of a support ticket."},"TicketStatus":{"type":"string","enum":["open","pending","resolved","closed"],"title":"TicketStatus","description":"Status of a support ticket."},"TicketStatusUpdate":{"properties":{"status":{"$ref":"#/components/schemas/TicketStatus"},"priority":{"anyOf":[{"$ref":"#/components/schemas/TicketPriority"},{"type":"null"}]}},"type":"object","required":["status"],"title":"TicketStatusUpdate","description":"Update ticket status."},"ToggleFavoriteRequest":{"properties":{"is_favorite":{"type":"boolean","title":"Is Favorite"}},"type":"object","required":["is_favorite"],"title":"ToggleFavoriteRequest","description":"Request model for toggling favorite status"},"TokenAccountResponse":{"properties":{"balance":{"type":"integer","title":"Balance","description":"Current token balance"},"total_purchased":{"type":"integer","title":"Total Purchased","description":"Total tokens purchased"},"total_spent":{"type":"integer","title":"Total Spent","description":"Total tokens spent"},"auto_reload_enabled":{"type":"boolean","title":"Auto Reload Enabled","description":"Auto-reload enabled","default":false},"auto_reload_threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Reload Threshold","description":"Reload threshold (1-100)"},"auto_reload_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Reload Amount","description":"Reload amount (min 10)"},"auto_reload_failure_count":{"type":"integer","title":"Auto Reload Failure Count","description":"Consecutive failures","default":0}},"type":"object","required":["balance","total_purchased","total_spent"],"title":"TokenAccountResponse","description":"Response model for token account queries.","example":{"auto_reload_amount":100,"auto_reload_enabled":true,"auto_reload_failure_count":0,"auto_reload_threshold":20,"balance":50,"total_purchased":100,"total_spent":50}},"TokenBalance":{"properties":{"email":{"type":"string","title":"Email"},"balance":{"type":"integer","title":"Balance"},"last_activity":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Activity"}},"type":"object","required":["email","balance"],"title":"TokenBalance"},"TokenBalanceDetail":{"properties":{"balance":{"type":"integer","title":"Balance","description":"Current token balance"},"total_purchased":{"type":"integer","title":"Total Purchased","description":"Total tokens purchased (lifetime)"},"total_spent":{"type":"integer","title":"Total Spent","description":"Total tokens spent (lifetime)"},"total_refunded":{"type":"integer","title":"Total Refunded","description":"Total tokens refunded","default":0}},"type":"object","required":["balance","total_purchased","total_spent"],"title":"TokenBalanceDetail","description":"Detailed token credit balance"},"TokenPurchaseSummary":{"properties":{"total_purchases":{"type":"integer","title":"Total Purchases"},"total_tokens_sold":{"type":"integer","title":"Total Tokens Sold"},"unique_buyers":{"type":"integer","title":"Unique Buyers"},"total_revenue_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Revenue Cents"}},"type":"object","required":["total_purchases","total_tokens_sold","unique_buyers"],"title":"TokenPurchaseSummary"},"TokenTransactionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"amount":{"type":"integer","title":"Amount"},"transaction_type":{"type":"string","title":"Transaction Type"},"description":{"type":"string","title":"Description"},"price_paid_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Paid Cents"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","amount","transaction_type","description","price_paid_cents","created_at"],"title":"TokenTransactionResponse","description":"Response model for token transaction queries.","example":{"amount":50,"created_at":"2025-01-20T14:45:00Z","description":"Purchased 50 tokens","id":"650e8400-e29b-41d4-a716-446655440000","price_paid_cents":4500,"transaction_type":"purchase"}},"TopConsumer":{"properties":{"api_key_id":{"type":"string","title":"Api Key Id"},"key_name":{"type":"string","title":"Key Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"design_count":{"type":"integer","title":"Design Count"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["api_key_id","key_name","key_prefix","design_count"],"title":"TopConsumer"},"TopUserResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"calls":{"type":"integer","title":"Calls"},"images":{"type":"integer","title":"Images"},"cost_usd":{"type":"number","title":"Cost Usd"}},"type":"object","required":["user_id","calls","images","cost_usd"],"title":"TopUserResponse","description":"Top user by spend."},"TrialBalanceDetail":{"properties":{"remaining":{"type":"integer","title":"Remaining","description":"Trial credits remaining"},"used":{"type":"integer","title":"Used","description":"Trial credits used"},"total_granted":{"type":"integer","title":"Total Granted","description":"Total trials granted on signup","default":3}},"type":"object","required":["remaining","used"],"title":"TrialBalanceDetail","description":"Detailed trial credit balance"},"TrialDetail":{"properties":{"email":{"type":"string","title":"Email"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"ends_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ends At"},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"status":{"type":"string","title":"Status"},"converted":{"type":"boolean","title":"Converted","default":false}},"type":"object","required":["email","started_at","status"],"title":"TrialDetail","description":"Individual trial subscription detail."},"TrialList":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"total_trials":{"type":"integer","title":"Total Trials"},"converted":{"type":"integer","title":"Converted"},"conversion_rate":{"type":"number","title":"Conversion Rate"},"trials":{"items":{"$ref":"#/components/schemas/TrialDetail"},"type":"array","title":"Trials"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","total_trials","converted","conversion_rate","trials","generated_at"],"title":"TrialList","description":"List of trial subscriptions."},"TuningIterationSummary":{"properties":{"iteration":{"type":"integer","title":"Iteration"},"front_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Front Score"},"back_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Back Score"},"adjustments":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Adjustments"}},"type":"object","required":["iteration"],"title":"TuningIterationSummary","description":"Summary of a single tuning iteration."},"UTMAttributionRequest":{"properties":{"utm_source":{"type":"string","title":"Utm Source","description":"UTM source (pro-referral or homeowner-referral)"},"utm_ref":{"type":"string","title":"Utm Ref","description":"The ref parameter value (pro slug or user ID)"}},"type":"object","required":["utm_source","utm_ref"],"title":"UTMAttributionRequest"},"UTMAttributionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"UTMAttributionResponse"},"UTMParams":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source","description":"Traffic source (e.g., 'nfc', 'google')"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium","description":"Marketing medium (e.g., 'card', 'cpc')"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign","description":"Campaign identifier"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term","description":"Paid search keywords"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content","description":"Content variant"}},"type":"object","title":"UTMParams","description":"UTM parameters from frontend for checkout attribution.\n\nUsed to track NFC card scans and marketing campaigns through to conversion."},"UnifiedBalanceResponse":{"properties":{"trial":{"$ref":"#/components/schemas/TrialBalanceDetail"},"token":{"$ref":"#/components/schemas/TokenBalanceDetail"}},"type":"object","required":["trial","token"],"title":"UnifiedBalanceResponse","description":"Unified credit balance response for all credit types.\n\nGET /v1/credits/balance\n\nReturns detailed balance information for trial and token credits\nin a single atomic query. Replaces individual balance endpoints.\n\nExample response:\n```json\n{\n    \"trial\": {\n        \"remaining\": 2,\n        \"used\": 1,\n        \"total_granted\": 3\n    },\n    \"token\": {\n        \"balance\": 50,\n        \"total_purchased\": 100,\n        \"total_spent\": 48,\n        \"total_refunded\": 2\n    }\n}\n```"},"UpdateContentRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"status":{"anyOf":[{"$ref":"#/components/schemas/ContentStatus"},{"type":"null"}]},"audience":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audience"},"hook":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hook"},"hashtags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Hashtags"},"call_to_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call To Action"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"image_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Prompt"},"scheduled_for":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled For"},"published_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published Url"},"campaign_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id"},"ai_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Model"},"metrics":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Metrics"}},"type":"object","title":"UpdateContentRequest","description":"Request to update content fields."},"UpdateFeedbackOptInRequest":{"properties":{"opt_in":{"type":"boolean","title":"Opt In","description":"Whether to opt in (true) or opt out (false)"}},"type":"object","required":["opt_in"],"title":"UpdateFeedbackOptInRequest","description":"Request to update user's feedback opt-in status"},"UpdateFeedbackOptInResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"feedback_opt_in":{"type":"boolean","title":"Feedback Opt In"}},"type":"object","required":["success","feedback_opt_in"],"title":"UpdateFeedbackOptInResponse","description":"Response after updating feedback opt-in status"},"UpdateGenerationRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","title":"UpdateGenerationRequest","description":"Request model for updating generation metadata"},"UpdateLanguagePreferenceRequest":{"properties":{"language":{"type":"string","pattern":"^(en|es|zh)$","title":"Language","description":"Preferred language code: en (English), es (Spanish), zh (Chinese Simplified)"}},"type":"object","required":["language"],"title":"UpdateLanguagePreferenceRequest","description":"Request to update user's language preference"},"UpdateLanguagePreferenceResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"preferred_language":{"type":"string","title":"Preferred Language"}},"type":"object","required":["success","preferred_language"],"title":"UpdateLanguagePreferenceResponse","description":"Response after updating language preference"},"UpdateMetricsRequest":{"properties":{"views":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Views"},"likes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Likes"},"comments":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Comments"},"shares":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Shares"},"clicks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Clicks"}},"type":"object","title":"UpdateMetricsRequest","description":"Request to update content metrics."},"UpdateModalStateRequest":{"properties":{"modal_shown":{"type":"boolean","title":"Modal Shown","default":true}},"type":"object","title":"UpdateModalStateRequest","description":"Request to mark What's New modal as shown"},"UpdateModalStateResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"whats_new_modal_shown":{"type":"boolean","title":"Whats New Modal Shown"}},"type":"object","required":["success","whats_new_modal_shown"],"title":"UpdateModalStateResponse","description":"Response after updating modal state"},"UpdateProModePreferencesRequest":{"properties":{"design_mode":{"anyOf":[{"type":"string","pattern":"^(quick|studio)$"},{"type":"null"}],"title":"Design Mode","description":"Design mode preference: quick or studio"},"has_seen_mode_explainer":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Seen Mode Explainer","description":"Mark mode explainer as seen"}},"type":"object","title":"UpdateProModePreferencesRequest","description":"Request to update Pro Mode preferences"},"UpdateStageRequest":{"properties":{"stage":{"$ref":"#/components/schemas/ClientStage","description":"New stage value (cannot go backwards from current stage)"}},"type":"object","required":["stage"],"title":"UpdateStageRequest","description":"Request to update client stage."},"User":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"email_verified":{"type":"boolean","title":"Email Verified"},"firebase_uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Firebase Uid"},"trial_remaining":{"type":"integer","minimum":0.0,"title":"Trial Remaining","description":"Trial credits remaining"},"trial_used":{"type":"integer","minimum":0.0,"title":"Trial Used","description":"Trial credits used"},"holiday_credits":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Holiday Credits","description":"Holiday decorator credits","default":0},"holiday_credits_earned":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Holiday Credits Earned","description":"Total holiday credits earned (lifetime)","default":0},"subscription_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Tier"},"subscription_status":{"type":"string","title":"Subscription Status","default":"inactive"},"stripe_customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Customer Id"},"stripe_subscription_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Subscription Id"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false},"preferred_language":{"type":"string","title":"Preferred Language","description":"Preferred language (en, es, zh)","default":"en"},"feedback_opt_in":{"type":"boolean","title":"Feedback Opt In","description":"Whether user has opted in to see the feedback button","default":false},"freemium_trial_used":{"type":"boolean","title":"Freemium Trial Used","description":"Whether user has used freemium trial","default":false},"freemium_generations_used":{"type":"integer","minimum":0.0,"title":"Freemium Generations Used","description":"Freemium Pro Mode generations used","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","email","email_verified","trial_remaining","trial_used","created_at"],"title":"User","description":"Complete user model (matches database schema)."},"UserProfile":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"email_verified":{"type":"boolean","title":"Email Verified"},"trial_remaining":{"type":"integer","title":"Trial Remaining"},"trial_used":{"type":"integer","title":"Trial Used"},"subscription_tier":{"type":"string","title":"Subscription Tier"},"subscription_status":{"type":"string","title":"Subscription Status"},"preferred_language":{"type":"string","title":"Preferred Language","default":"en"},"feedback_opt_in":{"type":"boolean","title":"Feedback Opt In","description":"Whether user has opted in to see the feedback button","default":false},"freemium_trial_used":{"type":"boolean","title":"Freemium Trial Used","description":"Whether user has used freemium trial","default":false},"freemium_generations_used":{"type":"integer","title":"Freemium Generations Used","description":"Freemium Pro Mode generations used","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["user_id","email","email_verified","trial_remaining","trial_used","subscription_tier","subscription_status","created_at"],"title":"UserProfile","description":"Public user profile (safe to expose to client)."},"UserRegisterRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","minLength":8,"title":"Password","description":"Password must be at least 8 characters"}},"type":"object","required":["email","password"],"title":"UserRegisterRequest","description":"Request model for user registration."},"UserRegisterResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"trial_remaining":{"type":"integer","title":"Trial Remaining","description":"Number of free trial credits","default":3},"verification_sent":{"type":"boolean","title":"Verification Sent","description":"Whether verification email was sent","default":true}},"type":"object","required":["user_id","email"],"title":"UserRegisterResponse","description":"Response model for successful registration."},"V27AutoTuneCameraRequest":{"properties":{"address":{"type":"string","title":"Address","description":"Property address"},"lat":{"type":"number","title":"Lat","description":"Property latitude"},"lng":{"type":"number","title":"Lng","description":"Property longitude"},"initial_params":{"additionalProperties":true,"type":"object","title":"Initial Params","description":"Initial camera parameters: altitude, heading, pitch, fov, distance"},"lot_size":{"type":"string","title":"Lot Size","description":"Lot size: SMALL, MEDIUM, LARGE, ESTATE","default":"MEDIUM"},"view_type":{"type":"string","title":"View Type","description":"View type to tune: 'front' or 'back'","default":"back"},"region":{"type":"string","title":"Region","description":"Geographic region for achievability","default":"default"}},"type":"object","required":["address","lat","lng","initial_params"],"title":"V27AutoTuneCameraRequest","description":"Request for complete auto-tuning loop."},"V27AutoTuneCameraResponse":{"properties":{"final_params":{"additionalProperties":true,"type":"object","title":"Final Params","description":"Final camera parameters"},"final_score":{"anyOf":[{"$ref":"#/components/schemas/V27DimensionScoresResponse"},{"type":"null"}],"description":"Final dimension scores"},"final_composite":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Final Composite","description":"Final composite score"},"accepted":{"type":"boolean","title":"Accepted","description":"Whether position was accepted"},"iterations":{"items":{"$ref":"#/components/schemas/V27AutoTuneIterationResponse"},"type":"array","title":"Iterations","description":"Iteration history","default":[]},"regional_achievability":{"type":"number","title":"Regional Achievability","description":"Expected achievability for region"},"manual_override_recommended":{"type":"boolean","title":"Manual Override Recommended","description":"Whether manual adjustment is recommended"},"reasoning":{"type":"string","title":"Reasoning","description":"Explanation of result","default":""},"skipped":{"type":"boolean","title":"Skipped","description":"Whether scoring was skipped","default":false},"skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip Reason","description":"Reason for skipping"}},"type":"object","required":["final_params","accepted","regional_achievability","manual_override_recommended"],"title":"V27AutoTuneCameraResponse","description":"Response from complete auto-tuning loop."},"V27AutoTuneIterationResponse":{"properties":{"iteration":{"type":"integer","title":"Iteration"},"params":{"additionalProperties":true,"type":"object","title":"Params"},"scores":{"anyOf":[{"$ref":"#/components/schemas/V27DimensionScoresResponse"},{"type":"null"}]},"accepted":{"type":"boolean","title":"Accepted"},"adjustments":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Adjustments"},"screenshot_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Base64"}},"type":"object","required":["iteration","params","accepted"],"title":"V27AutoTuneIterationResponse","description":"Single iteration result."},"V27ConfigResponse":{"properties":{"version":{"type":"string","title":"Version"},"accept_threshold":{"type":"number","title":"Accept Threshold"},"isolation_bonus":{"type":"number","title":"Isolation Bonus"},"orientation_bonus":{"type":"number","title":"Orientation Bonus"},"max_iterations":{"type":"integer","title":"Max Iterations"},"weights":{"additionalProperties":true,"type":"object","title":"Weights"},"fov_bounds":{"additionalProperties":true,"type":"object","title":"Fov Bounds"},"distance_bounds":{"additionalProperties":true,"type":"object","title":"Distance Bounds"},"pitch_bounds":{"additionalProperties":true,"type":"object","title":"Pitch Bounds"},"altitude_bounds":{"additionalProperties":true,"type":"object","title":"Altitude Bounds"},"lot_size_defaults":{"additionalProperties":true,"type":"object","title":"Lot Size Defaults"},"regional_achievability":{"additionalProperties":true,"type":"object","title":"Regional Achievability"}},"type":"object","required":["version","accept_threshold","isolation_bonus","orientation_bonus","max_iterations","weights","fov_bounds","distance_bounds","pitch_bounds","altitude_bounds","lot_size_defaults","regional_achievability"],"title":"V27ConfigResponse","description":"v27 algorithm configuration."},"V27DimensionScoresResponse":{"properties":{"orientation":{"type":"number","title":"Orientation","description":"Is correct side shown (1-10)"},"isolation":{"type":"number","title":"Isolation","description":"Target distinguished from neighbors (1-10)"},"geometry":{"type":"number","title":"Geometry","description":"3D rendering quality (1-10)"},"visibility":{"type":"number","title":"Visibility","description":"House fully visible (1-10)"},"composite":{"type":"number","title":"Composite","description":"Weighted composite score"}},"type":"object","required":["orientation","isolation","geometry","visibility","composite"],"title":"V27DimensionScoresResponse","description":"4-dimension scoring response."},"V27ScoreCameraViewRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded screenshot from 3D viewer"},"view_type":{"type":"string","title":"View Type","description":"Expected view type: 'front' or 'back'"},"lot_size":{"type":"string","title":"Lot Size","description":"Lot size: SMALL, MEDIUM, LARGE, ESTATE","default":"MEDIUM"},"current_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Current Params","description":"Current camera parameters"},"iteration":{"type":"integer","title":"Iteration","description":"Current iteration number","default":0}},"type":"object","required":["image_base64","view_type"],"title":"V27ScoreCameraViewRequest","description":"Request to score a camera view using v27 algorithm."},"V27ScoreCameraViewResponse":{"properties":{"composite_score":{"type":"number","title":"Composite Score","description":"Weighted composite score (1-10)"},"dimensions":{"$ref":"#/components/schemas/V27DimensionScoresResponse","description":"Individual dimension scores"},"should_accept":{"type":"boolean","title":"Should Accept","description":"Whether to accept this position"},"adjustments":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Adjustments","description":"Recommended parameter adjustments"},"reasoning":{"type":"string","title":"Reasoning","description":"Explanation of scoring","default":""},"regional_achievability":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Regional Achievability","description":"Expected achievability for region"}},"type":"object","required":["composite_score","dimensions","should_accept"],"title":"V27ScoreCameraViewResponse","description":"Response from v27 camera view scoring."},"VLMStatusResponse":{"properties":{"available":{"type":"boolean","title":"Available"},"endpoint":{"type":"string","title":"Endpoint"},"model":{"type":"string","title":"Model"},"last_check":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Check"}},"type":"object","required":["available","endpoint","model"],"title":"VLMStatusResponse","description":"Response model for VLM status check."},"ValidateReferralResponse":{"properties":{"is_valid":{"type":"boolean","title":"Is Valid","description":"Whether the code is valid"},"referrer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Name","description":"Referrer's first name (for personalization)"},"message":{"type":"string","title":"Message","description":"Validation message"}},"type":"object","required":["is_valid","message"],"title":"ValidateReferralResponse","description":"Response from validating a referral code."},"ValidateViewRequest":{"properties":{"image_base64":{"type":"string","title":"Image Base64","description":"Base64-encoded PNG image"},"view_type":{"$ref":"#/components/schemas/ViewType","description":"Expected view type (front/back)"},"property_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Type","description":"Property type for context"}},"type":"object","required":["image_base64","view_type"],"title":"ValidateViewRequest","description":"Request model for VLM validation."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ValidationResult":{"properties":{"orientation_score":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Orientation Score","description":"Is the correct side (front/back) shown? (30% weight)"},"visibility_score":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Visibility Score","description":"Is the house fully visible? (25% weight)"},"geometry_score":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Geometry Score","description":"Quality of 3D geometry (20% weight)"},"isolation_score":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Isolation Score","description":"Is target property distinguished from neighbors? (15% weight)"},"angle_score":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Angle Score","description":"Is camera angle appropriate? (10% weight)"},"composite_score":{"type":"number","maximum":10.0,"minimum":1.0,"title":"Composite Score","description":"Weighted average: orient*0.3 + vis*0.25 + geo*0.2 + iso*0.15 + angle*0.1"},"view_type_detected":{"$ref":"#/components/schemas/ViewType","description":"What the VLM thinks the view type is"},"orientation_correct":{"type":"boolean","title":"Orientation Correct","description":"True if detected view type matches expected"},"issues":{"items":{"type":"string"},"type":"array","title":"Issues","description":"List of detected issues (e.g., 'house partially cut off')"},"recommendations":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recommendations","description":"VLM suggestion for camera adjustment"},"skipped":{"type":"boolean","title":"Skipped","description":"True if validation was skipped (VLM unavailable)","default":false},"skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip Reason","description":"Reason validation was skipped"},"inference_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inference Time Ms","description":"VLM inference time in milliseconds"},"passes_threshold":{"type":"boolean","title":"Passes Threshold","description":"Check if composite score meets quality threshold (7/10).","readOnly":true}},"type":"object","required":["orientation_score","visibility_score","geometry_score","isolation_score","angle_score","composite_score","view_type_detected","orientation_correct","passes_threshold"],"title":"ValidationResult","description":"Result from local VLM quality validation.\n\nContains scores for each quality dimension plus computed composite score.\nUsed to determine if camera positioning is acceptable or needs adjustment."},"VerifyEmailRequest":{"properties":{"token":{"type":"string","title":"Token","description":"Verification token from email"}},"type":"object","required":["token"],"title":"VerifyEmailRequest","description":"Request model for email verification."},"ViewType":{"type":"string","enum":["front","back"],"title":"ViewType","description":"Type of camera view being captured."},"ViewpointResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"azimuth":{"type":"number","title":"Azimuth"},"elevation":{"type":"number","title":"Elevation"},"distance":{"type":"number","title":"Distance"},"alwaysInclude":{"type":"boolean","title":"Alwaysinclude"},"requiresFeature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requiresfeature"},"priority":{"type":"integer","title":"Priority"}},"type":"object","required":["id","name","description","azimuth","elevation","distance","alwaysInclude","priority"],"title":"ViewpointResponse","description":"A single viewpoint configuration for walkthrough generation."},"VolumeSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"daily":{"items":{"$ref":"#/components/schemas/DailyVolume"},"type":"array","title":"Daily"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["period_days","daily","generated_at"],"title":"VolumeSummary"},"WalkthroughViewpointsResponse":{"properties":{"viewpoints":{"items":{"$ref":"#/components/schemas/ViewpointResponse"},"type":"array","title":"Viewpoints"},"totalCount":{"type":"integer","title":"Totalcount"}},"type":"object","required":["viewpoints","totalCount"],"title":"WalkthroughViewpointsResponse","description":"Response with list of available viewpoints for walkthrough generation."},"WeeklyMetrics":{"properties":{"week_start":{"type":"string","title":"Week Start"},"signups":{"type":"integer","title":"Signups","default":0},"first_generations":{"type":"integer","title":"First Generations","default":0},"freemium_activations":{"type":"integer","title":"Freemium Activations","default":0},"paid_conversions":{"type":"integer","title":"Paid Conversions","default":0},"revenue_cents":{"type":"integer","title":"Revenue Cents","default":0},"signup_to_generation_pct":{"type":"number","title":"Signup To Generation Pct","default":0.0},"generation_to_payment_pct":{"type":"number","title":"Generation To Payment Pct","default":0.0}},"type":"object","required":["week_start"],"title":"WeeklyMetrics","description":"Metrics for a single week."},"WeeklyReport":{"properties":{"report_date":{"type":"string","title":"Report Date"},"period":{"type":"string","title":"Period"},"this_week":{"$ref":"#/components/schemas/WeeklyMetrics"},"last_week":{"$ref":"#/components/schemas/WeeklyMetrics"},"wow_signups_pct":{"type":"number","title":"Wow Signups Pct","default":0.0},"wow_generations_pct":{"type":"number","title":"Wow Generations Pct","default":0.0},"wow_payments_pct":{"type":"number","title":"Wow Payments Pct","default":0.0},"total_users":{"type":"integer","title":"Total Users","default":0},"total_generations":{"type":"integer","title":"Total Generations","default":0},"total_paying_customers":{"type":"integer","title":"Total Paying Customers","default":0},"estimated_mrr_cents":{"type":"integer","title":"Estimated Mrr Cents","default":0},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["report_date","period","this_week","last_week","generated_at"],"title":"WeeklyReport","description":"Unified weekly report for Jerry's Monday tracker."},"YardArea-Output":{"type":"string","enum":["front_yard","backyard","walkway","patio","pool_area"],"title":"YardArea","description":"Type of yard area for landscape generation"},"YardEstimates":{"properties":{"frontYardSqFt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Frontyardsqft"},"backyardSqFt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backyardsqft"},"sideYardSqFt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sideyardsqft"},"backyardWidth":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backyardwidth"},"backyardDepth":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backyarddepth"},"sizeClass":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sizeclass"},"recommendedMaxFeatures":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Recommendedmaxfeatures"}},"type":"object","title":"YardEstimates","description":"Yard size estimates for feature limit constraints"},"src__api__endpoints__admin__InpaintStatusResponse":{"properties":{"total_inpaint_generations":{"type":"integer","title":"Total Inpaint Generations"},"generations_with_inpaint_metadata":{"type":"integer","title":"Generations With Inpaint Metadata"},"sample_inpaint_urls":{"items":{},"type":"array","title":"Sample Inpaint Urls"}},"type":"object","required":["total_inpaint_generations","generations_with_inpaint_metadata","sample_inpaint_urls"],"title":"InpaintStatusResponse","description":"Inpaint data status response."},"src__api__endpoints__agent_api__ErrorResponse":{"properties":{"error":{"type":"string","title":"Error"},"detail":{"type":"string","title":"Detail"},"code":{"type":"string","title":"Code"}},"type":"object","required":["error","detail","code"],"title":"ErrorResponse"},"src__api__endpoints__agent_api__LotDimensions":{"properties":{"width_ft":{"type":"number","title":"Width Ft"},"depth_ft":{"type":"number","title":"Depth Ft"},"area_sqft":{"type":"number","title":"Area Sqft"}},"type":"object","required":["width_ft","depth_ft","area_sqft"],"title":"LotDimensions"},"src__api__endpoints__agent_proposals_api__ErrorResponse":{"properties":{"error":{"type":"string","title":"Error"},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["error","detail"],"title":"ErrorResponse"},"src__api__endpoints__analytics__FunnelStage":{"properties":{"stage":{"type":"string","title":"Stage"},"count":{"type":"integer","title":"Count"},"percent_of_previous":{"type":"number","title":"Percent Of Previous","default":100.0},"percent_of_total":{"type":"number","title":"Percent Of Total","default":100.0},"drop_off_rate":{"type":"number","title":"Drop Off Rate","default":0.0}},"type":"object","required":["stage","count"],"title":"FunnelStage","description":"Funnel stage metrics."},"src__api__endpoints__api_keys__ErrorResponse":{"properties":{"error":{"type":"string","title":"Error"},"detail":{"type":"string","title":"Detail"},"code":{"type":"string","title":"Code"}},"type":"object","required":["error","detail","code"],"title":"ErrorResponse"},"src__api__endpoints__leads__LeadResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"phone":{"type":"string","title":"Phone"},"address":{"type":"string","title":"Address"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"generated_areas":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Generated Areas"},"status":{"type":"string","title":"Status"},"message":{"type":"string","title":"Message"}},"type":"object","required":["id","name","email","phone","address","notes","generated_areas","status","message"],"title":"LeadResponse","description":"Response body for lead operations."},"src__api__endpoints__pro_mode__CameraPosition":{"properties":{"lat":{"type":"number","title":"Lat","description":"Camera latitude"},"lng":{"type":"number","title":"Lng","description":"Camera longitude"},"heading":{"type":"number","title":"Heading","description":"Direction camera faces (compass degrees)"},"pitch":{"type":"number","title":"Pitch","description":"Camera pitch angle (negative = looking down)"},"altitude":{"type":"number","title":"Altitude","description":"Camera altitude in meters"},"view_type":{"type":"string","title":"View Type","description":"Type of view: 'front' or 'backyard'"}},"type":"object","required":["lat","lng","heading","pitch","altitude","view_type"],"title":"CameraPosition","description":"A single camera position with coordinates and orientation."},"src__api__endpoints__pro_mode__MaterialItem":{"properties":{"name":{"type":"string","title":"Name","description":"Material name"},"category":{"type":"string","title":"Category","description":"Category: hardscaping, softscaping, feature, planting"},"quantity":{"type":"number","title":"Quantity","description":"Estimated quantity"},"unit":{"type":"string","title":"Unit","description":"Unit of measurement"},"unitPrice":{"type":"number","title":"Unitprice","description":"Price per unit (materials)"},"laborRate":{"type":"number","title":"Laborrate","description":"Labor cost per unit"},"materialCost":{"type":"number","title":"Materialcost","description":"Total material cost"},"laborCost":{"type":"number","title":"Laborcost","description":"Total labor cost"},"total":{"type":"number","title":"Total","description":"Total cost for this material"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Additional notes"}},"type":"object","required":["name","category","quantity","unit","unitPrice","laborRate","materialCost","laborCost","total"],"title":"MaterialItem","description":"A single material with pricing"},"src__api__endpoints__roi_dashboard__FunnelStage":{"properties":{"stage":{"type":"string","title":"Stage"},"count":{"type":"integer","title":"Count"},"percent_of_previous":{"type":"number","title":"Percent Of Previous","default":100.0},"percent_of_total":{"type":"number","title":"Percent Of Total","default":100.0}},"type":"object","required":["stage","count"],"title":"FunnelStage"},"src__marketplace__api__admin__ProjectSummary":{"properties":{"id":{"type":"string","title":"Id"},"homeowner_email":{"type":"string","title":"Homeowner Email"},"city":{"type":"string","title":"City"},"state_code":{"type":"string","title":"State Code"},"status":{"type":"string","title":"Status"},"proposal_count":{"type":"integer","title":"Proposal Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"bidding_closes_at":{"type":"string","format":"date-time","title":"Bidding Closes At"}},"type":"object","required":["id","homeowner_email","city","state_code","status","proposal_count","created_at","bidding_closes_at"],"title":"ProjectSummary","description":"Summary info for a project"},"src__marketplace__models__estimate__MaterialItem-Output":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"unit":{"type":"string","maxLength":50,"minLength":1,"title":"Unit"},"quantity":{"type":"string","title":"Quantity"},"unit_price_cents":{"type":"integer","minimum":0.0,"title":"Unit Price Cents","description":"Price per unit in cents"},"subtotal_cents":{"type":"integer","title":"Subtotal Cents","description":"Calculated: quantity * unit_price_cents","default":0}},"type":"object","required":["name","unit","quantity","unit_price_cents"],"title":"MaterialItem","description":"A single material line item in an estimate.","example":{"name":"Travertine Pavers - French Pattern","quantity":420.0,"subtotal_cents":189000,"unit":"sqft","unit_price_cents":450}},"src__marketplace__models__partner_project__LotDimensions":{"properties":{"width_ft":{"type":"number","exclusiveMinimum":0.0,"title":"Width Ft"},"depth_ft":{"type":"number","exclusiveMinimum":0.0,"title":"Depth Ft"},"total_sqft":{"type":"number","exclusiveMinimum":0.0,"title":"Total Sqft"}},"type":"object","required":["width_ft","depth_ft","total_sqft"],"title":"LotDimensions","description":"Overall lot dimensions from site analysis."},"src__marketplace__models__pro_engine__MaterialItem":{"properties":{"item":{"type":"string","title":"Item","description":"Material name, e.g., 'Decomposed Granite'"},"unit":{"type":"string","title":"Unit","description":"Unit of measure: cu_yd, each, sqft, linear_ft"},"quantity":{"type":"string","title":"Quantity"},"category":{"type":"string","title":"Category","description":"hardscape, planting, irrigation, lighting"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["item","unit","quantity","category"],"title":"MaterialItem","description":"Single material item in a bid pack."},"src__models__adaptive_camera__CameraPosition":{"properties":{"latitude":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Latitude","description":"Camera latitude in degrees"},"longitude":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Longitude","description":"Camera longitude in degrees"},"altitude":{"type":"number","maximum":500.0,"exclusiveMinimum":0.0,"title":"Altitude","description":"Camera altitude in meters above ground"},"heading":{"type":"number","exclusiveMaximum":360.0,"minimum":0.0,"title":"Heading","description":"Camera heading in degrees (0=North, 90=East)"},"pitch":{"type":"number","maximum":0.0,"minimum":-90.0,"title":"Pitch","description":"Camera pitch in degrees (negative = looking down)"},"view_type":{"$ref":"#/components/schemas/ViewType","description":"Whether this is front or back view"},"offset_distance":{"type":"number","exclusiveMinimum":0.0,"title":"Offset Distance","description":"Distance from property center in meters"},"triangle_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Triangle Count","description":"Triangle count from 3D tiles (filled after capture)"},"coverage_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Coverage Type","description":"Coverage classification (excellent/good/low_res/terrain_only)"}},"type":"object","required":["latitude","longitude","altitude","heading","pitch","view_type","offset_distance"],"title":"CameraPosition","description":"Camera position for 3D tile rendering.\n\nDefines where to place the virtual camera for capturing front or back views."},"src__models__agent_api_models__DesignStyle":{"type":"string","enum":["modern_minimalist","california_native","japanese_zen","english_garden","desert_landscape","mediterranean","tropical_resort"],"title":"DesignStyle","description":"Available design styles"},"src__models__agent_api_models__MaterialItem":{"properties":{"name":{"type":"string","title":"Name","description":"Material name, e.g., 'Patio Pavers'"},"quantity":{"type":"number","title":"Quantity","description":"Quantity needed"},"unit":{"$ref":"#/components/schemas/MaterialUnit","description":"Unit of measurement"},"estimated_cost":{"type":"number","title":"Estimated Cost","description":"Estimated cost in USD"}},"type":"object","required":["name","quantity","unit","estimated_cost"],"title":"MaterialItem","description":"A material item with cost estimate"},"src__models__agent_api_models__YardArea":{"type":"string","enum":["front","back","side","full"],"title":"YardArea","description":"Yard area selection"},"src__models__generation__DesignStyle":{"type":"string","enum":["modern_minimalist","california_native","japanese_zen","english_garden","desert_landscape","mediterranean","tropical_resort"],"title":"DesignStyle","description":"Landscape design style options (synced with frontend Feature 005)"},"src__models__generation__ProjectSummary":{"properties":{"place_id":{"type":"string","title":"Place Id"},"address":{"type":"string","title":"Address"},"generation_count":{"type":"integer","title":"Generation Count"},"latest_generation_at":{"type":"string","format":"date-time","title":"Latest Generation At"},"has_favorites":{"type":"boolean","title":"Has Favorites","default":false},"generation_types":{"items":{"type":"string"},"type":"array","title":"Generation Types","default":[]}},"type":"object","required":["place_id","address","generation_count","latest_generation_at"],"title":"ProjectSummary","description":"Summary of generations grouped by place_id"},"src__models__generation__YardArea":{"type":"string","enum":["front_yard","backyard","walkway","patio","pool_area"],"title":"YardArea","description":"Type of yard area for landscape generation"},"src__models__inpaint__ErrorResponse":{"properties":{"error":{"type":"string","enum":["validation_error","unauthorized","insufficient_credits","not_found","rate_limited","generation_failed"],"title":"Error","description":"Error code"},"message":{"type":"string","title":"Message","description":"Human-readable error message"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Additional error context"}},"type":"object","required":["error","message"],"title":"ErrorResponse","description":"Standard error response model."},"src__models__inpaint__InpaintStatusResponse":{"properties":{"editId":{"type":"string","format":"uuid","title":"Editid"},"status":{"$ref":"#/components/schemas/InpaintStatus"},"sourceVariantId":{"type":"string","title":"Sourcevariantid"},"resultVariantId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resultvariantid"},"resultImageUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resultimageurl"},"prompt":{"type":"string","title":"Prompt"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"completedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completedat"}},"type":"object","required":["editId","status","sourceVariantId","prompt","createdAt"],"title":"InpaintStatusResponse","description":"Response model for status polling endpoint."},"src__models__lead_discovery__LeadResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"business_name":{"type":"string","title":"Business Name"},"source":{"type":"string","title":"Source"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"lead_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Type"},"preferred_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Channel"},"outreach_status":{"type":"string","title":"Outreach Status","default":"new"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"zip_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip Code"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"rating":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rating"},"review_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Review Count"},"categories":{"items":{},"type":"array","title":"Categories"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"},"qualification_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Qualification Score"},"instagram_handle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instagram Handle"},"facebook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Facebook Url"},"nextdoor_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextdoor Url"},"houzz_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Houzz Url"},"yelp_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yelp Url"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"outreach_count":{"type":"integer","title":"Outreach Count","default":0},"canonical_lead_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Canonical Lead Id"},"enriched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Enriched At"},"last_outreach_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Outreach At"},"last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen At"},"stale_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Stale Since"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","business_name","source"],"title":"LeadResponse","description":"Discovered lead response."}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}