{"openapi":"3.1.0","info":{"title":"Homepage Keyword Search API","description":"Find websites where a keyword appears on the homepage, powered by Common Crawl + FTS5","version":"0.2.0"},"paths":{"/search":{"get":{"summary":"Search","description":"Search for websites whose homepage contains the given keyword or phrase.\n\nModes:\n  phrase - \"commercial roofing\" must appear as exact contiguous phrase\n  any    - both \"commercial\" AND \"roofing\" must appear, any position\n  single - each word searched independently (OR logic)","operationId":"search_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Keyword or phrase to search","title":"Q"},"description":"Keyword or phrase to search"},{"name":"mode","in":"query","required":false,"schema":{"type":"string","description":"Search mode: phrase (exact phrase), any (all words anywhere), single (each word independent)","default":"phrase","title":"Mode"},"description":"Search mode: phrase (exact phrase), any (all words anywhere), single (each word independent)"},{"name":"domains","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated domains to check","title":"Domains"},"description":"Comma-separated domains to check"},{"name":"crawl_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Override Common Crawl crawl ID","title":"Crawl Id"},"description":"Override Common Crawl crawl ID"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results per page","default":100,"title":"Limit"},"description":"Max results per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"},{"name":"title","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: title must contain this text","title":"Title"},"description":"Filter: title must contain this text"},{"name":"tech","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: tech_stack must contain this text","title":"Tech"},"description":"Filter: tech_stack must contain this text"},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: industry must match","title":"Industry"},"description":"Filter: industry must match"},{"name":"tld","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: TLD must match (e.g. com, io)","title":"Tld"},"description":"Filter: TLD must match (e.g. com, io)"},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: country code must match (e.g. US, GB)","title":"Country"},"description":"Filter: country code must match (e.g. US, GB)"},{"name":"has","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter: has email/phone/pricing/blog/ecommerce/contact","title":"Has"},"description":"Filter: has email/phone/pricing/blog/ecommerce/contact"},{"name":"exclude_seen","in":"query","required":false,"schema":{"type":"boolean","description":"Exclude domains already in the user's My Companies (from other searches)","default":false,"title":"Exclude Seen"},"description":"Exclude domains already in the user's My Companies (from other searches)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/search/count":{"get":{"summary":"Search Count","description":"Get total result count for a query (fast, no pagination).","operationId":"search_count_search_count_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/autocomplete":{"get":{"summary":"Autocomplete","description":"Return domain suggestions matching the query prefix.","operationId":"autocomplete_autocomplete_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":100,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":8,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/domain/{domain}":{"get":{"summary":"Get Domain Detail","description":"Return all 167 columns for a single domain — full company profile.\n\nCredit cost: 1 credit per lookup for paid API users (first 250 free for free accounts).","operationId":"get_domain_detail_domain__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lookup/{domain}":{"get":{"summary":"Lookup Domain","description":"Look up a domain — returns from index if available, otherwise fetches live and extracts.\n\nThis is the \"Domain Lookup\" feature: enter any domain and get a full 167-column profile.\nIf the domain isn't in our Common Crawl index, we scrape it live, extract all data,\nsave it to the index for future lookups, and return the profile.\nPass ?force=true to re-fetch even if the domain is already indexed (e.g. to fix a wrong page).","operationId":"lookup_domain_lookup__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force live re-fetch even if domain is already indexed","default":false,"title":"Force"},"description":"Force live re-fetch even if domain is already indexed"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/enrich/{domain}":{"get":{"summary":"Enrich Domain","description":"Real-time domain enrichment cascade.\n\nOrder of operations:\n  1. Cache — return in ~10ms if we have fresh (< 12 months) data for the domain.\n  2. Parallel race (up to `wait_ms`): live curl_cffi + Common Crawl WET/WARC.\n     First byte back wins. Loser is cancelled.\n  3. On race timeout / both fail: Playwright browser (JS-heavy / bot-walled).\n  4. On Playwright fail: Bright Data residential proxy ($0.003/req, silent-\n     skip if BRIGHTDATA_USER/PASS env vars unset).\n\nWinner is fast-extracted into all 178 columns and written through to the\nhomepage_content table so the next call is a cache hit.\n\nResponse includes `source`, `elapsed_ms`, `fetch_ms`, `cache_age_days`,\n`enriched_columns`, and `profile` (the 178-field dict).","operationId":"enrich_domain_enrich__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"wait_ms","in":"query","required":false,"schema":{"type":"integer","maximum":15000,"minimum":100,"description":"Max ms to wait for the live+CC-WET race. Sub-800 favors speed; higher favors coverage.","default":800,"title":"Wait Ms"},"description":"Max ms to wait for the live+CC-WET race. Sub-800 favors speed; higher favors coverage."},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cache and re-fetch even if we have fresh data.","default":false,"title":"Force"},"description":"Bypass cache and re-fetch even if we have fresh data."},{"name":"allow_playwright","in":"query","required":false,"schema":{"type":"boolean","description":"Enable Playwright browser fallback for JS-heavy / bot-walled sites.","default":true,"title":"Allow Playwright"},"description":"Enable Playwright browser fallback for JS-heavy / bot-walled sites."},{"name":"allow_brightdata","in":"query","required":false,"schema":{"type":"boolean","description":"Enable Bright Data residential proxy as last-resort fallback.","default":true,"title":"Allow Brightdata"},"description":"Enable Bright Data residential proxy as last-resort fallback."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk-lookup":{"post":{"summary":"Bulk Lookup","description":"Upload a CSV of domains (up to 100K), get all 57 columns back as CSV.\n\nChecks index first, live-fetches missing domains, extracts, saves, returns all.","operationId":"bulk_lookup_bulk_lookup_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_bulk_lookup_bulk_lookup_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/search/download":{"get":{"summary":"Download Search Results","description":"Download full search results as CSV.\n\nFree:       up to 100 rows\nPro:        up to 10,000 rows\nEnterprise: up to 1,000,000 rows\n\nStreams results so we never hold 1M rows in memory.","operationId":"download_search_results_search_download_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}},{"name":"mode","in":"query","required":false,"schema":{"type":"string","description":"Search mode: phrase, any, single","default":"phrase","title":"Mode"},"description":"Search mode: phrase, any, single"},{"name":"tier","in":"query","required":false,"schema":{"type":"string","description":"User tier: free, pro, enterprise","default":"free","title":"Tier"},"description":"User tier: free, pro, enterprise"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"Download format: csv","default":"csv","title":"Format"},"description":"Download format: csv"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk-search/count":{"get":{"summary":"Bulk Search Count","description":"Return per-keyword domain counts for a list of comma-separated keywords.\n\nRuns keyword counts with up to 20 concurrent FTS queries to avoid\noverwhelming SQLite. Returns individual counts plus a combined total\n(note: the combined total may double-count domains matching multiple keywords).","operationId":"bulk_search_count_bulk_search_count_get","parameters":[{"name":"keywords","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":10000,"description":"Comma-separated list of keywords (up to 200)","title":"Keywords"},"description":"Comma-separated list of keywords (up to 200)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk-search/download":{"get":{"summary":"Bulk Search Download","description":"Download deduplicated results across all keywords as a single CSV.\n\nIterates each keyword in order. Domains that match multiple keywords\nappear only once (first match wins). A 'matched_keyword' column shows\nwhich keyword triggered the match.","operationId":"bulk_search_download_bulk_search_download_get","parameters":[{"name":"keywords","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":5000,"description":"Comma-separated list of keywords","title":"Keywords"},"description":"Comma-separated list of keywords"},{"name":"tier","in":"query","required":false,"schema":{"type":"string","description":"User tier: free, pro, enterprise","default":"free","title":"Tier"},"description":"User tier: free, pro, enterprise"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/admin/cache-stats":{"get":{"summary":"Cache Stats","operationId":"cache_stats_admin_cache_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CacheStatsResponse"}}}}}}},"/admin/cache/clear":{"post":{"summary":"Clear Cache","operationId":"clear_cache_admin_cache_clear_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/fts-stats":{"get":{"summary":"Fts Stats","operationId":"fts_stats_admin_fts_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/domain-stats":{"get":{"summary":"Domain Stats","operationId":"domain_stats_admin_domain_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/domains/import-text":{"post":{"summary":"Import Domains Text","operationId":"import_domains_text_admin_domains_import_text_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/domains/import-csv":{"post":{"summary":"Import Domains Csv","operationId":"import_domains_csv_admin_domains_import_csv_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_domains_csv_admin_domains_import_csv_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/domains/list":{"get":{"summary":"List Domains","operationId":"list_domains_admin_domains_list_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"uncached_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Uncached Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/register":{"post":{"tags":["auth"],"summary":"Register","description":"Register with business email — sends magic link for verification.","operationId":"register_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/google":{"post":{"tags":["auth"],"summary":"Google Login","description":"Sign in with Google OAuth token.","operationId":"google_login_auth_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/verify":{"get":{"tags":["auth"],"summary":"Verify Magic Link","description":"Verify magic link token and complete registration.\n\nReturns an HTML page that stores the auth token and redirects to the app.","operationId":"verify_magic_link_auth_verify_get","parameters":[{"name":"token","in":"query","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"}}}}}}},"/auth/me":{"get":{"tags":["auth"],"summary":"Get Me","operationId":"get_me_auth_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/credits":{"get":{"tags":["auth"],"summary":"Get Credits","description":"Get current credit balance and recent transactions.","operationId":"get_credits_auth_credits_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/credits/add":{"post":{"tags":["auth"],"summary":"Add Credits Endpoint","description":"Add credits to account (for PAYG purchases / admin grants).","operationId":"add_credits_endpoint_auth_credits_add_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCreditsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/api-keys":{"post":{"tags":["auth"],"summary":"Create Api Key","description":"Create a new API key for the authenticated user.\n\nReturns the full key ONCE — store it securely, it cannot be retrieved again.","operationId":"create_api_key_auth_api_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["auth"],"summary":"List Api Keys","description":"List all API keys for the authenticated user (prefix only, not full key).","operationId":"list_api_keys_auth_api_keys_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/api-keys/{key_id}":{"delete":{"tags":["auth"],"summary":"Delete Api Key","description":"Delete an API key by ID.","operationId":"delete_api_key_auth_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/my-companies":{"get":{"tags":["auth"],"summary":"Get My Companies","description":"Return paginated My Companies list — all results the user has ever discovered.\n\nEach row includes the search_query column showing which keyword/domain found it.","operationId":"get_my_companies_auth_my_companies_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"query","in":"query","required":false,"schema":{"type":"string","default":"","title":"Query"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/search-sessions":{"post":{"tags":["auth"],"summary":"Upsert Search Session","description":"Save / update a search session so users can resume where they left off.","operationId":"upsert_search_session_auth_search_sessions_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["auth"],"summary":"Get Search Sessions","description":"Return the user's recent search sessions (newest first), for the resume banner.","operationId":"get_search_sessions_auth_search_sessions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/check-seen":{"post":{"tags":["auth"],"summary":"Check Seen","description":"Check which of the given domains are already in the user's My Companies.\n\nReturns a dict mapping domain → True for any domain that was found via a\n*different* search query (so the current search shows only net-new domains).\nPass current_query to exclude same-search auto-saves from the seen set.","operationId":"check_seen_auth_check_seen_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckSeenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/my-companies/{domain}":{"delete":{"tags":["auth"],"summary":"Delete My Company","description":"Remove a company (optionally only for a specific search) from My Companies.","operationId":"delete_my_company_auth_my_companies__domain__delete","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search Query"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/my-companies/export-check":{"get":{"tags":["auth"],"summary":"Export Check","description":"Pre-flight check before a CSV export — returns row count, credit cost, and current balance.\n\nCall this first; if the user confirms, call /export which deducts credits and streams the file.","operationId":"export_check_auth_my_companies_export_check_get","parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","default":"","title":"Query"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/my-companies/export":{"get":{"tags":["auth"],"summary":"Export My Companies","description":"Export My Companies as CSV — deducts 1 credit per row before streaming.\n\nReturns 402 if insufficient credits (with how many are needed).","operationId":"export_my_companies_auth_my_companies_export_get","parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","default":"","title":"Query"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lists":{"post":{"tags":["lists"],"summary":"Create List","operationId":"create_list_lists_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateListRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["lists"],"summary":"Get Lists","operationId":"get_lists_lists_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lists/{list_id}/items":{"post":{"tags":["lists"],"summary":"Add Items","operationId":"add_items_lists__list_id__items_post","parameters":[{"name":"list_id","in":"path","required":true,"schema":{"type":"integer","title":"List Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddItemsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/lists/{list_id}":{"get":{"tags":["lists"],"summary":"Get List Items","operationId":"get_list_items_lists__list_id__get","parameters":[{"name":"list_id","in":"path","required":true,"schema":{"type":"integer","title":"List Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["lists"],"summary":"Delete List","operationId":"delete_list_lists__list_id__delete","parameters":[{"name":"list_id","in":"path","required":true,"schema":{"type":"integer","title":"List Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitors":{"post":{"tags":["monitors"],"summary":"Create Monitor","operationId":"create_monitor_monitors_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMonitor"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["monitors"],"summary":"List Monitors","operationId":"list_monitors_monitors_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitors/{monitor_id}":{"delete":{"tags":["monitors"],"summary":"Delete Monitor","operationId":"delete_monitor_monitors__monitor_id__delete","parameters":[{"name":"monitor_id","in":"path","required":true,"schema":{"type":"integer","title":"Monitor Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/notifications":{"get":{"tags":["lists"],"summary":"Get Notifications","operationId":"get_notifications_notifications_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/notifications/{notification_id}/read":{"post":{"tags":["lists"],"summary":"Mark Read","operationId":"mark_read_notifications__notification_id__read_post","parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"integer","title":"Notification Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitors/notifications":{"get":{"tags":["monitors"],"summary":"Get Notifications","operationId":"get_notifications_monitors_notifications_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitors/notifications/{notification_id}/read":{"post":{"tags":["monitors"],"summary":"Mark Read","operationId":"mark_read_monitors_notifications__notification_id__read_post","parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"integer","title":"Notification Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/domain/{domain}/competitors":{"get":{"summary":"Get Competitors","description":"Return the top similar/competitor companies for a domain.\n\nWhen the FAISS embedding index is loaded, results come from ANN search over\n12.7 M domain embeddings (gte-Qwen2-7B-instruct). Without the index,\nresults fall back to IDF-weighted Jaccard keyword similarity.\n\nEach result includes a match_type (competitor / lookalike / similar) and\na similarity score (0–1).","operationId":"get_competitors_domain__domain__competitors_get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass Jaccard cache and recompute","default":false,"title":"Force"},"description":"Bypass Jaccard cache and recompute"},{"name":"min_score","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum similarity score filter","default":0.0,"title":"Min Score"},"description":"Minimum similarity score filter"},{"name":"match_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by match_type: competitor, lookalike, similar","title":"Match Type"},"description":"Filter by match_type: competitor, lookalike, similar"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max results to return (1-500, default 25)","default":25,"title":"Limit"},"description":"Max results to return (1-500, default 25)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/domain/{domain}/competitors/summary":{"get":{"summary":"Get Competitors Summary","description":"Return a lightweight competitor count summary — no full records.\n\nReturns::\n\n    {\n      \"domain\": \"stripe.com\",\n      \"method\": \"faiss_embedding\",\n      \"cached\": false,\n      \"total\": 87,\n      \"by_type\": {\"competitor\": 12, \"lookalike\": 31, \"similar\": 44},\n      \"top_3\": [{\"domain\": \"braintree.com\", \"score\": 0.91, \"match_type\": \"competitor\"}, ...]\n    }","operationId":"get_competitors_summary_domain__domain__competitors_summary_get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/competitors/status":{"get":{"summary":"Competitors Status","description":"Return which competitor search method is active.","operationId":"competitors_status_competitors_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/competitors/crawl-stats":{"get":{"summary":"Crawl Stats","description":"Return live crawl cache statistics.","operationId":"crawl_stats_competitors_crawl_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/copilot/health":{"get":{"summary":"Copilot Health","description":"Surface whether the Copilot is actually usable.","operationId":"copilot_health_copilot_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/copilot/query":{"post":{"summary":"Copilot Query","description":"Translate NL → tool call → executed results.","operationId":"copilot_query_copilot_query_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CopilotQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Serve Landing","description":"Serve the new redesigned marketing landing page.","operationId":"serve_landing__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/app":{"get":{"summary":"Serve App","description":"Serve the main search application.","operationId":"serve_app_app_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/classic":{"get":{"summary":"Serve Classic","description":"Preserve the original homepage design at a stable URL.","operationId":"serve_classic_classic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/copilot":{"get":{"summary":"Serve Copilot","description":"Serve the AI Search Copilot page (natural-language search over the index).","operationId":"serve_copilot_copilot_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/pricing":{"get":{"summary":"Serve Pricing","description":"Serve the dedicated pricing page.","operationId":"serve_pricing_pricing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AddCreditsRequest":{"properties":{"amount":{"type":"integer","title":"Amount"},"reason":{"type":"string","title":"Reason","default":"purchase"}},"type":"object","required":["amount"],"title":"AddCreditsRequest"},"AddItemsRequest":{"properties":{"domains":{"items":{"type":"string"},"type":"array","title":"Domains"}},"type":"object","required":["domains"],"title":"AddItemsRequest"},"Body_bulk_lookup_bulk_lookup_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_bulk_lookup_bulk_lookup_post"},"Body_import_domains_csv_admin_domains_import_csv_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_import_domains_csv_admin_domains_import_csv_post"},"CacheStatsResponse":{"properties":{"total_queries_cached":{"type":"integer","title":"Total Queries Cached","default":0},"total_homepages_cached":{"type":"integer","title":"Total Homepages Cached","default":0},"cache_db_size_mb":{"type":"number","title":"Cache Db Size Mb","default":0.0},"oldest_entry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oldest Entry"},"newest_entry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Newest Entry"}},"type":"object","title":"CacheStatsResponse"},"CheckSeenRequest":{"properties":{"domains":{"items":{"type":"string"},"type":"array","title":"Domains"},"current_query":{"type":"string","title":"Current Query","default":""}},"type":"object","required":["domains"],"title":"CheckSeenRequest"},"CopilotQuery":{"properties":{"message":{"type":"string","title":"Message"},"history":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"History"}},"type":"object","required":["message"],"title":"CopilotQuery"},"CreateApiKeyRequest":{"properties":{"name":{"type":"string","title":"Name","default":"Default"}},"type":"object","title":"CreateApiKeyRequest"},"CreateListRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"CreateListRequest"},"CreateMonitor":{"properties":{"query":{"type":"string","title":"Query"},"mode":{"type":"string","title":"Mode","default":"phrase"},"name":{"type":"string","title":"Name","default":""}},"type":"object","required":["query"],"title":"CreateMonitor"},"CreateMonitorRequest":{"properties":{"name":{"type":"string","title":"Name"},"query":{"type":"string","title":"Query"},"mode":{"type":"string","title":"Mode","default":"phrase"}},"type":"object","required":["name","query"],"title":"CreateMonitorRequest"},"GoogleLoginRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"GoogleLoginRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status","default":"ok"},"version":{"type":"string","title":"Version","default":"0.3.0"},"crawl_id":{"type":"string","title":"Crawl Id","default":""}},"type":"object","title":"HealthResponse"},"LoginRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MatchLocation":{"type":"string","enum":["title","meta","h1","h2","h3","body"],"title":"MatchLocation"},"RegisterRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"name":{"type":"string","title":"Name","default":""}},"type":"object","required":["email","password"],"title":"RegisterRequest"},"SearchResponse":{"properties":{"query":{"type":"string","title":"Query"},"normalized_query":{"type":"string","title":"Normalized Query"},"cached":{"type":"boolean","title":"Cached","default":false},"result_count":{"type":"integer","title":"Result Count","default":0},"total_count":{"type":"integer","title":"Total Count","default":0},"results":{"items":{"$ref":"#/components/schemas/SearchResultItem"},"type":"array","title":"Results"},"search_time_ms":{"type":"integer","title":"Search Time Ms","default":0},"credits_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits Remaining"},"credits_deducted":{"type":"integer","title":"Credits Deducted","default":0},"gate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gate"}},"type":"object","required":["query","normalized_query"],"title":"SearchResponse"},"SearchResultItem":{"properties":{"domain":{"type":"string","title":"Domain"},"homepage_url":{"type":"string","title":"Homepage Url"},"matched_in":{"items":{"$ref":"#/components/schemas/MatchLocation"},"type":"array","title":"Matched In"},"matched_snippet":{"type":"string","title":"Matched Snippet","default":""},"score":{"type":"number","title":"Score"},"crawl_id":{"type":"string","title":"Crawl Id"},"fetched_at":{"type":"string","title":"Fetched At"},"title":{"type":"string","title":"Title","default":""},"meta_description":{"type":"string","title":"Meta Description","default":""},"company_name":{"type":"string","title":"Company Name","default":""},"industry":{"type":"string","title":"Industry","default":""},"country":{"type":"string","title":"Country","default":""},"emails":{"items":{"type":"string"},"type":"array","title":"Emails"},"phones":{"items":{"type":"string"},"type":"array","title":"Phones"},"tech_stack":{"type":"string","title":"Tech Stack","default":""},"has_ecommerce":{"type":"boolean","title":"Has Ecommerce","default":false},"has_pricing":{"type":"boolean","title":"Has Pricing","default":false},"has_blog":{"type":"boolean","title":"Has Blog","default":false}},"type":"object","required":["domain","homepage_url","matched_in","score","crawl_id","fetched_at"],"title":"SearchResultItem"},"UpsertSessionRequest":{"properties":{"query":{"type":"string","title":"Query"},"mode":{"type":"string","title":"Mode","default":"phrase"},"filters":{"additionalProperties":true,"type":"object","title":"Filters","default":{}},"last_offset":{"type":"integer","title":"Last Offset","default":0},"total_results":{"type":"integer","title":"Total Results","default":0},"credits_spent":{"type":"integer","title":"Credits Spent","default":0},"results_per_page":{"type":"integer","title":"Results Per Page","default":25}},"type":"object","required":["query"],"title":"UpsertSessionRequest"},"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"}}}}