{"openapi":"3.1.0","info":{"title":"Zillow Property Data API","version":"0.1.0"},"paths":{"/billing/signup":{"post":{"tags":["billing"],"summary":"Signup","description":"Create a free-tier API key. No payment needed.","operationId":"signup_billing_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Signup Billing Signup Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/checkout":{"post":{"tags":["billing"],"summary":"Create Checkout","description":"Create a Stripe Checkout session for a paid plan.","operationId":"create_checkout_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Checkout Billing Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/success":{"get":{"tags":["billing"],"summary":"Checkout Success","description":"Handle successful checkout — called by the success page to confirm and get key.","operationId":"checkout_success_billing_success_get","parameters":[{"name":"session_id","in":"query","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Checkout Success Billing Success Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/webhook":{"post":{"tags":["billing"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events (subscription changes, cancellations).","operationId":"stripe_webhook_billing_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/billing/usage":{"get":{"tags":["billing"],"summary":"Get Usage","description":"Check current usage and quota for an API key.","operationId":"get_usage_billing_usage_get","parameters":[{"name":"api_key","in":"query","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Usage Billing Usage Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/track":{"post":{"tags":["admin"],"summary":"Track Pageview","description":"Record a page view. Called from the landing page JS.","operationId":"track_pageview_admin_track_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Track Pageview Admin Track Post"}}}}}}},"/admin/login":{"get":{"tags":["admin"],"summary":"Login Page","description":"Render the admin login page.","operationId":"login_page_admin_login_get","parameters":[{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin"],"summary":"Login Submit","description":"Validate username/password and set session cookie.","operationId":"login_submit_admin_login_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/logout":{"get":{"tags":["admin"],"summary":"Logout","description":"Clear the session cookie and redirect to login.","operationId":"logout_admin_logout_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/dashboard":{"get":{"tags":["admin"],"summary":"Dashboard","operationId":"dashboard_admin_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/users":{"get":{"tags":["admin"],"summary":"Users List","operationId":"users_list_admin_users_get","parameters":[{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"usage","title":"Sort"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","default":"desc","title":"Order"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{api_key}/revoke":{"post":{"tags":["admin"],"summary":"Revoke User","operationId":"revoke_user_admin_users__api_key__revoke_post","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{api_key}/reactivate":{"post":{"tags":["admin"],"summary":"Reactivate User","operationId":"reactivate_user_admin_users__api_key__reactivate_post","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{api_key}/delete":{"post":{"tags":["admin"],"summary":"Delete User","operationId":"delete_user_admin_users__api_key__delete_post","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{api_key}":{"get":{"tags":["admin"],"summary":"User Detail","operationId":"user_detail_admin_users__api_key__get","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/logs":{"get":{"tags":["admin"],"summary":"Api Logs","operationId":"api_logs_admin_logs_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/emails":{"get":{"tags":["admin"],"summary":"Email Logs","operationId":"email_logs_admin_emails_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/health":{"get":{"tags":["admin"],"summary":"Admin Health","operationId":"admin_health_admin_health_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/seo":{"get":{"tags":["admin"],"summary":"Seo Dashboard","operationId":"seo_dashboard_admin_seo_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/seo/live":{"get":{"tags":["admin"],"summary":"Seo Live","description":"JSON counters for the 30s poll.","operationId":"seo_live_admin_seo_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/revenue":{"get":{"tags":["admin"],"summary":"Revenue","operationId":"revenue_admin_revenue_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/broadcast":{"get":{"tags":["admin"],"summary":"Broadcast Compose","operationId":"broadcast_compose_admin_broadcast_get","parameters":[{"name":"plan","in":"query","required":false,"schema":{"type":"string","default":"all","title":"Plan"}},{"name":"template","in":"query","required":false,"schema":{"type":"string","default":"","title":"Template"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/broadcast/test":{"post":{"tags":["admin"],"summary":"Broadcast Test","operationId":"broadcast_test_admin_broadcast_test_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/broadcast/send":{"post":{"tags":["admin"],"summary":"Broadcast Send","operationId":"broadcast_send_admin_broadcast_send_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/broadcast/preview":{"post":{"tags":["admin"],"summary":"Broadcast Preview","operationId":"broadcast_preview_admin_broadcast_preview_post","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/broadcast/templates/save":{"post":{"tags":["admin"],"summary":"Broadcast Template Save","operationId":"broadcast_template_save_admin_broadcast_templates_save_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/broadcast/status/{campaign_id}":{"get":{"tags":["admin"],"summary":"Broadcast Status","operationId":"broadcast_status_admin_broadcast_status__campaign_id__get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/broadcast/history":{"get":{"tags":["admin"],"summary":"Broadcast History","operationId":"broadcast_history_admin_broadcast_history_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/login":{"get":{"tags":["account"],"summary":"Login Page","description":"Render the login/signup page.","operationId":"login_page_account_login_get","parameters":[{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}},{"name":"tab","in":"query","required":false,"schema":{"type":"string","default":"signin","title":"Tab"}},{"name":"email","in":"query","required":false,"schema":{"type":"string","default":"","title":"Email"}},{"name":"notice","in":"query","required":false,"schema":{"type":"string","default":"","title":"Notice"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["account"],"summary":"Login Submit","description":"Handle email/password login.","operationId":"login_submit_account_login_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/signup":{"post":{"tags":["account"],"summary":"Signup Submit","description":"Handle email/password signup.","operationId":"signup_submit_account_signup_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/verify":{"get":{"tags":["account"],"summary":"Verify Email","description":"Confirm an email-verification link: activate the account and log the user in.","operationId":"verify_email_account_verify_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account/forgot":{"get":{"tags":["account"],"summary":"Forgot Page","description":"Render the reset-request form, or the neutral 'check your email' confirmation.","operationId":"forgot_page_account_forgot_get","parameters":[{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}},{"name":"sent","in":"query","required":false,"schema":{"type":"string","default":"","title":"Sent"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["account"],"summary":"Forgot Submit","description":"Email a reset link.\n\nResponds identically whether or not the account exists — the only signal is\nwhether an email actually goes out. The send is deferred to a background task\nso the request path has the same shape either way.","operationId":"forgot_submit_account_forgot_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/reset":{"get":{"tags":["account"],"summary":"Reset Page","description":"Render the new-password form, if the token is currently valid.","operationId":"reset_page_account_reset_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}},{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["account"],"summary":"Reset Submit","description":"Set the new password.\n\nSECURITY: this re-validates the token. The check in reset_page() is UX only —\nwithout this one, POST /account/reset would be an unauthenticated\n\"set any password for any email\" endpoint.","operationId":"reset_submit_account_reset_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/auth/google":{"get":{"tags":["account"],"summary":"Google Login","description":"Initiate Google OAuth flow.","operationId":"google_login_account_auth_google_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/auth/google/callback":{"get":{"tags":["account"],"summary":"Google Callback","description":"Handle Google OAuth callback.","operationId":"google_callback_account_auth_google_callback_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/logout":{"get":{"tags":["account"],"summary":"Logout","operationId":"logout_account_logout_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/":{"get":{"tags":["account"],"summary":"Dashboard","operationId":"dashboard_account__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account":{"get":{"tags":["account"],"summary":"Dashboard","operationId":"dashboard_account_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/calls":{"get":{"tags":["account"],"summary":"Calls Page","operationId":"calls_page_account_calls_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account/settings":{"get":{"tags":["account"],"summary":"Settings Page","operationId":"settings_page_account_settings_get","parameters":[{"name":"msg","in":"query","required":false,"schema":{"type":"string","default":"","title":"Msg"}},{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account/settings/password":{"post":{"tags":["account"],"summary":"Change Password","operationId":"change_password_account_settings_password_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/settings/regenerate-key":{"post":{"tags":["account"],"summary":"Regenerate Key","operationId":"regenerate_key_account_settings_regenerate_key_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/settings/manage-billing":{"post":{"tags":["account"],"summary":"Manage Billing","description":"Create a Stripe Customer Portal session for plan changes and billing management.\n\nIf the request body specifies a target_plan, drop the user directly into\nthe portal's plan-switcher pre-loaded for their active subscription. The\nin-app Upgrade button uses this so paying customers don't have to navigate\nthe portal homepage to find the plan-change UI. Without target_plan, opens\nthe standard portal homepage (used by Downgrade and the generic billing\nmanagement link).","operationId":"manage_billing_account_settings_manage_billing_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/settings/change-plan":{"post":{"tags":["account"],"summary":"Change Plan","description":"Switch between paid plans (Pro/Ultra/Mega) directly via Stripe API.\n\nThe Stripe Customer Portal can't host this flow because all our paid plans\nare monthly prices on a single product, and the portal's plan-switcher\nrequires distinct products per plan tier. Calling Subscription.modify\ndirectly with create_prorations gives the customer a one-click upgrade\nwithout leaving our settings page.\n\nFree→paid still goes through /billing/checkout (no existing sub to modify).\nPaid→Free still goes through the Stripe portal (cancellation flow).","operationId":"change_plan_account_settings_change_plan_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/settings/change-plan/preview":{"post":{"tags":["account"],"summary":"Change Plan Preview","description":"Compute proration cost + period dates for a plan change WITHOUT applying it.\n\nDrives the confirmation modal so the customer sees the actual prorated\ncharge and billing-cycle dates before clicking Confirm. Read-only — calls\nStripe's Invoice.create_preview API which doesn't modify any state.","operationId":"change_plan_preview_account_settings_change_plan_preview_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/settings/delete":{"post":{"tags":["account"],"summary":"Delete Account","operationId":"delete_account_account_settings_delete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/ses-events":{"post":{"tags":["ses"],"summary":"Ses Events","description":"Receive SES bounce/complaint/delivery events forwarded by SNS.","operationId":"ses_events_webhooks_ses_events_post","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Ses Events Webhooks Ses Events Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/properties":{"post":{"summary":"Get Property Data","description":"Get Zillow property data.\n\nAccepts multiple input types:\n- **urls**: Zillow listing URLs or search URLs (e.g. zillow.com/los-angeles-ca/)\n- **search**: Free-text search query (e.g. \"Los Angeles\", \"90210\")\n- **zpids**: Zillow Property IDs\n- **zipcodes**: US ZIP codes\n\nOptions:\n- **type**: Filter by listing type: \"all\", \"sale\", \"fsbo\", \"rent\", \"sold\"\n- **max_items**: Maximum results to return (default 200, max 1000)\n\nAll requests are async — returns a job_id instantly. Poll GET /v1/results/{job_id} for results.","operationId":"get_property_data_v1_properties_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/results/{job_id}":{"get":{"summary":"Get Results","description":"Get results for an async batch job.\n\nAuth-only — polling does not consume monthly quota. The reservation was\nmade at submit time on POST /v1/properties; releasing the result of an\nalready-submitted job is a free status read.\n\nSet `format=csv` to download successful properties as a CSV file. While the\njob is still processing or has failed, the JSON status is returned regardless\nof `format` so existing poll loops keep working; CSV is only emitted once the\njob is complete.","operationId":"get_results_v1_results__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"Response format: 'json' (default) or 'csv'. CSV returns successful properties as a flat spreadsheet once the job is complete.","default":"json","title":"Format"},"description":"Response format: 'json' (default) or 'csv'. CSV returns successful properties as a flat spreadsheet once the job is complete."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage":{"get":{"summary":"Get Usage","description":"Return the caller's current monthly usage, plan, and quota.\n\nAll figures are in properties returned, not API calls: a search that\nreturns 10 properties consumes 10 units of quota.\n\n`used_this_month` is reservation-inclusive: when a POST /v1/properties\nsubmits with max_items=N, all N slots are counted immediately and the\nunused portion is refunded when the job completes. This means the number\ncan settle downward over the course of a billing period.\n\nAuthentication is required but quota is not enforced, so callers can\nalways retrieve their own usage even after exceeding their limit.","operationId":"get_usage_v1_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}}}}}},"components":{"schemas":{"CheckoutRequest":{"properties":{"email":{"type":"string","title":"Email"},"plan":{"type":"string","title":"Plan"}},"type":"object","required":["email","plan"],"title":"CheckoutRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PropertyRequest":{"properties":{"urls":{"items":{"type":"string"},"type":"array","maxItems":1000,"title":"Urls","description":"Zillow URLs -- listing URLs or search URLs (e.g. zillow.com/los-angeles-ca/)"},"search":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search","description":"Free-text search query (e.g. 'Los Angeles', 'Miami Beach FL')"},"addresses":{"items":{"type":"string"},"type":"array","title":"Addresses","description":"Street addresses to look up. Each must include a city and state, or a ZIP code -- a bare street line such as '766 Throne Dr' matches many streets nationwide and will not resolve to a property. Example: '1874 Bromton Dr, Lyndhurst, OH 44124'"},"zpids":{"items":{"type":"integer"},"type":"array","title":"Zpids","description":"Zillow Property IDs to look up directly"},"zipcodes":{"items":{"anyOf":[{"type":"integer"},{"type":"string"}]},"type":"array","title":"Zipcodes","description":"US ZIP codes to search"},"type":{"type":"string","title":"Type","description":"Listing type filter: 'all', 'sale', 'fsbo', 'rent', 'sold'","default":"all"},"max_items":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Max Items","description":"Maximum number of results to return","default":200},"property_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Type","description":"Property type filter: 'house', 'condo', 'townhouse', 'land', 'apartment', 'manufactured', 'multi_family'"},"price_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Min","description":"Minimum price filter (USD)"},"price_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Max","description":"Maximum price filter (USD)"},"check_only":{"type":"boolean","title":"Check Only","description":"If true, only check if listings exist without fetching full data. Much faster for bulk address checks.","default":false},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"bulk_password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bulk Password"}},"type":"object","title":"PropertyRequest"},"PropertyResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"status":{"type":"string","title":"Status"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results"},"errors":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Errors"},"webhook":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Webhook","description":"Delivery status of the webhook_url notification, if one was submitted: {status: pending|delivered|failed, attempts, last_status, delivered_at}. null if no webhook_url was submitted."}},"type":"object","required":["job_id","status"],"title":"PropertyResponse"},"SignupRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"SignupRequest"},"UsageResponse":{"properties":{"plan":{"type":"string","title":"Plan","description":"Current plan: 'free', 'pro', 'ultra', 'mega'"},"monthly_limit":{"type":"integer","title":"Monthly Limit","description":"Included monthly quota for the plan, in properties returned. Usage is counted per property, not per API call."},"used_this_month":{"type":"integer","title":"Used This Month","description":"Properties returned this period. Reservation-inclusive: counts in-flight jobs at their submitted max_items and settles downward as jobs complete and unused portions are refunded."},"remaining":{"type":"integer","title":"Remaining","description":"monthly_limit minus used_this_month, floored at 0. For paid plans with overages, additional properties beyond this are billed at overage_rate_per_1k."},"overage_count":{"type":"integer","title":"Overage Count","description":"Properties returned beyond monthly_limit in the current period. 0 unless used_this_month > monthly_limit on a paid plan with overages."},"overage_rate_per_1k":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Overage Rate Per 1K","description":"USD price per 1,000 overage properties ($5.00 = $0.005 per property). Null for free / grandfathered hard-capped plans."},"billing_period_start":{"type":"string","title":"Billing Period Start","description":"ISO 8601 UTC start of the current quota period (subscription billing date for paid plans; 1st of the calendar month for free keys)."},"billing_period_end":{"type":"string","title":"Billing Period End","description":"ISO 8601 UTC end of the current quota period (1st of the next calendar month, exclusive)."}},"type":"object","required":["plan","monthly_limit","used_this_month","remaining","overage_count","overage_rate_per_1k","billing_period_start","billing_period_end"],"title":"UsageResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}