{"openapi":"3.0.0","info":{"title":"MapView API","description":"MapView property data API — Fastify (replacing Laravel). All endpoints require Bearer token authentication.","version":"1.0.0","contact":{"name":"MapView","url":"https://mapview.ai"}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{}},"paths":{"/health":{"get":{"summary":"Health check","tags":["health"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"service":{"type":"string"},"version":{"type":"string"},"commit":{"type":"string"},"timestamp":{"type":"string"},"cache":{"type":"object"}}}}}}}}},"/health/db":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/login":{"post":{"summary":"Login and get access token","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["login_id","password"],"properties":{"login_id":{"type":"string"},"password":{"type":"string"},"remember":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/check-login":{"post":{"summary":"Check if user exists (returns 1 or 0)","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"login_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/register":{"post":{"summary":"Register new account","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/social-login":{"post":{"summary":"Social login (Google/Facebook/LinkedIn)","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["account_id","email","provider"],"properties":{"account_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"client_token":{"type":"string"},"provider":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/apple":{"post":{"summary":"Apple Sign In","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["identity_token"],"properties":{"identity_token":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/google":{"post":{"summary":"Google Sign In","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id_token":{"type":"string"},"server_auth_code":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/register-member":{"post":{"summary":"Register new team member on an account","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/accept-terms":{"post":{"summary":"Record acceptance of current T&C + privacy policy","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/otp/send":{"post":{"summary":"Send 6-digit OTP code via email or SMS","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/otp/verify":{"post":{"summary":"Verify OTP code and issue access token","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/magic-link/send":{"post":{"summary":"Email a single-use magic sign-in link (15-min expiry)","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/magic-link/poll":{"post":{"summary":"Poll for cross-device magic-link sign-in completion","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/magic-link/verify":{"post":{"summary":"Verify magic link token and issue access token","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/magic-link/verify-code":{"post":{"summary":"Sign in with the 6-digit code from the email","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/forgot-password":{"post":{"summary":"Send password reset email","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/reset":{"post":{"summary":"Reset password using token","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/logout":{"post":{"summary":"Revoke current token","tags":["auth"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user":{"get":{"summary":"Get current authenticated user","tags":["users"],"responses":{"200":{"description":"Default Response"}}},"put":{"summary":"Update current user profile","tags":["users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"display_name":{"type":"string"},"phone":{"type":"string"},"avatar_url":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user/add-user":{"post":{"summary":"Add a user (admin)","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user/edit-user":{"post":{"summary":"Edit a user (admin)","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/user-setting":{"post":{"summary":"Set a user preference key-value pair","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user/change-password":{"post":{"summary":"Change own password","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user/account":{"get":{"summary":"Get current account details + members","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user/list":{"get":{"summary":"List users in current account","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/info":{"get":{"summary":"Get user detail + company + plan (webapp)","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/me":{"get":{"summary":"Get lightweight user profile (mobile)","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/list-users":{"get":{"summary":"List users in account (webapp)","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/logout":{"post":{"summary":"Logout (revoke token)","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/usage-stats":{"get":{"summary":"Get usage stats for current billing period","tags":["users"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/invitations":{"get":{"summary":"List invitations for current account","tags":["invitations"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Send an invitation (email or phone)","tags":["invitations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"phone":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/invitations/{id}/resend":{"post":{"summary":"Resend invitation","tags":["invitations"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/invitations/{id}":{"delete":{"summary":"Revoke an invitation","tags":["invitations"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/invitations/{token}":{"get":{"summary":"Look up invitation by token (public)","tags":["invitations"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"token","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/account-members/{userId}":{"delete":{"summary":"Remove a member from the current account","tags":["accounts"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/invitations/{token}/accept":{"post":{"summary":"Accept an invitation (must be authenticated)","tags":["invitations"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"token","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/auth/invitation-accept":{"post":{"summary":"One-click invitation accept: token acts as the credential","tags":["auth","invitations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/get-companies":{"get":{"summary":"Get CRM companies","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-company":{"post":{"summary":"Create/update company","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/get-contacts":{"get":{"summary":"Get CRM contacts","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-contact":{"post":{"summary":"Create/update contact","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/get-tasks":{"get":{"summary":"Get CRM tasks","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-task":{"post":{"summary":"Create/update task","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/get-deals":{"get":{"summary":"Get CRM deals","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-deal":{"post":{"summary":"Create/update deal","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/get-deal-action":{"get":{"summary":"Get deal actions","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-deal-action":{"post":{"summary":"Store deal action","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/get-custom-attribute":{"get":{"summary":"Get custom fields","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-custom-attribute":{"post":{"summary":"Store custom field","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/store-custom-attribute-value":{"post":{"summary":"Store field value","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/delete-custom-attribute":{"post":{"summary":"Delete custom field","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crm/delete-stage":{"post":{"summary":"Delete deals by stage","tags":["crm"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburbs":{"get":{"summary":"Get all suburbs","tags":["suburbs"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburbs/searchs":{"get":{"summary":"Search suburb by code/name","tags":["suburbs"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburbs/autosuggest":{"get":{"summary":"Autosuggest suburb by text","tags":["suburbs"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/autosuggest":{"get":{"summary":"Autosuggest (alias)","tags":["suburbs"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites":{"get":{"summary":"Fetch all sites for current account","tags":["sites"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create a new site/property","tags":["sites"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["latitude","longitude","formatted_address"],"properties":{"latitude":{"type":"number"},"longitude":{"type":"number"},"formatted_address":{"type":"string"},"street_number":{"type":"string"},"street_name":{"type":"string"},"suburb":{"type":"string"},"state":{"type":"string"},"postcode":{"type":"string"},"zone_code":{"type":"string"},"category_id":{"type":"integer"},"status_id":{"type":"integer"},"sale_price":{"type":"number"},"land_area_sqm":{"type":"number"},"notes":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/all-projects":{"get":{"summary":"Get all sites summary (legacy compat)","tags":["sites"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/number-marker":{"get":{"summary":"Get marker count this month (from activity log)","tags":["sites"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/{id}":{"get":{"summary":"Get a single site by ID","tags":["sites"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"put":{"summary":"Update a site","tags":["sites"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Delete a site","tags":["sites"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/portfolio":{"post":{"summary":"Upsert site by address (legacy compat)","tags":["sites"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/view-estimate/{id}":{"get":{"summary":"Get view estimate count","tags":["user-action"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/order-title":{"get":{"summary":"Order title","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/request-property-report":{"get":{"summary":"Request property report by email","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/generate-report-package":{"post":{"summary":"Generate property report package","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/proceed-high-res":{"post":{"summary":"Log high-res map action","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/get-cards":{"get":{"summary":"Get payment card info","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/order-document":{"post":{"summary":"Order document","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/add-card":{"post":{"summary":"Add payment card (Stripe)","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/get-report/{id}":{"get":{"summary":"Get report by ID","tags":["user-action"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/get-list-reports":{"get":{"summary":"Get list of reports","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/recent-searching-address":{"get":{"summary":"Get recent search addresses","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/save-recent-search":{"post":{"summary":"Save a recent property search","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/get-planning-info":{"post":{"summary":"Get planning info by codes","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/log-google":{"get":{"summary":"Log Google API usage","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/share-report":{"post":{"summary":"Track report share event","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/track/email-click":{"get":{"summary":"Track email link click (from re-engagement emails)","tags":["tracking"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/track/b2b-report-access":{"post":{"summary":"Track B2B report access (co-branded reports)","tags":["tracking"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/app-install":{"post":{"summary":"Track app install/open session","tags":["user-action"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/geocode":{"get":{"parameters":[{"schema":{"type":"string","minLength":5,"maxLength":500},"in":"query","name":"address","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/geo/building-units":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"string","minLength":5,"maxLength":500},"in":"query","name":"address","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-parcel-info":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-building-outlines":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-planning-zone":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-planing-info":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-permits-v2":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"address","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-suburb":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-post-code":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-orientation":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-lot-analysis":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-listing":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-building":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-epa-audit":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-planning-overlay":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-school-catchment":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-nbn":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-lga":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-council":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-assembly":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-gov-region":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"gnaf_pid","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-fire-info":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-water-retailer":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-power-dist":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-rural-water":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-melbourne-water-corp":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string","minLength":5},"in":"query","name":"address","required":true},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"includeGeom","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/nearby-planning-permit":{"get":{"parameters":[{"schema":{"type":"number"},"in":"query","name":"lat","required":true},{"schema":{"type":"number"},"in":"query","name":"lng","required":true},{"schema":{"type":"number","minimum":100,"maximum":10000},"in":"query","name":"radius","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/nearby-planning-permit-batch":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["origins"],"properties":{"origins":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["lat","lng"],"properties":{"id":{"type":"string","maxLength":128},"lat":{"type":"number"},"lng":{"type":"number"}}}},"radiusM":{"type":"number","minimum":100,"maximum":10000,"default":2000},"maxAgeDays":{"type":"number","minimum":7,"maximum":3650,"default":365},"perOriginLimit":{"type":"number","minimum":1,"maximum":200,"default":50}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/suburb-history":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"integer"},"in":"query","name":"regionId","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/get-sale-information":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"address","required":true},{"schema":{"type":"string"},"in":"query","name":"suburb","required":false},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false},{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"number"},"in":"query","name":"lat","required":false},{"schema":{"type":"number"},"in":"query","name":"lng","required":false},{"schema":{"type":"string"},"in":"query","name":"skip_gallery","required":false},{"schema":{"type":"string"},"in":"query","name":"skip_s3_gallery","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/get-suburb-demographics":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"integer"},"in":"query","name":"regionId","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/suburb-stats":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/get-data":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"method","required":true},{"schema":{"type":"string"},"in":"query","name":"address","required":false},{"schema":{"type":"string"},"in":"query","name":"suburb","required":false},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false},{"schema":{"type":"string"},"in":"query","name":"state","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/suburb-demographics-v2":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/suburb-stats":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-near-by":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-near-by/pt-stops":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/places/search-pois-batch":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/places/search-near-by":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/listing-weekly":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/listing-weekly-counts":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/rent-estimate":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/sale-comparables":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/get-property-services":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/get-list-myviews":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/store-my-views":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/delete-myview":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/update-my-views":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/update-property-ordinal":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/bookmarks":{"post":{"responses":{"200":{"description":"Default Response"}}},"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/activity":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/activity/unread-count":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/activity/read-all":{"patch":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/activity/{id}/read":{"patch":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/activity/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/bin-schedule":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/nearby-schools":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/utility-contacts":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/state-market-trends":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/auction-clearance":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/suburb-market-data":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/suggest-address":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/property-tracking-action":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/notify-my-properties":{"post":{"responses":{"200":{"description":"Default Response"}}},"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/advertise-with-mapview":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/place-detail/{placeId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"placeId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/unit-sale-info":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/notification-preferences":{"get":{"responses":{"200":{"description":"Default Response"}}},"patch":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/profile":{"patch":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/device-token":{"delete":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/users/change-password":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/generate-report-mobile-payment":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/generate-report-mobile":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/generate-report-credit":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/generate-report-coupon-code":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/send-report-email/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/report-url/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/order-title-coupon":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/generate-suburb-report":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/user-action/send-suburb-report/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/bookmarks/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/mv-intel/saved":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/mv-intel/saved/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/mv-intel/saved/{id}/alert":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abs/seek":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/nsw-land-zoning":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/news":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/news/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/nearby-childcare":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-address-info":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/generate-report-preview":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/generate-report-preview/health":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suggest-address":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/place-detail/{placeId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"placeId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/aws/search-pois-batch":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/aws/search-near-by":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/report-proxy":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/listing-address-search":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburb-data/market-trends":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburb-data/centroid":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburb-data/zone-mix":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburb-data/geojson":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-list-reports":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/recent-address":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/recent-searching-address":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sell-compare":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sale-comparables":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/due-diligence":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/due-diligence/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"put":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburb/amenities":{"get":{"summary":"School + park counts within a suburb","tags":["suburb"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/property-reports":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/suburb-reports":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/addresses/resolve":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/reports/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/reports":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/reports/{id}/pdf":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/reports/{id}/deliveries":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/reports/{id}/webhook/replay":{"post":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/usage":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/signup/config":{"get":{"summary":"Is self-serve sign-up open, and what is the free allowance?","tags":["cobranded"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/signup":{"post":{"summary":"Start a free co-branded sign-up; emails a confirmation link","tags":["cobranded"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/signup/{id}/verify":{"post":{"summary":"Confirm the email and provision the organisation (idempotent)","tags":["cobranded"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/signup/{id}/claim":{"post":{"summary":"Issue the API key and a 1-hour branding setup token (single use)","tags":["cobranded"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/setup/branding":{"put":{"summary":"Set branding with a setup token (full replace)","tags":["cobranded"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/cobranded/setup/logo":{"post":{"summary":"Upload a logo with a setup token","tags":["cobranded"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/categories":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/categories/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/status":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/status/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/proposed":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/proposed/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/portfolio":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/portfolio/{id}":{"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/contract-condition":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/contract-condition/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/menu":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/template-maker":{"get":{"responses":{"200":{"description":"Default Response"}}},"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/template-maker/{id}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/sites/all-users":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/customer":{"get":{"summary":"Get Stripe customer info + payment methods","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/subscription":{"get":{"summary":"Get current subscription status","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/create-checkout-session":{"post":{"summary":"Create Stripe Checkout session","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/cancel-subscription":{"post":{"summary":"Cancel subscription at period end","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/resume-subscription":{"post":{"summary":"Resume cancelled subscription","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/portal-return":{"get":{"summary":"Stripe portal return redirect (deep link back to app)","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/portal-session":{"post":{"summary":"Create Stripe Customer Portal URL","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/invoices":{"get":{"summary":"List past invoices","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/credits":{"get":{"summary":"Get credit balance","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/webhook":{"post":{"summary":"Stripe webhook handler","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/plans":{"get":{"summary":"List available plans with all prices","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/title-prices":{"get":{"summary":"Per-state title search prices (cents AUD, GST incl)","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/create-payment-intent":{"post":{"summary":"Create PaymentIntent for report purchase","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/validate-coupon":{"post":{"summary":"Validate a coupon code","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/create-report-payment":{"post":{"summary":"Create PaymentIntent for report purchase + optional coupon","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/billing/complete-report-purchase":{"post":{"summary":"Verify payment + generate report","tags":["billing"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/infotrack/address-lookup":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/infotrack/address/{orderId}":{"get":{"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/infotrack/order-title":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/transactions/iap":{"post":{"summary":"Record an Apple or Google IAP transaction","tags":["transactions"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["processor","processor_ref","amount","currency"],"properties":{"processor":{"type":"string","enum":["apple","google"]},"processor_ref":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string","default":"AUD"},"description":{"type":"string"},"metadata":{"type":"object"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/transactions":{"get":{"summary":"Current user's transaction history","tags":["transactions"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"in":"query","name":"pageSize","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/iap/redeem-coupon":{"post":{"summary":"Redeem a local coupon code (IAP-compatible)","tags":["iap","coupons"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","userId"],"properties":{"code":{"type":"string"},"userId":{"type":"integer"},"context":{"type":"string"},"reference":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/iap/verify":{"post":{"summary":"Verify an Apple or Google IAP purchase and record it","tags":["iap"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["platform","userId"],"properties":{"platform":{"type":"string","enum":["ios","android"]},"token":{"type":"string"},"purchaseToken":{"type":"string"},"productId":{"type":"string"},"userId":{"type":"integer"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/auth/login":{"post":{"summary":"Admin login","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/auth/magic-link/send":{"post":{"summary":"Email a staff magic sign-in link (15-min expiry)","tags":["admin","auth"],"responses":{"200":{"description":"Default Response"}}}},"/admin/auth/magic-link/verify":{"post":{"summary":"Verify staff magic link token and issue admin token","tags":["admin","auth"],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/test-send":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["user_ids","title","body"],"properties":{"user_ids":{"type":"array","items":{"type":"integer"},"minItems":1,"maxItems":10},"title":{"type":"string","minLength":1,"maxLength":120},"body":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","maxLength":60},"lat":{"type":"number"},"lng":{"type":"number"},"address":{"type":"string","maxLength":300},"suburb":{"type":"string","maxLength":120},"propertyId":{"type":"string","maxLength":40},"title_url":{"type":"string","maxLength":1000},"reference_id":{"type":"string","maxLength":200},"deep_link":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/dashboard/stats":{"get":{"summary":"Dashboard KPI stats","tags":["admin"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"totalAccounts":{"type":"integer"},"activeSubscriptions":{"type":"integer"},"mrr":{"type":"number"},"reportsGenerated":{"type":"integer"},"apiCalls":{"type":"integer"},"linksMonitored":{"type":"integer"},"newAccountsThisMonth":{"type":"integer"}}}}}}}}},"/admin/dashboard/overview":{"get":{"summary":"Dashboard overview with real operational trends","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts":{"get":{"summary":"List all accounts (paginated)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"string","enum":["active","suspended","cancelled"]},"in":"query","name":"status","required":false},{"schema":{"type":"string","default":"created_at"},"in":"query","name":"sort","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"order","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}":{"get":{"summary":"Get account details","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Update account","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["active","suspended","cancelled"]}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/members":{"get":{"summary":"List account members (sub-users)","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/activity":{"get":{"summary":"Account activity log","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"pageSize","required":false},{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/subscription":{"get":{"summary":"Get account subscription details","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/api-calls":{"get":{"summary":"API call log for all account sub-users","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"pageSize","required":false},{"schema":{"type":"integer"},"in":"query","name":"userId","required":false},{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/reports":{"get":{"summary":"List account reports","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/reports/{reportId}/download":{"get":{"summary":"Get presigned S3 URL for a report PDF","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true},{"schema":{"type":"integer"},"in":"path","name":"reportId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/invoices":{"get":{"summary":"Invoices for account (DB: Blesta history + Stripe)","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/transactions":{"get":{"summary":"Transactions for account (DB first, Stripe fallback)","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/saved-views":{"get":{"summary":"Saved properties / My Research for account","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/payment-methods":{"get":{"summary":"Stripe customers + payment methods for account","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/accounts/{id}/local-transactions":{"get":{"summary":"All local transactions for an account (Stripe + Apple + Google)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/transactions":{"get":{"summary":"All transactions across all accounts","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string","enum":["stripe","apple","google","blesta"]},"in":"query","name":"processor","required":false},{"schema":{"type":"string"},"in":"query","name":"status","required":false},{"schema":{"type":"string","enum":["sandbox","production"]},"in":"query","name":"environment","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/subscriptions":{"get":{"summary":"List all subscriptions (paginated)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/invoices/{id}/lines":{"get":{"summary":"Line items for an invoice","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/invoices":{"get":{"summary":"List all invoices from the invoices table (Blesta history + Stripe, cursor-paginated)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"starting_after","required":false},{"schema":{"type":"string"},"in":"query","name":"status","required":false},{"schema":{"type":"string","enum":["blesta","stripe","manual"]},"in":"query","name":"source","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/stripe-subscriptions":{"get":{"summary":"List all active Stripe subscriptions (cursor-paginated)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"starting_after","required":false},{"schema":{"type":"string","default":"active"},"in":"query","name":"status","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/links":{"get":{"summary":"List managed links","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"integer"},"in":"query","name":"categoryId","required":false},{"schema":{"type":"string"},"in":"query","name":"region","required":false},{"schema":{"type":"string","enum":["up","down","all"]},"in":"query","name":"status","required":false}],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create a new link","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["link_name","link_url"],"properties":{"link_name":{"type":"string"},"link_url":{"type":"string","format":"uri"},"link_category_id":{"type":"integer"},"region":{"type":"string"},"sort_order":{"type":"integer"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/links/categories":{"get":{"summary":"List link categories","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/links/{id}":{"patch":{"summary":"Update a link","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"link_name":{"type":"string"},"link_url":{"type":"string"},"link_category_id":{"type":"integer"},"region":{"type":"string"},"sort_order":{"type":"integer"}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Soft-delete a link","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/links/{id}/check":{"post":{"summary":"Trigger a health check for one link","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/links/check-all":{"post":{"summary":"Trigger health check for all links","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/activity":{"get":{"summary":"Global activity log (paginated)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"action","required":false},{"schema":{"type":"integer"},"in":"query","name":"userId","required":false},{"schema":{"type":"integer"},"in":"query","name":"accountId","required":false},{"schema":{"type":"string","format":"date"},"in":"query","name":"from","required":false},{"schema":{"type":"string","format":"date"},"in":"query","name":"to","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/crm/companies":{"get":{"summary":"List CRM companies","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"integer"},"in":"query","name":"account_id","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/crm/contacts":{"get":{"summary":"List CRM contacts","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"integer"},"in":"query","name":"companyId","required":false},{"schema":{"type":"integer"},"in":"query","name":"account_id","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/crm/deals":{"get":{"summary":"List CRM deals","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"integer"},"in":"query","name":"account_id","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/plans":{"get":{"summary":"List all plans with prices","tags":["admin"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create a new plan","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"plan_type":{"type":"string","enum":["free","recurring"]},"price_monthly":{"type":"number"},"stripe_price_id":{"type":"string"},"attributes":{},"is_active":{"type":"boolean"},"sort_order":{"type":"integer"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/plans/{id}":{"get":{"summary":"Get single plan with attached addons","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Update a plan","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"plan_type":{"type":"string","enum":["free","recurring"]},"price_monthly":{"type":"number"},"stripe_price_id":{"type":"string"},"attributes":{},"is_active":{"type":"boolean"},"sort_order":{"type":"integer"}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Delete plan","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/plans/{id}/prices":{"get":{"summary":"List prices for a plan","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Add a price to a plan","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stripe_price_id","billing_interval","price"],"properties":{"stripe_price_id":{"type":"string"},"billing_interval":{"type":"string","enum":["month","year","week","one_time"]},"price":{"type":"number"},"currency":{"type":"string","default":"AUD"},"is_active":{"type":"boolean","default":true}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/plans/{planId}/prices/{priceId}":{"patch":{"summary":"Update a plan price","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"stripe_price_id":{"type":"string"},"billing_interval":{"type":"string","enum":["month","year","week","one_time"]},"price":{"type":"number"},"currency":{"type":"string"},"is_active":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"planId","required":true},{"schema":{"type":"integer"},"in":"path","name":"priceId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Delete a plan price","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"planId","required":true},{"schema":{"type":"integer"},"in":"path","name":"priceId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/plans/{id}/addons":{"get":{"summary":"List addons attached to a plan","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/plans/{planId}/addons":{"put":{"summary":"Set addons for a plan (replaces all)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["addon_ids"],"properties":{"addon_ids":{"type":"array","items":{"type":"integer"}}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"planId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/plans/{planId}/addons/{addonId}":{"post":{"summary":"Attach addon to plan","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"planId","required":true},{"schema":{"type":"integer"},"in":"path","name":"addonId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Detach addon from plan","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"planId","required":true},{"schema":{"type":"integer"},"in":"path","name":"addonId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/addons":{"get":{"summary":"List all addons with attached plan IDs","tags":["admin"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create addon","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"price_monthly":{"type":"number"},"price_once":{"type":"number"},"billing_type":{"type":"string","enum":["recurring","one_time"]},"stripe_price_id":{"type":"string"},"attributes":{},"is_active":{"type":"boolean"},"sort_order":{"type":"integer"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/addons/{id}/plans":{"put":{"summary":"Set plans for an addon (replaces all)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan_ids"],"properties":{"plan_ids":{"type":"array","items":{"type":"integer"}}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/addons/{id}":{"patch":{"summary":"Update addon","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"price_monthly":{"type":"number"},"price_once":{"type":"number"},"billing_type":{"type":"string","enum":["recurring","one_time"]},"stripe_price_id":{"type":"string"},"attributes":{},"is_active":{"type":"boolean"},"sort_order":{"type":"integer"}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Delete addon","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics/client-routes":{"get":{"summary":"Client API route performance stats","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50,"default":15},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":1,"maximum":90,"default":30},"in":"query","name":"days","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics/external-apis":{"get":{"summary":"External API performance stats","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":90,"default":30},"in":"query","name":"days","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics/places-backend":{"get":{"summary":"Places backend mode + osm_places nightly sync freshness","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics/daily-volume":{"get":{"summary":"Daily API call volume","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":90,"default":30},"in":"query","name":"days","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/active-services":{"get":{"summary":"Active system services status (from background health checker)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/recent-signups":{"get":{"summary":"Most recent client sign-ups","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/daily-signins":{"get":{"summary":"Daily sign-in counts for last 30 days","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/recent-signin-events":{"get":{"summary":"Most recent individual sign-in events with user details","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/return-signin-leaderboard":{"get":{"summary":"Top 20 return client sign-in leaderboard","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/recent-searches":{"get":{"summary":"Recent address searches","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/default-regions":{"get":{"summary":"Default region by user total","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/recent-searches-timescale":{"get":{"summary":"Recent address searches by time, pivoted by search type","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/search-leaderboard":{"get":{"summary":"Address searching by user leaderboard","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/popular-addresses":{"get":{"summary":"Most popular addresses looked up","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/heavy-users":{"get":{"summary":"Heavy users nearby places and view estimates (saved properties)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/market-totals":{"get":{"summary":"Market totals by user (property reports generated)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/reports-by-day":{"get":{"summary":"Property reports generated by day (30 days)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/satellite-subscribers":{"get":{"summary":"High resolution satellite subscribers matched to customer accounts","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/recent-reports":{"get":{"summary":"Recently generated property reports","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/cohort-retention":{"get":{"summary":"Weekly signup cohort retention (8 weeks)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/subscription-funnel":{"get":{"summary":"Conversion funnel stages","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/feature-adoption":{"get":{"summary":"Feature adoption rates across active accounts","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/churn-risk":{"get":{"summary":"Accounts at risk of churning","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/revenue-metrics":{"get":{"summary":"Revenue per user, LTV, plan mix","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/peak-usage":{"get":{"summary":"Hour-of-day and day-of-week usage heatmap","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/platform-split":{"get":{"summary":"API calls by platform (iOS, Android, Web)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/report-types":{"get":{"summary":"Distribution of report types generated","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/event-volumes":{"get":{"summary":"30-day event volume per event type","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/investigator-guardian":{"get":{"summary":"Investigator vs Guardian user segmentation","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/b2b-funnel":{"get":{"summary":"B2B report funnel stages","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/acquisition-sources":{"get":{"summary":"Registration attribution by channel","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/analytics-page/lifecycle-emails":{"get":{"summary":"Email re-engagement metrics","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/users/{id}":{"get":{"summary":"Get user detail with device tokens","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/users/{id}/api-calls":{"get":{"summary":"User API call log (paginated)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"route","required":false},{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/stats":{"get":{"summary":"Push device token stats + recent registrations","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/users":{"get":{"summary":"Search users for push audience (email/name, includes device counts)","tags":["admin"],"parameters":[{"schema":{"type":"string","minLength":2},"in":"query","name":"q","required":true},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"in":"query","name":"limit","required":false},{"schema":{"type":"boolean","default":false},"in":"query","name":"devices_only","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/send":{"post":{"summary":"Send an on-demand push notification","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","body"],"properties":{"title":{"type":"string","minLength":1,"maxLength":100},"body":{"type":"string","minLength":1,"maxLength":300},"user_ids":{"type":"array","items":{"type":"integer"},"maxItems":500},"send_to_all":{"type":"boolean"},"deep_link":{"type":"string","maxLength":500},"title_url":{"type":"string","maxLength":1000},"reference_id":{"type":"string","maxLength":200},"type":{"type":"string","maxLength":40,"default":"admin_message"}},"anyOf":[{"required":["user_ids"]},{"required":["send_to_all"]}]}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/history":{"get":{"summary":"Recent admin push campaigns","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/sweep-reports":{"get":{"summary":"Recent property-alert sweep reports (alerts sent + devices reached per sweep)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":200,"default":30},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/reactivate-token":{"post":{"summary":"Reactivate a device token by id (recovery from wrongful deactivation)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token_id"],"properties":{"token_id":{"type":"integer"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/analytics":{"get":{"summary":"Notification performance analytics (last 30 days)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/detail":{"get":{"summary":"Recent notifications with per-user read/engaged breakdown (filterable)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":30},"in":"query","name":"limit","required":false},{"schema":{"type":"integer"},"in":"query","name":"user_id","required":false},{"schema":{"type":"string","maxLength":60},"in":"query","name":"action","required":false},{"schema":{"type":"string","enum":["read","unread","pushed","not_pushed","engaged","not_engaged"]},"in":"query","name":"state","required":false},{"schema":{"type":"integer","minimum":1,"maximum":90,"default":7},"in":"query","name":"days","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/preferences":{"get":{"summary":"Per-user notification preferences — which alerts/categories each user has enabled (read-only)","tags":["admin"],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":120},"in":"query","name":"q","required":false},{"schema":{"type":"string","enum":["property_updates","recent_sales","new_listings","demographics","service_providers","price_alerts","planning_permits","compliance"]},"in":"query","name":"category","required":false},{"schema":{"type":"boolean"},"in":"query","name":"enabled","required":false},{"schema":{"type":"boolean"},"in":"query","name":"has_device","required":false},{"schema":{"type":"boolean"},"in":"query","name":"no_prefs","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/notifications/preferences/{userId}":{"get":{"summary":"Single user notification preferences + per-property alert settings (read-only)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Set a user's notification preferences (category flags + quiet hours)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"property_updates":{"type":"boolean"},"recent_sales":{"type":"boolean"},"new_listings":{"type":"boolean"},"demographics":{"type":"boolean"},"service_providers":{"type":"boolean"},"price_alerts":{"type":"boolean"},"planning_permits":{"type":"boolean"},"compliance":{"type":"boolean"},"quiet_hours":{"type":"object","properties":{"enabled":{"type":"boolean"},"start":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"end":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/contacts":{"get":{"summary":"List contacts (users) with assigned accounts and marketing notifications flag","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"pageSize","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"integer"},"in":"query","name":"accountId","required":false},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"marketing","required":false},{"schema":{"type":"string"},"in":"query","name":"source","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/contacts/{id}":{"get":{"summary":"Get contact detail with memberships and activity stats","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Update contact fields","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":["string","null"]},"phone_number":{"type":["string","null"]},"status":{"type":"string"},"source":{"type":"string"},"marketing_notifications":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/contacts/{id}/notifications":{"patch":{"summary":"Update marketing notifications flag for a contact","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"marketing_notifications":{"type":"boolean"}},"required":["marketing_notifications"]}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/staff":{"get":{"summary":"List all admin staff members","tags":["admin"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Add a user as admin staff","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","editor","viewer"],"default":"admin"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/staff/{userId}":{"patch":{"summary":"Update staff member role","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["admin","editor","viewer"]}}}}}},"parameters":[{"schema":{"type":"integer"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Remove admin staff access","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/reports":{"get":{"summary":"List all reports (admin)","tags":["admin"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string","enum":["queued","generating","completed","failed","expired",""]},"in":"query","name":"status","required":false},{"schema":{"type":"string","enum":["0","1",""]},"in":"query","name":"premium","required":false},{"schema":{"type":"integer","minimum":1,"maximum":365,"default":30},"in":"query","name":"days","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/reports/stats":{"get":{"summary":"Report stats summary","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/investor/documents":{"get":{"summary":"List investor documents with presigned S3 download URLs","tags":["admin"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"format":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"},"key":{"type":"string"},"category":{"type":"string"}}}},"legal":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"format":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"},"key":{"type":"string"},"category":{"type":"string"}}}}}}}}}}}}}},"/admin/investor/logos":{"get":{"summary":"Get signed URLs for software support logos","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/coupons":{"get":{"summary":"List coupons with usage stats","tags":["admin","coupons"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create a coupon","tags":["admin","coupons"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","minLength":3,"maxLength":64},"description":{"type":"string"},"discount_type":{"type":"string","enum":["percent","fixed"]},"discount_value":{"type":"number"},"max_uses":{"type":["integer","null"]},"max_uses_per_user":{"type":"integer"},"expires_at":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/admin/coupons/{id}":{"patch":{"summary":"Update a coupon (status, expiry, limits, discount)","tags":["admin","coupons"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"status":{"type":"string","enum":["active","paused","expired"]},"discount_type":{"type":"string","enum":["percent","fixed"]},"discount_value":{"type":"number"},"max_uses":{"type":["integer","null"]},"max_uses_per_user":{"type":"integer"},"expires_at":{"type":["string","null"]}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Delete a coupon (blocked if it has redemptions)","tags":["admin","coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/coupons/{id}/usage":{"get":{"summary":"Per-client usage report for a coupon","tags":["admin","coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/gis/status":{"get":{"summary":"GIS pipeline status: layers, schedules, services, events, council health","tags":["admin","gis"],"responses":{"200":{"description":"Default Response"}}}},"/admin/gis/layer/{id}":{"get":{"summary":"Single GIS layer: status row + recent events","tags":["admin","gis"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/gis/db-tables":{"get":{"summary":"Prod database table row estimates (top tables)","tags":["admin","gis"],"responses":{"200":{"description":"Default Response"}}}},"/admin/gis/pipeline-health":{"get":{"summary":"Five-stage layer pipeline verification snapshot","tags":["admin","gis"],"responses":{"200":{"description":"Default Response"}}}},"/admin/gis/pipeline-coverage":{"get":{"summary":"Per-tileset seed coverage from the map pipeline collector","tags":["admin","gis"],"responses":{"200":{"description":"Default Response"}}}},"/admin/listings/summary":{"get":{"summary":"Listings pipeline summary: crawl ledger, weekly stock, classification, canaries","tags":["admin","listings"],"responses":{"200":{"description":"Default Response"}}}},"/admin/listings/activity":{"get":{"summary":"Recent listings-pipeline activity feed (agent + cron events, newest first)","tags":["admin","listings"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":200,"default":60},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/listings/schedule":{"get":{"summary":"RTC listings pipeline — scheduled runs & last status","tags":["admin","listings"],"responses":{"200":{"description":"Default Response"}}}},"/admin/listings/ingest":{"get":{"summary":"Listings ingest detail: recent scrapes, sweep progress, daily/hourly throughput","tags":["admin","listings"],"responses":{"200":{"description":"Default Response"}}}},"/admin/images/summary":{"get":{"summary":"Image classification coverage, drain runs, recently classified, activity","tags":["admin","images"],"responses":{"200":{"description":"Default Response"}}}},"/admin/images/serving":{"get":{"summary":"Per-tier image serving counters since last API deploy (primary/secondary/GSV)","tags":["admin","images"],"responses":{"200":{"description":"Default Response"}}}},"/admin/images/lookup":{"get":{"summary":"Address lookup — tier-by-tier resolution for one address (same chain as the mobile app)","tags":["admin","images"],"responses":{"200":{"description":"Default Response"}}}},"/admin/permits/summary":{"get":{"summary":"Permit pipeline summary: rows, coverage, daily series, fleet, docs, schedule","tags":["admin","permits"],"responses":{"200":{"description":"Default Response"}}}},"/admin/permits/activity":{"get":{"summary":"Recent permit-pipeline activity (run stream, newest first)","tags":["admin","permits"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":200,"default":60},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/permits/documents":{"get":{"summary":"Explore tracked DA documents (filter by council/type, search, paginate)","tags":["admin","permits"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"council","required":false},{"schema":{"type":"string"},"in":"query","name":"type","required":false},{"schema":{"type":"string"},"in":"query","name":"q","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/admin/permits/coverage":{"get":{"summary":"Coverage snapshot + upskill feed + recent scrape feed","tags":["admin","permits"],"responses":{"200":{"description":"Default Response"}}}},"/admin/snapshots":{"get":{"summary":"Dashboard snapshots: git activity, codebase stats, LLM usage","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations":{"get":{"summary":"List co-branded organisations, with self-serve provenance","tags":["admin"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create a co-branded organisation and first API key","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}":{"get":{"tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/keys":{"post":{"tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/keys/{keyId}":{"delete":{"tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true},{"schema":{"type":"integer"},"in":"path","name":"keyId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/branding":{"put":{"tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/logo":{"post":{"summary":"Upload and normalise an organisation logo","tags":["admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}},"get":{"summary":"A presigned URL for the saved logo","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/signup/approve":{"post":{"summary":"Approve a self-serve sign-up and email a fresh link","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/signup/reject":{"post":{"summary":"Reject a self-serve sign-up","tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/webhook":{"put":{"tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/organisations/{id}/status":{"patch":{"tags":["admin"],"parameters":[{"schema":{"type":"integer"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/scores/cache/clear":{"post":{"summary":"Drop every cached score (derived versions handle releases; this is the manual lever)","tags":["admin"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/trades/categories":{"get":{"summary":"List all trade categories","tags":["trades"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/trades":{"get":{"summary":"Get local trades for a suburb","tags":["trades"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true,"description":"Suburb name"},{"schema":{"type":"string"},"in":"query","name":"state","required":true,"description":"State code (VIC, NSW, QLD, SA, WA, TAS, ACT, NT)"},{"schema":{"type":"string"},"in":"query","name":"category","required":false,"description":"Optional category slug filter"}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/auction-clearance":{"get":{"summary":"Weekly auction clearance rates by city","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"state","required":false,"description":"Filter by state (e.g. NSW, VIC)"},{"schema":{"type":"string"},"in":"query","name":"city","required":false,"description":"Filter by city (e.g. Sydney, Melbourne)"},{"schema":{"type":"integer","default":52,"minimum":1,"maximum":520},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/auction-clearance/latest":{"get":{"summary":"Latest auction clearance rates (most recent week, all cities)","tags":["au-markets"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/auction-results":{"get":{"summary":"Individual auction results per property","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":false},{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false},{"schema":{"type":"string"},"in":"query","name":"result","required":false,"description":"Filter by result (sold, passed-in, withdrawn)"},{"schema":{"type":"integer","default":50,"maximum":500},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/suburb-profile":{"get":{"summary":"Suburb profile: demographics, median prices, growth, yield","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/suburb-profile/history":{"get":{"summary":"Suburb profile history (time series of snapshots)","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"integer","default":12,"maximum":104},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/sold":{"get":{"summary":"Recently sold properties","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":false},{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false},{"schema":{"type":"string"},"in":"query","name":"property_type","required":false},{"schema":{"type":"number"},"in":"query","name":"min_price","required":false},{"schema":{"type":"number"},"in":"query","name":"max_price","required":false},{"schema":{"type":"integer"},"in":"query","name":"beds","required":false},{"schema":{"type":"integer","default":50,"maximum":500},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/sold/stats":{"get":{"summary":"Sold property aggregate stats for a suburb","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/suburb-rankings":{"get":{"summary":"Suburb rankings by state and property type","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string"},"in":"query","name":"property_type","required":false,"description":"house or unit"},{"schema":{"type":"string","enum":["median_price","growth_pct","yield_pct"],"default":"median_price"},"in":"query","name":"sort_by","required":false},{"schema":{"type":"integer","default":50,"maximum":500},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/state-summary":{"get":{"summary":"State/city market summary (median prices, clearance rate, listings)","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string"},"in":"query","name":"city","required":false},{"schema":{"type":"integer","default":52,"maximum":520},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/state-summary/latest":{"get":{"summary":"Latest state market summary (all states)","tags":["au-markets"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/suburb-market-stats":{"get":{"summary":"Suburb market stats for Market Score cell (DOM, growth, clearance)","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"postcode","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"string","default":"House","enum":["House","Unit","ALL"]},"in":"query","name":"propertyType","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/suburb-market-stats/beds":{"get":{"summary":"Suburb market stats per bedroom count","tags":["au-markets"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true},{"schema":{"type":"string"},"in":"query","name":"postcode","required":true},{"schema":{"type":"string"},"in":"query","name":"state","required":true},{"schema":{"type":"string","default":"House","enum":["House","Unit","ALL"]},"in":"query","name":"propertyType","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/au-markets/planning-permits-nearby":{"get":{"summary":"Nearby planning permits from dagster pipeline (all states, geocoded)","tags":["au-markets"],"parameters":[{"schema":{"type":"number"},"in":"query","name":"lat","required":true},{"schema":{"type":"number"},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","default":1000,"maximum":5000},"in":"query","name":"radius","required":false},{"schema":{"type":"integer","default":50,"maximum":200},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/market-flow/growth":{"get":{"summary":"Suburb/LGA sales-value growth (6mo vs prior 6mo)","tags":["market-flow"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"state","required":false,"description":"Filter by state (NSW, VIC, ...)"},{"schema":{"type":"string","enum":["suburb","lga","both"],"default":"suburb"},"in":"query","name":"scope","required":false},{"schema":{"type":"string","enum":["all","house"],"default":"all"},"in":"query","name":"metric","required":false,"description":"all = all property types pooled; house = houses only"},{"schema":{"type":"integer","default":10,"minimum":0,"maximum":500},"in":"query","name":"min_sales","required":false},{"schema":{"type":"integer","default":1,"minimum":1,"maximum":10},"in":"query","name":"years","required":false,"description":"Growth window: 1Y (6mo-vs-6mo) or 2Y-10Y (full-year windows)"},{"schema":{"type":"string"},"in":"query","name":"city","required":false,"description":"Greater-city slug (sydney, melbourne, ...)"}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/market-flow/volume":{"get":{"summary":"Suburb weekly new listings/sales volume (bubble layer)","tags":["market-flow"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"state","required":false},{"schema":{"type":"string","enum":["sale","sold","rent"],"default":"sale"},"in":"query","name":"source_type","required":false},{"schema":{"type":"string"},"in":"query","name":"week","required":false,"description":"ISO date of week start (Monday). Default: latest week"},{"schema":{"type":"integer","default":1,"minimum":0},"in":"query","name":"min_count","required":false},{"schema":{"type":"string","enum":["suburb","lga"],"default":"suburb"},"in":"query","name":"scope","required":false},{"schema":{"type":"boolean","default":false},"in":"query","name":"all_weeks","required":false,"description":"Return all weeks (timelapse), not just latest"},{"schema":{"type":"string"},"in":"query","name":"city","required":false,"description":"Greater-city slug (sydney, melbourne, ...)"}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/market-flow/trends":{"get":{"summary":"Weekly volume trend series (national / state / suburb)","tags":["market-flow"],"parameters":[{"schema":{"type":"string","enum":["national","state","suburb"],"default":"state"},"in":"query","name":"scope","required":false},{"schema":{"type":"string"},"in":"query","name":"state","required":false,"description":"Required when scope=state"},{"schema":{"type":"string"},"in":"query","name":"suburb","required":false,"description":"Required when scope=suburb (lowercase)"},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false,"description":"Required when scope=suburb"},{"schema":{"type":"string","enum":["sale","sold","rent"]},"in":"query","name":"source_type","required":false},{"schema":{"type":"integer","default":52,"minimum":4,"maximum":260},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/market-flow/suburb/{state}/{suburb}/{postcode}":{"get":{"summary":"Full market profile for one suburb","tags":["market-flow"],"parameters":[{"schema":{"type":"integer","default":1,"minimum":1,"maximum":10},"in":"query","name":"years","required":false},{"schema":{"type":"string"},"in":"path","name":"state","required":true},{"schema":{"type":"string"},"in":"path","name":"suburb","required":true},{"schema":{"type":"string"},"in":"path","name":"postcode","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/get-property-images":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/dagster/graphql":{"post":{"tags":["internal"],"description":"Proxy for internal Dagster GraphQL API","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"variables":{"type":"object"},"operationName":{"type":"string"}},"required":["query"]}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/mapbox/budget":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/mapbox/matrix":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["profile","origin","dests"],"properties":{"profile":{"type":"string"},"origin":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}}},"dests":{"type":"array","minItems":1,"maxItems":24,"items":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}}}},"annotations":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/osrm/matrix":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["profile","origin","dests"],"properties":{"profile":{"type":"string"},"origin":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}}},"dests":{"type":"array","minItems":1,"maxItems":24,"items":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}}}},"annotations":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/noise/exposure":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"string","maxLength":3},"in":"query","name":"state","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/scores/config":{"get":{"summary":"The effective server-side scoring configuration","tags":["scores"],"responses":{"200":{"description":"Default Response"}}},"put":{"summary":"Update the server-side scoring configuration (admin)","tags":["scores"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/scores/{category}":{"get":{"summary":"One score category, computed server-side","tags":["scores"],"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"string","maxLength":3},"in":"query","name":"state","required":false},{"schema":{"type":"string","maxLength":80},"in":"query","name":"suburb","required":false},{"schema":{"type":"string","maxLength":8},"in":"query","name":"postcode","required":false},{"schema":{"type":"string","maxLength":16},"in":"query","name":"regionId","required":false},{"schema":{"type":"integer","minimum":0,"maximum":99},"in":"query","name":"regionNumber","required":false},{"schema":{"type":"string","maxLength":200},"in":"query","name":"address","required":false},{"schema":{"type":"string","maxLength":40},"in":"query","name":"placeId","required":false},{"schema":{"type":"string","maxLength":20},"in":"path","name":"category","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/scores":{"get":{"summary":"Every served score category, computed server-side","tags":["scores"],"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"string","maxLength":3},"in":"query","name":"state","required":false},{"schema":{"type":"string","maxLength":80},"in":"query","name":"suburb","required":false},{"schema":{"type":"string","maxLength":8},"in":"query","name":"postcode","required":false},{"schema":{"type":"string","maxLength":16},"in":"query","name":"regionId","required":false},{"schema":{"type":"integer","minimum":0,"maximum":99},"in":"query","name":"regionNumber","required":false},{"schema":{"type":"string","maxLength":200},"in":"query","name":"address","required":false},{"schema":{"type":"string","maxLength":40},"in":"query","name":"placeId","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/permits/coverage-at":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"string","maxLength":3},"in":"query","name":"state","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/hazards/parcel-extent":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","geom"],"properties":{"state":{"type":"string","maxLength":3},"geom":{}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/reverse-geocode":{"get":{"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/suburb-boundary":{"get":{"parameters":[{"schema":{"type":"string","minLength":2,"maxLength":80},"in":"query","name":"suburb","required":true},{"schema":{"type":"string","minLength":2,"maxLength":40},"in":"query","name":"state","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/crime-stats":{"get":{"summary":"Crime statistics for a suburb","tags":["crime"],"description":"Returns annual crime rates, breakdown, and nearest police station distance for a given suburb/state.","parameters":[{"schema":{"type":"string"},"in":"query","name":"suburb","required":true,"description":"Suburb name (required)"},{"schema":{"type":"string"},"in":"query","name":"state","required":true,"description":"State code e.g. NSW, VIC, QLD (required)"},{"schema":{"type":"string"},"in":"query","name":"postcode","required":false,"description":"Postcode (optional — used to disambiguate same-name suburbs)"},{"schema":{"type":"integer"},"in":"query","name":"year","required":false,"description":"Year (optional — defaults to latest available)"}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/resources":{"get":{"summary":"List resource links grouped by region and category","tags":["resources"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"region","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/get-folder-project":{"get":{"summary":"List files/folders for a site","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/create-folder":{"get":{"summary":"Create an empty folder","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/update-folder-project":{"post":{"summary":"Upload file(s) to a site folder","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/delete-file-project":{"get":{"summary":"Delete a single file","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/delete-folder":{"get":{"summary":"Delete a folder and all its contents","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/rename-file-project":{"get":{"summary":"Rename/move a file or folder (copy+delete)","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/files-manager/get-storage":{"get":{"summary":"Get storage usage for the account","tags":["file-manager"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/properties/sustainability-score":{"get":{"summary":"MapView Sustainability Rating (MVSR) — 0-100 score with pillar breakdown","tags":["sustainability"],"parameters":[{"schema":{"type":"number","minimum":-90,"maximum":90},"in":"query","name":"lat","required":true},{"schema":{"type":"number","minimum":-180,"maximum":180},"in":"query","name":"lng","required":true},{"schema":{"type":"integer","minimum":1,"maximum":99},"in":"query","name":"regionId","required":true},{"schema":{"type":"string"},"in":"query","name":"address","required":false},{"schema":{"type":"string"},"in":"query","name":"permitHistory","required":false},{"schema":{"type":"number"},"in":"query","name":"trainDistance","required":false},{"schema":{"type":"number"},"in":"query","name":"busDistance","required":false},{"schema":{"type":"number","minimum":0,"maximum":100},"in":"query","name":"walkScore","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/v1/events":{"post":{"summary":"Batch event ingestion (1-100 events)","tags":["instrumentation"],"description":"Accepts a batch of 1-100 events. Unknown event names or malformed props → 422 with per-event errors. Valid events are never lost because a sibling failed. Writes are idempotent on event_uuid.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object"}}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"inserted":{"type":"integer"},"skipped":{"type":"integer"},"errors":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"object"}}}}}}}}}},"/r/{token}":{"get":{"summary":"Tracked redirect (email clicks, shared pages, co-branded reports, PDF links)","tags":["instrumentation"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"redirect","required":false},{"schema":{"type":"string"},"in":"query","name":"type","required":false},{"schema":{"type":"string"},"in":"query","name":"property_id","required":false},{"schema":{"type":"integer"},"in":"query","name":"referring_user_id","required":false},{"schema":{"type":"string"},"in":"query","name":"partner_id","required":false},{"schema":{"type":"string"},"in":"query","name":"report_id","required":false},{"schema":{"type":"string"},"in":"query","name":"sequence_id","required":false},{"schema":{"type":"string"},"in":"path","name":"token","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/px/{token}.gif":{"get":{"summary":"Email open tracking pixel (1x1 transparent GIF)","tags":["instrumentation"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"sequence_id","required":false},{"schema":{"type":"string"},"in":"path","name":"token","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/v1/server-events":{"post":{"summary":"Server-only event ingestion (alerts, B2B, money events)","tags":["instrumentation"],"description":"Accepts server-side events: alert_received, cobranded_report_generated, cobranded_report_link_clicked, pdf_report_purchased, title_order_completed. Requires service token.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object"}}}}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-mapview-service-token","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/v1/instrumentation/health":{"get":{"summary":"Instrumentation health check","tags":["instrumentation"],"responses":{"200":{"description":"Default Response"}}}},"/v1/instrumentation/metrics":{"get":{"summary":"Basic ingestion metrics (events/sec, reject rate)","tags":["instrumentation"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":168,"default":24},"in":"query","name":"hours","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/retention-curve":{"get":{"summary":"P0: Weekly retention by monthly cohort (Investigators + Guardians)","tags":["metrics"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"cohort","required":false,"description":"YYYY-MM-DD (first of month). Omit for all."}],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/consistent-users":{"get":{"summary":"P1: Consistent user rate by cohort","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/guardian-retention":{"get":{"summary":"P2: Guardian retention + Investigator→Guardian conversion rate","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/cost-per-retaining-user":{"get":{"summary":"P3: Cost per retaining user by acquisition source","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/organic-share":{"get":{"summary":"P3: Organic share % trend","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/activation-funnel":{"get":{"summary":"Activation funnel: property_viewed → full_data_viewed → site_alert_viewed","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/b2b-funnel":{"get":{"summary":"B2B funnel: report → click → registration → consistent user, per partner","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/transactional-funnel":{"get":{"summary":"$2: title_ordered → title_order_completed funnel","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/email-lifecycle":{"get":{"summary":"Email lifecycle performance by sequence","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/subscore-popularity":{"get":{"summary":"Subscore category popularity (feeds PR-story selection)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/vanity":{"get":{"summary":"Vanity strip: registrations, downloads, views (context only, clearly labelled)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/overview":{"get":{"summary":"All key metrics in one call (dashboard hero view)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/event-taxonomy":{"get":{"summary":"Per-event counts for all taxonomy events ( Measurement dashboard)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/topics":{"get":{"summary":"section_viewed by section — topic engagement (7d / 30d / all-time)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/freshness":{"get":{"summary":"Data freshness stamp (latest event received_at)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/live-events":{"get":{"summary":"Live event log (recent events feed for Measurement dashboard)","tags":["metrics"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":30},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response"}}}},"/v1/metrics/notifications":{"get":{"summary":"Notification funnel: sent/pushed/read/engaged per alert type (7d + 30d)","tags":["metrics"],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/app/version":{"get":{"responses":{"200":{"description":"Default Response"}}}},"/api/v1/unsubscribe":{"post":{"summary":"Opt a user out of marketing notifications via a signed unsubscribe link","tags":["unsubscribe"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hash"],"properties":{"hash":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}}},"servers":[{"url":"https://api.mapview.ai","description":"Production"},{"url":"http://localhost:3001","description":"Local dev"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"geo","description":"Property & parcel geo lookups"},{"name":"utilities","description":"NBN, schools, water, power, council"},{"name":"planning","description":"Planning permits & zones"},{"name":"demographics","description":"Suburb history, demographics, sale info"},{"name":"admin","description":"Admin & reporting endpoints (Phase 3)"},{"name":"billing","description":"Stripe billing endpoints (Phase 2)"},{"name":"health","description":"Health & status"}],"correlation_id":"f4ffc700-6d01-4070-9cd7-307039a1891a"}