{"openapi":"3.1.0","info":{"title":"PreyReach API","version":"0.1.0","description":"Local business lead generation API — search, enrich, and manage leads"},"servers":[{"url":"https://api.preyreach.com","description":"Production"},{"url":"https://leadgen-api-beta.cnames-dev.workers.dev","description":"Beta"},{"url":"http://localhost:8989","description":"Local development"}],"security":[{"bearerAuth":[]},{"cookieAuth":[]},{"adminKey":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"session token","description":"Session token from /auth/verify-code"},"cookieAuth":{"type":"apiKey","in":"cookie","name":"lg_session","description":"Session cookie (set automatically on login)"},"adminKey":{"type":"apiKey","in":"header","name":"x-admin-key","description":"Admin key for /admin/* endpoints"}},"schemas":{},"parameters":{}},"paths":{"/auth/request-code":{"post":{"tags":["Auth"],"summary":"Request a magic login code","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]}}}},"responses":{"200":{"description":"Code sent","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"devCode":{"type":"string"}},"required":["ok"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/auth/verify-code":{"post":{"tags":["Auth"],"summary":"Verify magic code and create session","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"code":{"type":"string"}},"required":["email","code"]}}}},"responses":{"200":{"description":"Verified","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"user":{"nullable":true}},"required":["ok"]}}}},"401":{"description":"Invalid code","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"reason":{"type":"string"}},"required":["ok"]}}}}}}},"/auth/me":{"get":{"tags":["Auth"],"summary":"Get current user from session cookie","responses":{"200":{"description":"Current user","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"nullable":true}}}}}}}}},"/auth/signout":{"post":{"tags":["Auth"],"summary":"Sign out and clear session","responses":{"200":{"description":"Signed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}}}}},"/chats":{"get":{"tags":["Chats"],"summary":"List user chats (cursor-paginated by updated_at desc)","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"Chat list","content":{"application/json":{"schema":{"type":"object","properties":{"chats":{"type":"array","items":{"nullable":true}}},"required":["chats"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"tags":["Chats"],"summary":"Create a new chat","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"}}}}}},"responses":{"201":{"description":"Chat created","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/chats/{id}":{"get":{"tags":["Chats"],"summary":"Get a chat by ID","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Chat data","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"patch":{"tags":["Chats"],"summary":"Update a chat","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"messages":{"nullable":true},"results":{"nullable":true},"customColumns":{"nullable":true}}}}}},"responses":{"200":{"description":"Updated chat","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"delete":{"tags":["Chats"],"summary":"Delete a chat","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/search":{"post":{"tags":["Search"],"summary":"Search businesses","description":"Search for local businesses within a bounding box using smart query resolution + category mapping.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"south":{"type":"number","example":49.2},"west":{"type":"number","example":-123.2},"north":{"type":"number","example":49.3},"east":{"type":"number","example":-123},"centerLat":{"type":"number"},"centerLon":{"type":"number"},"userQuery":{"type":"string","example":"barbershop"},"query":{"type":"string"},"category":{"type":"string"},"sort":{"type":"string","example":"completeness,distance"},"limit":{"type":"number","example":50},"offset":{"type":"number","example":0},"includeSummary":{"type":"boolean"}},"required":["south","west","north","east"]}}}},"responses":{"200":{"description":"Search results with businesses and summary stats","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"number"},"count":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"},"enrichedCount":{"type":"number"},"summary":{"type":"object","properties":{"withPhone":{"type":"number"},"withWebsite":{"type":"number"},"withEmail":{"type":"number"},"withHours":{"type":"number"},"withSocial":{"type":"number"}},"required":["withPhone","withWebsite","withEmail","withHours","withSocial"]},"businesses":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"phone":{"type":"string"},"website":{"type":"string"},"email":{"type":"string"},"category":{"type":"string"},"lat":{"type":"number","nullable":true},"lon":{"type":"number","nullable":true},"score":{"type":"number"}},"required":["name","address","phone","website","email","category","lat","lon","score"]}}},"required":["total","count","limit","offset","enrichedCount","businesses"]}}}}}}},"/credits":{"get":{"tags":["Credits"],"summary":"Get user quota and credit balance","responses":{"200":{"description":"User quota","content":{"application/json":{"schema":{"type":"object","properties":{"quota":{"type":"object","properties":{"userId":{"type":"string"},"creditBalance":{"type":"number"},"promptsUsed":{"type":"number"},"promptLimit":{"type":"number"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["userId","creditBalance","promptsUsed","promptLimit","createdAt","updatedAt"]}},"required":["quota"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/credits/packages":{"get":{"tags":["Credits"],"summary":"List sellable credit packages","responses":{"200":{"description":"Credit packages","content":{"application/json":{"schema":{"type":"object","properties":{"packages":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"amountCents":{"type":"number"},"credits":{"type":"number"},"popular":{"type":"boolean"}},"required":["key","name","amountCents","credits"]}}},"required":["packages"]}}}}}}},"/credits/checkout":{"post":{"tags":["Credits"],"summary":"Create a Stripe Checkout Session for a credit pack","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"packageKey":{"type":"string","enum":["mini","starter","growth","scale","pro"]},"onboarding":{"type":"boolean"},"expectedAmountCents":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["packageKey"]}}}},"responses":{"200":{"description":"Stripe-hosted checkout URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Stripe didn't return a checkout URL","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/enrich":{"post":{"tags":["Enrich"],"summary":"Enrich websites with contact info","description":"Scrape websites to extract email and phone numbers. Max 20 per request.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"websites":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":20,"example":["example.com"]},"chatId":{"type":"string"}},"required":["websites"]}}}},"responses":{"200":{"description":"Enrichment results","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"website":{"type":"string"},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"socialLinks":{"type":"object","additionalProperties":{"type":"string"}},"source":{"type":"string","nullable":true}},"required":["website","email","phone","socialLinks","source"]}},"leads":{"type":"array","items":{"nullable":true}}},"required":["results"]}}}}}}},"/saved-leads":{"get":{"tags":["Saved Leads"],"summary":"List saved leads","responses":{"200":{"description":"Saved leads","content":{"application/json":{"schema":{"type":"object","properties":{"leads":{"type":"array","items":{"nullable":true}}},"required":["leads"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"tags":["Saved Leads"],"summary":"Save a lead","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"lead":{"nullable":true},"sourceChatId":{"type":"string"},"notes":{"type":"string"}}}}}},"responses":{"201":{"description":"Lead saved","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"delete":{"tags":["Saved Leads"],"summary":"Unsave a lead by dedupe key","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"dedupeKey":{"type":"string"}},"required":["dedupeKey"]}}}},"responses":{"200":{"description":"Lead unsaved","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/user":{"get":{"tags":["User"],"summary":"Get current user profile","responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string","nullable":true},"createdAt":{"type":"string"}},"required":["id","email","name","createdAt"]}},"required":["user"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/admin/users":{"get":{"tags":["Admin"],"summary":"List users with quota info (searchable + paginated)","parameters":[{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"User list","content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","items":{"nullable":true}},"total":{"type":"number"}},"required":["users","total"]}}}}}}},"/admin/usage":{"get":{"tags":["Admin"],"summary":"List usage logs (searchable + paginated)","parameters":[{"schema":{"type":"string"},"required":false,"name":"userId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Usage logs","content":{"application/json":{"schema":{"type":"object","properties":{"usage":{"type":"array","items":{"nullable":true}},"total":{"type":"number"}},"required":["usage","total"]}}}}}}},"/admin/stats":{"get":{"tags":["Admin"],"summary":"Dashboard stats — totals + daily time series for charts","parameters":[{"schema":{"type":"string"},"required":false,"name":"days","in":"query"}],"responses":{"200":{"description":"Stats","content":{"application/json":{"schema":{"type":"object","properties":{"stats":{"nullable":true}}}}}}}}},"/admin/users/{id}/quota":{"post":{"tags":["Admin"],"summary":"Adjust user quota","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"creditBalance":{"type":"number"},"promptsUsed":{"type":"number"},"promptLimit":{"type":"number"},"lifetimeSearches":{"type":"number"}}}}}},"responses":{"200":{"description":"Updated quota","content":{"application/json":{"schema":{"type":"object","properties":{"quota":{"nullable":true}}}}}}}}},"/admin/users/{id}/paid":{"post":{"tags":["Admin"],"summary":"Mark a user as paid (testing) — bypasses the free-search gate","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"paid":{"type":"boolean"}},"required":["paid"]}}}},"responses":{"200":{"description":"Updated paid status","content":{"application/json":{"schema":{"type":"object","properties":{"isPaid":{"type":"boolean"}},"required":["isPaid"]}}}}}}},"/admin/api-keys":{"post":{"tags":["Admin"],"summary":"Create a new API key","description":"Returns the plaintext sk_live_... token ONCE. Store it securely.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"My Integration"},"promptLimit":{"type":"number","example":100}},"required":["name"]}}}},"responses":{"200":{"description":"API key created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string","description":"Plaintext token — shown ONCE"},"promptLimit":{"type":"number"},"createdAt":{"type":"string"}},"required":["id","name","key","promptLimit","createdAt"]}}}}}},"get":{"tags":["Admin"],"summary":"List all API keys","responses":{"200":{"description":"API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"nullable":true}}},"required":["keys"]}}}}}}},"/admin/users/{id}":{"delete":{"tags":["Admin"],"summary":"Delete a user completely","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"email":{"type":"string"}},"required":["ok"]}}}}}}},"/admin/api-keys/{id}":{"delete":{"tags":["Admin"],"summary":"Revoke an API key","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}}}}},"/admin/feedback":{"get":{"tags":["Admin"],"summary":"List product feedback submissions","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Feedback rows","content":{"application/json":{"schema":{"type":"object","properties":{"feedback":{"type":"array","items":{"nullable":true}}},"required":["feedback"]}}}}}}},"/admin/feedback/messages":{"get":{"tags":["Admin"],"summary":"List per-message thumbs-up/down votes","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Vote rows","content":{"application/json":{"schema":{"type":"object","properties":{"votes":{"type":"array","items":{"nullable":true}}},"required":["votes"]}}}}}}},"/v1/searches":{"post":{"tags":["Public API"],"summary":"Submit a search","description":"Submit a natural-language prompt. Returns immediately with an ID; poll GET /v1/searches/:id for results.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"nullable":true,"example":"find car washes in downtown Toronto with rating above 4 and dog friendly"}}}}}},"responses":{"202":{"description":"Search queued","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued"]},"pollUrl":{"type":"string"}},"required":["id","status","pollUrl"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}}}}},"/v1/searches/{id}":{"get":{"tags":["Public API"],"summary":"Get search status & result","description":"Poll this endpoint until status is 'completed' or 'failed'.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Search status","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed"]},"createdAt":{"type":"string"},"completedAt":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"creditsCharged":{"type":"number"},"result":{"nullable":true}},"required":["id","prompt","status","createdAt","completedAt","error","creditsCharged"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/v1/searches/{id}/enrich":{"post":{"tags":["Public API"],"summary":"Enrich a stored search result","description":"Enrich every not-yet-attempted lead that has a website and persist the merged result. Search credits already cover these returned leads, so this operation never double-charges them.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The persisted enriched search result.","content":{"application/json":{"schema":{"type":"object","properties":{"attempted":{"type":"integer","minimum":0},"enriched":{"type":"integer","minimum":0},"additionalCreditsCharged":{"type":"number","enum":[0]},"creditsCharged":{"type":"number"},"result":{"nullable":true}},"required":["attempted","enriched","additionalCreditsCharged","creditsCharged"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Search not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Search is incomplete or changed concurrently","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}}}}},"/v1/tokens":{"post":{"tags":["Public API"],"summary":"Register an API token","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"name":{"type":"string"}},"required":["token","name"]}}}},"responses":{"200":{"description":"Token registered","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"delete":{"tags":["Public API"],"summary":"Revoke an API token","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}}}},"responses":{"200":{"description":"Token revoked","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/suggestions":{"post":{"tags":["Suggestions"],"summary":"Get next-action suggestions","description":"Generate contextual next-step suggestions based on conversation state.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"recentMessages":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string"},"text":{"type":"string"}},"required":["role","text"]}},"results":{"type":"object","nullable":true,"properties":{"city":{"type":"string"},"category":{"type":"string"},"count":{"type":"number"},"withWebsite":{"type":"number"},"withPhone":{"type":"number"},"withEmail":{"type":"number"}},"required":["city","category","count","withWebsite","withPhone","withEmail"]}}}}}},"responses":{"200":{"description":"Suggestions","content":{"application/json":{"schema":{"type":"object","properties":{"suggestions":{"type":"array","items":{"type":"string"}}},"required":["suggestions"]}}}}}}},"/onboarding":{"get":{"tags":["Onboarding"],"summary":"Get the current user's onboarding state","responses":{"200":{"description":"Onboarding state","content":{"application/json":{"schema":{"type":"object","properties":{"authenticated":{"type":"boolean"},"needsOnboarding":{"type":"boolean"},"onboarding":{"type":"object","nullable":true,"properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]}},"required":["authenticated","needsOnboarding","onboarding"]}}}}}}},"/onboarding/prompts":{"get":{"tags":["Onboarding"],"summary":"Get suggestion chips for the chatbox","responses":{"200":{"description":"Suggestion chips","content":{"application/json":{"schema":{"type":"object","properties":{"prompts":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"personalized":{"type":"boolean"}},"required":["prompts","personalized"]}}}}}},"patch":{"tags":["Onboarding"],"summary":"Save user-customized suggestion chips","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"prompts":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]},"minItems":1,"maxItems":6}},"required":["prompts"]}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]}},"required":["onboarding"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/onboarding/source":{"post":{"tags":["Onboarding"],"summary":"Record how the user found us","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","minLength":1,"maxLength":60},"sourceDetail":{"type":"string","nullable":true,"maxLength":300}},"required":["source"]}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]}},"required":["onboarding"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/onboarding/profile":{"post":{"tags":["Onboarding"],"summary":"Investigate the user's website / target market and personalize","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"website":{"type":"string","nullable":true,"maxLength":400},"targetMarket":{"type":"string","nullable":true,"maxLength":600}}}}}},"responses":{"200":{"description":"Generated profile","content":{"application/json":{"schema":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"businessSummary":{"type":"string"},"audienceSummary":{"type":"string"},"customerType":{"type":"string"},"customerSegment":{"type":"string"},"customerSignal":{"type":"string"},"prompts":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"scraped":{"type":"boolean"},"screenshotUrl":{"type":"string","nullable":true,"format":"uri"}},"required":["onboarding","listingFilters","businessSummary","audienceSummary","customerType","customerSegment","customerSignal","prompts","scraped","screenshotUrl"]}}}},"400":{"description":"Neither a website nor a target market was supplied","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"The LLM provider isn't configured on the server","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}}}}},"/onboarding/targeting":{"post":{"tags":["Onboarding"],"summary":"Save the user's confirmed prospecting target","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","minLength":2,"maxLength":160},"customerSegment":{"type":"string","maxLength":240,"default":""},"customerSignal":{"type":"string","maxLength":240,"default":""},"targetLocation":{"type":"string","minLength":2,"maxLength":160},"goal":{"type":"string","maxLength":240,"default":""},"location":{"type":"object","nullable":true,"properties":{"lat":{"type":"number","nullable":true},"lon":{"type":"number","nullable":true},"south":{"type":"number","nullable":true},"west":{"type":"number","nullable":true},"north":{"type":"number","nullable":true},"east":{"type":"number","nullable":true}}}},"required":["customerType","targetLocation"]}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]}},"required":["onboarding"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/onboarding/locations":{"get":{"tags":["Onboarding"],"summary":"Search cities and locations for onboarding","parameters":[{"schema":{"type":"string","minLength":2,"maxLength":120},"required":true,"name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":8},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Matching locations","content":{"application/json":{"schema":{"type":"object","properties":{"locations":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string"},"label":{"type":"string"},"city":{"type":"string"},"country":{"type":"string"},"lat":{"type":"number"},"lon":{"type":"number"},"south":{"type":"number"},"west":{"type":"number"},"north":{"type":"number"},"east":{"type":"number"}},"required":["placeId","label","city","country","lat","lon","south","west","north","east"]}}},"required":["locations"]}}}}}}},"/onboarding/complete":{"post":{"tags":["Onboarding"],"summary":"Mark onboarding finished","responses":{"200":{"description":"Completed","content":{"application/json":{"schema":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]}},"required":["onboarding"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/onboarding/skip":{"post":{"tags":["Onboarding"],"summary":"Dismiss onboarding without personalizing","responses":{"200":{"description":"Skipped","content":{"application/json":{"schema":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"userId":{"type":"string"},"source":{"type":"string","nullable":true},"sourceDetail":{"type":"string","nullable":true},"website":{"type":"string","nullable":true},"targetMarket":{"type":"string","nullable":true},"listingFilters":{"type":"object","properties":{"website":{"type":"string","enum":["any","missing","present"],"default":"any"},"minRating":{"type":"number","minimum":0,"maximum":5},"minReviews":{"type":"integer","minimum":0,"maximum":10000000},"hasPhone":{"type":"boolean"}}},"customerType":{"type":"string","nullable":true},"customerSegment":{"type":"string","nullable":true},"customerSignal":{"type":"string","nullable":true},"targetLocation":{"type":"string","nullable":true},"goal":{"type":"string","nullable":true},"targetLat":{"type":"number","nullable":true},"targetLon":{"type":"number","nullable":true},"targetSouth":{"type":"number","nullable":true},"targetWest":{"type":"number","nullable":true},"targetNorth":{"type":"number","nullable":true},"targetEast":{"type":"number","nullable":true},"businessSummary":{"type":"string","nullable":true},"audienceSummary":{"type":"string","nullable":true},"personaPrompt":{"type":"string","nullable":true},"suggestedPrompts":{"type":"array","nullable":true,"items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":44},"text":{"type":"string","minLength":4,"maxLength":160},"icon":{"type":"string","enum":["utensils","hotel","scissors","building","stethoscope","dumbbell","car","home","briefcase","shoppingBag","wrench","camera","graduation","paw","coffee","heart","gavel","palette","truck","sparkles"]}},"required":["label","text"]}},"step":{"type":"number"},"completedAt":{"type":"string","nullable":true},"skipped":{"type":"boolean"}},"required":["userId","source","sourceDetail","website","targetMarket","listingFilters","customerType","customerSegment","customerSignal","targetLocation","goal","targetLat","targetLon","targetSouth","targetWest","targetNorth","targetEast","businessSummary","audienceSummary","personaPrompt","suggestedPrompts","step","completedAt","skipped"]}},"required":["onboarding"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/feedback":{"post":{"tags":["Feedback"],"summary":"Submit message feedback (thumbs up/down)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"chatId":{"type":"string"},"messageId":{"type":"string"},"vote":{"type":"string","nullable":true,"enum":["up","down"]},"prompt":{"type":"string"},"response":{"type":"string"}},"required":["chatId","messageId","vote"]}}}},"responses":{"200":{"description":"Feedback recorded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"cleared":{"type":"boolean"}},"required":["ok"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"get":{"tags":["Feedback"],"summary":"List a chat's message votes","parameters":[{"schema":{"type":"string"},"required":true,"name":"chatId","in":"query"}],"responses":{"200":{"description":"Vote list","content":{"application/json":{"schema":{"type":"object","properties":{"votes":{"type":"array","items":{"nullable":true}}},"required":["votes"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Chat not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/feedback/product":{"post":{"tags":["Feedback"],"summary":"Submit free-text product feedback","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"content":{"type":"string","minLength":1,"maxLength":5000}},"required":["content"]}}}},"responses":{"200":{"description":"Feedback recorded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/columns/run":{"post":{"tags":["Columns"],"summary":"Run an AI custom column","description":"Resolves an AI custom column for the top 10 leads in a chat's results.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"chatId":{"type":"string"},"columnId":{"type":"string"},"prompt":{"type":"string"},"columnName":{"type":"string"}},"required":["chatId","columnId","prompt","columnName"]}}}},"responses":{"200":{"description":"Column resolved","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"column":{"nullable":true},"llmCalls":{"type":"number"},"leadKeys":{"type":"array","items":{"type":"string"}}},"required":["ok","llmCalls","leadKeys"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Out of credits","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}},"404":{"description":"Chat not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/sessions":{"get":{"tags":["Sessions"],"summary":"List sessions for a user","parameters":[{"schema":{"type":"string"},"required":true,"name":"userId","in":"query"}],"responses":{"200":{"description":"Sessions","content":{"application/json":{"schema":{"type":"object","properties":{"sessions":{"type":"array","items":{"nullable":true}}},"required":["sessions"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"tags":["Sessions"],"summary":"Create a new session","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"}},"required":["userId"]}}}},"responses":{"200":{"description":"Session created","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"nullable":true}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/sessions/{id}":{"get":{"tags":["Sessions"],"summary":"Get a session by ID","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Session","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"nullable":true}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"patch":{"tags":["Sessions"],"summary":"Update session name","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}}}},"delete":{"tags":["Sessions"],"summary":"Delete a session","parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}}}}},"/debug/search-logs":{"get":{"tags":["Debug"],"summary":"List search logs","parameters":[{"schema":{"type":"string"},"required":false,"name":"sessionId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"userId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Search logs","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"number"},"logs":{"type":"array","items":{"nullable":true}}},"required":["count","logs"]}}}}}}},"/v1/enrich":{"post":{"tags":["Public API"],"summary":"Enrich websites","description":"Extract email, phone, and social profiles from up to 20 websites. Uses one API-key request and charges one credit per attempted website.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"websites":{"type":"array","items":{"type":"string","minLength":1,"maxLength":2048},"minItems":1,"maxItems":20}},"required":["websites"]}}}},"responses":{"200":{"description":"Enrichment results","content":{"application/json":{"schema":{"type":"object","properties":{"attempted":{"type":"integer","minimum":0},"enriched":{"type":"integer","minimum":0},"creditsCharged":{"type":"integer","minimum":0},"results":{"type":"array","items":{"type":"object","properties":{"website":{"type":"string"},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"socialLinks":{"type":"object","additionalProperties":{"type":"string"}},"source":{"type":"string","nullable":true,"enum":["scrape","hunter","scrape+hunter"]}},"required":["website","email","phone","socialLinks","source"]}}},"required":["attempted","enriched","creditsCharged","results"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}}}}},"/reports/website":{"get":{"tags":["Reports"],"summary":"Get existing website report artifacts for a URL","parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"url","in":"query"}],"responses":{"200":{"description":"Report row (or empty fields)","content":{"application/json":{"schema":{"nullable":true}}}},"400":{"description":"Bad URL","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/reports/website/lookup":{"post":{"tags":["Reports"],"summary":"Bulk lookup existing reports by URL list","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"urls":{"type":"array","items":{"type":"string"},"maxItems":200}},"required":["urls"]}}}},"responses":{"200":{"description":"Map of url-slug → report","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/reports/website/generate":{"post":{"tags":["Reports"],"summary":"Generate a website report artifact (idempotent + cached)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1},"kind":{"type":"string","enum":["full","masked","screenshot"]},"chatId":{"type":"string"},"force":{"type":"boolean"}},"required":["url","kind"]}}}},"responses":{"200":{"description":"Report shape with public URLs","content":{"application/json":{"schema":{"nullable":true}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Out of credits","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"]}}}},"500":{"description":"Generation failure","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error"]}}}}}}},"/lindo/connect/start":{"post":{"tags":["Lindo"],"summary":"Start Lindo OAuth","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"redirectTo":{"type":"string"}}}}}},"responses":{"200":{"description":"Authorization URL","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/lindo/status":{"get":{"tags":["Lindo"],"summary":"Get Lindo connection status","responses":{"200":{"description":"Status","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/lindo/connect":{"delete":{"tags":["Lindo"],"summary":"Disconnect the current Lindo account","responses":{"200":{"description":"Stored Lindo connection removed","content":{"application/json":{"schema":{"type":"object","properties":{"disconnected":{"type":"boolean"}},"required":["disconnected"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/lindo/website/preview":{"post":{"tags":["Lindo"],"summary":"Preview the Lindo website request","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"lead":{"nullable":true}}}}}},"responses":{"200":{"description":"Editable prompt and immutable Google Maps source","content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string"},"mapUrl":{"type":"string","format":"uri"}},"required":["prompt","mapUrl"]}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"nullable":true}}}}}}},"/lindo/website/create":{"post":{"tags":["Lindo"],"summary":"Create a Lindo website from a lead","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"lead":{"nullable":true},"prompt":{"type":"string","minLength":10,"maxLength":50000}},"required":["prompt"]}}}},"responses":{"200":{"description":"Workflow started","content":{"application/json":{"schema":{"nullable":true}}}},"401":{"description":"Unauthenticated","content":{"application/json":{"schema":{"nullable":true}}}},"409":{"description":"Lindo not connected","content":{"application/json":{"schema":{"nullable":true}}}},"502":{"description":"Lindo upstream error","content":{"application/json":{"schema":{"nullable":true}}}}}}}}}