{"openapi":"3.1.0","info":{"title":"Deal Radar","version":"1.0.0"},"paths":{"/api/public/lead":{"post":{"summary":"Submit Lead","description":"Capture an inbound \"request access\" lead from the marketing site.","operationId":"submit_lead_api_public_lead_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/stats-export":{"get":{"summary":"Stats Export","description":"Aggregate, PII-free per-region + per-market counts (6h cached).","operationId":"stats_export_api_public_stats_export_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/public/demo-map":{"get":{"summary":"Demo Map","description":"Sanitized live nodes for the public demo market (6h cached).","operationId":"demo_map_api_public_demo_map_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/public/trades":{"get":{"summary":"Trades","description":"The CSLB trade registry, public shape (no template names, no gap list).\n\nLives on the PUBLIC surface because the signup flow needs to render a trade\npicker before the visitor has a tenant, and the middleware already skips\n/api/public/* (so no tenant is resolved and none is required). Static data\nfrom trades.py: nothing here reads the database.","operationId":"trades_api_public_trades_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/public/coverage":{"get":{"summary":"Coverage","description":"Market coverage for the map overlay: live markets + announced ones.","operationId":"coverage_api_public_coverage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/coverage":{"get":{"tags":["SentientData public API"],"summary":"Coverage","operationId":"coverage_v1_coverage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/signals":{"get":{"tags":["SentientData public API"],"summary":"List Public Signals","operationId":"list_public_signals_v1_signals_get","parameters":[{"name":"market_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Market Id"}},{"name":"signal_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Signal Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/entities/{organization_id}":{"get":{"tags":["SentientData public API"],"summary":"Public Entity","operationId":"public_entity_v1_entities__organization_id__get","parameters":[{"name":"organization_id","in":"path","required":true,"schema":{"type":"string","title":"Organization Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/proof":{"get":{"tags":["SentientData public API"],"summary":"Proof Manifest","description":"Machine-readable disclosure for the public graph endpoints.","operationId":"proof_manifest_v1_proof_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/intake/signals":{"post":{"tags":["SentientOS intake"],"summary":"Receive Signal","operationId":"receive_signal_v1_intake_signals_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalEnvelope"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me":{"get":{"summary":"Me","operationId":"me_api_auth_me_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"}}}}}}},"/api/clerk/webhook":{"post":{"summary":"Clerk Webhook","description":"Tenant provisioning on Clerk `organization.created` (svix-verified).\n\nKeyless / no webhook secret => 503: the endpoint declines cleanly rather\nthan accepting unverifiable payloads.","operationId":"clerk_webhook_api_clerk_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/signals":{"get":{"summary":"Get Signals","operationId":"get_signals_api_signals_get","parameters":[{"name":"stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Signal"},"title":"Response Get Signals Api Signals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/export.csv":{"get":{"summary":"Export Signals Csv","description":"This tenant's signals as a spreadsheet. repo.list_signals is tenant-\nscoped (WHERE tenant_id = ?), so no other tenant's work product can appear.","operationId":"export_signals_csv_api_signals_export_csv_get","parameters":[{"name":"stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"}},{"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"}}}}}}},"/api/signals/{signal_id}":{"get":{"summary":"Get One","operationId":"get_one_api_signals__signal_id__get","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/{signal_id}/stage":{"patch":{"summary":"Set Stage","operationId":"set_stage_api_signals__signal_id__stage_patch","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StageUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/{signal_id}/pipedrive":{"post":{"summary":"Push To Pipedrive","operationId":"push_to_pipedrive_api_signals__signal_id__pipedrive_post","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipedrivePushResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/{signal_id}/draft":{"post":{"summary":"Regenerate Draft","description":"Re-run the model router to (optionally) polish the intro draft.\n\nNever auto-sends. Just refreshes the draft text in place.\n\nIncluded from Starter (it was Pro): drafting is the other half of the\nbriefing, and an alert you cannot act on is not worth sending. Unmask and\nenrich stay Pro because each call spends vendor money.","operationId":"regenerate_draft_api_signals__signal_id__draft_post","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/signals/{signal_id}/text-sent":{"post":{"summary":"Text Sent","description":"Pat sent a text — log the touch to the Pipedrive deal (on command).","operationId":"text_sent_api_signals__signal_id__text_sent_post","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextSent"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pipedrive/sync":{"post":{"summary":"Pipedrive Sync Now","description":"Manually run the inbound Pipedrive→Deal Radar context sync.","operationId":"pipedrive_sync_now_api_pipedrive_sync_post","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"}}}}}}},"/api/pipedrive/status":{"get":{"summary":"Pipedrive Status","operationId":"pipedrive_status_api_pipedrive_status_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"}}}}}}},"/api/unmask/health":{"get":{"summary":"Unmask Health","description":"Confirm the CALICO subscription key is live (pings ServerStatus).","operationId":"unmask_health_api_unmask_health_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"}}}}}}},"/api/signals/{signal_id}/unmask":{"post":{"summary":"Unmask Signal","description":"Follow the money: resolve the shell LLC behind a signal to its CA SOS\nregistered agent + principal address (dry-runs without a subscription key).","operationId":"unmask_signal_api_signals__signal_id__unmask_post","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal 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"}}}}}}},"/api/signals/{signal_id}/enrich":{"post":{"summary":"Enrich","description":"Apollo contact enrichment for the buying committee (dry-runs without a key).","operationId":"enrich_api_signals__signal_id__enrich_post","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal 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"}}}}}}},"/api/stats":{"get":{"summary":"Stats","operationId":"stats_api_stats_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"}}}}}}},"/api/accounts":{"get":{"summary":"Accounts","description":"The hunting list, annotated with which accounts have live signals.","operationId":"accounts_api_accounts_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"}}}}}}},"/api/scan":{"post":{"summary":"Run Scan","description":"Manual trigger of the (graceful) public-source scan.","operationId":"run_scan_api_scan_post","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"}}}}}}},"/api/audit":{"get":{"summary":"Audit","operationId":"audit_api_audit_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"}}}}}}},"/api/monitors":{"get":{"summary":"Monitors","operationId":"monitors_api_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"}}}}}}},"/api/monitors/run":{"post":{"summary":"Run All","description":"Run all monitors now (force=true) or just those due (force=false),\nacross the tenant's subscribed active markets.","operationId":"run_all_api_monitors_run_post","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Force"}},{"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"}}}}}}},"/api/monitors/{key}/run":{"post":{"summary":"Run One","description":"Run one source by bare key across the tenant's subscribed active markets.\nThe registry is data-driven (source_configs), so the monitor is built\nper market — the same bare key can be configured differently per market.","operationId":"run_one_api_monitors__key__run_post","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"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"}}}}}}},"/api/monitors/{key}/toggle":{"post":{"summary":"Toggle","description":"Enable or disable a source. `monitors` rows are MARKET-scoped shared\ninfrastructure: one row serves every tenant subscribed to that market, so\nthis is an operator action, never a tenant preference. A tenant-scoped\ncaller here would silently stop ingestion for every other customer.","operationId":"toggle_api_monitors__key__toggle_post","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Enabled"}},{"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"}}}}}}},"/api/geocode/run":{"post":{"summary":"Run Geocode","description":"Backfill lat/lng on address-only feed items so they plot on the radar.","operationId":"run_geocode_api_geocode_run_post","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":120,"title":"Limit"}},{"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"}}}}}}},"/api/map":{"get":{"summary":"Map Points","description":"Mappable signals (those with coordinates) for the Radar view — slim payload.","operationId":"map_points_api_map_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":1500,"title":"Limit"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"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"}}}}}}},"/api/route/plan":{"post":{"summary":"Plan Route","description":"Truck-Route day planner: order the selected map stops into a short\ndrive-by path and hand back Google Maps directions links. Pure geometry,\nno keys — straight-line sequencing; Google does the turn-by-turn.","operationId":"plan_route_api_route_plan_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/RoutePlanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects":{"get":{"summary":"Projects","description":"G4 grouped project view: entity-resolved projects across the tenant's\nsubscribed markets (canonical name, address, signal count, types, latest\nactivity). Feed items link back via their project_id.","operationId":"projects_api_projects_get","parameters":[{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Market"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"needs_review","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Needs Review"}},{"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"}}}}}}},"/api/projects/{project_id}/timeline":{"get":{"summary":"Project Timeline","description":"One project's story, with observed facts and our reading kept apart.\n\n`events` cite the record each fact came from. `interpretation` is ours and\nis labelled as ours. What to DO about it is not here on purpose: that\ndepends on the contractor's trade and radius, and an opinion about one\ncustomer does not belong inside a fact about a project.","operationId":"project_timeline_api_projects__project_id__timeline_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"integer","title":"Project 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"}}}}}}},"/api/feed/{item_id}/timeline":{"get":{"summary":"Item Timeline","description":"The story around one feed item.\n\n404 when the record has not been threaded onto a project yet, which is a\nreal and common state rather than an error: entity resolution runs in\nbatches and a record can arrive before its neighbours.","operationId":"item_timeline_api_feed__item_id__timeline_get","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item 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"}}}}}}},"/api/projects/resolve":{"post":{"summary":"Resolve Projects","description":"Run incremental entity resolution NOW over the tenant's subscribed\nactive markets (the scheduler also runs this after every monitor tick).","operationId":"resolve_projects_api_projects_resolve_post","parameters":[{"name":"batch","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Batch"}},{"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"}}}}}}},"/api/feed/item/{item_id}":{"get":{"summary":"Feed Item","operationId":"feed_item_api_feed_item__item_id__get","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item 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"}}}}}}},"/api/feed":{"get":{"summary":"Feed","operationId":"feed_api_feed_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":80,"title":"Limit"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"candidates_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Candidates Only"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"new","title":"Sort"}},{"name":"include_dismissed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Dismissed"}},{"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"}}}}}}},"/api/feed/export.csv":{"get":{"summary":"Export Feed Csv","description":"The feed as a spreadsheet: the columns a contractor actually works from\n(who, where, what, what it is worth), not the raw source blob.","operationId":"export_feed_csv_api_feed_export_csv_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":1000,"title":"Limit"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"candidates_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Candidates Only"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"new","title":"Sort"}},{"name":"include_dismissed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Dismissed"}},{"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"}}}}}}},"/api/feed/{item_id}/unmask":{"post":{"summary":"Unmask Feed","description":"Crack the shell behind a feed item's applicant/business (CA SOS) and\nenrich the agent's contact — stored on the item so the card shows it.","operationId":"unmask_feed_api_feed__item_id__unmask_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item 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"}}}}}}},"/api/feed/{item_id}/enrich":{"post":{"summary":"Enrich Feed","description":"Apollo-enrich a feed item's business contact (dry-runs without a key).","operationId":"enrich_feed_api_feed__item_id__enrich_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item 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"}}}}}}},"/api/feed/{item_id}/promote":{"post":{"summary":"Promote","operationId":"promote_api_feed__item_id__promote_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item 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"}}}}}}},"/api/feed/reasons":{"get":{"summary":"Feedback Reasons","description":"The closed reason set, for a client to render as buttons.\n\nServed rather than hard-coded in the client so the set can only ever be\nchanged in one place. A reason the server does not know is refused below.","operationId":"feedback_reasons_api_feed_reasons_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"}}}}}}},"/api/feed/feedback":{"get":{"summary":"Feedback Summary","description":"What this tenant's own rejections argue for.\n\nOnly ever proposes a change to a setting that exists; everything else comes\nback `actionable: false` with its count, which is the product backlog\nstated in the customer's own taps rather than in a meeting.","operationId":"feedback_summary_api_feed_feedback_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"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"}}}}}}},"/api/feed/{item_id}/dismiss":{"post":{"summary":"Dismiss","description":"Record what the contractor thought, and archive it if that was a no.\n\nUngated on purpose: clearing work you have already looked at is the daily\nworkflow, not a feature. Per-tenant like promotion, so dismissing here never\ntouches another tenant subscribed to the same market.\n\nThe reason is validated against the closed set. Free text is refused, not\nstored: an unrecognised reason cannot be counted, and a reason nobody can\ncount is one nobody will ever act on. `good_fit` is in the same set and\ndeliberately does NOT archive the card, because a contractor telling us to\nsend more like this is not asking for it to disappear.","operationId":"dismiss_api_feed__item_id__dismiss_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DismissRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Undismiss","description":"Undo a dismissal: the item returns to this tenant's feed and queue.","operationId":"undismiss_api_feed__item_id__dismiss_delete","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item 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"}}}}}}},"/api/alerts":{"get":{"summary":"List Alerts","description":"This tenant's queued alerts, soonest first.\n\nEach carries the recipients the SUBSCRIBER would contact, with the channel\n(business-to-business or mail) that applies. The platform never contacts\nthem itself.","operationId":"list_alerts_api_alerts_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"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"}}}}}}},"/api/alerts/counts":{"get":{"summary":"Alert Counts","operationId":"alert_counts_api_alerts_counts_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"}}}}}}},"/api/routes/today/build":{"post":{"summary":"Build Today","description":"Auto-compose today's route: fresh (first_seen/event_time within `days`)\ngeocoded feed items from the tenant's subscribed markets, trade-filtered,\npriority-ranked, capped at max_stops, then optimized. Upserts the current\nuser's route row for today (second build replaces, no duplicate row).","operationId":"build_today_api_routes_today_build_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/BuildRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/routes/today":{"get":{"summary":"Today Route","description":"The current user's saved route for today, or null.","operationId":"today_route_api_routes_today_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"}}}}}}},"/api/routes":{"get":{"summary":"List Routes","description":"The current user's recent routes (newest first, slim rows).","operationId":"list_routes_api_routes_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"}}}}}}},"/api/routes/{route_id}/stops/{feed_item_id}":{"patch":{"summary":"Mark Stop","description":"Mark a stop visited / skipped (or back to pending) + optional note.\nVisit marks land in the audit log. 404 for another user's/tenant's route.","operationId":"mark_stop_api_routes__route_id__stops__feed_item_id__patch","parameters":[{"name":"route_id","in":"path","required":true,"schema":{"type":"integer","title":"Route Id"}},{"name":"feed_item_id","in":"path","required":true,"schema":{"type":"string","title":"Feed Item Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StopPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/routes/{route_id}":{"patch":{"summary":"Set Route Status","description":"Move the route through its lifecycle: planned | active | done.","operationId":"set_route_status_api_routes__route_id__patch","parameters":[{"name":"route_id","in":"path","required":true,"schema":{"type":"integer","title":"Route Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/intelligence/daily-brief":{"get":{"summary":"Daily Brief","description":"Executive summary of today's biggest opportunities (cached; refresh=1 forces).","operationId":"daily_brief_api_intelligence_daily_brief_get","parameters":[{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Refresh"}},{"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"}}}}}}},"/api/intelligence/status":{"get":{"summary":"Status","operationId":"status_api_intelligence_status_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"}}}}}}},"/api/intelligence/queue":{"get":{"summary":"Queue","operationId":"queue_api_intelligence_queue_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"default":"queued","title":"Status"}},{"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"}}}}}}},"/api/intelligence/draft-sms/{signal_id}":{"post":{"summary":"Draft Sms","description":"Draft a peer-to-peer BD text for a signal; optionally add it to the queue.","operationId":"draft_sms_api_intelligence_draft_sms__signal_id__post","parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","title":"Signal Id"}},{"name":"queue","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Queue"}},{"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"}}}}}}},"/api/intelligence/messages/{message_id}/status":{"post":{"summary":"Set Status","operationId":"set_status_api_intelligence_messages__message_id__status_post","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"integer","title":"Message Id"}},{"name":"status","in":"query","required":true,"schema":{"type":"string","title":"Status"}},{"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"}}}}}}},"/api/billing/checkout":{"post":{"summary":"Checkout","description":"Start a subscription checkout for this tenant (org admins only).","operationId":"checkout_api_billing_checkout_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/CheckoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/portal":{"post":{"summary":"Portal","description":"Open the Stripe customer portal for this tenant (org admins only).","operationId":"portal_api_billing_portal_post","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"}}}}}}},"/api/billing":{"get":{"summary":"Billing Summary","description":"The tenant's current plan + the configured price matrix (for the SPA).","operationId":"billing_summary_api_billing_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"}}}}}}},"/api/stripe/webhook":{"post":{"summary":"Stripe Webhook","description":"Stripe events. Signature verification is the only auth; the tenant\nmiddleware skips this path (no Host/tenant context — the event itself says\nwhich tenant it belongs to).","operationId":"stripe_webhook_api_stripe_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/leads/quote":{"post":{"summary":"Quote","operationId":"quote_api_leads_quote_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/QuoteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leads/purchase":{"post":{"summary":"Purchase","operationId":"purchase_api_leads_purchase_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/PurchaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leads/{entity_key}":{"get":{"summary":"Read Lead","description":"The full lead — ONLY for tenants holding a purchase row (or platform\nadmins). Everyone else gets 402 purchase_required with a quote.","operationId":"read_lead_api_leads__entity_key__get","parameters":[{"name":"entity_key","in":"path","required":true,"schema":{"type":"string","title":"Entity Key"}},{"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"}}}}}}},"/mcp":{"get":{"summary":"Mcp Get","operationId":"mcp_get_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Mcp Post","operationId":"mcp_post_mcp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/mcp/stats":{"get":{"summary":"Mcp Stats","operationId":"mcp_stats_api_mcp_stats_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"}}}}}}},"/api/org/usage":{"get":{"summary":"Usage","description":"Everything the Settings → Usage tab shows for the current tenant.","operationId":"usage_api_org_usage_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"}}}}}}},"/api/org/profile":{"patch":{"summary":"Set Profile","description":"Workspace settings: the trade profile (G6) and the service radius.\n\nPATCH semantics, deliberately: only the keys actually PRESENT in the request\nare written, so setting a radius cannot silently clear the trade profile (or\nthe reverse). An explicit null clears the field it names.\n\nThe radius is what an owner-operator actually has in their head: miles from\nthe shop, not the operator's market boundary. Once a radius AND a center are\nboth set, feed_repo drops rows whose coordinates fall outside the circle;\nrows with no coordinates are never dropped, because a permit without a\ngeocode is not evidence of distance.","operationId":"set_profile_api_org_profile_patch","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/ProfilePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/org/billing-summary":{"get":{"summary":"Billing Summary","description":"Read-side plan state from the tenant row (Stripe webhooks keep it true).","operationId":"billing_summary_api_org_billing_summary_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"}}}}}}},"/api/org/markets/catalog":{"get":{"summary":"Catalog","description":"Every market with this tenant's subscribed flags + data counts, plus the\nrunning billing summary (included / subscribed / billable-extra / price).","operationId":"catalog_api_org_markets_catalog_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"}}}}}}},"/api/org/markets/{market_id}/subscribe":{"post":{"summary":"Subscribe","description":"Subscribe the current tenant to a market and reconcile add-on billing.","operationId":"subscribe_api_org_markets__market_id__subscribe_post","parameters":[{"name":"market_id","in":"path","required":true,"schema":{"type":"string","title":"Market 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"}}}}}}},"/api/org/markets/{market_id}":{"delete":{"summary":"Unsubscribe","description":"Unsubscribe the current tenant from a market (never the last) and\nreconcile add-on billing.","operationId":"unsubscribe_api_org_markets__market_id__delete","parameters":[{"name":"market_id","in":"path","required":true,"schema":{"type":"string","title":"Market 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"}}}}}}},"/api/org/markets/request":{"post":{"summary":"Request Market","description":"Record a lead-style request for a market that isn't live yet (the\ncoming-soon \"Request this market\" action). Stored in the marketing leads\ntable when present (source = 'market_request'); always mirrored to the audit\nlog so the request is never lost.","operationId":"request_market_api_org_markets_request_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/MarketRequestBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/tenants":{"get":{"summary":"List Tenants","description":"Every tenant with its plan state + per-tenant work-product counts.","operationId":"list_tenants_api_admin_tenants_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"}}}}}}},"/api/admin/tenants/{slug}":{"get":{"summary":"Tenant Detail","description":"One tenant in depth: plan state, stage breakdown, markets, recent audit.","operationId":"tenant_detail_api_admin_tenants__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"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"}}}}}}},"/api/admin/gate":{"get":{"summary":"Gate","description":"The global 100-paid-MCP-calls gate (metering ledger stats, all tenants).","operationId":"gate_api_admin_gate_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"}}}}}}},"/api/admin/leads":{"get":{"summary":"Leads","description":"Phase J lead-store economics: inventory, sales, revenue, repeat sales\n(the near-zero-marginal-cost cache-hit revenue).","operationId":"leads_api_admin_leads_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"}}}}}}},"/api/admin/marketing-leads":{"get":{"summary":"Marketing Leads","description":"Phase K inbound marketing leads (public /api/public/lead captures).\n\nDistinct from GET /api/admin/leads (Phase J lead-store economics) — this is\nthe top-of-funnel \"request access\" contact list. Paginated, newest first.","operationId":"marketing_leads_api_admin_marketing_leads_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"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":"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"}}}}}}},"/api/admin/monitors":{"get":{"summary":"All Monitors","description":"Monitor health across EVERY market (the tenant repos only see one scope).","operationId":"all_monitors_api_admin_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"}}}}}}},"/api/admin/markets":{"get":{"summary":"All Markets","description":"Every market + how many tenants subscribe to it.","operationId":"all_markets_api_admin_markets_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"}}}}}},"post":{"summary":"Create Market","description":"Create a market and kick off source discovery for it. CA markets get the\nCA state pack + RSS watch templates as candidate sources immediately\n(discovery.kickoff — G3 adds probe/LLM discovery behind the same hook).","operationId":"create_market_api_admin_markets_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/MarketCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/tenants/{slug}/plan":{"post":{"summary":"Override Plan","description":"Manual plan override (support/ops escape hatch) — audited.\n\nStripe webhooks own subscription state in the normal flow; this writes the\nsame absolute fields directly and records who did it, under the TARGET\ntenant so the override shows up in that tenant's audit trail.","operationId":"override_plan_api_admin_tenants__slug__plan_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanOverride"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/sources":{"get":{"summary":"List Sources","description":"Source registry rows (optionally per market/status) joined with each\nsource's monitor run state, plus the review-queue counts for the badge.","operationId":"list_sources_api_admin_sources_get","parameters":[{"name":"market","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Market"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"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"}}}}}},"post":{"summary":"Create Source","description":"Manually add a source (discovered_by='human').","operationId":"create_source_api_admin_sources_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/SourceCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/sources/{source_id}":{"patch":{"summary":"Patch Source","operationId":"patch_source_api_admin_sources__source_id__patch","parameters":[{"name":"source_id","in":"path","required":true,"schema":{"type":"integer","title":"Source Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/sources/{source_id}/run":{"post":{"summary":"Run Source","description":"Force one run NOW (any status — that's how a candidate gets validated).\nReturns the run report; records last_error on the source row.","operationId":"run_source_api_admin_sources__source_id__run_post","parameters":[{"name":"source_id","in":"path","required":true,"schema":{"type":"integer","title":"Source 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"}}}}}}},"/api/admin/sources/{source_id}/validate":{"post":{"summary":"Validate Source","description":"G3 stage 4 on demand: run the mapped source against live data, score the\nautomated checks, and flip its status (>=0.75 live / 0.4-0.75 stays\ncandidate for review / <0.4 rejected). Offline it skips cleanly (status\nunchanged, last_error recorded). Runs the probe/mapping stages first if\nthe row hasn't been through them yet.","operationId":"validate_source_api_admin_sources__source_id__validate_post","parameters":[{"name":"source_id","in":"path","required":true,"schema":{"type":"integer","title":"Source 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"}}}}}}},"/api/admin/markets/{slug}/discover":{"post":{"summary":"Discover Market","description":"Run the G3 discovery kickoff for a market NOW and return the stage\nsummary (templates instantiated, catalog probes, the bounded\nprobe->map->validate pipeline, what's still queued). Idempotent — safe to\nrun repeatedly; each run advances the queue.","operationId":"discover_market_api_admin_markets__slug__discover_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"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"}}}}}}},"/api/admin/markets/{slug}":{"patch":{"summary":"Patch Market","description":"THE SWITCH: activate/pause a market. Active markets are ingested by the\nscheduler's per-market fan-out; paused markets keep their data but stop.","operationId":"patch_market_api_admin_markets__slug__patch","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health/live":{"get":{"summary":"Health Live","description":"Liveness probe: is the process up and serving HTTP? Always 200, never\ntouches the scheduler — used by the container/Caddy liveness check so a\ndead-scheduler readiness 503 never triggers a restart loop of a healthy web\nprocess.","operationId":"health_live_api_health_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/health":{"get":{"summary":"Health","description":"Readiness probe. 200 normally; 503 when monitoring is enabled and the\nscheduler has gone silent (no successful tick in 3× MONITOR_TICK_MINUTES) —\nthe silent-dead-scheduler failure mode (app up, ingestion dead). A freshly\nbooted process is healthy through the boot grace window (measured from\nprocess start) so it never 503s before its first tick.","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/{full_path}":{"get":{"summary":"Spa","operationId":"spa__full_path__get","parameters":[{"name":"full_path","in":"path","required":true,"schema":{"type":"string","title":"Full Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"BuildRequest":{"properties":{"max_stops":{"type":"integer","title":"Max Stops","default":10},"days":{"type":"integer","title":"Days","default":7},"min_priority":{"type":"integer","title":"Min Priority","default":0},"trades":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Trades"}},"type":"object","title":"BuildRequest"},"CheckoutRequest":{"properties":{"tier":{"type":"string","title":"Tier"},"interval":{"type":"string","title":"Interval","default":"month"}},"type":"object","required":["tier"],"title":"CheckoutRequest"},"CommitteeRole":{"properties":{"role":{"type":"string","title":"Role"},"why":{"type":"string","title":"Why","default":""},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"status":{"type":"string","title":"Status","default":"enrich via Apollo API"}},"type":"object","required":["role"],"title":"CommitteeRole"},"DismissRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"DismissRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LeadIn":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"company":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company"},"trade":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Trade"},"market":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Market"},"message":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Message"},"utm":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Utm"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"}},"type":"object","required":["name","email"],"title":"LeadIn"},"MarketCreate":{"properties":{"slug":{"type":"string","maxLength":40,"minLength":2,"pattern":"^[a-z0-9-]+$","title":"Slug"},"name":{"type":"string","title":"Name"},"state":{"type":"string","maxLength":2,"minLength":2,"title":"State"},"geo":{"additionalProperties":true,"type":"object","title":"Geo","default":{}},"status":{"type":"string","title":"Status","default":"paused"}},"type":"object","required":["slug","name","state"],"title":"MarketCreate"},"MarketPatch":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"MarketPatch"},"MarketRequestBody":{"properties":{"market_name":{"type":"string","maxLength":120,"minLength":1,"title":"Market Name"},"note":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Note"}},"type":"object","required":["market_name"],"title":"MarketRequestBody"},"PipedrivePushResult":{"properties":{"signal_id":{"type":"string","title":"Signal Id"},"dry_run":{"type":"boolean","title":"Dry Run"},"pushed":{"type":"boolean","title":"Pushed"},"deal_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Deal Id"},"message":{"type":"string","title":"Message"},"payload":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Payload"}},"type":"object","required":["signal_id","dry_run","pushed","message"],"title":"PipedrivePushResult"},"PlanOverride":{"properties":{"plan":{"type":"string","title":"Plan"},"plan_status":{"type":"string","title":"Plan Status"}},"type":"object","required":["plan","plan_status"],"title":"PlanOverride"},"ProfilePatch":{"properties":{"trade_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trade Profile"},"service_radius_miles":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Service Radius Miles"},"service_center_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Service Center Lat"},"service_center_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Service Center Lng"}},"type":"object","title":"ProfilePatch"},"PurchaseRequest":{"properties":{"entity_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Key"},"feed_item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feed Item Id"},"entity_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Name"},"state":{"type":"string","title":"State","default":"CA"}},"type":"object","title":"PurchaseRequest"},"QuoteRequest":{"properties":{"feed_item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feed Item Id"},"entity_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Name"},"state":{"type":"string","title":"State","default":"CA"}},"type":"object","title":"QuoteRequest"},"RoutePatch":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"RoutePatch"},"RoutePlanRequest":{"properties":{"ids":{"items":{"type":"string"},"type":"array","title":"Ids"},"use_current_location":{"type":"boolean","title":"Use Current Location","default":true}},"type":"object","required":["ids"],"title":"RoutePlanRequest"},"Signal":{"properties":{"id":{"type":"string","title":"Id"},"organization":{"type":"string","title":"Organization"},"project":{"type":"string","title":"Project"},"trigger":{"type":"string","title":"Trigger"},"vertical_fit":{"type":"string","title":"Vertical Fit"},"likely_architect":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Likely Architect"},"warm_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Warm Path"},"drafted_intro":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Drafted Intro"},"score":{"type":"integer","title":"Score","default":0},"stage":{"type":"string","title":"Stage","default":"Signal"},"phase":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phase"},"pipeline":{"type":"string","title":"Pipeline","default":"Programs"},"account":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account"},"account_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Tier"},"strike_zone":{"type":"boolean","title":"Strike Zone","default":false},"on_account":{"type":"boolean","title":"On Account","default":false},"is_shell":{"type":"boolean","title":"Is Shell","default":false},"unmasked":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Unmasked"},"crm":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Crm"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"buying_committee":{"items":{"$ref":"#/components/schemas/CommitteeRole"},"type":"array","title":"Buying Committee"},"deep_links":{"additionalProperties":true,"type":"object","title":"Deep Links"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","organization","project","trigger","vertical_fit"],"title":"Signal"},"SignalEnvelope":{"properties":{"schema_version":{"type":"string","const":"sentientos.signal.v1","title":"Schema Version"},"dedupe_key":{"type":"string","maxLength":256,"minLength":16,"title":"Dedupe Key"},"producer":{"type":"string","maxLength":100,"minLength":2,"title":"Producer"},"market_id":{"type":"string","maxLength":100,"minLength":2,"title":"Market Id"},"source_id":{"type":"string","maxLength":300,"minLength":2,"title":"Source Id"},"raw_fetch_id":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Raw Fetch Id"},"event_ts":{"type":"string","format":"date-time","title":"Event Ts"},"publish_ts":{"type":"string","format":"date-time","title":"Publish Ts"},"fetch_ts":{"type":"string","format":"date-time","title":"Fetch Ts"},"signal_type":{"type":"string","maxLength":200,"minLength":3,"title":"Signal Type"},"subject":{"$ref":"#/components/schemas/SignalSubject"},"payload":{"additionalProperties":true,"type":"object","title":"Payload"},"geo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Geo"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence"},"review_status":{"type":"string","enum":["auto","queued","human_approved","rejected"],"title":"Review Status"},"lineage":{"$ref":"#/components/schemas/SignalLineage"},"scope":{"$ref":"#/components/schemas/SignalScope"}},"additionalProperties":false,"type":"object","required":["schema_version","dedupe_key","producer","market_id","source_id","event_ts","publish_ts","fetch_ts","signal_type","subject","payload","confidence","review_status","lineage","scope"],"title":"SignalEnvelope"},"SignalLineage":{"properties":{"evidence_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Evidence Url"},"content_hash":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Content Hash"},"detector_version":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Detector Version"},"job_ref":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Job Ref"}},"additionalProperties":false,"type":"object","title":"SignalLineage"},"SignalScope":{"properties":{"visibility":{"type":"string","enum":["public","portfolio","internal","restricted"],"title":"Visibility"},"data_rung":{"type":"integer","enum":[1,2,3,4],"title":"Data Rung"},"customer_scope":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Customer Scope"}},"additionalProperties":false,"type":"object","required":["visibility","data_rung"],"title":"SignalScope"},"SignalSubject":{"properties":{"key":{"type":"string","maxLength":300,"minLength":3,"title":"Key"},"type":{"type":"string","const":"organization","title":"Type"},"name":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Name"},"identifiers":{"additionalProperties":{"type":"string"},"type":"object","title":"Identifiers"}},"additionalProperties":false,"type":"object","required":["key","type"],"title":"SignalSubject"},"SourceCreate":{"properties":{"market_id":{"type":"string","title":"Market Id"},"bare_key":{"type":"string","maxLength":80,"minLength":1,"title":"Bare Key"},"name":{"type":"string","title":"Name"},"category":{"type":"string","title":"Category"},"platform":{"type":"string","title":"Platform"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"endpoint_url":{"type":"string","title":"Endpoint Url","default":""},"params":{"additionalProperties":true,"type":"object","title":"Params","default":{}},"field_map":{"additionalProperties":true,"type":"object","title":"Field Map","default":{}},"cadence_minutes":{"type":"integer","title":"Cadence Minutes","default":360},"confidence":{"type":"number","title":"Confidence","default":0.5},"status":{"type":"string","title":"Status","default":"candidate"}},"type":"object","required":["market_id","bare_key","name","category","platform"],"title":"SourceCreate"},"SourcePatch":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"endpoint_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint Url"},"params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Params"},"field_map":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Field Map"},"cadence_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cadence Minutes"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},"type":"object","title":"SourcePatch","description":"The review-queue approve/reject/edit surface — all fields optional."},"StageUpdate":{"properties":{"stage":{"type":"string","title":"Stage"}},"type":"object","required":["stage"],"title":"StageUpdate"},"StopPatch":{"properties":{"status":{"type":"string","title":"Status"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["status"],"title":"StopPatch"},"TextSent":{"properties":{"body":{"type":"string","title":"Body"}},"type":"object","required":["body"],"title":"TextSent"},"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"}}}}