{"openapi":"3.1.0","info":{"title":"Apartment Hunting Platform","version":"0.1.0"},"paths":{"/api/v1/cities/coming-soon":{"get":{"tags":["city-waitlist"],"summary":"List Coming Soon Cities","description":"List all cities marked as coming soon.","operationId":"list_coming_soon_cities_api_v1_cities_coming_soon_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ComingSoonCity"},"type":"array","title":"Response List Coming Soon Cities Api V1 Cities Coming Soon Get"}}}}}}},"/api/v1/cities/{city_slug}/waitlist":{"get":{"tags":["city-waitlist"],"summary":"Get Waitlist Page Data","description":"Get all data needed for a city's coming-soon page.","operationId":"get_waitlist_page_data_api_v1_cities__city_slug__waitlist_get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistPageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/{city_slug}/waitlist/join":{"post":{"tags":["city-waitlist"],"summary":"Join Waitlist","description":"Join a city's waitlist.","operationId":"join_waitlist_api_v1_cities__city_slug__waitlist_join_post","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistJoin"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistEntry"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/{city_slug}/waitlist/position":{"get":{"tags":["city-waitlist"],"summary":"Get Waitlist Position","description":"Get your position on the waitlist.","operationId":"get_waitlist_position_api_v1_cities__city_slug__waitlist_position_get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}},{"name":"referral_code","in":"query","required":true,"schema":{"type":"string","description":"Your waitlist referral code","title":"Referral Code"},"description":"Your waitlist referral code"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistPosition"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/{city_slug}/neighborhoods":{"get":{"tags":["neighborhoods"],"summary":"List City Neighborhoods","description":"List neighborhoods for a city (public endpoint).","operationId":"list_city_neighborhoods_api_v1_cities__city_slug__neighborhoods_get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}},{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Active Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NeighborhoodSummary"},"title":"Response List City Neighborhoods Api V1 Cities  City Slug  Neighborhoods Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/neighborhoods/{neighborhood_id}":{"get":{"tags":["neighborhoods"],"summary":"Get Neighborhood","description":"Get a specific neighborhood by ID. Optionally include GeoJSON boundary.","operationId":"get_neighborhood_api_v1_neighborhoods__neighborhood_id__get","parameters":[{"name":"neighborhood_id","in":"path","required":true,"schema":{"type":"integer","title":"Neighborhood Id"}},{"name":"include_boundary","in":"query","required":false,"schema":{"type":"boolean","description":"Include GeoJSON boundary","default":false,"title":"Include Boundary"},"description":"Include GeoJSON boundary"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NeighborhoodWithBoundary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/neighborhoods/{neighborhood_id}/landing":{"get":{"tags":["neighborhood-landing"],"summary":"Get Neighborhood Landing","description":"Get the full landing-page payload for a neighborhood by ID.","operationId":"get_neighborhood_landing_api_v1_neighborhoods__neighborhood_id__landing_get","parameters":[{"name":"neighborhood_id","in":"path","required":true,"schema":{"type":"integer","title":"Neighborhood Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/{city_slug}/neighborhoods/{neighborhood_slug}/landing":{"get":{"tags":["neighborhood-landing"],"summary":"Get Neighborhood Landing By Slug","description":"Get the full landing-page payload by city + neighborhood slug (SEO URL).","operationId":"get_neighborhood_landing_by_slug_api_v1_cities__city_slug__neighborhoods__neighborhood_slug__landing_get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}},{"name":"neighborhood_slug","in":"path","required":true,"schema":{"type":"string","title":"Neighborhood Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/autocomplete":{"get":{"tags":["cities-listing"],"summary":"City Autocomplete","description":"Public endpoint: freeform US-city autocomplete over the Census\nGazetteer us_cities table (~32k places).\n\nPrefix search on the normalized name, ranked by land area as a prominence\nproxy (the Gazetteer ships no population column) then alphabetically.\nMounted here (before the cities router) so /cities/autocomplete is not\ncaptured by /{city_id}.","operationId":"city_autocomplete_api_v1_cities_autocomplete_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/listing":{"get":{"tags":["cities-listing"],"summary":"Get Cities Listing","description":"Public endpoint: list all active cities for the consumer Cities page.\n\nReturns ``{\"live\": [...], \"coming_soon\": [...]}`` where each entry has:\nid, name, slug, state, tagline, coming_soon, neighborhood_count,\nestimated_launch_date, waitlist_count.","operationId":"get_cities_listing_api_v1_cities_listing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/cities/directory":{"get":{"tags":["cities-listing"],"summary":"Get Cities Directory","description":"Public endpoint: State→City cascading-selector directory.\n\nReturns live cities (is_active AND NOT coming_soon) grouped by normalized\nstate, sorted by state display name then city name, plus the distinct\nstate codes of coming-soon cities (a code may appear in BOTH lists when a\nstate has live and coming-soon cities — the frontend's tier logic handles\nthe overlap). Building counts come from ONE aggregate query (Building has\nno is_active/archived flag, so all rows count). Cities whose state string\nfails normalization are excluded rather than crashing the response.","operationId":"get_cities_directory_api_v1_cities_directory_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/geo/state":{"get":{"tags":["geo"],"summary":"Visitor State","operationId":"visitor_state_api_v1_geo_state_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/cities/":{"get":{"tags":["cities"],"summary":"Read Cities","description":"Retrieve cities with optional search and pagination.\nBy default, only returns active cities (is_active=True).\nAdmin users can pass active_only=false to see all cities.","operationId":"read_cities_api_v1_cities__get","parameters":[{"name":"skip","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Skip"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":100,"title":"Limit"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","description":"Filter to only return active cities","default":true,"title":"Active Only"},"description":"Filter to only return active cities"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/City"},"title":"Response Read Cities Api V1 Cities  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/{city_id}":{"get":{"tags":["cities"],"summary":"Read City","description":"Get a specific city by ID.","operationId":"read_city_api_v1_cities__city_id__get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/City"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cities/{city_id}/pois":{"get":{"tags":["cities-pois"],"summary":"Get City Pois","description":"Get all POIs for a city.","operationId":"get_city_pois_api_v1_cities__city_id__pois_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/register":{"post":{"tags":["authentication"],"summary":"Register","description":"Register a new user.\n\nIf `become_ambassador=True`, also creates an ACTIVE ambassador record so the\nuser can start referring immediately (auto-approve flow used by the\nambassador Join CTA).","operationId":"register_api_v1_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["authentication"],"summary":"Login","description":"Authenticate, mint access + refresh tokens, set auth cookies.\n\nThe JSON body still carries `access_token`/`refresh_token` so non-browser\nclients (scripts, mobile) keep working without cookies.","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_login_api_v1_auth_login_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/refresh":{"post":{"tags":["authentication"],"summary":"Refresh","description":"Exchange a valid refresh token for a fresh access + refresh pair.\n\nRefresh tokens are single-use (rotated). Browser clients don't need to send\na body - the refresh_token cookie is read automatically.","operationId":"refresh_api_v1_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/RefreshTokenRequest"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["authentication"],"summary":"Logout","description":"Revoke refresh token + blacklist current access token, clear cookies.","operationId":"logout_api_v1_auth_logout_post","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/RefreshTokenRequest"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["authentication"],"summary":"Read Users Me","description":"Get current user information (no per-call last_login write).","operationId":"read_users_me_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/api/v1/auth/status":{"get":{"tags":["authentication"],"summary":"Auth Status","description":"Anonymous-safe session check.\n\nReturns 200 with `{authenticated: true, user: {...}}` when a valid session\nexists, or 200 with `{authenticated: false, user: null}` when it doesn't.\n\nUnlike `/auth/me` (which 401s for anonymous visitors), this NEVER returns a\n4xx status, so the browser doesn't log a \"Failed to load resource: 401\"\nconsole error on every public page load. The SPA bootstrap uses this\ninstead of `/auth/me` (SEO Phase 3.9 — clears the `errors-in-console` audit).","operationId":"auth_status_api_v1_auth_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/password-reset/request":{"post":{"tags":["authentication"],"summary":"Password Reset Request","description":"Request a password reset link by email.\n\nAlways returns 200 (never reveals whether the email exists) to prevent\naccount enumeration. If the user exists, a reset email is sent.","operationId":"password_reset_request_api_v1_auth_password_reset_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/password-reset/confirm":{"post":{"tags":["authentication"],"summary":"Password Reset Confirm","description":"Confirm a password reset: verify token, set new password, clear token.","operationId":"password_reset_confirm_api_v1_auth_password_reset_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/map/search":{"get":{"tags":["map-pois"],"summary":"Search Pois","description":"POI search using only local database","operationId":"search_pois_api_v1_map_search_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","description":"Center latitude","title":"Lat"},"description":"Center latitude"},{"name":"lng","in":"query","required":true,"schema":{"type":"number","description":"Center longitude","title":"Lng"},"description":"Center longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"number","description":"Search radius in miles","default":5,"title":"Radius"},"description":"Search radius in miles"},{"name":"query","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search query for POI names","title":"Query"},"description":"Search query for POI names"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category name","title":"Category"},"description":"Filter by category name"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/app__schemas__poi__POIResponse"},"title":"Response Search Pois Api V1 Map Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/map/cities/{city_id}/pois":{"get":{"tags":["map-pois"],"summary":"Get City Pois","description":"Get all POIs for a specific city from local database","operationId":"get_city_pois_api_v1_map_cities__city_id__pois_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}},{"name":"lat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Center latitude for distance calculation","title":"Lat"},"description":"Center latitude for distance calculation"},{"name":"lng","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Center longitude for distance calculation","title":"Lng"},"description":"Center longitude for distance calculation"},{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Search radius in miles","default":50,"title":"Radius"},"description":"Search radius in miles"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category name","title":"Category"},"description":"Filter by category name"},{"name":"query","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search query for POI names","title":"Query"},"description":"Search query for POI names"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/app__schemas__poi__POIResponse"},"title":"Response Get City Pois Api V1 Map Cities  City Id  Pois Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/map/categories":{"get":{"tags":["map-pois"],"summary":"Get Poi Categories","description":"Get all POI categories","operationId":"get_poi_categories_api_v1_map_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/app__schemas__poi__POICategoryResponse"},"type":"array","title":"Response Get Poi Categories Api V1 Map Categories Get"}}}}}}},"/api/v1/pois/search":{"get":{"tags":["pois"],"summary":"Search Pois","description":"Search for POIs using local database","operationId":"search_pois_api_v1_pois_search_get","parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":2,"description":"Search query for POI","title":"Query"},"description":"Search query for POI"},{"name":"lat","in":"query","required":true,"schema":{"type":"number","description":"Latitude for search center","title":"Lat"},"description":"Latitude for search center"},{"name":"lng","in":"query","required":true,"schema":{"type":"number","description":"Longitude for search center","title":"Lng"},"description":"Longitude for search center"},{"name":"radius","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":100,"description":"Search radius in meters","default":5000,"title":"Radius"},"description":"Search radius in meters"},{"name":"categories","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter by POI categories","title":"Categories"},"description":"Filter by POI categories"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/app__schemas__hunt_poi__POIResponse"},"title":"Response Search Pois Api V1 Pois Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pois/categories":{"get":{"tags":["pois"],"summary":"Get Poi Categories","description":"Get available POI categories","operationId":"get_poi_categories_api_v1_pois_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/app__schemas__hunt_poi__POICategoryResponse"},"type":"array","title":"Response Get Poi Categories Api V1 Pois Categories Get"}}}}}}},"/api/v1/pois":{"get":{"tags":["pois"],"summary":"Get Pois By City","description":"Get all POIs for a city","operationId":"get_pois_by_city_api_v1_pois_get","parameters":[{"name":"city_id","in":"query","required":true,"schema":{"type":"integer","description":"City ID to filter POIs","title":"City Id"},"description":"City ID to filter POIs"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Pois By City Api V1 Pois Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/client-invitations/{token}":{"get":{"tags":["client-invitations"],"summary":"Get Client Invitation","description":"PUBLIC landing payload for /client-invite/{token}.\n\n404 invalid/revoked token, 410 expired (rows auto-marked expired). An\nalready-accepted invitation still lands with status='accepted' so the\npage can say 'log in instead'.","operationId":"get_client_invitation_api_v1_client_invitations__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientInvitationLanding"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/client-invitations/{token}/accept":{"post":{"tags":["client-invitations"],"summary":"Accept Client Invitation","description":"PUBLIC accept: create the client account + profile + consume the token.\n\nMirrors the auth login response shape (tokens + user dict + auth cookies)\nso the frontend can auto-login immediately after accepting.\n\n404 invalid token, 410 expired, 409 when the email already belongs to a\nverified user (log in instead), 429 rate-limited (20 accepts/hour/IP).","operationId":"accept_client_invitation_api_v1_client_invitations__token__accept_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientInviteAcceptRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tiles/{city_id}/{z}/{x}/{y}.pbf":{"get":{"tags":["tiles"],"summary":"Get Tile","description":"Serve vector tiles for a city from MBTiles file.\n\nThis endpoint serves vector tiles in Protocol Buffer Binary Format (PBF) for use with MapLibre GL JS.\nTiles are served from pre-generated MBTiles files stored on disk.\n\nArgs:\n    city_id: ID of the city\n    z: Zoom level (0-18)\n    x: Tile X coordinate\n    y: Tile Y coordinate\n    db: Database session\n\nReturns:\n    Vector tile data in PBF format\n\nRaises:\n    404: If city or tile file not found, or tile doesn't exist in MBTiles","operationId":"get_tile_api_v1_tiles__city_id___z___x___y__pbf_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}},{"name":"z","in":"path","required":true,"schema":{"type":"integer","title":"Z"}},{"name":"x","in":"path","required":true,"schema":{"type":"integer","title":"X"}},{"name":"y","in":"path","required":true,"schema":{"type":"integer","title":"Y"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tiles/{city_id}/tiles.json":{"get":{"tags":["tiles"],"summary":"Get Tile Metadata","description":"Get tile metadata for a city (for MapLibre GL JS).\n\nThis endpoint returns tile metadata in the format expected by MapLibre GL JS,\nincluding tile URLs and zoom level ranges.\n\nArgs:\n    city_id: ID of the city\n    db: Database session\n\nReturns:\n    Tile metadata dictionary with tiles array and zoom levels\n\nRaises:\n    404: If city tiles not found","operationId":"get_tile_metadata_api_v1_tiles__city_id__tiles_json_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tiles/{city_id}/info":{"get":{"tags":["tiles"],"summary":"Get City Tile Info","description":"Get detailed information about a city's tiles.\n\nThis endpoint returns comprehensive information about a city's tile configuration,\nincluding file path, size, zoom levels, and last refresh timestamp.\n\nArgs:\n    city_id: ID of the city\n    db: Database session\n\nReturns:\n    Detailed tile information dictionary\n\nRaises:\n    404: If city or tiles not found","operationId":"get_city_tile_info_api_v1_tiles__city_id__info_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tiles/{city_id}/raster/{z}/{x}/{y}.png":{"get":{"tags":["tiles"],"summary":"Get Raster Tile","description":"Serve raster tiles for a city from MBTiles file.\n\nThis endpoint serves raster (PNG) tiles for the base map layer.\nTiles are served from pre-downloaded MBTiles files stored on disk.\n\nArgs:\n    city_id: ID of the city\n    z: Zoom level (10-18)\n    x: Tile X coordinate\n    y: Tile Y coordinate\n    db: Database session\n\nReturns:\n    Raster tile data in PNG format\n\nRaises:\n    404: If city or tile file not found, or tile doesn't exist\n    500: If tiles not ready (show error message for debugging)","operationId":"get_raster_tile_api_v1_tiles__city_id__raster__z___x___y__png_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}},{"name":"z","in":"path","required":true,"schema":{"type":"integer","title":"Z"}},{"name":"x","in":"path","required":true,"schema":{"type":"integer","title":"X"}},{"name":"y","in":"path","required":true,"schema":{"type":"integer","title":"Y"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tiles/{city_id}/raster/status":{"get":{"tags":["tiles"],"summary":"Get Raster Tile Status","description":"Get the status of raster tile downloads for a city.\n\nThis endpoint returns the current status of raster tile downloads,\nincluding progress information and any error messages.\n\nArgs:\n    city_id: ID of the city\n    db: Database session\n\nReturns:\n    Status dictionary with download progress and file info\n\nRaises:\n    404: If city not found","operationId":"get_raster_tile_status_api_v1_tiles__city_id__raster_status_get","parameters":[{"name":"city_id","in":"path","required":true,"schema":{"type":"integer","title":"City Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/support/inquiries":{"post":{"tags":["support"],"summary":"Create Inquiry","description":"Submit an inquiry from the public /contact page (anonymous allowed).","operationId":"create_inquiry_api_v1_support_inquiries_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InquiryCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/service-providers/leads":{"post":{"tags":["service-providers"],"summary":"Create Provider Lead","description":"Submit a provider lead from a public provider page (anonymous).\n\n/for-movers → service_type=\"moving\"; /for-buildings →\nservice_type=\"property_management\" (website required, optional\nrss_feed_url); /for-realtors → service_type=\"realtor\" (website required,\nsingle-org, rss_feed_url accepted but optional).","operationId":"create_provider_lead_api_v1_service_providers_leads_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderLeadCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pending-hunts/":{"post":{"tags":["pending-hunts"],"summary":"Create Pending Hunt","description":"Create a new pending hunt.\n\nThis endpoint is used by guest users (not logged in) to submit a hunt.\nIf the email matches an existing verified user, the hunt is auto-verified.\nOtherwise, a verification email is sent.\n\nCRITICAL: All emails are sent to aptrelay@proton.me for testing.","operationId":"create_pending_hunt_api_v1_pending_hunts__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingHuntCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingHuntResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pending-hunts/verify/{token}":{"get":{"tags":["pending-hunts"],"summary":"Verify Email","description":"Verify email address using token from verification link.\n\nThis endpoint is called when user clicks the verification link in their email.\nIt validates the token and either:\n- Starts hunt processing (if no payment required)\n- Redirects to payment page (if payment required)","operationId":"verify_email_api_v1_pending_hunts_verify__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pending-hunts/resend-verification":{"post":{"tags":["pending-hunts"],"summary":"Resend Verification","description":"Resend verification email (rate-limited: max 3 per hour per email).","operationId":"resend_verification_api_v1_pending_hunts_resend_verification_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendVerificationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendVerificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/plans":{"get":{"tags":["payments"],"summary":"Get Pricing Plans","description":"Get all active pricing plans.","operationId":"get_pricing_plans_api_v1_payments_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingPlanListResponse"}}}}}}},"/api/v1/payments/plans/{plan_id}":{"get":{"tags":["payments"],"summary":"Get Pricing Plan","description":"Get a specific pricing plan.","operationId":"get_pricing_plan_api_v1_payments_plans__plan_id__get","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","title":"Plan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/invoice/{invoice_id}":{"get":{"tags":["payments"],"summary":"Get Invoice Status","description":"Get the status of an invoice.\n\nThis endpoint fetches the current status from both the database\nand the payment service.","operationId":"get_invoice_status_api_v1_payments_invoice__invoice_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/exchange-rate":{"get":{"tags":["payments"],"summary":"Get Exchange Rate","description":"Get the current exchange rate between crypto and fiat.","operationId":"get_exchange_rate_api_v1_payments_exchange_rate_get","parameters":[{"name":"crypto","in":"query","required":false,"schema":{"type":"string","default":"BTC","title":"Crypto"}},{"name":"fiat","in":"query","required":false,"schema":{"type":"string","default":"USD","title":"Fiat"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeRateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/webhooks/bitcart":{"post":{"tags":["payments"],"summary":"Handle Bitcart Webhook","description":"Handle BitCart webhook notifications.\n\nThis endpoint receives payment status updates from BitCart and\nupdates the database accordingly.","operationId":"handle_bitcart_webhook_api_v1_payments_webhooks_bitcart_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}}}}},"/api/v1/credits/packages":{"get":{"tags":["credits"],"summary":"Get Packages","description":"Get all credit funding packages. Public endpoint.\n\nBy default only active packages are returned. Admin callers may pass\n``include_inactive=true`` to see all packages (including the Free tier\nwhich has price_usd=0).","operationId":"get_packages_api_v1_credits_packages_get","parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditPackageListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/credits/events":{"get":{"tags":["credits"],"summary":"Get Events","description":"Get all billable events. Public endpoint.\n\nBy default only active events are returned. Admin callers may pass\n``include_inactive=true`` to see all events.","operationId":"get_events_api_v1_credits_events_get","parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillableEventListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/status/public":{"get":{"tags":["public-status"],"summary":"Get Public Status","description":"Public status endpoint — no auth required.\n\nReturns the operational status of core platform services.\nResponse is cached for 30 seconds via Cache-Control header.","operationId":"get_public_status_api_v1_status_public_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/newsroom/sitemap.xml":{"get":{"tags":["newsroom"],"summary":"Get Sitemap","description":"Generate XML sitemap for all published newsroom content.\n\nReturns a sitemap.xml with all published articles and the newsroom listing page.\nNo authentication required.","operationId":"get_sitemap_api_v1_newsroom_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/newsroom/feed.xml":{"get":{"tags":["newsroom"],"summary":"Get Rss Feed","description":"Generate RSS 2.0 feed for the latest 20 published articles.\n\nReturns a standard RSS 2.0 XML feed.\nNo authentication required.","operationId":"get_rss_feed_api_v1_newsroom_feed_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/newsroom/articles/{slug}/structured-data":{"get":{"tags":["newsroom"],"summary":"Get Article Structured Data","description":"Get JSON-LD structured data for a published article.\n\nReturns schema.org NewsArticle structured data for SEO.\nNo authentication required.","operationId":"get_article_structured_data_api_v1_newsroom_articles__slug__structured_data_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/newsroom/articles":{"get":{"tags":["newsroom"],"summary":"List Articles","description":"List published articles with pagination and optional filtering.\n\n- **page**: Page number (1-indexed)\n- **per_page**: Items per page (max 50)\n- **category**: Filter by category (product, company, insights, press, partnership, announcement)\n- **tag**: Filter by tag","operationId":"list_articles_api_v1_newsroom_articles_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":12,"title":"Per Page"},"description":"Items per page"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category","title":"Category"},"description":"Filter by category"},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by tag","title":"Tag"},"description":"Filter by tag"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/newsroom/articles/featured":{"get":{"tags":["newsroom"],"summary":"Get Featured Articles","description":"Get featured articles for homepage display.\n\nReturns articles marked as is_featured=True, ordered by published_at.","operationId":"get_featured_articles_api_v1_newsroom_articles_featured_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"description":"Maximum number of featured articles","default":3,"title":"Limit"},"description":"Maximum number of featured articles"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ArticleSummary"},"title":"Response Get Featured Articles Api V1 Newsroom Articles Featured Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/newsroom/articles/{slug}":{"get":{"tags":["newsroom"],"summary":"Get Article By Slug","description":"Get a single published article by slug.\n\n- **slug**: Article URL slug","operationId":"get_article_by_slug_api_v1_newsroom_articles__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/newsroom/categories":{"get":{"tags":["newsroom"],"summary":"List Categories","description":"List all article categories with article counts.\n\nReturns all valid categories with counts of published articles.","operationId":"list_categories_api_v1_newsroom_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryListResponse"}}}}}}},"/api/v1/newsroom/media-pack":{"get":{"tags":["newsroom"],"summary":"List Media Pack Assets","description":"List all downloadable media pack assets.\n\n- **category**: Optional filter by asset category (brand, product, team)","operationId":"list_media_pack_assets_api_v1_newsroom_media_pack_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category (brand, product, team)","title":"Category"},"description":"Filter by category (brand, product, team)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaPackAssetListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/newsroom/media-pack/{asset_id}/file":{"get":{"tags":["newsroom"],"summary":"Get Media Pack File","description":"Serve a media pack file for downloading or inline viewing.\n\nReturns the file content with appropriate Content-Type.\nNo authentication required.","operationId":"get_media_pack_file_api_v1_newsroom_media_pack__asset_id__file_get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"integer","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/posts":{"get":{"tags":["blog"],"summary":"List Posts","description":"List published blog posts with pagination and optional filtering.\n\n- **page**: Page number (1-indexed)\n- **per_page**: Items per page (max 50)\n- **city_slug**: Filter by city slug\n- **topic_slug**: Filter by topic slug\n- **topic_category**: Filter by topic category\n- **tag**: Filter by tag\n- **is_featured**: Filter by featured status","operationId":"list_posts_api_v1_blog_posts_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":12,"title":"Per Page"},"description":"Items per page"},{"name":"city_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by city slug","title":"City Slug"},"description":"Filter by city slug"},{"name":"topic_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by topic slug","title":"Topic Slug"},"description":"Filter by topic slug"},{"name":"topic_category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by topic category","title":"Topic Category"},"description":"Filter by topic category"},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by tag","title":"Tag"},"description":"Filter by tag"},{"name":"is_featured","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by featured status","title":"Is Featured"},"description":"Filter by featured status"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/posts/featured":{"get":{"tags":["blog"],"summary":"Get Featured Posts","description":"Get featured posts for display.\n\nReturns posts marked as is_featured=True, ordered by published_at.","operationId":"get_featured_posts_api_v1_blog_posts_featured_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Maximum number of featured posts","default":5,"title":"Limit"},"description":"Maximum number of featured posts"},{"name":"city_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by city slug","title":"City Slug"},"description":"Filter by city slug"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlogPostSummary"},"title":"Response Get Featured Posts Api V1 Blog Posts Featured Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/posts/{city_slug}/{slug}":{"get":{"tags":["blog"],"summary":"Get Post By City And Slug","description":"Get a published post by city slug and post slug.\n\n- **city_slug**: City URL slug\n- **slug**: Post URL slug","operationId":"get_post_by_city_and_slug_api_v1_blog_posts__city_slug___slug__get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/posts/general/{slug}":{"get":{"tags":["blog"],"summary":"Get General Post By Slug","description":"Get a published general post (no city) by slug.\n\n- **slug**: Post URL slug","operationId":"get_general_post_by_slug_api_v1_blog_posts_general__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/cities-with-posts":{"get":{"tags":["blog"],"summary":"Get Cities With Posts","description":"Get list of cities that have published blog posts.\n\nReturns cities with their post counts, ordered alphabetically by name.\nUsed by the blog homepage to display city navigation.","operationId":"get_cities_with_posts_api_v1_blog_cities_with_posts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/blog/cities/{city_slug}/posts":{"get":{"tags":["blog"],"summary":"Get City Posts","description":"Get all published posts for a city.\n\n- **city_slug**: City URL slug\n- **page**: Page number (1-indexed)\n- **per_page**: Items per page (max 50)","operationId":"get_city_posts_api_v1_blog_cities__city_slug__posts_get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":12,"title":"Per Page"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/cities/{city_slug}/stats":{"get":{"tags":["blog"],"summary":"Get City Blog Stats","description":"Get blog statistics for a city.\n\nReturns post counts and available topics for a city.","operationId":"get_city_blog_stats_api_v1_blog_cities__city_slug__stats_get","parameters":[{"name":"city_slug","in":"path","required":true,"schema":{"type":"string","title":"City Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CityBlogStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/topics":{"get":{"tags":["blog"],"summary":"List Topics","description":"List all blog topics.\n\n- **category**: Optional filter by category","operationId":"list_topics_api_v1_blog_topics_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category","title":"Category"},"description":"Filter by category"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogTopicListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/preview/{token}":{"get":{"tags":["blog"],"summary":"Get Post By Preview Token","description":"Get a post by preview token (for draft previews).\n\nThis endpoint allows viewing unpublished posts via a secure preview link.\n- **token**: Preview token (64-character hex string)","operationId":"get_post_by_preview_token_api_v1_blog_preview__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/posts/{post_id}/related":{"get":{"tags":["blog"],"summary":"Get Related Posts","description":"Get related posts for a given post.\n\n- **post_id**: Post ID\n- **limit**: Maximum number of related posts","operationId":"get_related_posts_api_v1_blog_posts__post_id__related_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"description":"Maximum number of related posts","default":5,"title":"Limit"},"description":"Maximum number of related posts"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlogPostSummary"},"title":"Response Get Related Posts Api V1 Blog Posts  Post Id  Related Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blog/sitemap.xml":{"get":{"tags":["blog"],"summary":"Get Sitemap","description":"Generate XML sitemap for all published blog content.\n\nReturns a sitemap.xml with all published posts.\nNo authentication required.","operationId":"get_sitemap_api_v1_blog_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/blog/feed.xml":{"get":{"tags":["blog"],"summary":"Get Rss Feed","description":"Generate RSS 2.0 feed for the blog.\n\nReturns an RSS feed with the latest published posts.\nNo authentication required.\n\n- **limit**: Maximum number of posts to include (default 20, max 50)","operationId":"get_rss_feed_api_v1_blog_feed_xml_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum number of posts","default":20,"title":"Limit"},"description":"Maximum number of posts"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/careers/jobs":{"get":{"tags":["careers"],"summary":"List Published Jobs","description":"List published job postings with pagination and optional department filter.\n\n- **page**: Page number (1-indexed)\n- **per_page**: Items per page (max 50)\n- **department**: Filter by department (Marketing, Sales, Operations, Product, Design, Engineering, People)","operationId":"list_published_jobs_api_v1_careers_jobs_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":20,"title":"Per Page"},"description":"Items per page"},{"name":"department","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by department","title":"Department"},"description":"Filter by department"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobPostingListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/careers/jobs/{slug}":{"get":{"tags":["careers"],"summary":"Get Job By Slug","description":"Get a published job posting by slug.\n\n- **slug**: Job posting URL slug","operationId":"get_job_by_slug_api_v1_careers_jobs__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobPostingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/careers/jobs/{job_id}/apply":{"post":{"tags":["careers"],"summary":"Submit Application","description":"Submit a job application (public).\n\nAccepts multipart form data with optional resume file upload.\n- **first_name**: Required\n- **last_name**: Required\n- **email**: Required\n- **resume**: Optional PDF/DOCX file (max 10MB)","operationId":"submit_application_api_v1_careers_jobs__job_id__apply_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"integer","title":"Job Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_submit_application_api_v1_careers_jobs__job_id__apply_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobApplicationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/careers/departments":{"get":{"tags":["careers"],"summary":"List Departments","description":"List all valid department values.","operationId":"list_departments_api_v1_careers_departments_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/sharing/invitations/pending":{"get":{"tags":["sharing"],"summary":"List Pending Invitations","description":"List pending invitations for the current user (matched by email).","operationId":"list_pending_invitations_api_v1_sharing_invitations_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/HuntInvitationResponse"},"type":"array","title":"Response List Pending Invitations Api V1 Sharing Invitations Pending Get"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/api/v1/sharing/invitations/{token}":{"get":{"tags":["sharing"],"summary":"Get Invitation Details","description":"Get invitation details by token. Requires authentication.\n\nReturns invitation details so the frontend can show who invited\nthe user and what hunt/permission before they accept or decline.","operationId":"get_invitation_details_api_v1_sharing_invitations__token__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HuntInvitationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sharing/invitations/{token}/accept":{"post":{"tags":["sharing"],"summary":"Accept Invitation","description":"Accept a hunt invitation. Requires authentication.","operationId":"accept_invitation_api_v1_sharing_invitations__token__accept_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HuntShareResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sharing/invitations/{token}/decline":{"post":{"tags":["sharing"],"summary":"Decline Invitation","description":"Decline a hunt invitation.","operationId":"decline_invitation_api_v1_sharing_invitations__token__decline_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ambassador/leaderboard":{"get":{"tags":["ambassador"],"summary":"Get Ambassador Leaderboard","description":"Get the public ambassador leaderboard (no auth required).","operationId":"get_ambassador_leaderboard_api_v1_ambassador_leaderboard_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AmbassadorLeaderboardEntry"},"title":"Response Get Ambassador Leaderboard Api V1 Ambassador Leaderboard Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ambassador/tiers":{"get":{"tags":["ambassador"],"summary":"Get Ambassador Tiers","description":"Get all tier definitions (public — no auth required).","operationId":"get_ambassador_tiers_api_v1_ambassador_tiers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AmbassadorTierInfo"},"type":"array","title":"Response Get Ambassador Tiers Api V1 Ambassador Tiers Get"}}}}}}},"/api/v1/sitemap.xml":{"get":{"tags":["sitemap"],"summary":"Get Full Sitemap","description":"Generate a comprehensive XML sitemap covering ALL consumer-facing routes.\n\nIncludes: static pages, cities, neighborhoods, blog posts, newsroom articles, careers.\nNo authentication required.","operationId":"get_full_sitemap_api_v1_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/robots.txt":{"get":{"tags":["sitemap"],"summary":"Get Robots Txt","description":"Generate robots.txt content (belt-and-suspenders mirror of the static file).\n\nThe primary robots.txt is the static file in frontend/public/robots.txt\n(served by the CRA build). This endpoint provides a dynamic fallback.","operationId":"get_robots_txt_api_v1_robots_txt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/media/transform":{"get":{"tags":["media"],"summary":"Transform Image","description":"Return a resized/re-encoded image variant, cached on disk.\n\nResponses are immutable (1-year cache). Unknown/escaped paths or\nunsupported extensions return 404; render failures return 500.","operationId":"transform_image_api_v1_media_transform_get","parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Source path relative to the data dir, e.g. uploads/blog/images/abc.png","title":"Path"},"description":"Source path relative to the data dir, e.g. uploads/blog/images/abc.png"},{"name":"w","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":16,"description":"Target width in CSS pixels (height auto-scaled).","default":800,"title":"W"},"description":"Target width in CSS pixels (height auto-scaled)."},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"Output format: webp | jpeg | png.","default":"webp","title":"Format"},"description":"Output format: webp | jpeg | png."}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent/hunt-links":{"post":{"tags":["agent-api"],"summary":"Create Hunt Link","operationId":"create_hunt_link_api_v1_agent_hunt_links_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HuntLinkCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent/city-requests":{"post":{"tags":["agent-api"],"summary":"Create City Request","description":"Submit a city expansion request. Anonymous, rate-limited, deduplicated.\n\nSources: agents (mcp / agent_api), humans (ai-agents-page /\nhomepage-dropdown / geo-sheet). Optional email records a lead.","operationId":"create_city_request_api_v1_agent_city_requests_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CityRequestCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent/city-requests/lead":{"post":{"tags":["agent-api"],"summary":"Create City Request Lead","description":"Attach an email to an already-submitted city request (notify-on-launch\n+ 30 signup credits incentive). Anonymous, rate-limited, deduplicated;\ndoes NOT increment the demand counter (the city request already did).","operationId":"create_city_request_lead_api_v1_agent_city_requests_lead_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CityRequestLeadCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent/city-requests/stats":{"get":{"tags":["agent-api"],"summary":"City Request Stats","description":"Public: top requested cities for expansion.","operationId":"city_request_stats_api_v1_agent_city_requests_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/agent/error-reports":{"post":{"tags":["agent-api"],"summary":"Create Error Report","description":"Submit an error report. Anonymous, rate-limited, strictly sanitized.\n\nFree text is enum/regex-validated + injection-blocklisted + XSS-checked\nafter sanitizing (agent_error_report_service). Admins triage via the\nAgent Analytics page; no personal data is collected (ip_hash only).","operationId":"create_error_report_api_v1_agent_error_reports_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorReportCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent/hunt-links/{token}":{"get":{"tags":["agent-api"],"summary":"Resolve Hunt Link","operationId":"resolve_hunt_link_api_v1_agent_hunt_links__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agent/hunt-links/{token}/status":{"get":{"tags":["agent-api"],"summary":"Hunt Link Status","operationId":"hunt_link_status_api_v1_agent_hunt_links__token__status_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proxy-check/echo":{"get":{"tags":["proxy-check","proxy-check"],"summary":"Proxy Check Echo","description":"Return the caller's exit IP, ground-truth country, and anonymity headers.\n\nResponse shape is fixed and minimal. No request input is reflected other\nthan the standard headers listed above.","operationId":"proxy_check_echo_api_v1_proxy_check_echo_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AmbassadorLeaderboardEntry":{"properties":{"rank":{"type":"integer","title":"Rank"},"ambassador_id":{"type":"integer","title":"Ambassador Id"},"name":{"type":"string","title":"Name"},"tier":{"type":"string","title":"Tier"},"total_referrals":{"type":"integer","title":"Total Referrals"},"personal_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Personal Slug"}},"type":"object","required":["rank","ambassador_id","name","tier","total_referrals"],"title":"AmbassadorLeaderboardEntry","description":"Single entry on the ambassador leaderboard."},"AmbassadorTierInfo":{"properties":{"tier":{"type":"string","title":"Tier"},"display_name":{"type":"string","title":"Display Name"},"referrals_required":{"type":"integer","title":"Referrals Required"},"monthly_credits":{"type":"integer","title":"Monthly Credits"},"gxgy_give":{"type":"integer","title":"Gxgy Give"},"gxgy_get":{"type":"integer","title":"Gxgy Get"},"revenue_share_percentage":{"type":"string","title":"Revenue Share Percentage"},"additional_requirements":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Additional Requirements"},"color":{"type":"string","title":"Color","default":"#f59e0b"}},"type":"object","required":["tier","display_name","referrals_required","monthly_credits","gxgy_give","gxgy_get","revenue_share_percentage"],"title":"AmbassadorTierInfo","description":"Tier definition with requirements and perks."},"ArticleListResponse":{"properties":{"articles":{"items":{"$ref":"#/components/schemas/ArticleSummary"},"type":"array","title":"Articles"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["articles","total","page","per_page","has_more"],"title":"ArticleListResponse","description":"Paginated article list response."},"ArticleResponse":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"content":{"type":"string","title":"Content"},"excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Excerpt"},"featured_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Featured Image Url"},"hero_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hero Image Url"},"category":{"type":"string","title":"Category"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"author":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__newsroom__AuthorInfo"},{"type":"null"}]},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"is_published":{"type":"boolean","title":"Is Published","default":false},"reading_time_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reading Time Minutes"},"meta_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Title"},"meta_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Description"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","slug","title","content","category","created_at"],"title":"ArticleResponse","description":"Full article response for detail pages."},"ArticleSummary":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Excerpt"},"featured_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Featured Image Url"},"category":{"type":"string","title":"Category"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"reading_time_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reading Time Minutes"},"is_featured":{"type":"boolean","title":"Is Featured","default":false}},"type":"object","required":["id","slug","title","category"],"title":"ArticleSummary","description":"Brief article summary for listings."},"BillableEventListResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/BillableEventResponse"},"type":"array","title":"Events"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["events","total"],"title":"BillableEventListResponse","description":"List of all billable events."},"BlogPostListResponse":{"properties":{"posts":{"items":{"$ref":"#/components/schemas/BlogPostSummary"},"type":"array","title":"Posts"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["posts","total","page","per_page","has_more"],"title":"BlogPostListResponse","description":"Paginated blog post list response."},"BlogPostResponse":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"content":{"type":"string","title":"Content"},"excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Excerpt"},"city_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"City Id"},"city_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City Name"},"city_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City Slug"},"topic_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic Slug"},"topic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic Name"},"topic_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic Category"},"featured_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Featured Image Url"},"hero_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hero Image Url"},"video_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Url"},"video_file_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video File Url"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"author":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__blog__AuthorInfo"},{"type":"null"}]},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"is_published":{"type":"boolean","title":"Is Published","default":false},"reading_time_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reading Time Minutes"},"review_status":{"type":"string","title":"Review Status","default":"pending"},"review_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Notes"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"reviewed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewed By"},"preview_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview Token"},"meta_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Title"},"meta_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Description"},"canonical_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Url"},"schema_type":{"type":"string","title":"Schema Type","default":"Article"},"widget":{"anyOf":[{"$ref":"#/components/schemas/WidgetConfig"},{"type":"null"}]},"related_posts":{"items":{"$ref":"#/components/schemas/BlogPostSummary"},"type":"array","title":"Related Posts"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","slug","title","content","created_at"],"title":"BlogPostResponse","description":"Full blog post response for detail pages."},"BlogPostSummary":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Excerpt"},"featured_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Featured Image Url"},"city_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"City Id"},"city_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City Name"},"city_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City Slug"},"topic_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic Slug"},"topic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic Name"},"topic_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Topic Category"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"reading_time_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reading Time Minutes"},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"is_published":{"type":"boolean","title":"Is Published","default":false},"review_status":{"type":"string","title":"Review Status","default":"pending"},"review_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Notes"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"reviewed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewed By"}},"type":"object","required":["id","slug","title"],"title":"BlogPostSummary","description":"Brief blog post summary for listings."},"BlogTopicListResponse":{"properties":{"topics":{"items":{"$ref":"#/components/schemas/BlogTopicResponse"},"type":"array","title":"Topics"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["topics","total"],"title":"BlogTopicListResponse","description":"List of blog topics."},"Body_login_api_v1_auth_login_post":{"properties":{"grant_type":{"anyOf":[{"type":"string","pattern":"password"},{"type":"null"}],"title":"Grant Type"},"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"},"scope":{"type":"string","title":"Scope","default":""},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"}},"type":"object","required":["username","password"],"title":"Body_login_api_v1_auth_login_post"},"Body_submit_application_api_v1_careers_jobs__job_id__apply_post":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"type":"string","title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"portfolio_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portfolio Url"},"cover_letter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Letter"},"resume":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Resume"}},"type":"object","required":["first_name","last_name","email"],"title":"Body_submit_application_api_v1_careers_jobs__job_id__apply_post"},"CategoryListResponse":{"properties":{"categories":{"items":{"$ref":"#/components/schemas/CategoryResponse"},"type":"array","title":"Categories"}},"type":"object","required":["categories"],"title":"CategoryListResponse","description":"List of categories."},"City":{"properties":{"name":{"type":"string","title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"state_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State Code"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"boundary_kml":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Boundary Kml"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active","default":true},"default_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Default Lat"},"default_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Default Lng"},"default_zoom":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Default Zoom"},"bbox_north":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bbox North"},"bbox_south":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bbox South"},"bbox_east":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bbox East"},"bbox_west":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bbox West"},"osm_data_fetched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Osm Data Fetched At"},"osm_data_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Osm Data Version"},"poi_count_cached":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Poi Count Cached"},"tile_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tile Status"},"raster_tile_file_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raster Tile File Path"},"raster_tiles_downloaded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Raster Tiles Downloaded At"},"raster_tile_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raster Tile Status"},"raster_tile_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raster Tile Error"},"coming_soon":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Coming Soon","default":false},"estimated_launch_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Launch Date"},"waitlist_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Waitlist Count","default":0},"tagline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tagline"},"id":{"type":"integer","title":"Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["name","id","created_at","updated_at"],"title":"City"},"CityBlogStats":{"properties":{"city_id":{"type":"integer","title":"City Id"},"city_name":{"type":"string","title":"City Name"},"city_slug":{"type":"string","title":"City Slug"},"post_count":{"type":"integer","title":"Post Count"},"featured_count":{"type":"integer","title":"Featured Count"},"topics":{"items":{"$ref":"#/components/schemas/BlogTopicResponse"},"type":"array","title":"Topics"}},"type":"object","required":["city_id","city_name","city_slug","post_count","featured_count"],"title":"CityBlogStats","description":"Blog statistics for a city."},"CityRequestCreate":{"properties":{"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"}},"type":"object","required":["city","state"],"title":"CityRequestCreate"},"CityRequestLeadCreate":{"properties":{"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"email":{"type":"string","title":"Email"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["city","state","email"],"title":"CityRequestLeadCreate"},"ClientInvitationLanding":{"properties":{"email":{"type":"string","title":"Email"},"first_name":{"type":"string","title":"First Name"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"status":{"type":"string","title":"Status"}},"type":"object","required":["email","first_name","expires_at","status"],"title":"ClientInvitationLanding"},"ClientInviteAcceptRequest":{"properties":{"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"}},"type":"object","required":["password"],"title":"ClientInviteAcceptRequest"},"ComingSoonCity":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"tagline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tagline"},"coming_soon":{"type":"boolean","title":"Coming Soon","default":true},"estimated_launch_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Launch Date"},"waitlist_count":{"type":"integer","title":"Waitlist Count","default":0},"default_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Default Lat"},"default_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Default Lng"}},"type":"object","required":["id","name"],"title":"ComingSoonCity","description":"Summary of a coming-soon city for the listing page."},"CreditPackageListResponse":{"properties":{"packages":{"items":{"$ref":"#/components/schemas/CreditPackageResponse"},"type":"array","title":"Packages"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["packages","total"],"title":"CreditPackageListResponse","description":"List of available funding packages."},"ErrorReportCreate":{"properties":{"error_type":{"type":"string","title":"Error Type"},"tool_name":{"type":"string","title":"Tool Name"},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Code"},"what_happened":{"type":"string","title":"What Happened"},"what_expected":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"What Expected"},"client":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client"},"server_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Server Version"}},"type":"object","required":["error_type","tool_name","what_happened"],"title":"ErrorReportCreate"},"ExchangeRateResponse":{"properties":{"crypto":{"type":"string","title":"Crypto"},"fiat":{"type":"string","title":"Fiat"},"rate":{"type":"number","title":"Rate"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"}},"type":"object","required":["crypto","fiat","rate","timestamp"],"title":"ExchangeRateResponse","description":"Exchange rate response."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HuntInvitationResponse":{"properties":{"id":{"type":"integer","title":"Id"},"hunt_id":{"type":"integer","title":"Hunt Id"},"hunt_name":{"type":"string","title":"Hunt Name"},"invitee_email":{"type":"string","title":"Invitee Email"},"invited_by_user_id":{"type":"integer","title":"Invited By User Id"},"invited_by_name":{"type":"string","title":"Invited By Name"},"permission":{"type":"string","title":"Permission"},"status":{"type":"string","title":"Status"},"token":{"type":"string","title":"Token"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","hunt_id","hunt_name","invitee_email","invited_by_user_id","invited_by_name","permission","status","token","expires_at","created_at"],"title":"HuntInvitationResponse"},"HuntLinkCreateRequest":{"properties":{"hunt_params":{"type":"object","title":"Hunt Params"},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel"}},"type":"object","required":["hunt_params"],"title":"HuntLinkCreateRequest"},"HuntShareResponse":{"properties":{"id":{"type":"integer","title":"Id"},"hunt_id":{"type":"integer","title":"Hunt Id"},"shared_with_user_id":{"type":"integer","title":"Shared With User Id"},"shared_with_name":{"type":"string","title":"Shared With Name"},"shared_with_email":{"type":"string","title":"Shared With Email"},"permission":{"type":"string","title":"Permission"},"shared_by_user_id":{"type":"integer","title":"Shared By User Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","hunt_id","shared_with_user_id","shared_with_name","shared_with_email","permission","shared_by_user_id","created_at"],"title":"HuntShareResponse"},"InquiryCreate":{"properties":{"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"topic":{"type":"string","maxLength":32,"title":"Topic","default":"general"},"message":{"type":"string","maxLength":4000,"minLength":5,"title":"Message"},"website":{"type":"string","maxLength":200,"title":"Website","default":""}},"type":"object","required":["name","email","message"],"title":"InquiryCreate"},"InvoiceStatusResponse":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"amount":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amount"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"exception_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exception Status"},"tx_hashes":{"items":{"type":"string"},"type":"array","title":"Tx Hashes","default":[]},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"paid_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paid At"}},"type":"object","required":["id","status"],"title":"InvoiceStatusResponse","description":"Invoice status response."},"JobApplicationResponse":{"properties":{"id":{"type":"integer","title":"Id"},"job_posting_id":{"type":"integer","title":"Job Posting Id"},"job_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Title"},"job_department":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Department"},"job_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Slug"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"type":"string","title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"portfolio_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portfolio Url"},"cover_letter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Letter"},"resume_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resume Url"},"status":{"type":"string","title":"Status","default":"new"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"applied_at":{"type":"string","format":"date-time","title":"Applied At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","job_posting_id","first_name","last_name","email","applied_at"],"title":"JobApplicationResponse","description":"Full job application response."},"JobPostingListResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/JobPostingSummary"},"type":"array","title":"Jobs"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["jobs","total","page","per_page","has_more"],"title":"JobPostingListResponse","description":"Paginated job posting list response."},"JobPostingResponse":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"department":{"type":"string","title":"Department"},"location":{"type":"string","title":"Location"},"employment_type":{"type":"string","title":"Employment Type"},"experience_level":{"type":"string","title":"Experience Level"},"description":{"type":"string","title":"Description"},"requirements":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requirements"},"benefits":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Benefits"},"salary_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Min"},"salary_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Max"},"salary_currency":{"type":"string","title":"Salary Currency","default":"USD"},"show_salary":{"type":"boolean","title":"Show Salary","default":false},"is_published":{"type":"boolean","title":"Is Published","default":false},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"meta_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Title"},"meta_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Description"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"application_count":{"type":"integer","title":"Application Count","default":0}},"type":"object","required":["id","slug","title","department","location","employment_type","experience_level","description","created_at"],"title":"JobPostingResponse","description":"Full job posting response for detail pages."},"MediaPackAssetListResponse":{"properties":{"assets":{"items":{"$ref":"#/components/schemas/MediaPackAssetResponse"},"type":"array","title":"Assets"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["assets","total"],"title":"MediaPackAssetListResponse","description":"List of media pack assets."},"NeighborhoodSummary":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"city_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City Name"},"tagline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tagline"},"median_rent_1br":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Rent 1Br"},"median_rent_2br":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Rent 2Br"},"walk_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Walk Score"},"transit_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transit Score"},"bike_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bike Score"},"hero_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hero Image Url"},"map_screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Map Screenshot Url"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"}},"type":"object","required":["id","name","slug"],"title":"NeighborhoodSummary","description":"Lightweight neighborhood info for the coming-soon page grid."},"NeighborhoodWithBoundary":{"properties":{"name":{"type":"string","title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"city_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City Name"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"county":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tagline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tagline"},"median_rent_1br":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Rent 1Br"},"median_rent_2br":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Rent 2Br"},"rent_data_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rent Data Source"},"walk_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Walk Score"},"transit_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Transit Score"},"bike_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bike Score"},"scores_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scores Source"},"hero_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hero Image Url"},"map_screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Map Screenshot Url"},"seo_content":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Seo Content"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active","default":true},"sort_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sort Order","default":0},"id":{"type":"integer","title":"Id"},"city_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"City Id"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"source_region_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Source Region Id"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"rent_data_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Rent Data Updated At"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"boundary":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Boundary"}},"type":"object","required":["name","id"],"title":"NeighborhoodWithBoundary","description":"Neighborhood response including GeoJSON boundary."},"PasswordResetConfirm":{"properties":{"token":{"type":"string","title":"Token"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["token","new_password"],"title":"PasswordResetConfirm"},"PasswordResetRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest","description":"Body for POST /auth/password-reset/request."},"PendingHuntCreate":{"properties":{"first_name":{"type":"string","maxLength":100,"minLength":1,"title":"First Name"},"last_name":{"type":"string","maxLength":100,"minLength":1,"title":"Last Name"},"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":100,"minLength":8,"title":"Password","description":"Password for account creation"},"hunt_data":{"$ref":"#/components/schemas/HuntCreate"}},"type":"object","required":["first_name","last_name","email","password","hunt_data"],"title":"PendingHuntCreate","description":"Schema for creating a pending hunt (guest user submission)"},"PendingHuntResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email_verified":{"type":"boolean","title":"Email Verified"},"requires_payment":{"type":"boolean","title":"Requires Payment"},"payment_status":{"type":"string","title":"Payment Status"},"status":{"type":"string","title":"Status"},"verification_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Token"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","email","first_name","last_name","email_verified","requires_payment","payment_status","status","created_at"],"title":"PendingHuntResponse","description":"Schema for pending hunt creation response"},"PricingPlanListResponse":{"properties":{"plans":{"items":{"$ref":"#/components/schemas/PricingPlanResponse"},"type":"array","title":"Plans"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["plans","total"],"title":"PricingPlanListResponse","description":"List of pricing plans."},"PricingPlanResponse":{"properties":{"name":{"type":"string","title":"Name"},"price":{"type":"string","title":"Price"},"billing_type":{"type":"string","title":"Billing Type"},"max_pois":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Pois"},"max_tours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tours"},"max_hunts":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Hunts"},"features":{"type":"object","title":"Features"},"id":{"type":"string","title":"Id"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["name","price","billing_type","id","is_active"],"title":"PricingPlanResponse","description":"Pricing plan response schema."},"ProviderLeadCreate":{"properties":{"company_name":{"type":"string","maxLength":255,"minLength":1,"title":"Company Name"},"lead_email":{"type":"string","format":"email","title":"Lead Email"},"website":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Website"},"rss_feed_url":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Rss Feed Url"},"building_names":{"anyOf":[{"items":{"type":"string","maxLength":255},"type":"array"},{"type":"null"}],"title":"Building Names"},"service_type":{"type":"string","maxLength":50,"title":"Service Type","default":"moving"},"city_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"City Id"},"city_name":{"type":"string","maxLength":100,"minLength":1,"title":"City Name"},"state_code":{"type":"string","maxLength":50,"minLength":1,"title":"State Code"},"company_verification":{"type":"string","maxLength":200,"title":"Company Verification","default":""}},"type":"object","required":["company_name","lead_email","city_name","state_code"],"title":"ProviderLeadCreate"},"RefreshTokenRequest":{"properties":{"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"type":"object","title":"RefreshTokenRequest","description":"Body for POST /auth/refresh.\n\n`refresh_token` is optional - if omitted, the endpoint reads the\n`refresh_token` cookie (browser flow). API clients pass it in the body."},"ResendVerificationRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ResendVerificationRequest","description":"Schema for resend verification request"},"ResendVerificationResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"attempts_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Attempts Remaining"}},"type":"object","required":["success","message"],"title":"ResendVerificationResponse","description":"Schema for resend verification response"},"UserCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address_street":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Street"},"address_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address City"},"address_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address State"},"address_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Zip"},"password":{"type":"string","title":"Password"},"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"},"become_ambassador":{"type":"boolean","title":"Become Ambassador","default":false},"account_type":{"type":"string","enum":["individual","realtor"],"title":"Account Type","default":"individual"},"brokerage_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Brokerage Name"},"website":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Website"}},"type":"object","required":["email","first_name","last_name","password"],"title":"UserCreate"},"UserResponse":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address_street":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Street"},"address_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address City"},"address_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address State"},"address_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address Zip"},"id":{"type":"integer","title":"Id"},"role":{"type":"string","title":"Role"},"is_active":{"type":"boolean","title":"Is Active"},"email_verified":{"type":"boolean","title":"Email Verified"},"account_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Type","default":"individual"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"last_login":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login"},"calendar_configured":{"type":"boolean","title":"Calendar Configured","default":false},"default_availability_start":{"type":"string","title":"Default Availability Start","default":"09:00"},"default_availability_end":{"type":"string","title":"Default Availability End","default":"20:00"},"default_availability_days":{"type":"string","title":"Default Availability Days","default":"1,2,3,4,5,6,7"}},"type":"object","required":["email","first_name","last_name","id","role","is_active","email_verified","created_at","updated_at"],"title":"UserResponse"},"VerificationResponse":{"properties":{"status":{"type":"string","title":"Status"},"next_step":{"type":"string","title":"Next Step"},"hunt_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hunt Id"},"pending_hunt_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pending Hunt Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["status","next_step","message"],"title":"VerificationResponse","description":"Schema for email verification response"},"WaitlistEntry":{"properties":{"id":{"type":"integer","title":"Id"},"city_id":{"type":"integer","title":"City Id"},"neighborhood_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Neighborhood Id"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"budget_range":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Budget Range"},"referral_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Source"},"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"},"position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position"},"notified":{"type":"boolean","title":"Notified","default":false},"converted_to_user":{"type":"boolean","title":"Converted To User","default":false},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","city_id","email"],"title":"WaitlistEntry"},"WaitlistJoin":{"properties":{"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"budget_range":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Budget Range"},"neighborhood_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Neighborhood Id"},"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"}},"type":"object","required":["email"],"title":"WaitlistJoin","description":"Request body for joining a city waitlist."},"WaitlistPageData":{"properties":{"city_name":{"type":"string","title":"City Name"},"city_slug":{"type":"string","title":"City Slug"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"tagline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tagline"},"neighborhood_insight":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Neighborhood Insight"},"coming_soon":{"type":"boolean","title":"Coming Soon","default":true},"estimated_launch_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Launch Date"},"waitlist_count":{"type":"integer","title":"Waitlist Count","default":0},"neighborhoods":{"items":{},"type":"array","title":"Neighborhoods","default":[]},"blog_posts":{"items":{"$ref":"#/components/schemas/WaitlistBlogPost"},"type":"array","title":"Blog Posts","default":[]}},"type":"object","required":["city_name","city_slug"],"title":"WaitlistPageData","description":"Aggregated data for a city's coming-soon page."},"WaitlistPosition":{"properties":{"position":{"type":"integer","title":"Position"},"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"},"referral_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Url"},"total_waitlist":{"type":"integer","title":"Total Waitlist","default":0}},"type":"object","required":["position"],"title":"WaitlistPosition","description":"Response for waitlist position lookup."},"WebhookResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"invoice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Id"},"new_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Status"}},"type":"object","required":["success","message"],"title":"WebhookResponse","description":"Webhook processing response."},"app__schemas__hunt_poi__POICategoryResponse":{"properties":{"value":{"type":"string","title":"Value"},"label":{"type":"string","title":"Label"},"subcategories":{"items":{"type":"string"},"type":"array","title":"Subcategories"}},"type":"object","required":["value","label","subcategories"],"title":"POICategoryResponse"},"app__schemas__hunt_poi__POIResponse":{"properties":{"name":{"type":"string","title":"Name"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"osm_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Osm Id"},"osm_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Osm Type"},"category":{"type":"string","title":"Category"}},"type":"object","required":["name","address","latitude","longitude","osm_id","osm_type","category"],"title":"POIResponse"},"app__schemas__poi__POICategoryResponse":{"properties":{"name":{"type":"string","title":"Name"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"id":{"type":"integer","title":"Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["name","id","created_at"],"title":"POICategoryResponse"},"app__schemas__poi__POIResponse":{"properties":{"name":{"type":"string","title":"Name"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"category":{"type":"string","title":"Category"},"osm_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Osm Id"},"osm_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Osm Type"},"data_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data Source"},"osm_timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Osm Timestamp"},"id":{"type":"integer","title":"Id"},"city_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"City Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"distance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance"},"max_distance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Distance"}},"type":"object","required":["name","latitude","longitude","category","id","created_at","updated_at"],"title":"POIResponse"}}}}