{"openapi":"3.1.0","info":{"title":"WYRM Sentinel API","description":"Agentic procurement intelligence — sanctions screening, CO₂ + CBAM, FX, route risk, supplier discovery, and the Jormungandr decision engine. See https://wyrm.ai/docs/api for authentication, quickstart, and rate limits.","contact":{"name":"WYRM Sentinel","url":"https://wyrm.ai/docs/api","email":"support@wyrm.ai"},"license":{"name":"Proprietary — see https://wyrm.ai/terms"},"version":"1.0.0"},"servers":[{"url":"https://api.wyrm.ai","description":"Production"}],"paths":{"/feeds":{"get":{"tags":["feeds"],"summary":"List Feeds","description":"List all registered feeds with their current health status.","operationId":"list_feeds_feeds_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/FeedHealth"},"type":"array","title":"Response List Feeds Feeds Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/feeds/stats":{"get":{"tags":["feeds"],"summary":"Feed Stats","description":"Aggregate statistics across all feeds.","operationId":"feed_stats_feeds_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/feeds/{name}":{"get":{"tags":["feeds"],"summary":"Get Feed","description":"Get health status for a specific feed.","operationId":"get_feed_feeds__name__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9_]{1,50}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedHealth"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feeds/{name}/latest":{"get":{"tags":["feeds"],"summary":"Get Feed Latest","description":"Get the latest events from a specific feed.\n\nRequires authentication. Queries events table filtered by feed name.","operationId":"get_feed_latest_feeds__name__latest_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9_]{1,50}$","title":"Name"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Feed Latest Feeds  Name  Latest Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feeds/{name}/trigger":{"post":{"tags":["feeds"],"summary":"Trigger Feed","description":"Manually trigger a feed collection cycle.\n\nRequires authentication. Only available in development mode.","operationId":"trigger_feed_feeds__name__trigger_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9_]{1,50}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Trigger Feed Feeds  Name  Trigger Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/feeds/health":{"get":{"tags":["feeds"],"summary":"Feed Health Map","description":"Return a name→status map for every registered feed.\n\nA feed is \"live\" when its last fetch completed within 2× its configured\npoll interval AND its status is OK. Any other state reports \"down\".\nNever-fetched or unknown feeds report \"unknown\".","operationId":"feed_health_map_v1_feeds_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Feed Health Map V1 Feeds Health Get"}}}}}}},"/v1/alerts":{"get":{"tags":["alerts"],"summary":"List Alerts","description":"List alerts with optional filters.","operationId":"list_alerts_v1_alerts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity"}},{"name":"agent","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent"}},{"name":"delta_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delta Type"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Since"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/alerts/{alert_id}":{"get":{"tags":["alerts"],"summary":"Get Alert","description":"Get a single alert with full details (own alerts + system alerts only).","operationId":"get_alert_v1_alerts__alert_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/alerts/{alert_id}/thread":{"get":{"tags":["alerts"],"summary":"Get Alert Thread","description":"Get an alert thread (parent + children).","operationId":"get_alert_thread_v1_alerts__alert_id__thread_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/watchlists":{"get":{"tags":["watchlists"],"summary":"List Watchlists","operationId":"list_watchlists_v1_watchlists_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["watchlists"],"summary":"Create Watchlist","operationId":"create_watchlist_v1_watchlists_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/watchlists/{watchlist_id}":{"get":{"tags":["watchlists"],"summary":"Get Watchlist","operationId":"get_watchlist_v1_watchlists__watchlist_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["watchlists"],"summary":"Delete Watchlist","operationId":"delete_watchlist_v1_watchlists__watchlist_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/watchlists/{watchlist_id}/items":{"post":{"tags":["watchlists"],"summary":"Add Item","operationId":"add_item_v1_watchlists__watchlist_id__items_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistItemCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/watchlists/{watchlist_id}/items/{item_id}":{"delete":{"tags":["watchlists"],"summary":"Remove Item","operationId":"remove_item_v1_watchlists__watchlist_id__items__item_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}},{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/zones":{"get":{"tags":["zones"],"summary":"List Zones","operationId":"list_zones_v1_zones_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["zones"],"summary":"Create Zone","operationId":"create_zone_v1_zones_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZoneCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/zones/{zone_id}":{"delete":{"tags":["zones"],"summary":"Delete Zone","operationId":"delete_zone_v1_zones__zone_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","title":"Zone Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/digests":{"get":{"tags":["digests"],"summary":"List Digests","operationId":"list_digests_v1_digests_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"digest_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Digest Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/digests/latest":{"get":{"tags":["digests"],"summary":"Get Latest Digest","operationId":"get_latest_digest_v1_digests_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/digests/{digest_id}":{"get":{"tags":["digests"],"summary":"Get Digest","operationId":"get_digest_v1_digests__digest_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"digest_id","in":"path","required":true,"schema":{"type":"string","title":"Digest Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/situational-analysis/run":{"post":{"tags":["situational-analysis"],"summary":"Launch Situational Analysis","description":"Launch a situational-analysis simulation. Runs in background,\nreturns an ID for polling. Pro+ only.","operationId":"launch_situational_analysis_v1_situational_analysis_run_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SituationalAnalysisCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/situational-analysis":{"get":{"tags":["situational-analysis"],"summary":"List Situational Analyses","operationId":"list_situational_analyses_v1_situational_analysis_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/situational-analysis/{run_id}":{"get":{"tags":["situational-analysis"],"summary":"Get Situational Analysis","operationId":"get_situational_analysis_v1_situational_analysis__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tm65/report":{"post":{"tags":["tm65"],"summary":"Generate Report","description":"Compute a TM65 Level 2 embodied-carbon report for a bill of materials.\n\nInput size is capped at 500 BOM items / 20 materials per item (enforced\nby the Pydantic schema). Calculation is synchronous and O(items); for\nlarge enterprise BOMs this still completes in well under a second.","operationId":"generate_report_v1_tm65_report_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tm65Request"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tm65Report"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/tm65/reports":{"get":{"tags":["tm65"],"summary":"List Reports","operationId":"list_reports_v1_tm65_reports_get","security":[{"HTTPBearer":[]}],"parameters":[{"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":{"type":"object","additionalProperties":true,"title":"Response List Reports V1 Tm65 Reports Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tm65/reports/{report_id}":{"get":{"tags":["tm65"],"summary":"Get Report","operationId":"get_report_v1_tm65_reports__report_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Report Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tm65Report"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/delivery/preferences":{"get":{"tags":["delivery"],"summary":"Get Preferences","operationId":"get_preferences_v1_delivery_preferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["delivery"],"summary":"Upsert Preference","description":"Create or update a delivery preference for a channel.","operationId":"upsert_preference_v1_delivery_preferences_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryPreferenceUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/delivery/history":{"get":{"tags":["delivery"],"summary":"Delivery History","description":"Recent delivery log for this user.","operationId":"delivery_history_v1_delivery_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/account":{"get":{"tags":["account"],"summary":"Get Profile","description":"Fetch the caller's profile row, creating it on-the-fly if missing.\n\nAccounts that predate the auto-insert trigger (migration 001) can end up\nwithout a profiles row. `.single()` raises PGRST116 in that case which\nsurfaces as an opaque 500 — so we use the anon-safe fallback of\nselecting into a list and upserting via the service-role client if\nempty.","operationId":"get_profile_v1_account_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["account"],"summary":"Update Profile","description":"Update (or insert) the caller's buyer-context fields.\n\nUses upsert so accounts missing a profiles row still save — the first\nsave becomes the row-creation. Only non-null fields are written.","operationId":"update_profile_v1_account_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/account/admin/set-tier":{"post":{"tags":["account"],"summary":"Admin Set Tier","description":"Self-switch the caller's tier. Gated by the ADMIN_EMAILS allow-list.\n\nExists so we (the WYRM team) can test tier-gated behaviour without\nediting the Supabase row by hand each time. Never hit by a real\ncustomer — unlisted emails get a 403. Also opportunistically syncs\nthe ``subscriptions`` row so the Settings UI doesn't look\nhalf-upgraded (Pro badge on profile, Free renewal info in the\nsubscription card).","operationId":"admin_set_tier_v1_account_admin_set_tier_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTierUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/account/api-keys":{"get":{"tags":["account"],"summary":"List Api Keys","operationId":"list_api_keys_v1_account_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["account"],"summary":"Create Api Key","description":"Generate a new API key. Returns the raw key ONCE — store it securely.\n\nREST API access is a Pro+ feature; this endpoint enforces that\nserver-side as a defence-in-depth layer alongside the dashboard\nUI gate.","operationId":"create_api_key_v1_account_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/account/api-keys/{key_id}":{"delete":{"tags":["account"],"summary":"Revoke Api Key","description":"Revoke an API key (soft delete — sets is_active=false).","operationId":"revoke_api_key_v1_account_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/account/subscription":{"get":{"tags":["account"],"summary":"Get Subscription","description":"Return the caller's active Lemon Squeezy subscription, or null.\n\nReads public.subscriptions (webhook-populated). Prefers the most\nrecently created active subscription; falls back to the latest row\nregardless of status so cancelled/past_due users can still see their\nsubscription state and renew/update billing.\n\nThe customer_portal_url is the generic Lemon Squeezy billing portal\nwhere customers authenticate with the email on file. Per-customer\nsigned portal sessions are a future polish — out of scope for M2.","operationId":"get_subscription_v1_account_subscription_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/webhooks/lemonsqueezy":{"post":{"tags":["webhooks"],"summary":"Lemonsqueezy Webhook","description":"Handle LemonSqueezy subscription events.\n\nEvents we care about:\n- subscription_created: new paying customer\n- subscription_updated: plan change (upgrade/downgrade)\n- subscription_cancelled: churned\n- subscription_resumed: reactivated\n- subscription_payment_success: renewal\n- subscription_payment_failed: payment issue\n\nReplay protection: each (event_name, subscription_id) pair is recorded\nin Redis for 7 days; duplicates are acknowledged without re-executing.","operationId":"lemonsqueezy_webhook_webhooks_lemonsqueezy_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/resend/inbound":{"post":{"tags":["webhooks"],"summary":"Resend Inbound Webhook","description":"Receive an inbound email from Resend's Inbound-Email feature.\n\nFlow:\n1. Supplier hits Reply on an RFQ email → routes to ``rfq+<uuid>@wyrm.ai``.\n2. Resend Inbound POSTs metadata JSON here with Svix signature + timestamp.\n3. We verify signature + timestamp skew, extract the plus-address RFQ id,\n   validate the sender matches the RFQ's supplier email, fetch the body\n   from Resend's receiving API (webhook payload is metadata-only), run\n   Haiku on the plain text, persist into ``rfq_messages``.\n4. Dedup fires AFTER the persist succeeds so a transient failure\n   doesn't permanently drop a retry.\n5. Only then transition the RFQ status.","operationId":"resend_inbound_webhook_webhooks_resend_inbound_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/freightos/tracking":{"post":{"tags":["webhooks"],"summary":"Freightos Tracking Webhook","description":"Ingest a Freightos tracking event.\n\nFlow:\n  1. Verify HMAC signature against ``settings.freightos_webhook_secret``\n  2. Dedup by ``(booking_id, event_code, occurred_at)`` so replays are idempotent\n  3. Parse the payload → ``TrackingEvent``\n  4. Look up the ``shipments`` row via ``freightos_booking_id``\n  5. Append event + update status + stamp pickup/delivery timestamps\n  6. On notifiable terminal events, send a buyer email via Resend\n\nAlways ACKs 200 if the signature is valid, even when our downstream\nprocessing fails — we want Freightos to stop retrying after they've\ndelivered the event. Failures are logged + tracked in the shipments\nrow's ``events`` JSONB array for ops to reconcile.","operationId":"freightos_tracking_webhook_webhooks_freightos_tracking_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/enterprise-enquiry":{"post":{"tags":["enterprise"],"summary":"Submit Enterprise Enquiry","operationId":"submit_enterprise_enquiry_api_enterprise_enquiry_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnterpriseEnquiryRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/welcome":{"post":{"tags":["auth-events"],"summary":"Send Welcome","description":"Fire the welcome email. Idempotent per-user.\n\nReturns ``{\"sent\": bool, \"already_welcomed\": bool}`` so the dashboard\ncan decide whether to show a toast — no-op paths return\n``{\"sent\": False, \"already_welcomed\": True}``.","operationId":"send_welcome_v1_auth_welcome_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Send Welcome V1 Auth Welcome Post"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/rfqs":{"post":{"tags":["rfqs"],"summary":"Create Rfq","description":"Persist the RFQ and dispatch an email to the supplier.\n\nThe email send is awaited so the caller sees delivery success/failure\nin the response. On Resend failure the row still exists in ``draft``\nstate so the buyer can retry without losing the captured details.","operationId":"create_rfq_v1_rfqs_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfqCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Rfq V1 Rfqs Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["rfqs"],"summary":"List Rfqs","description":"List the caller's RFQs, newest first.","operationId":"list_rfqs_v1_rfqs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Rfqs V1 Rfqs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}":{"get":{"tags":["rfqs"],"summary":"Get Rfq","operationId":"get_rfq_v1_rfqs__rfq_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Rfq V1 Rfqs  Rfq Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/status":{"patch":{"tags":["rfqs"],"summary":"Update Status","description":"Advance the RFQ lifecycle.\n\nWe enforce a very loose state machine — the buyer is authoritative on\nwhether a supplier has responded, so over-constraining would just get\nin the way. But we do block nonsense like moving ``accepted`` → ``sent``.","operationId":"update_status_v1_rfqs__rfq_id__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfqStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Status V1 Rfqs  Rfq Id  Status Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/auto-negotiate":{"patch":{"tags":["rfqs"],"summary":"Toggle Auto Negotiate","description":"Kill-switch: pause/resume auto-negotiation on an in-flight RFQ.\n\nFlipping ``enabled=false`` does NOT immediately stop anything in flight\n— we don't have a pending-dispatch queue — but the next inbound reply\nfrom the supplier will fall through to manual escalation instead of\nauto-countering. ``enabled=true`` resumes on the following reply.\n\nOwnership check is RLS-enforced via the user_id eq filter.","operationId":"toggle_auto_negotiate_v1_rfqs__rfq_id__auto_negotiate_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoNegotiateToggle"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Toggle Auto Negotiate V1 Rfqs  Rfq Id  Auto Negotiate Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/messages":{"get":{"tags":["rfqs"],"summary":"List Rfq Messages","description":"Return the chronological thread (outbound + inbound) for one RFQ.","operationId":"list_rfq_messages_v1_rfqs__rfq_id__messages_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/counter-draft":{"post":{"tags":["rfqs"],"summary":"Counter Draft","description":"Generate a counter-offer reply draft using Claude Haiku.\n\nReads the full thread, the RFQ context, and any steering the\nbuyer supplied, and returns ``{subject, body_plain}`` ready to\nedit and send. Does NOT send — the buyer reviews + clicks Send\nwhich hits ``/counter-send``.","operationId":"counter_draft_v1_rfqs__rfq_id__counter_draft_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CounterDraftBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/counter-send":{"post":{"tags":["rfqs"],"summary":"Counter Send","description":"Send the buyer-approved counter-offer to the supplier.\n\nUses the same reply-to so further replies continue threading into\nthis RFQ. Records an outbound ``rfq_messages`` row with an\nincremented ``round_number``.","operationId":"counter_send_v1_rfqs__rfq_id__counter_send_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CounterSendBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/accept-preview":{"get":{"tags":["rfqs"],"summary":"Accept Preview","description":"Return the context the AcceptQuoteModal needs: supplier quote,\nbuyer target, computed spread, and the PO reference we'd issue.\n\nNo side effects — safe to call whenever the modal opens.","operationId":"accept_preview_v1_rfqs__rfq_id__accept_preview_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Accept Preview V1 Rfqs  Rfq Id  Accept Preview Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/accept":{"post":{"tags":["rfqs"],"summary":"Accept Rfq","description":"Dispatch an acceptance email to the supplier and transition the RFQ.\n\nUntil the full auto-negotiation loop lands, this is the buyer's\nexplicit \"lock it in\" action. We:\n  1. confirm the caller is the buyer and the RFQ is in an\n     acceptable state (sent / responded / quoted),\n  2. pick the latest parsed quote as the source of truth (or use\n     an explicit override_* if the buyer wants to accept at a\n     different figure),\n  3. issue a WYRM-PO-XXXXXXXX reference,\n  4. render + send the acceptance email via Resend,\n  5. persist the outbound row in ``rfq_messages`` so the thread\n     reflects the confirmation,\n  6. update supplier_rfqs: status = 'accepted', accepted_at = now,\n  7. log the arbitrage delta (buyer target total vs supplier total).\n\nAccept also closes out the ``arbitrage_ledger`` row for this RFQ\n(buyer target vs supplier final vs WYRM fee) so revenue capture\nis auditable long after the RFQ's status has moved on.","operationId":"accept_rfq_v1_rfqs__rfq_id__accept_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfqAcceptBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Accept Rfq V1 Rfqs  Rfq Id  Accept Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/cost-stack":{"get":{"tags":["rfqs"],"summary":"Get Cost Stack","description":"Return the landed-cost breakdown for this RFQ.\n\nUses the latest parsed supplier quote when one exists; otherwise\nfalls back to the buyer's ``target_price_usd`` so the estimate\nstill surfaces before the first supplier reply. Layers we can't\ncompute yet (missing HS code, non-GB destination, etc.) return\n``pending=true`` so the UI can render placeholders consistently.","operationId":"get_cost_stack_v1_rfqs__rfq_id__cost_stack_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Cost Stack V1 Rfqs  Rfq Id  Cost Stack Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rfqs/{rfq_id}/fx-strategy":{"get":{"tags":["rfqs"],"summary":"Get Fx Strategy","description":"Return an FX impact summary + strategy recommendation.\n\nBuilds on the cost-stack output: we need ``landed_usd`` and the\n``fx_spread`` layer to size the exposure. Rule engine classifies\nthe position (pay spot / compare providers / forward hedge) and\nHaiku rewrites the copy. No Anthropic key = deterministic fallback.","operationId":"get_fx_strategy_v1_rfqs__rfq_id__fx_strategy_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Fx Strategy V1 Rfqs  Rfq Id  Fx Strategy Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/shipping/quote":{"post":{"tags":["shipping"],"summary":"Quote Shipping","description":"Return a list of bookable door-to-door options.\n\nEach option includes the buyer-facing retail total (wholesale +\nplatform markup) plus transit, forwarder/carrier labels, and a\n``quote_id`` the buyer can feed to ``/book-shipment``.","operationId":"quote_shipping_v1_shipping_quote_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShippingQuoteRequestBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Quote Shipping V1 Shipping Quote Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/rfqs/{rfq_id}/book-shipment":{"post":{"tags":["shipping"],"summary":"Book Shipment","description":"Commit a quote_id to a real booking and persist a shipments row.\n\nPayment handoff:\n  - free / starter / pro → payment_mode='upfront', caller must\n    complete Stripe/LemonSqueezy checkout before Freightos actually\n    dispatches (we return the checkout URL; shipment stays in\n    ``accepted`` + ``payment_status='pending'`` until webhook flips it)\n  - enterprise → may be invoiced NET-30 case-by-case (flag passed\n    from settings; default is still upfront)","operationId":"book_shipment_v1_rfqs__rfq_id__book_shipment_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rfq_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rfq Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookShipmentBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Book Shipment V1 Rfqs  Rfq Id  Book Shipment Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/supply-root/disambiguate":{"post":{"tags":["supply-root"],"summary":"Disambiguate","description":"Score ``body.query`` and, when ambiguous, return clarifying Qs.","operationId":"disambiguate_v1_supply_root_disambiguate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisambiguateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisambiguateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/supply-root/suppliers":{"get":{"tags":["supply-root"],"summary":"List Directory Suppliers","description":"Supply-Root supplier directory.\n\nPublic-read listing of vetted + seed suppliers. Filters compose:\ncountry AND sector AND hs_chapter AND (text-match on name /\nkeywords / sectors). Feeds the dashboard's directory page and\nthe upcoming MCP supplier-search tool.","operationId":"list_directory_suppliers_v1_supply_root_suppliers_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Q"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":2},{"type":"null"}],"title":"Country"}},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Sector"}},{"name":"hs_chapter","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":99,"minimum":0},{"type":"null"}],"title":"Hs Chapter"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stream/alerts":{"get":{"tags":["stream"],"summary":"Stream Alerts","description":"SSE endpoint for real-time alert streaming.\n\nConnect with EventSource:\n```js\nconst es = new EventSource('/v1/stream/alerts', {\n  headers: { 'Authorization': 'Bearer ...' }\n});\nes.onmessage = (e) => console.log(JSON.parse(e.data));\n```","operationId":"stream_alerts_v1_stream_alerts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/events/geojson":{"get":{"tags":["events"],"summary":"Events Geojson","description":"Return recent events as GeoJSON FeatureCollection for map rendering.\n\nUses a PostGIS function to properly extract coordinates from geography\ncolumns. The RPC is SECURITY DEFINER — the anon role needs EXECUTE\ngranted explicitly (see migration 012). If the call fails we log the\nerror (no longer silently swallowed) so regressions surface.","operationId":"events_geojson_v1_events_geojson_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"default":500,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/events/newsworthy":{"get":{"tags":["events"],"summary":"Newsworthy Events","description":"Return only newsworthy events (geopolitical, seismic, weather, etc.) for the ticker.","operationId":"newsworthy_events_v1_events_newsworthy_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/events/entities/geojson":{"get":{"tags":["events"],"summary":"Entities Geojson","description":"Return tracked entities as GeoJSON via PostGIS function.\n\nAccepts either ``type`` (used by the dashboard frontend) or\n``entity_type`` (legacy name kept for backward compatibility). When both\nare supplied ``type`` wins. Without either, all entity types are\nreturned — this is why vessels were leaking through on the OSINT Map\nwhen the caller passed ``type=satellite``: the backend only looked at\n``entity_type`` and silently ignored the filter, returning everything.","operationId":"entities_geojson_v1_events_entities_geojson_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},{"name":"entity_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"default":500,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/events/track/{entity_id}":{"get":{"tags":["events"],"summary":"Entity Track","description":"Return an entity's position history as a GeoJSON LineString for route display.","operationId":"entity_track_v1_events_track__entity_id__get","parameters":[{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/events/satellites/positions":{"get":{"tags":["events"],"summary":"Satellite Positions","description":"Compute real-time satellite positions using SGP4 propagation.\n\nReturns GeoJSON with lat/lon/altitude computed from TLE orbital elements.","operationId":"satellite_positions_v1_events_satellites_positions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"default":500,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rules":{"get":{"tags":["rules"],"summary":"List Rules","description":"List user's monitoring rules.","operationId":"list_rules_v1_rules_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["rules"],"summary":"Create Rule","description":"Create a monitoring rule from natural language.\n\nParses the description into a structured filter using keyword matching.\nEnterprise users get LLM-powered parsing for complex rules.","operationId":"create_rule_v1_rules_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/analysis/crowd-estimate":{"post":{"tags":["analysis"],"summary":"Crowd Estimate","description":"Estimate crowd size using Jacobs Method.","operationId":"crowd_estimate_v1_analysis_crowd_estimate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrowdEstimateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/analysis/sun-position":{"post":{"tags":["analysis"],"summary":"Sun Position","description":"Calculate sun position for a given location and time.","operationId":"sun_position_v1_analysis_sun_position_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SunPositionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/analysis/shadow-verify":{"post":{"tags":["analysis"],"summary":"Shadow Verify","description":"Verify shadow consistency in an image against claimed location and time.","operationId":"shadow_verify_v1_analysis_shadow_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShadowVerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/markets":{"get":{"tags":["markets"],"summary":"Get Market Data","description":"Get all market data (indexes + commodities). Cached for 5 min.","operationId":"get_market_data_v1_markets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/markets/chart/{symbol}":{"get":{"tags":["markets"],"summary":"Get Chart Data","description":"Get historical OHLCV chart data for a symbol via Alpha Vantage.\n\nReturns date, open, high, low, close, and volume for each data point.\nRequires ALPHA_VANTAGE_API_KEY in config.","operationId":"get_chart_data_v1_markets_chart__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"interval","in":"query","required":false,"schema":{"type":"string","description":"Chart interval: daily, weekly, or monthly","default":"daily","title":"Interval"},"description":"Chart interval: daily, weekly, or monthly"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max data points","default":100,"title":"Limit"},"description":"Max data points"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/markets/crypto":{"get":{"tags":["markets"],"summary":"Get Crypto Markets","description":"Get top 20 cryptocurrencies by market cap from CoinGecko.\n\nReturns name, symbol, price, 24h change, market cap, volume, and sparkline.\nCached for 5 minutes to respect CoinGecko free tier rate limits.","operationId":"get_crypto_markets_v1_markets_crypto_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/markets/crypto/{coin_id}":{"get":{"tags":["markets"],"summary":"Get Crypto Detail","description":"Get detailed data for a single cryptocurrency by CoinGecko ID.\n\nReturns extended info: description, links, market data, developer stats.","operationId":"get_crypto_detail_v1_markets_crypto__coin_id__get","parameters":[{"name":"coin_id","in":"path","required":true,"schema":{"type":"string","title":"Coin Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/news":{"get":{"tags":["news"],"summary":"Get News","description":"Get latest news headlines. Uses NewsAPI if key configured, falls back to RSS feeds.\n\nQuery params:\n- category: business, entertainment, general, health, science, sports, technology\n- country: 2-letter country code (default: us)\n- q: free-text search query\n- limit: max items to return (default: 20, max: 50)","operationId":"get_news_v1_news_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"default":20,"title":"Limit"}},{"name":"category","in":"query","required":false,"schema":{"type":"string","description":"NewsAPI category","default":"general","title":"Category"},"description":"NewsAPI category"},{"name":"country","in":"query","required":false,"schema":{"type":"string","maxLength":2,"description":"2-letter country code","default":"us","title":"Country"},"description":"2-letter country code"},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Search query","default":"","title":"Q"},"description":"Search query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/news/panel/feed":{"get":{"tags":["news-panel"],"summary":"News Feed","description":"Return a news feed for a category, with a Claude summary at the top.","operationId":"news_feed_v1_news_panel_feed_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"type":"string","default":"global","title":"Category"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response News Feed V1 News Panel Feed Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inventory":{"get":{"tags":["inventory"],"summary":"List Items","operationId":"list_items_v1_inventory_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InventoryItem"},"type":"array","title":"Response List Items V1 Inventory Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["inventory"],"summary":"Create Item","operationId":"create_item_v1_inventory_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/inventory/{item_id}":{"patch":{"tags":["inventory"],"summary":"Update Item","operationId":"update_item_v1_inventory__item_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["inventory"],"summary":"Delete Item","operationId":"delete_item_v1_inventory__item_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inventory/{item_id}/signals":{"get":{"tags":["inventory"],"summary":"List Signals","operationId":"list_signals_v1_inventory__item_id__signals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inventory/{item_id}/mark-read":{"post":{"tags":["inventory"],"summary":"Mark Signals Read","operationId":"mark_signals_read_v1_inventory__item_id__mark_read_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inventory/{item_id}/bulk-quote":{"post":{"tags":["inventory"],"summary":"Bulk Quote","operationId":"bulk_quote_v1_inventory__item_id__bulk_quote_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Item Id"}},{"name":"requested_qty","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Requested Qty"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDiscountQuote"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/opportunities":{"get":{"tags":["opportunities"],"summary":"List Opportunities","operationId":"list_opportunities_v1_opportunities_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO-2 buyer country","title":"Country"},"description":"ISO-2 buyer country"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"default":"open","title":"Status"}},{"name":"min_value_gbp","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"title":"Min Value Gbp"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Opportunity"},"title":"Response List Opportunities V1 Opportunities Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/opportunities/{opportunity_id}":{"get":{"tags":["opportunities"],"summary":"Get Opportunity","operationId":"get_opportunity_v1_opportunities__opportunity_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Opportunity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Opportunity"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/opportunities/{opportunity_id}/analyze":{"post":{"tags":["opportunities"],"summary":"Force Analyze","operationId":"force_analyze_v1_opportunities__opportunity_id__analyze_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Opportunity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityAnalysis"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/opportunities/collect":{"post":{"tags":["opportunities"],"summary":"Run Collectors","description":"Triggered by the scheduler or admin; ingests new opportunities.","operationId":"run_collectors_v1_opportunities_collect_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only run this collector","title":"Source"},"description":"Only run this collector"},{"name":"lookback_hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Lookback Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Run Collectors V1 Opportunities Collect Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/integrations/outlook/connect":{"get":{"tags":["integrations-outlook"],"summary":"Connect","operationId":"connect_v1_integrations_outlook_connect_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Connect V1 Integrations Outlook Connect Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/integrations/outlook/callback":{"get":{"tags":["integrations-outlook"],"summary":"Callback","operationId":"callback_v1_integrations_outlook_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/integrations/outlook/status":{"get":{"tags":["integrations-outlook"],"summary":"Status","operationId":"status_v1_integrations_outlook_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Status V1 Integrations Outlook Status Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/integrations/outlook/disconnect":{"delete":{"tags":["integrations-outlook"],"summary":"Disconnect","operationId":"disconnect_v1_integrations_outlook_disconnect_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Disconnect V1 Integrations Outlook Disconnect Delete"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/integrations/outlook/calendar/events":{"post":{"tags":["integrations-outlook"],"summary":"Create Calendar Event","operationId":"create_calendar_event_v1_integrations_outlook_calendar_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarEventCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Calendar Event V1 Integrations Outlook Calendar Events Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/integrations/outlook/mail/send":{"post":{"tags":["integrations-outlook"],"summary":"Send Mail","operationId":"send_mail_v1_integrations_outlook_mail_send_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailSend"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Send Mail V1 Integrations Outlook Mail Send Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cyber/scan":{"post":{"tags":["cyber"],"summary":"Attack Surface Scan","description":"Run an attack surface scan on a domain. Returns DNS, SSL, headers, subdomains.\n\nAuthenticated — this performs active recon against an arbitrary\ndomain (DNS / subdomain enumeration / header probe) and must not be\nexposed as a free OSINT tool.","operationId":"attack_surface_scan_v1_cyber_scan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cyber/ip/{ip_address}":{"get":{"tags":["cyber"],"summary":"Ip Lookup","description":"Lookup IP geolocation, ASN, and reputation (includes AbuseIPDB if key configured).","operationId":"ip_lookup_v1_cyber_ip__ip_address__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ip_address","in":"path","required":true,"schema":{"type":"string","title":"Ip Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/ip/{ip_address}/reputation":{"get":{"tags":["cyber"],"summary":"Ip Reputation","description":"Dedicated AbuseIPDB reputation endpoint for an IP address.\n\nReturns abuse confidence score (0-100), total reports, country, ISP,\nusage type, and domain. Requires ABUSEIPDB_API_KEY in config.","operationId":"ip_reputation_v1_cyber_ip__ip_address__reputation_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ip_address","in":"path","required":true,"schema":{"type":"string","title":"Ip Address"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/username/{username}":{"get":{"tags":["cyber"],"summary":"Username Search","description":"Search for a username across 300+ platforms (social, dating, gaming, tech, etc.).","operationId":"username_search_v1_cyber_username__username__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/cve/search":{"get":{"tags":["cyber"],"summary":"Cve Keyword Search","description":"Search CVEs by keyword using the NVD API.","operationId":"cve_keyword_search_v1_cyber_cve_search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"keyword","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200,"title":"Keyword"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/cve/{cve_id}":{"get":{"tags":["cyber"],"summary":"Cve Lookup","description":"Lookup a specific CVE by ID from the NVD database.","operationId":"cve_lookup_v1_cyber_cve__cve_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"cve_id","in":"path","required":true,"schema":{"type":"string","title":"Cve Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/email/{email}":{"get":{"tags":["cyber"],"summary":"Email Breach Check","description":"Check if an email appears in known data breaches.\n\nQueries both XposedOrNot (free, no key) and Mozilla Monitor (free, no key)\nin parallel, then deduplicates by breach name.","operationId":"email_breach_check_v1_cyber_email__email__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/threats/summary":{"get":{"tags":["cyber"],"summary":"Threat Feed Summary","description":"Aggregate threat intelligence summary from ingested feeds.\n\nReturns counts and recent entries from CISA KEV, Feodo C2 servers,\nand URLhaus malware URLs stored in the Supabase events table.","operationId":"threat_feed_summary_v1_cyber_threats_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cyber/scan/url":{"post":{"tags":["cyber"],"summary":"Scan Url Virustotal","description":"Submit a URL to VirusTotal for malware/phishing scanning.\n\nTwo-step process:\n1. Submit URL for analysis\n2. Poll for results (up to 30s)\n\nRequires VIRUSTOTAL_API_KEY in config.","operationId":"scan_url_virustotal_v1_cyber_scan_url_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cyber/phone/{number}":{"get":{"tags":["cyber"],"summary":"Phone Lookup","description":"Lookup phone number information using Numverify API.\n\nReturns validity, country, location, carrier, and line type.\nRequires NUMVERIFY_API_KEY in config.","operationId":"phone_lookup_v1_cyber_phone__number__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string","title":"Number"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/email/{email}/platforms":{"get":{"tags":["cyber"],"summary":"Email Platform Enumeration","description":"Check if an email is registered on common platforms by probing\npassword reset / signup validation endpoints (Holehe-style).\n\nTests platforms concurrently with a 3-second timeout per probe.\nReturns platform name, registration status, and profile URL if available.","operationId":"email_platform_enumeration_v1_cyber_email__email__platforms_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/network/scan":{"post":{"tags":["cyber"],"summary":"Network Scan","description":"Enhanced network scan with service detection, banner grabbing, and vulnerability matching.\n\nFor each port:\n1. TCP connection check (open/closed/filtered)\n2. Banner grabbing — sends probe bytes and reads service response\n3. Service version extraction from banners\n4. For web ports (80, 443, 8080, 8443): HTTP header analysis (server version, security headers)\n5. CVE lookup via NVD API for detected service versions\n\nRate limited to 2 requests per minute due to resource intensity.","operationId":"network_scan_v1_cyber_network_scan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cyber/recon":{"post":{"tags":["cyber"],"summary":"Spiderfoot Recon","description":"Automated reconnaissance against a domain, email, or IP address.\n\nAuto-detects target type and runs appropriate OSINT checks:\n- Domain: DNS, WHOIS, SSL cert, subdomains (crt.sh), tech detection,\n  robots.txt, security.txt\n- Email: Gravatar, breach check, platform enumeration\n- IP: Geolocation, reverse DNS, open ports, WHOIS\n\nReturns a comprehensive report object.","operationId":"spiderfoot_recon_v1_cyber_recon_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReconRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cyber/wayback/{domain}":{"get":{"tags":["cyber"],"summary":"Wayback Machine","description":"Query the Wayback Machine for archived snapshots of a domain.\n\nReturns up to 50 snapshots with timestamps, URLs, status codes,\nand content types, plus overall availability information.","operationId":"wayback_machine_v1_cyber_wayback__domain__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/darkweb":{"get":{"tags":["cyber"],"summary":"Dark Web Search","description":"Search dark web content via Ahmia (clearnet gateway to Tor hidden services).\n\nQueries Ahmia's search index for .onion sites matching the query.\nResults are from Tor hidden services. For research purposes only.\n\n**Disclaimer**: Results are sourced from Tor hidden services indexed by\nAhmia.fi. This tool is provided for legitimate OSINT research only.\nWYRM Sentinel does not host, cache, or proxy any dark web content.","operationId":"dark_web_search_v1_cyber_darkweb_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200,"description":"Search query for dark web content","title":"Q"},"description":"Search query for dark web content"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cyber/dork":{"post":{"tags":["cyber"],"summary":"Google Dork","description":"Generate Google dork queries for OSINT reconnaissance.\n\nReturns constructed Google search URLs for the user to click.\nDoes NOT scrape Google — only generates the search queries.\n\nCategories:\n- **social**: Find social media profiles and mentions\n- **files**: Discover exposed documents and files\n- **email**: Find email addresses in public sources\n- **credentials**: Locate login pages, admin panels, exposed secrets\n- **infrastructure**: Map subdomains, open directories, tech stack\n- **all**: Run all categories","operationId":"google_dork_v1_cyber_dork_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DorkRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/sanctions/search":{"get":{"tags":["sanctions"],"summary":"Sanctions Search","description":"Search OpenSanctions for sanctioned entities matching a query.\n\nReturns entity name, schema type (Person/Company/Vessel), datasets\n(which sanctions lists), countries, and key properties.\n\nNo API key required (free tier).","operationId":"sanctions_search_v1_sanctions_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200,"description":"Entity name to screen","title":"Q"},"description":"Entity name to screen"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max results","default":10,"title":"Limit"},"description":"Max results"},{"name":"schema_type","in":"query","required":false,"schema":{"type":"string","description":"Filter by entity type: Person, Company, Vessel, Organization, LegalEntity","default":"","title":"Schema Type"},"description":"Filter by entity type: Person, Company, Vessel, Organization, LegalEntity"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/crowd/estimate":{"post":{"tags":["crowd"],"summary":"Crowd Estimate","description":"Estimate crowd size using Jacobs Method with multiple density zones.","operationId":"crowd_estimate_v1_crowd_estimate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/crowd/simulate":{"post":{"tags":["crowd"],"summary":"Start Simulation","description":"Start a crowd simulation. Returns an ID to poll for results.","operationId":"start_simulation_v1_crowd_simulate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__routers__crowd__SimulateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__routers__crowd__SimulationStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/crowd/simulate/{sim_id}":{"get":{"tags":["crowd"],"summary":"Get Simulation","description":"Poll simulation status and results.","operationId":"get_simulation_v1_crowd_simulate__sim_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sim_id","in":"path","required":true,"schema":{"type":"string","title":"Sim Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Simulation V1 Crowd Simulate  Sim Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/crowd/network":{"get":{"tags":["crowd"],"summary":"City Road Network","description":"Fetch the road network around a point for crowd simulation pathfinding.\n\nReturns GeoJSON LineString features from OpenStreetMap via the Overpass API.\nResults are cached in Redis for 1 hour.","operationId":"city_road_network_v1_crowd_network_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Center latitude","title":"Lat"},"description":"Center latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Center longitude","title":"Lon"},"description":"Center longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":100,"description":"Radius in meters","default":500,"title":"Radius"},"description":"Radius in meters"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response City Road Network V1 Crowd Network Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/flood/simulate":{"post":{"tags":["flood"],"summary":"Start Flood Simulation","description":"Start a flood simulation. Returns an ID to poll for status/results.","operationId":"start_flood_simulation_v1_flood_simulate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__routers__flood__SimulateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__routers__flood__SimulationStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/flood/simulate/{sim_id}":{"get":{"tags":["flood"],"summary":"Get Flood Simulation","description":"Poll simulation status and results.","operationId":"get_flood_simulation_v1_flood_simulate__sim_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sim_id","in":"path","required":true,"schema":{"type":"string","title":"Sim Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Flood Simulation V1 Flood Simulate  Sim Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/flood/elevation":{"get":{"tags":["flood"],"summary":"Get Elevation Data","description":"Proxy to get elevation data for a given area.\n\nIn production, this would fetch from OpenTopography SRTM API\nor Mapbox Terrain-RGB tiles. For MVP, returns synthetic terrain\nmetadata since real DEM fetching requires API keys and caching.","operationId":"get_elevation_data_v1_flood_elevation_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","title":"Lat"}},{"name":"lon","in":"query","required":true,"schema":{"type":"number","title":"Lon"}},{"name":"radius_km","in":"query","required":false,"schema":{"type":"number","default":5.0,"title":"Radius Km"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Elevation Data V1 Flood Elevation Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/status":{"get":{"tags":["chat"],"summary":"Chat Status","description":"Check whether the AI chat service is available and which provider is active.","operationId":"chat_status_v1_chat_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Chat Status V1 Chat Status Get"}}}}}}},"/v1/chat":{"post":{"tags":["chat"],"summary":"Chat","description":"Send a message to the AI assistant with OSINT context.\n\nThe assistant automatically searches WYRM Sentinel's database for\nevents, alerts, and entities relevant to the user's question, then\nuses that context to provide informed intelligence analysis.","operationId":"chat_v1_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/threat-intel/iocs":{"get":{"tags":["threat-intel"],"summary":"Check Ioc","description":"Check an indicator of compromise against multiple threat intelligence feeds.\n\nQueries AlienVault OTX (free, no key), AbuseIPDB (if key), and VirusTotal (if key).\nReturns an aggregated risk score and per-source results.","operationId":"check_ioc_v1_threat_intel_iocs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","pattern":"^(ip|ipv4|ipv6|domain|hostname|hash|md5|sha1|sha256|url)$","description":"Indicator type: ip, domain, hash, url","title":"Type"},"description":"Indicator type: ip, domain, hash, url"},{"name":"value","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":500,"description":"Indicator value","title":"Value"},"description":"Indicator value"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IOCResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/threat-intel/feed":{"get":{"tags":["threat-intel"],"summary":"Get Threat Feed","description":"Fetch the latest threat intelligence entries from a specific feed.\n\nSupported sources:\n- otx: AlienVault OTX recent pulses (free, no key)\n- cisa: CISA Known Exploited Vulnerabilities catalog\n- abusech: abuse.ch Feodo Tracker botnet C2 indicators","operationId":"get_threat_feed_v1_threat_intel_feed_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source","in":"query","required":true,"schema":{"type":"string","pattern":"^(otx|cisa|abusech)$","description":"Feed source: otx, cisa, abusech","title":"Source"},"description":"Feed source: otx, cisa, abusech"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max entries to return","default":50,"title":"Limit"},"description":"Max entries to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/image/exif":{"post":{"tags":["image-analysis"],"summary":"Extract Exif","description":"Extract EXIF metadata including GPS coordinates from an image.\n\nAccepts either a base64-encoded image or a URL to fetch.\nReturns GPS coordinates (decimal degrees), camera info, datetime, and all EXIF tags.\n\nAuthenticated users only — the URL-fetch path is an SSRF-sensitive\nsurface we don't want open to anonymous callers even with validation.","operationId":"extract_exif_v1_image_exif_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExifRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/image/analyze":{"post":{"tags":["image-analysis"],"summary":"Analyze Image","description":"Analyze an image for dimensions, dominant colors, histogram, and sharpness.\n\nAccepts a base64-encoded image. Returns structural and color analysis.\nFoundation endpoint — advanced CV (YOLO object detection) will be added\nwhen GPU resources are available.","operationId":"analyze_image_v1_image_analyze_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/cell-towers":{"get":{"tags":["cell-towers"],"summary":"Search Cell Towers","description":"Find cell towers and communication masts near a location.\n\nQueries OpenStreetMap Overpass API for communication infrastructure.\nReturns a GeoJSON FeatureCollection with tower locations, operators,\nheights, and network types where available.","operationId":"search_cell_towers_v1_cell_towers_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Latitude","title":"Lat"},"description":"Latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Longitude","title":"Lon"},"description":"Longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":100,"description":"Search radius in meters (max 50km)","default":5000,"title":"Radius"},"description":"Search radius in meters (max 50km)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cameras/search":{"get":{"tags":["cameras"],"summary":"Search Cameras","description":"Find CCTV cameras and public webcams near a location.\n\nCombines OpenStreetMap surveillance data with Windy Webcam API\nfor comprehensive camera coverage. Returns a GeoJSON FeatureCollection\nwith camera type (CCTV/webcam/traffic), location, operator, and\nstream/thumbnail URLs where available.","operationId":"search_cameras_v1_cameras_search_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Latitude","title":"Lat"},"description":"Latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Longitude","title":"Lon"},"description":"Longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":100,"description":"Search radius in meters (max 50km)","default":5000,"title":"Radius"},"description":"Search radius in meters (max 50km)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cameras/count":{"get":{"tags":["cameras"],"summary":"Count Cameras","description":"Count CCTV cameras and webcams near a location.\n\nLightweight endpoint that returns only counts, not full features.","operationId":"count_cameras_v1_cameras_count_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Latitude","title":"Lat"},"description":"Latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Longitude","title":"Lon"},"description":"Longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":100,"description":"Search radius in meters (max 50km)","default":5000,"title":"Radius"},"description":"Search radius in meters (max 50km)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/traffic":{"get":{"tags":["traffic"],"summary":"Get Traffic","description":"Get traffic conditions near a location.\n\nIf TomTom API key is configured, returns real-time traffic flow data\nand incidents. Always includes road infrastructure from OpenStreetMap\nas a base layer.","operationId":"get_traffic_v1_traffic_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Latitude","title":"Lat"},"description":"Latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Longitude","title":"Lon"},"description":"Longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"integer","maximum":25000,"minimum":100,"description":"Search radius in meters (max 25km)","default":5000,"title":"Radius"},"description":"Search radius in meters (max 25km)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/marine/animals":{"get":{"tags":["marine"],"summary":"Get Tracked Animals","description":"Fetch currently tracked marine animals from OCEARCH.\n\nReturns GPS-tagged sharks, turtles, and other marine animals\nwith their latest known positions.","operationId":"get_tracked_animals_v1_marine_animals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnimalsResponse"}}}}}}},"/v1/marine/animals/{name}/track":{"get":{"tags":["marine"],"summary":"Get Animal Track","description":"Get position history for a specific animal as a GeoJSON LineString.\n\nThe name parameter should match the animal's name (case-insensitive,\nspaces replaced with hyphens).","operationId":"get_animal_track_v1_marine_animals__name__track_get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/marine/sharks":{"get":{"tags":["marine"],"summary":"Get Shark Detections","description":"Fetch recent shark detections from NSW SharkSmart.\n\nReturns detections from drones, drumlines, and tagged sharks\nalong the NSW coastline.","operationId":"get_shark_detections_v1_marine_sharks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharksResponse"}}}}}}},"/v1/ocean/buoys":{"get":{"tags":["ocean"],"summary":"Find Nearby Buoys","description":"Find NDBC buoys within a given radius of a coordinate.\n\nReturns station ID, name, lat, lon, and distance from the search point.","operationId":"find_nearby_buoys_v1_ocean_buoys_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Latitude","title":"Lat"},"description":"Latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Longitude","title":"Lon"},"description":"Longitude"},{"name":"radius","in":"query","required":false,"schema":{"type":"number","maximum":2000,"minimum":1,"description":"Search radius in km","default":500,"title":"Radius"},"description":"Search radius in km"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NearbyBuoysResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocean/buoys/{station_id}":{"get":{"tags":["ocean"],"summary":"Get Buoy Conditions","description":"Get latest ocean conditions from a specific NDBC buoy.\n\nReturns wave height, period, direction, wind, temperature, pressure,\nand visibility from the buoy's most recent observation.","operationId":"get_buoy_conditions_v1_ocean_buoys__station_id__get","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuoyConditions"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocean/surf":{"get":{"tags":["ocean"],"summary":"Get Surf Conditions","description":"Get surf-relevant conditions from the nearest NDBC buoy.\n\nFinds the closest buoy and returns wave height, period, direction,\nwater temperature, and wind data. Includes a surf quality score (1-10)\nbased on wave height, period, and wind conditions.","operationId":"get_surf_conditions_v1_ocean_surf_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"description":"Latitude","title":"Lat"},"description":"Latitude"},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"description":"Longitude","title":"Lon"},"description":"Longitude"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfConditions"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jormungandr/decide":{"post":{"tags":["jormungandr"],"summary":"Decide","description":"The single decision endpoint. Routes to the appropriate optimizer.\n\nStarter+ only — the agentic search suite is included from the Starter\ntier upwards (5,000/month on Starter, 25,000 on Pro, unlimited on\nEnterprise). Free users hit a 403 with `tier_required`. Writes to\nproduct.decisions under the caller's tenant.","operationId":"decide_v1_jormungandr_decide_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/jormungandr/otc/quote":{"post":{"tags":["jormungandr"],"summary":"Otc Quote","description":"Get aggregated quotes from OTC desks for fiat→crypto conversion. Pro+ only.","operationId":"otc_quote_v1_jormungandr_otc_quote_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTCQuoteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTCQuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/jormungandr/otc/execute":{"post":{"tags":["jormungandr"],"summary":"Otc Execute","description":"Execute a crypto purchase on a specific OTC desk. Pro+ only.","operationId":"otc_execute_v1_jormungandr_otc_execute_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTCExecuteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTCExecuteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/health":{"get":{"summary":"Health Check","description":"Basic liveness probe.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/ready":{"get":{"summary":"Readiness Check","description":"Readiness probe. Returns summary for anonymous callers, detail for authenticated.","operationId":"readiness_check_health_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"APIKeyCreate":{"properties":{"name":{"type":"string","title":"Name","default":"Default"}},"type":"object","title":"APIKeyCreate"},"AcceptedModifier":{"properties":{"trigger":{"type":"string","maxLength":500,"minLength":1,"title":"Trigger"},"price_delta":{"type":"number","title":"Price Delta"},"currency":{"anyOf":[{"type":"string","maxLength":3},{"type":"null"}],"title":"Currency"}},"type":"object","required":["trigger","price_delta"],"title":"AcceptedModifier","description":"Conditional modifier the buyer chose when accepting (e.g. \"+$30\nfor 7 May delivery\"). The supplier total is adjusted by\n``price_delta``; the trigger is logged on the acceptance email so\nthe supplier knows which deal variant was picked."},"AdminTierUpdate":{"properties":{"tier":{"type":"string","maxLength":32,"minLength":1,"title":"Tier"}},"type":"object","required":["tier"],"title":"AdminTierUpdate"},"AlertRules":{"properties":{"price_drop_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Drop Pct","description":"Trigger when any supplier's price drops by at least this percentage from target.","default":5.0},"stock_surplus":{"type":"boolean","title":"Stock Surplus","description":"Trigger when a supplier declares surplus or clearance.","default":true},"news_daily":{"type":"boolean","title":"News Daily","description":"Emit a daily AI news summary signal.","default":true}},"type":"object","title":"AlertRules"},"AnalyzeRequest":{"properties":{"image_base64":{"type":"string","maxLength":28000000,"title":"Image Base64","description":"Base64-encoded image data"}},"type":"object","required":["image_base64"],"title":"AnalyzeRequest"},"AnimalsResponse":{"properties":{"count":{"type":"integer","title":"Count"},"animals":{"items":{"$ref":"#/components/schemas/TrackedAnimal"},"type":"array","title":"Animals"},"source":{"type":"string","title":"Source","default":"OCEARCH"}},"type":"object","required":["count","animals"],"title":"AnimalsResponse"},"AutoNegotiateToggle":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"}},"type":"object","required":["enabled"],"title":"AutoNegotiateToggle","description":"Kill-switch payload for an in-flight RFQ.\n\nBuyers can flip auto-negotiation off when a round goes sideways (odd\ncounter-offer copy, supplier attaching a contract, etc.) and the next\nsupplier reply will escalate to the buyer instead of auto-countering.\nTurning it back on resumes auto-negotiation on the next reply."},"BOMItem":{"properties":{"description":{"type":"string","title":"Description"},"hs_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hs Code"},"qty_estimate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Qty Estimate"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"unit_price_estimate_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Unit Price Estimate Gbp"},"total_estimate_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Estimate Gbp"}},"type":"object","required":["description"],"title":"BOMItem"},"BankWireComparison":{"properties":{"fiat_amount":{"type":"number","title":"Fiat Amount"},"fx_spread_bps":{"type":"number","title":"Fx Spread Bps","description":"Typical bank FX spread","default":80},"correspondent_fee":{"type":"number","title":"Correspondent Fee","description":"Correspondent bank fee","default":0},"settlement_time":{"type":"string","title":"Settlement Time","default":"3-5 business days"},"total_cost_fiat":{"type":"number","title":"Total Cost Fiat"},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","required":["fiat_amount","total_cost_fiat"],"title":"BankWireComparison","description":"Comparison: what the same payment would cost via bank wire."},"BomItem":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"category":{"type":"string","maxLength":80,"minLength":1,"title":"Category"},"mass_kg":{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0,"title":"Mass Kg"},"quantity":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Quantity"},"materials":{"items":{"$ref":"#/components/schemas/BomMaterial"},"type":"array","maxItems":20,"minItems":1,"title":"Materials"},"manufacturing_country":{"type":"string","pattern":"^[A-Za-z]{2}$","title":"Manufacturing Country"},"product_code":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Product Code"}},"type":"object","required":["name","category","mass_kg","quantity","materials","manufacturing_country"],"title":"BomItem","description":"Single line in a TM65 bill of materials.\n\n``mass_kg`` is the mass of ONE unit. ``quantity`` is how many units\nappear in the schedule. ``manufacturing_country`` is the ISO-2 code\nof the factory location — the grid-intensity multiplier adjusts\nmanufacturing emissions accordingly."},"BomMaterial":{"properties":{"name":{"type":"string","maxLength":60,"minLength":1,"title":"Name"},"fraction":{"type":"number","maximum":1.0,"exclusiveMinimum":0.0,"title":"Fraction"}},"type":"object","required":["name","fraction"],"title":"BomMaterial","description":"Single material fraction within a BOM item.\n\n``fraction`` is a 0-1 mass fraction (sum across the item's materials\nshould approximate 1.0; the calculator normalises if it doesn't)."},"BookShipmentBody":{"properties":{"quote_id":{"type":"string","maxLength":200,"minLength":1,"title":"Quote Id"},"expected_wholesale_usd":{"type":"number","exclusiveMinimum":0.0,"title":"Expected Wholesale Usd"},"load_type":{"$ref":"#/components/schemas/CargoLoadType"},"service":{"$ref":"#/components/schemas/ShipmentService","default":"door_to_door"},"incoterm":{"$ref":"#/components/schemas/Incoterm","default":"DDP"},"buyer_phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Buyer Phone"},"supplier_contact_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Supplier Contact Name"},"supplier_contact_phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Supplier Contact Phone"},"commodity_description":{"type":"string","maxLength":300,"minLength":2,"title":"Commodity Description"}},"type":"object","required":["quote_id","expected_wholesale_usd","load_type","commodity_description"],"title":"BookShipmentBody","description":"Commit a specific option returned by a previous /v1/shipping/quote call.\n\nThe caller MUST echo back the cargo's ``load_type``, ``service``, and\n``incoterm`` from the quote request — Freightos's booking payload\ndoesn't round-trip them reliably, and the shipments table needs\naccurate values for analytics + the arbitrage ledger. Storing a\nhardcoded default would silently corrupt every row."},"BulkDiscountQuote":{"properties":{"base_unit_price_usd":{"type":"number","title":"Base Unit Price Usd"},"base_total_usd":{"type":"number","title":"Base Total Usd"},"requested_qty":{"type":"number","title":"Requested Qty"},"unit":{"type":"string","title":"Unit"},"tiers":{"items":{"$ref":"#/components/schemas/BulkTier"},"type":"array","title":"Tiers"},"recommended_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Recommended Qty"},"recommended_total_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Recommended Total Usd"},"recommended_savings_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Recommended Savings Usd"},"recommended_savings_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Recommended Savings Pct"},"source":{"type":"string","enum":["supplier","heuristic"],"title":"Source"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["base_unit_price_usd","base_total_usd","requested_qty","unit","tiers","source"],"title":"BulkDiscountQuote","description":"Snapshot of the bulk-discount curve for a candidate purchase."},"BulkTier":{"properties":{"min_qty":{"type":"number","title":"Min Qty"},"unit_price_usd":{"type":"number","title":"Unit Price Usd"},"discount_pct":{"type":"number","title":"Discount Pct"},"total_usd":{"type":"number","title":"Total Usd"}},"type":"object","required":["min_qty","unit_price_usd","discount_pct","total_usd"],"title":"BulkTier"},"BuoyConditions":{"properties":{"station_id":{"type":"string","title":"Station Id"},"timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timestamp"},"wave_height_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wave Height M"},"wave_period_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wave Period Sec"},"wave_direction_deg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wave Direction Deg"},"wind_speed_mps":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wind Speed Mps"},"wind_direction_deg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wind Direction Deg"},"wind_gust_mps":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wind Gust Mps"},"water_temp_c":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Water Temp C"},"air_temp_c":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Air Temp C"},"pressure_hpa":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pressure Hpa"},"visibility_nmi":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Visibility Nmi"},"dewpoint_c":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dewpoint C"},"source":{"type":"string","title":"Source","default":"NDBC"}},"type":"object","required":["station_id"],"title":"BuoyConditions"},"BuoyLocation":{"properties":{"station_id":{"type":"string","title":"Station Id"},"name":{"type":"string","title":"Name"},"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"},"distance_km":{"type":"number","title":"Distance Km"}},"type":"object","required":["station_id","name","lat","lon","distance_km"],"title":"BuoyLocation"},"CO2Breakdown":{"properties":{"production_kg":{"type":"number","title":"Production Kg","description":"Manufacturing CO2 at origin (kg CO2e)","default":0},"transport_kg":{"type":"number","title":"Transport Kg","description":"Shipping/freight CO2 (kg CO2e)","default":0},"total_kg":{"type":"number","title":"Total Kg","description":"Total lifecycle CO2 (kg CO2e)","default":0},"per_unit_kg":{"type":"number","title":"Per Unit Kg","description":"CO2 per unit of product (kg CO2e/unit)","default":0},"rating":{"type":"string","title":"Rating","description":"A-E rating for quick comparison (A=lowest)","default":""},"compliance_notes":{"type":"string","title":"Compliance Notes","description":"UK Carbon Budget / EU CBAM notes","default":""},"cbam":{"anyOf":[{"$ref":"#/components/schemas/CbamLiability"},{"type":"null"}],"description":"Quantified CBAM liability — populated on EU-bound non-EU imports"}},"type":"object","title":"CO2Breakdown","description":"Carbon footprint breakdown for a procurement option."},"CalendarEventCreate":{"properties":{"subject":{"type":"string","title":"Subject"},"start":{"type":"string","format":"date-time","title":"Start"},"end":{"type":"string","format":"date-time","title":"End"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"categories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Categories"}},"type":"object","required":["subject","start","end"],"title":"CalendarEventCreate"},"CargoLoadType":{"type":"string","enum":["fcl_20","fcl_40","fcl_40_hc","fcl_45","lcl","air","parcel"],"title":"CargoLoadType","description":"How the cargo physically travels."},"CbamLiability":{"properties":{"in_scope":{"type":"boolean","title":"In Scope","description":"Whether CBAM applies to this line"},"sector":{"type":"string","title":"Sector","description":"Human-readable CBAM sector label","default":""},"hs_code":{"type":"string","title":"Hs Code","description":"Normalised HS tariff code","default":""},"origin_country":{"type":"string","title":"Origin Country","description":"ISO-2 origin country","default":""},"destination_country":{"type":"string","title":"Destination Country","description":"ISO-2 destination country","default":""},"year":{"type":"integer","title":"Year","description":"Year used for free-allocation lookup","default":0},"embedded_emissions_tonnes":{"type":"number","title":"Embedded Emissions Tonnes","description":"Embedded CO2e (tonnes)","default":0},"ets_price_eur":{"type":"number","title":"Ets Price Eur","description":"EU ETS spot used (€/tCO2e)","default":0},"free_allocation_pct":{"type":"number","title":"Free Allocation Pct","description":"Free allocation fraction (0-1)","default":0},"certificates_due":{"type":"number","title":"Certificates Due","description":"CBAM certificates to surrender","default":0},"liability_eur":{"type":"number","title":"Liability Eur","description":"Total CBAM liability in EUR","default":0},"notes":{"type":"string","title":"Notes","description":"Explanation shown in the Audit/Tax Pack","default":""}},"type":"object","required":["in_scope"],"title":"CbamLiability","description":"Quantified EU Carbon Border Adjustment Mechanism liability.\n\nPopulated whenever destination is EU27 + origin is non-EU + HS code is\nin CBAM scope. When ``in_scope`` is False the remaining fields are\nzero and ``notes`` explains why — the frontend can then render an\n\"N/A\" row instead of a liability figure on the Audit/Tax Pack."},"ChatRequest":{"properties":{"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message"},"context":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Context","description":"Optional additional context for the assistant"}},"type":"object","required":["message"],"title":"ChatRequest"},"ChatResponse":{"properties":{"response":{"type":"string","title":"Response"},"sources":{"items":{"$ref":"#/components/schemas/ChatSource"},"type":"array","title":"Sources"},"model":{"type":"string","title":"Model"},"timestamp":{"type":"string","title":"Timestamp"}},"type":"object","required":["response","sources","model","timestamp"],"title":"ChatResponse"},"ChatSource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"title":{"type":"string","title":"Title"},"relevance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relevance"}},"type":"object","required":["type","title"],"title":"ChatSource"},"ComplianceDetail":{"properties":{"origin_country":{"type":"string","title":"Origin Country"},"status":{"$ref":"#/components/schemas/ComplianceStatus"},"sanctions_lists":{"items":{"type":"string"},"type":"array","title":"Sanctions Lists","description":"e.g. ['OFAC', 'UK_OFSI']"},"intermediary_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intermediary Country","description":"If routed via intermediary"},"explanation":{"type":"string","title":"Explanation","default":""}},"type":"object","required":["origin_country","status"],"title":"ComplianceDetail","description":"Compliance assessment for a specific origin."},"ComplianceStatus":{"type":"string","enum":["clear","compliant_with_advisory","blocked"],"title":"ComplianceStatus"},"CostComponents":{"properties":{"product":{"type":"number","title":"Product","description":"Product cost in buyer's currency"},"shipping":{"type":"number","title":"Shipping","description":"Freight + handling","default":0},"insurance":{"type":"number","title":"Insurance","description":"Transit insurance","default":0},"tariff":{"type":"number","title":"Tariff","description":"Import duty / tariff","default":0},"fx_cost":{"type":"number","title":"Fx Cost","description":"FX conversion spread + any forward premium","default":0},"re_export_fee":{"type":"number","title":"Re Export Fee","description":"If routed via intermediary for compliance","default":0}},"type":"object","required":["product"],"title":"CostComponents","description":"Itemized breakdown of the total landed cost."},"CounterDraftBody":{"properties":{"target_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Price","description":"What the buyer wants to pay per unit"},"target_currency":{"anyOf":[{"type":"string","maxLength":3,"minLength":3},{"type":"null"}],"title":"Target Currency"},"tone":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Tone","default":"firm-but-polite"},"extra_instruction":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Extra Instruction"}},"type":"object","title":"CounterDraftBody","description":"Buyer steering for the counter-offer draft.\n\nFields are all optional — Haiku works from the thread alone if\nnone are supplied, but a target price or tone hint produces much\ntighter copy."},"CounterSendBody":{"properties":{"subject":{"type":"string","maxLength":500,"minLength":3,"title":"Subject"},"body_plain":{"type":"string","maxLength":8000,"minLength":20,"title":"Body Plain"}},"type":"object","required":["subject","body_plain"],"title":"CounterSendBody"},"CrowdEstimateRequest":{"properties":{"area_m2":{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0,"title":"Area M2"},"density_per_m2":{"type":"number","maximum":10.0,"minimum":0.0,"title":"Density Per M2"},"occupancy_factor":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Occupancy Factor","default":1.0}},"type":"object","required":["area_m2","density_per_m2"],"title":"CrowdEstimateRequest"},"DecideRequest":{"properties":{"intent":{"$ref":"#/components/schemas/Intent"},"product":{"anyOf":[{"$ref":"#/components/schemas/ProductSpec"},{"type":"null"}],"description":"Single product (use this OR items)"},"items":{"anyOf":[{"items":{"$ref":"#/components/schemas/ProductSpec"},"type":"array"},{"type":"null"}],"title":"Items","description":"Multiple products for combined order"},"origin_candidates":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Origin Candidates","description":"ISO country codes to consider, or null for 'auto' (engine picks)"},"destination":{"type":"string","title":"Destination","description":"Destination code, e.g. 'GB-LON', 'US-NYC'"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline","description":"Latest acceptable delivery date"},"budget_ccy":{"type":"string","title":"Budget Ccy","description":"Buyer's currency for cost display","default":"GBP"},"risk_appetite":{"$ref":"#/components/schemas/RiskAppetite","default":"balanced"},"sort_by":{"$ref":"#/components/schemas/SortBy","description":"Optimize results by cost, CO2, or balanced","default":"balanced"},"route_constraints":{"$ref":"#/components/schemas/RouteConstraints"},"buyer_country":{"type":"string","title":"Buyer Country","description":"Buyer's country (ISO alpha-2)","default":"GB"},"buyer_sector":{"type":"string","title":"Buyer Sector","description":"Buyer's sector: 'private', 'government', 'defence', 'ngo'","default":"private"},"compliance_regime":{"type":"string","title":"Compliance Regime","description":"Which sanctions regime to apply: 'uk', 'us', 'eu', 'un'","default":"uk"},"target_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Currency","description":"ISO-4217 target currency for FX analysis, e.g. 'USD', 'EUR'. Overrides origin-derived pair."}},"type":"object","required":["intent","destination"],"title":"DecideRequest","description":"Input to the /decide endpoint."},"DecideResponse":{"properties":{"decision_id":{"type":"string","title":"Decision Id","description":"UUID for audit trail + re-render"},"recommendation":{"$ref":"#/components/schemas/Recommendation"},"alternatives":{"items":{"$ref":"#/components/schemas/Recommendation"},"type":"array","title":"Alternatives"},"intelligence":{"$ref":"#/components/schemas/IntelligenceBreakdown"},"explanation":{"type":"string","title":"Explanation","description":"Claude-generated plain English reasoning","default":""},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence"},"inputs_used":{"items":{"type":"string"},"type":"array","title":"Inputs Used","description":"Data sources consulted"},"computed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Computed At"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"}},"type":"object","required":["decision_id","recommendation","intelligence","confidence"],"title":"DecideResponse","description":"Output from the /decide endpoint."},"DeliveryPreferenceUpdate":{"properties":{"channel":{"type":"string","enum":["email","slack","discord","sms","webhook","telegram"],"title":"Channel"},"enabled":{"type":"boolean","title":"Enabled","default":true},"config":{"additionalProperties":true,"type":"object","title":"Config","default":{}},"min_severity":{"type":"string","enum":["FLASH","CRITICAL","HIGH","MEDIUM","LOW","ROUTINE"],"title":"Min Severity","default":"MEDIUM"}},"type":"object","required":["channel"],"title":"DeliveryPreferenceUpdate"},"DensityClass":{"type":"string","enum":["light","moderate","dense","very_dense","packed"],"title":"DensityClass"},"DeskQuote":{"properties":{"desk_name":{"type":"string","title":"Desk Name"},"desk_id":{"type":"string","title":"Desk Id"},"fiat_amount":{"type":"number","title":"Fiat Amount"},"fiat_currency":{"type":"string","title":"Fiat Currency"},"crypto_amount":{"type":"number","title":"Crypto Amount"},"crypto_asset":{"type":"string","title":"Crypto Asset"},"rate":{"type":"number","title":"Rate","description":"Price per 1 unit of crypto in fiat"},"spread_bps":{"type":"number","title":"Spread Bps","description":"Spread over mid-market in basis points"},"settlement_time":{"type":"string","title":"Settlement Time","description":"e.g. '2 hours', 'same day', 'T+1'"},"min_order":{"type":"number","title":"Min Order","description":"Minimum order in fiat","default":0},"max_order":{"type":"number","title":"Max Order","description":"Maximum order in fiat (0 = no limit)","default":0},"fees_fiat":{"type":"number","title":"Fees Fiat","description":"Additional fees in fiat currency","default":0},"total_cost_fiat":{"type":"number","title":"Total Cost Fiat","description":"Total including fees"},"kyc_required":{"type":"boolean","title":"Kyc Required","default":true},"available":{"type":"boolean","title":"Available","default":true},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","required":["desk_name","desk_id","fiat_amount","fiat_currency","crypto_amount","crypto_asset","rate","spread_bps","settlement_time","total_cost_fiat"],"title":"DeskQuote","description":"Quote from a single OTC desk."},"DimensionPayload":{"properties":{"key":{"type":"string","title":"Key"},"score":{"type":"number","title":"Score"},"evidence":{"items":{"type":"string"},"type":"array","title":"Evidence"},"conflict":{"type":"boolean","title":"Conflict"},"conflict_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conflict Reason"}},"type":"object","required":["key","score","evidence","conflict","conflict_reason"],"title":"DimensionPayload"},"DirectPurchaseRecommendation":{"properties":{"eligible":{"type":"boolean","title":"Eligible"},"est_direct_cost_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Direct Cost Gbp"},"est_prime_markup_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Prime Markup Gbp"},"est_savings_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Savings Gbp"},"est_savings_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Savings Pct"},"rationale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rationale"}},"type":"object","required":["eligible"],"title":"DirectPurchaseRecommendation","description":"What the buyer gains by sourcing inputs directly and supplying\nthem to installers / manufacturers rather than letting the prime\ncontractor mark them up."},"DirectoryEntryPayload":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"country_code":{"type":"string","title":"Country Code"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"contact_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact Email"},"sectors":{"items":{"type":"string"},"type":"array","title":"Sectors"},"hs_chapters":{"items":{"type":"integer"},"type":"array","title":"Hs Chapters"},"product_keywords":{"items":{"type":"string"},"type":"array","title":"Product Keywords"},"certifications":{"items":{"type":"string"},"type":"array","title":"Certifications"},"min_order_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Order Qty"},"min_order_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Min Order Unit"},"typical_lead_time_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Typical Lead Time Days"},"export_capable":{"type":"boolean","title":"Export Capable"},"verified_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verified At"},"sanctions_clean":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sanctions Clean"},"source":{"type":"string","title":"Source"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["id","name","slug","country_code","city","website","contact_email","sectors","hs_chapters","product_keywords","certifications","min_order_qty","min_order_unit","typical_lead_time_days","export_capable","verified_at","sanctions_clean","source","notes"],"title":"DirectoryEntryPayload"},"DirectoryResponse":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/DirectoryEntryPayload"},"type":"array","title":"Entries"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["entries","total","limit","offset"],"title":"DirectoryResponse"},"DisambiguateRequest":{"properties":{"query":{"type":"string","maxLength":500,"minLength":0,"title":"Query"}},"type":"object","required":["query"],"title":"DisambiguateRequest"},"DisambiguateResponse":{"properties":{"query":{"type":"string","title":"Query"},"total_score":{"type":"number","title":"Total Score"},"ambiguous":{"type":"boolean","title":"Ambiguous"},"ambiguity_reasons":{"items":{"type":"string"},"type":"array","title":"Ambiguity Reasons"},"dimensions":{"items":{"$ref":"#/components/schemas/DimensionPayload"},"type":"array","title":"Dimensions"},"clarifying_questions":{"items":{"type":"string"},"type":"array","title":"Clarifying Questions"}},"type":"object","required":["query","total_score","ambiguous","ambiguity_reasons","dimensions","clarifying_questions"],"title":"DisambiguateResponse"},"DorkRequest":{"properties":{"target":{"type":"string","maxLength":200,"minLength":2,"title":"Target","description":"Target domain or organization name"},"dork_type":{"type":"string","title":"Dork Type","description":"Type of dork: all, social, files, email, credentials, infrastructure","default":"all"}},"type":"object","required":["target"],"title":"DorkRequest"},"EnterpriseEnquiryRequest":{"properties":{"company":{"type":"string","maxLength":200,"minLength":1,"title":"Company"},"contact_name":{"type":"string","maxLength":200,"minLength":1,"title":"Contact Name"},"contact_email":{"type":"string","format":"email","title":"Contact Email"},"team_size":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Team Size"},"monthly_volume":{"anyOf":[{"type":"integer","maximum":10000000.0,"minimum":1.0},{"type":"null"}],"title":"Monthly Volume"},"jurisdictions":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Jurisdictions"},"industry":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Industry"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["company","contact_name","contact_email"],"title":"EnterpriseEnquiryRequest"},"EstimateRequest":{"properties":{"zones":{"items":{"$ref":"#/components/schemas/ZoneDefinition"},"type":"array","maxItems":50,"minItems":1,"title":"Zones"},"meters_per_pixel":{"type":"number","maximum":100.0,"exclusiveMinimum":0.0,"title":"Meters Per Pixel","description":"Scale: meters per pixel"},"image_width":{"type":"integer","maximum":10000.0,"exclusiveMinimum":0.0,"title":"Image Width"},"image_height":{"type":"integer","maximum":10000.0,"exclusiveMinimum":0.0,"title":"Image Height"}},"type":"object","required":["zones","meters_per_pixel","image_width","image_height"],"title":"EstimateRequest"},"EstimateResponse":{"properties":{"zones":{"items":{"$ref":"#/components/schemas/ZoneResult"},"type":"array","title":"Zones"},"total_people":{"type":"integer","title":"Total People"},"total_area_m2":{"type":"number","title":"Total Area M2"},"confidence_low":{"type":"integer","title":"Confidence Low"},"confidence_high":{"type":"integer","title":"Confidence High"},"avg_density":{"type":"number","title":"Avg Density"},"crush_risk":{"type":"boolean","title":"Crush Risk"},"timestamp":{"type":"string","title":"Timestamp"}},"type":"object","required":["zones","total_people","total_area_m2","confidence_low","confidence_high","avg_density","crush_risk","timestamp"],"title":"EstimateResponse"},"ExifRequest":{"properties":{"image_base64":{"anyOf":[{"type":"string","maxLength":28000000},{"type":"null"}],"title":"Image Base64","description":"Base64-encoded image data"},"image_url":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}],"title":"Image Url","description":"URL to fetch the image from"}},"type":"object","title":"ExifRequest"},"FXRecommendation":{"properties":{"pair":{"type":"string","title":"Pair"},"action":{"type":"string","title":"Action"},"reason":{"type":"string","title":"Reason"},"expected_savings_bps":{"type":"number","title":"Expected Savings Bps","default":0},"confidence":{"type":"number","title":"Confidence","default":0}},"type":"object","required":["pair","action","reason"],"title":"FXRecommendation","description":"FX strategy for a single currency pair."},"FeedEntry":{"properties":{"source":{"type":"string","title":"Source"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"indicator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Indicator"},"indicator_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Indicator Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"published_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published At"},"severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity"},"reference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference"}},"type":"object","required":["source"],"title":"FeedEntry"},"FeedHealth":{"properties":{"name":{"type":"string","title":"Name"},"status":{"$ref":"#/components/schemas/FeedStatus","default":"ok"},"last_fetch_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Fetch At"},"next_fetch_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Fetch At"},"error_count":{"type":"integer","title":"Error Count","default":0},"events_last_hour":{"type":"integer","title":"Events Last Hour","default":0},"consecutive_failures":{"type":"integer","title":"Consecutive Failures","default":0},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"}},"type":"object","required":["name"],"title":"FeedHealth","description":"Real-time health snapshot for a single feed."},"FeedResponse":{"properties":{"source":{"type":"string","title":"Source"},"entries":{"items":{"$ref":"#/components/schemas/FeedEntry"},"type":"array","title":"Entries"},"total":{"type":"integer","title":"Total"},"fetched_at":{"type":"string","title":"Fetched At"}},"type":"object","required":["source","entries","total","fetched_at"],"title":"FeedResponse"},"FeedStats":{"properties":{"total_feeds":{"type":"integer","title":"Total Feeds","default":0},"feeds_ok":{"type":"integer","title":"Feeds Ok","default":0},"feeds_degraded":{"type":"integer","title":"Feeds Degraded","default":0},"feeds_error":{"type":"integer","title":"Feeds Error","default":0},"feeds_disabled":{"type":"integer","title":"Feeds Disabled","default":0},"total_events_last_hour":{"type":"integer","title":"Total Events Last Hour","default":0},"feeds":{"items":{"$ref":"#/components/schemas/FeedHealth"},"type":"array","title":"Feeds"}},"type":"object","title":"FeedStats","description":"Aggregate statistics across all feeds."},"FeedStatus":{"type":"string","enum":["ok","degraded","error","disabled"],"title":"FeedStatus","description":"Operational status of a feed collector."},"FiatCurrency":{"type":"string","enum":["GBP","USD","EUR"],"title":"FiatCurrency"},"GridResolution":{"type":"integer","enum":[10,30,100],"title":"GridResolution"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IOCResult":{"properties":{"indicator":{"type":"string","title":"Indicator"},"indicator_type":{"type":"string","title":"Indicator Type"},"sources":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Sources"},"risk_score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Risk Score","description":"Aggregated risk score","default":0},"malicious":{"type":"boolean","title":"Malicious","default":false},"checked_at":{"type":"string","title":"Checked At"}},"type":"object","required":["indicator","indicator_type","sources","checked_at"],"title":"IOCResult"},"Incoterm":{"type":"string","enum":["EXW","FCA","FOB","CFR","CIF","DAP","DDP"],"title":"Incoterm","description":"2020 Incoterms. DDP = delivered-duty-paid; EXW = ex-works."},"IntelligenceBreakdown":{"properties":{"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"Weighted composite confidence"},"signal_count":{"type":"integer","title":"Signal Count"},"signals":{"items":{"$ref":"#/components/schemas/SignalDetail"},"type":"array","title":"Signals"},"dissenting":{"items":{"$ref":"#/components/schemas/SignalDetail"},"type":"array","title":"Dissenting","description":"Signals that disagree with majority"},"timing_recommendation":{"type":"string","title":"Timing Recommendation","description":"'buy_now', 'wait_N_days', 'lock_forward_Nd'","default":"buy_now"}},"type":"object","required":["confidence","signal_count","signals"],"title":"IntelligenceBreakdown","description":"Composite intelligence summary returned with every recommendation."},"Intent":{"type":"string","enum":["source","ship","pay","benchmark"],"title":"Intent"},"InventoryItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"name":{"type":"string","title":"Name"},"hs_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hs Code"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"unit":{"type":"string","title":"Unit"},"typical_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Qty"},"target_price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Price Usd"},"reorder_frequency_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reorder Frequency Days"},"supplier_pool":{"items":{"$ref":"#/components/schemas/SupplierEntry"},"type":"array","title":"Supplier Pool"},"alert_rules":{"$ref":"#/components/schemas/AlertRules"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Code"},"last_purchase_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Purchase At"},"auto_discovered":{"type":"boolean","title":"Auto Discovered","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","tenant_id","user_id","name","unit","supplier_pool","alert_rules","created_at","updated_at"],"title":"InventoryItem"},"InventoryItemCreate":{"properties":{"name":{"type":"string","title":"Name"},"hs_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hs Code"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"unit":{"type":"string","title":"Unit","default":"unit"},"typical_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Qty"},"target_price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Price Usd"},"reorder_frequency_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reorder Frequency Days"},"supplier_pool":{"items":{"$ref":"#/components/schemas/SupplierEntry"},"type":"array","title":"Supplier Pool"},"alert_rules":{"$ref":"#/components/schemas/AlertRules"},"product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Code"}},"type":"object","required":["name"],"title":"InventoryItemCreate"},"InventoryItemUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"hs_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hs Code"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"typical_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Qty"},"target_price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Price Usd"},"reorder_frequency_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reorder Frequency Days"},"supplier_pool":{"anyOf":[{"items":{"$ref":"#/components/schemas/SupplierEntry"},"type":"array"},{"type":"null"}],"title":"Supplier Pool"},"alert_rules":{"anyOf":[{"$ref":"#/components/schemas/AlertRules"},{"type":"null"}]},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Code"}},"type":"object","title":"InventoryItemUpdate"},"LastPing":{"properties":{"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lon":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lon"},"datetime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Datetime"}},"type":"object","title":"LastPing"},"MailSend":{"properties":{"to":{"items":{"type":"string"},"type":"array","title":"To"},"subject":{"type":"string","title":"Subject"},"body_html":{"type":"string","title":"Body Html"},"cc":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Cc"}},"type":"object","required":["to","subject","body_html"],"title":"MailSend"},"ManningsPreset":{"type":"string","enum":["urban","suburban","rural","forest"],"title":"ManningsPreset"},"MaterialBreakdown":{"properties":{"name":{"type":"string","title":"Name"},"mass_kg":{"type":"number","title":"Mass Kg"},"factor_kg_co2e_per_kg":{"type":"number","title":"Factor Kg Co2E Per Kg"},"kg_co2e":{"type":"number","title":"Kg Co2E"},"is_known_material":{"type":"boolean","title":"Is Known Material"}},"type":"object","required":["name","mass_kg","factor_kg_co2e_per_kg","kg_co2e","is_known_material"],"title":"MaterialBreakdown"},"NearbyBuoysResponse":{"properties":{"count":{"type":"integer","title":"Count"},"buoys":{"items":{"$ref":"#/components/schemas/BuoyLocation"},"type":"array","title":"Buoys"},"search_lat":{"type":"number","title":"Search Lat"},"search_lon":{"type":"number","title":"Search Lon"},"radius_km":{"type":"number","title":"Radius Km"},"source":{"type":"string","title":"Source","default":"NDBC"}},"type":"object","required":["count","buoys","search_lat","search_lon","radius_km"],"title":"NearbyBuoysResponse"},"NetworkScanRequest":{"properties":{"target":{"type":"string","maxLength":253,"minLength":1,"title":"Target","description":"IP address or domain"},"ports":{"items":{"type":"integer"},"type":"array","title":"Ports","description":"List of TCP ports to scan","default":[21,22,25,53,80,110,143,443,445,993,995,3306,3389,5432,5900,8080,8443]}},"type":"object","required":["target"],"title":"NetworkScanRequest"},"OTCAsset":{"type":"string","enum":["USDT","USDC","BTC","ETH","DAI"],"title":"OTCAsset"},"OTCExecuteRequest":{"properties":{"quote_id":{"type":"string","title":"Quote Id"},"desk_id":{"type":"string","title":"Desk Id"},"destination_wallet":{"type":"string","title":"Destination Wallet"},"confirm":{"type":"boolean","title":"Confirm","description":"Must be True to execute","default":false}},"type":"object","required":["quote_id","desk_id","destination_wallet"],"title":"OTCExecuteRequest","description":"Execute a quote from a specific desk."},"OTCExecuteResponse":{"properties":{"execution_id":{"type":"string","title":"Execution Id"},"status":{"type":"string","title":"Status"},"desk_name":{"type":"string","title":"Desk Name"},"fiat_amount":{"type":"number","title":"Fiat Amount"},"crypto_amount":{"type":"number","title":"Crypto Amount"},"crypto_asset":{"type":"string","title":"Crypto Asset"},"rate":{"type":"number","title":"Rate"},"tx_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tx Hash"},"settlement_eta":{"type":"string","title":"Settlement Eta"},"audit_trail":{"additionalProperties":true,"type":"object","title":"Audit Trail"}},"type":"object","required":["execution_id","status","desk_name","fiat_amount","crypto_amount","crypto_asset","rate","settlement_eta"],"title":"OTCExecuteResponse","description":"Execution confirmation."},"OTCQuoteRequest":{"properties":{"fiat_amount":{"type":"number","exclusiveMinimum":0.0,"title":"Fiat Amount","description":"Amount in fiat currency to convert"},"fiat_currency":{"$ref":"#/components/schemas/FiatCurrency","default":"GBP"},"target_asset":{"$ref":"#/components/schemas/OTCAsset","default":"USDC"},"purpose":{"type":"string","title":"Purpose","description":"Payment purpose for compliance","default":"procurement_payment"},"destination_wallet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Destination Wallet","description":"Recipient wallet address"},"supplier_country":{"type":"string","title":"Supplier Country","description":"ISO alpha-2 of the supplier's country","default":""}},"type":"object","required":["fiat_amount"],"title":"OTCQuoteRequest","description":"Request a quote from OTC desks."},"OTCQuoteResponse":{"properties":{"quote_id":{"type":"string","title":"Quote Id"},"desk_quotes":{"items":{"$ref":"#/components/schemas/DeskQuote"},"type":"array","title":"Desk Quotes"},"bank_wire":{"$ref":"#/components/schemas/BankWireComparison"},"best_desk":{"type":"string","title":"Best Desk","description":"Desk with lowest total cost"},"savings_vs_wire_fiat":{"type":"number","title":"Savings Vs Wire Fiat","description":"How much cheaper OTC is vs bank wire"},"savings_vs_wire_pct":{"type":"number","title":"Savings Vs Wire Pct"},"requested_at":{"type":"string","format":"date-time","title":"Requested At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"compliance_status":{"type":"string","title":"Compliance Status","description":"KYC/AML status","default":"pending_kyc"}},"type":"object","required":["quote_id","desk_quotes","bank_wire","best_desk","savings_vs_wire_fiat","savings_vs_wire_pct","requested_at","expires_at"],"title":"OTCQuoteResponse","description":"Aggregated quotes from all desks + bank wire comparison."},"Obstacle":{"properties":{"type":{"$ref":"#/components/schemas/ObstacleType"},"x":{"type":"integer","minimum":0.0,"title":"X"},"y":{"type":"integer","minimum":0.0,"title":"Y"},"width":{"type":"integer","maximum":500.0,"exclusiveMinimum":0.0,"title":"Width"},"height":{"type":"integer","maximum":500.0,"exclusiveMinimum":0.0,"title":"Height"},"label":{"type":"string","maxLength":100,"title":"Label","default":""}},"type":"object","required":["type","x","y","width","height"],"title":"Obstacle"},"ObstacleType":{"type":"string","enum":["barrier","road_closure","stage","entry","exit"],"title":"ObstacleType"},"Opportunity":{"properties":{"source":{"type":"string","title":"Source"},"external_id":{"type":"string","title":"External Id"},"title":{"type":"string","title":"Title"},"buyer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer"},"buyer_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Country"},"sector":{"anyOf":[{"type":"string","enum":["construction","manufacturing","supply_chain","facilities","healthcare","defence","transport","it","renewables","marine","education","other"]},{"type":"null"}],"title":"Sector"},"cpv_codes":{"items":{"type":"string"},"type":"array","title":"Cpv Codes"},"naics_codes":{"items":{"type":"string"},"type":"array","title":"Naics Codes"},"value_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value Gbp"},"value_min_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value Min Gbp"},"value_max_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value Max Gbp"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"deadline_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deadline At"},"award_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Award At"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"id":{"type":"string","format":"uuid","title":"Id"},"analysis":{"anyOf":[{"$ref":"#/components/schemas/OpportunityAnalysis"},{"type":"null"}]},"analysis_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Analysis At"},"status":{"type":"string","enum":["open","awarded","cancelled","expired"],"title":"Status","default":"open"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["source","external_id","title","id","created_at","updated_at"],"title":"Opportunity"},"OpportunityAnalysis":{"properties":{"summary":{"type":"string","title":"Summary"},"bom":{"items":{"$ref":"#/components/schemas/BOMItem"},"type":"array","title":"Bom"},"direct_purchase":{"$ref":"#/components/schemas/DirectPurchaseRecommendation"},"resale":{"$ref":"#/components/schemas/ResaleRecommendation"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"generated_by":{"type":"string","enum":["claude","stub"],"title":"Generated By","default":"stub"}},"type":"object","required":["summary","direct_purchase","resale","generated_at"],"title":"OpportunityAnalysis","description":"Output of app.opportunities.analyzer.analyze()."},"OriginScore":{"properties":{"country":{"type":"string","title":"Country"},"country_name":{"type":"string","title":"Country Name"},"score":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Score"},"components":{"additionalProperties":{"type":"number"},"type":"object","title":"Components"},"compliance":{"anyOf":[{"$ref":"#/components/schemas/ComplianceDetail"},{"type":"null"}]},"co2":{"anyOf":[{"$ref":"#/components/schemas/CO2Breakdown"},{"type":"null"}],"description":"Carbon footprint for this origin"},"spot_price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Spot Price Usd"},"lead_time_weeks":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Time Weeks"},"suppliers":{"items":{"$ref":"#/components/schemas/Supplier"},"type":"array","title":"Suppliers"}},"type":"object","required":["country","country_name","score"],"title":"OriginScore","description":"Ranked origin for a commodity."},"ProductSpec":{"properties":{"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query","description":"Free text query, e.g. '15kg raw aluminium'"},"sku_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sku Id","description":"Canonical SKU ID if known"},"hs_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hs Code","description":"HS code if known (e.g. '7601')"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Product name if known"},"qty":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Qty","description":"Quantity"},"unit":{"type":"string","title":"Unit","description":"Unit of measure","default":"kg"}},"type":"object","title":"ProductSpec","description":"What the buyer wants to procure."},"ProfileUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Display Name"},"country_code":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Country Code"},"ship_to_address":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Ship To Address"},"ship_to_city":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Ship To City"},"ship_to_postcode":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Ship To Postcode"},"billing_currency":{"anyOf":[{"type":"string","maxLength":3,"minLength":3},{"type":"null"}],"title":"Billing Currency"},"buyer_sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Sector"},"compliance_regime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compliance Regime"},"default_destination":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Default Destination"},"job_title":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Job Title"},"company_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company Name"},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Phone"},"signature_block":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Signature Block"}},"type":"object","title":"ProfileUpdate","description":"Patch payload for /v1/account. Every field optional."},"QuoteCargoPayload":{"properties":{"load_type":{"$ref":"#/components/schemas/CargoLoadType"},"weight_kg":{"type":"number","maximum":100000000.0,"exclusiveMinimum":0.0,"title":"Weight Kg"},"volume_cbm":{"anyOf":[{"type":"number","maximum":10000.0,"minimum":0.0},{"type":"null"}],"title":"Volume Cbm"},"piece_count":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Piece Count","default":1},"commodity_hs":{"type":"string","maxLength":14,"minLength":6,"title":"Commodity Hs"},"commodity_description":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Commodity Description"},"hazmat":{"type":"boolean","title":"Hazmat","default":false},"temperature_controlled":{"type":"boolean","title":"Temperature Controlled","default":false},"declared_value_usd":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Declared Value Usd"}},"type":"object","required":["load_type","weight_kg","commodity_hs"],"title":"QuoteCargoPayload"},"QuoteLocationPayload":{"properties":{"country":{"type":"string","maxLength":2,"minLength":2,"title":"Country"},"city":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"City"},"postal_code":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Postal Code"},"address_line":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Address Line"},"residential":{"type":"boolean","title":"Residential","default":false},"port_code":{"anyOf":[{"type":"string","maxLength":5},{"type":"null"}],"title":"Port Code"}},"type":"object","required":["country"],"title":"QuoteLocationPayload"},"Recommendation":{"properties":{"intent":{"$ref":"#/components/schemas/Intent"},"summary":{"type":"string","title":"Summary","description":"One-line headline, e.g. 'Source from Canada via Panama Canal'"},"product_description":{"type":"string","title":"Product Description","description":"2-3 sentence product description for the buyer","default":""},"route":{"anyOf":[{"$ref":"#/components/schemas/RoutePlan"},{"type":"null"}]},"fx":{"anyOf":[{"$ref":"#/components/schemas/FXRecommendation"},{"type":"null"}]},"origins":{"anyOf":[{"items":{"$ref":"#/components/schemas/OriginScore"},"type":"array"},{"type":"null"}],"title":"Origins"},"landed_cost":{"anyOf":[{"$ref":"#/components/schemas/TotalLandedCost"},{"type":"null"}]},"compliance":{"anyOf":[{"$ref":"#/components/schemas/ComplianceDetail"},{"type":"null"}]}},"type":"object","required":["intent","summary"],"title":"Recommendation","description":"The top-ranked option, varies by intent."},"ReconRequest":{"properties":{"target":{"type":"string","maxLength":253,"minLength":1,"title":"Target","description":"Domain, email, or IP address"}},"type":"object","required":["target"],"title":"ReconRequest"},"ResaleRecommendation":{"properties":{"eligible":{"type":"boolean","title":"Eligible"},"est_acquisition_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Acquisition Gbp"},"est_resale_value_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Resale Value Gbp"},"est_margin_gbp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Margin Gbp"},"est_margin_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Margin Pct"},"rationale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rationale"}},"type":"object","required":["eligible"],"title":"ResaleRecommendation","description":"Private-sector resale path: if acquired as surplus / post-award,\nwhat is the expected resale margin?"},"RfqAcceptBody":{"properties":{"confirm":{"type":"boolean","title":"Confirm","description":"Must be True to dispatch.","default":false},"override_price":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Override Price"},"override_basis":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Override Basis"},"override_qty":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Override Qty"},"note":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Note"},"accepted_modifier":{"anyOf":[{"$ref":"#/components/schemas/AcceptedModifier"},{"type":"null"}]}},"type":"object","title":"RfqAcceptBody","description":"Body for POST /v1/rfqs/{id}/accept. All fields optional — we fall\nback to the latest parsed quote when omitted."},"RfqCreate":{"properties":{"decision_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Decision Id"},"supplier":{"$ref":"#/components/schemas/SupplierSnapshot"},"product_query":{"type":"string","maxLength":500,"minLength":1,"title":"Product Query"},"product_hs_code":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Product Hs Code"},"qty":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Qty"},"qty_unit":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Qty Unit"},"target_price_usd":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Target Price Usd"},"deadline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deadline"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"},"auto_negotiate":{"type":"boolean","title":"Auto Negotiate","default":false}},"type":"object","required":["supplier","product_query"],"title":"RfqCreate"},"RfqStatusUpdate":{"properties":{"status":{"type":"string","maxLength":32,"minLength":1,"title":"Status"},"note":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Note"}},"type":"object","required":["status"],"title":"RfqStatusUpdate"},"RiskAppetite":{"type":"string","enum":["conservative","balanced","aggressive"],"title":"RiskAppetite"},"RouteConstraints":{"properties":{"via_nodes":{"items":{"type":"string"},"type":"array","title":"Via Nodes","description":"Must pass through these ports/nodes, e.g. ['PA-PTY'] for Panama"},"avoid_nodes":{"items":{"type":"string"},"type":"array","title":"Avoid Nodes","description":"Must NOT pass through these, e.g. ['EG-SUZ'] to avoid Suez"},"exclude_modes":{"items":{"$ref":"#/components/schemas/TransportMode"},"type":"array","title":"Exclude Modes","description":"Transport modes to exclude, e.g. ['air'] for no air freight"},"preferred_mode":{"anyOf":[{"$ref":"#/components/schemas/TransportMode"},{"type":"null"}],"description":"Preferred mode if multiple available"}},"type":"object","title":"RouteConstraints","description":"User-specified route preferences and restrictions."},"RouteLeg":{"properties":{"from_node":{"type":"string","title":"From Node"},"to_node":{"type":"string","title":"To Node"},"mode":{"type":"string","title":"Mode"},"carrier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Carrier"},"transit_days":{"type":"number","title":"Transit Days"},"cost_usd":{"type":"number","title":"Cost Usd"},"risk_score":{"type":"number","title":"Risk Score","default":0},"co2_kg":{"type":"number","title":"Co2 Kg","default":0}},"type":"object","required":["from_node","to_node","mode","transit_days","cost_usd"],"title":"RouteLeg","description":"One segment of a multimodal route."},"RoutePlan":{"properties":{"rank":{"type":"integer","title":"Rank"},"legs":{"items":{"$ref":"#/components/schemas/RouteLeg"},"type":"array","title":"Legs"},"total_transit_days":{"type":"number","title":"Total Transit Days"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"},"total_risk":{"type":"number","title":"Total Risk"},"total_co2_kg":{"type":"number","title":"Total Co2 Kg"},"compliance":{"anyOf":[{"$ref":"#/components/schemas/ComplianceDetail"},{"type":"null"}]},"score":{"type":"number","title":"Score","description":"Blended score (lower = better)"}},"type":"object","required":["rank","legs","total_transit_days","total_cost_usd","total_risk","total_co2_kg","score"],"title":"RoutePlan","description":"A complete route option with cost and risk."},"RuleCreate":{"properties":{"description":{"type":"string","maxLength":500,"minLength":10,"title":"Description"},"watchlist_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Watchlist Id"}},"type":"object","required":["description"],"title":"RuleCreate"},"ScanRequest":{"properties":{"target":{"type":"string","maxLength":253,"minLength":1,"title":"Target","description":"Domain name"}},"type":"object","required":["target"],"title":"ScanRequest"},"ScenarioType":{"type":"string","enum":["river_flood","flash_flood","storm_surge","dam_break","tidal"],"title":"ScenarioType"},"ShadowVerifyRequest":{"properties":{"claimed_lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Claimed Lat"},"claimed_lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Claimed Lon"},"claimed_time":{"type":"string","title":"Claimed Time"},"observed_shadow_direction":{"anyOf":[{"type":"number","maximum":360.0,"minimum":0.0},{"type":"null"}],"title":"Observed Shadow Direction"}},"type":"object","required":["claimed_lat","claimed_lon","claimed_time"],"title":"ShadowVerifyRequest"},"SharkDetection":{"properties":{"species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species"},"detection_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detection Type"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lon":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lon"},"datetime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Datetime"},"beach_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Beach Name"}},"type":"object","title":"SharkDetection"},"SharksResponse":{"properties":{"count":{"type":"integer","title":"Count"},"detections":{"items":{"$ref":"#/components/schemas/SharkDetection"},"type":"array","title":"Detections"},"source":{"type":"string","title":"Source","default":"SharkSmart NSW"}},"type":"object","required":["count","detections"],"title":"SharksResponse"},"ShipmentService":{"type":"string","enum":["door_to_door","door_to_port","port_to_door","port_to_port"],"title":"ShipmentService","description":"Service leg coverage.\n\n``door_to_door`` is the target for the Alibaba-parallel UX (WYRM's\nstrong preference). The others exist because Freightos occasionally\nhas coverage on partial legs only, and buyers with their own\ncustoms brokers may prefer port-to-port pricing."},"ShippingQuoteRequestBody":{"properties":{"origin":{"$ref":"#/components/schemas/QuoteLocationPayload"},"destination":{"$ref":"#/components/schemas/QuoteLocationPayload"},"cargo":{"$ref":"#/components/schemas/QuoteCargoPayload"},"service":{"$ref":"#/components/schemas/ShipmentService","default":"door_to_door"},"incoterm":{"$ref":"#/components/schemas/Incoterm","default":"DDP"},"ready_date":{"type":"string","format":"date","title":"Ready Date"},"required_by":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Required By"}},"type":"object","required":["origin","destination","cargo","ready_date"],"title":"ShippingQuoteRequestBody"},"SignalDetail":{"properties":{"name":{"type":"string","title":"Name","description":"Signal identifier: 'price_forecast', 'sentiment', 'route_risk', etc."},"value":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Value","description":"Normalized 0-1 score"},"direction":{"$ref":"#/components/schemas/SignalDirection"},"summary":{"type":"string","title":"Summary","description":"One-line human-readable explanation"},"raw_data":{"additionalProperties":true,"type":"object","title":"Raw Data","description":"Full signal detail for UI cards"}},"type":"object","required":["name","value","direction","summary"],"title":"SignalDetail","description":"One signal in the intelligence breakdown."},"SignalDirection":{"type":"string","enum":["bullish","bearish","neutral"],"title":"SignalDirection"},"SituationalAnalysisConfig":{"properties":{"lookback_days":{"type":"integer","maximum":90.0,"minimum":1.0,"title":"Lookback Days","default":30}},"type":"object","title":"SituationalAnalysisConfig"},"SituationalAnalysisCreate":{"properties":{"scenario":{"type":"string","maxLength":5000,"minLength":10,"title":"Scenario"},"seed_alert_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seed Alert Id"},"config":{"$ref":"#/components/schemas/SituationalAnalysisConfig","default":{"lookback_days":30}}},"type":"object","required":["scenario"],"title":"SituationalAnalysisCreate"},"SortBy":{"type":"string","enum":["cost","co2","balanced"],"title":"SortBy"},"SunPositionRequest":{"properties":{"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lon"},"timestamp":{"type":"string","title":"Timestamp"}},"type":"object","required":["lat","lon","timestamp"],"title":"SunPositionRequest"},"Supplier":{"properties":{"name":{"type":"string","title":"Name"},"location":{"type":"string","title":"Location","default":""},"factory":{"type":"string","title":"Factory","description":"Factory/facility name if known","default":""},"price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Usd"},"capacity":{"type":"string","title":"Capacity","default":""},"max_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Qty","description":"Maximum order quantity this supplier can fill"},"capacity_unit":{"type":"string","title":"Capacity Unit","description":"Unit for max_qty, e.g. 'tonnes/month'","default":""},"certifications":{"items":{"type":"string"},"type":"array","title":"Certifications","description":"e.g. ['ISO 9001', 'ISO 14001']"},"can_fill_order":{"type":"boolean","title":"Can Fill Order","description":"Whether supplier can fill the requested quantity","default":true},"verified":{"type":"boolean","title":"Verified","description":"Whether supplier was verified against company registry","default":false},"registration_number":{"type":"string","title":"Registration Number","description":"Company registration number","default":""},"jurisdiction":{"type":"string","title":"Jurisdiction","description":"Registry jurisdiction code","default":""},"registry_url":{"type":"string","title":"Registry Url","description":"Link to official registry record","default":""},"parent_company":{"type":"string","title":"Parent Company","description":"Ultimate beneficial owner / parent corp","default":""},"sanctions_hit":{"type":"boolean","title":"Sanctions Hit","description":"Whether matched against OpenSanctions data","default":false},"contact_email":{"type":"string","title":"Contact Email","description":"Sales/RFQ email if known","default":""},"website":{"type":"string","title":"Website","description":"Canonical company website","default":""},"source_url":{"type":"string","title":"Source Url","description":"Original source page for this supplier record","default":""},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","required":["name"],"title":"Supplier","description":"A specific supplier/producer in a country."},"SupplierEntry":{"properties":{"name":{"type":"string","title":"Name"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"unit_price_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Unit Price Usd"},"min_order_qty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Order Qty"},"lead_time_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Lead Time Days"},"product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Code"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"}},"type":"object","required":["name"],"title":"SupplierEntry"},"SupplierSnapshot":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"location":{"type":"string","maxLength":200,"title":"Location","default":""},"country":{"type":"string","maxLength":4,"title":"Country","default":""},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"website":{"type":"string","maxLength":500,"title":"Website","default":""},"registration_number":{"type":"string","maxLength":120,"title":"Registration Number","default":""},"jurisdiction":{"type":"string","maxLength":16,"title":"Jurisdiction","default":""}},"type":"object","required":["name"],"title":"SupplierSnapshot"},"SurfConditions":{"properties":{"station_id":{"type":"string","title":"Station Id"},"station_name":{"type":"string","title":"Station Name"},"distance_km":{"type":"number","title":"Distance Km"},"wave_height_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wave Height M"},"wave_period_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wave Period Sec"},"wave_direction_deg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wave Direction Deg"},"water_temp_c":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Water Temp C"},"wind_speed_mps":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wind Speed Mps"},"wind_direction_deg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Wind Direction Deg"},"surf_quality_score":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Surf Quality Score"},"surf_quality_label":{"type":"string","title":"Surf Quality Label"},"timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timestamp"},"source":{"type":"string","title":"Source","default":"NDBC"}},"type":"object","required":["station_id","station_name","distance_km","surf_quality_score","surf_quality_label"],"title":"SurfConditions"},"Tm65ItemReport":{"properties":{"name":{"type":"string","title":"Name"},"category":{"type":"string","title":"Category"},"product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Code"},"quantity":{"type":"integer","title":"Quantity"},"unit_mass_kg":{"type":"number","title":"Unit Mass Kg"},"manufacturing_country":{"type":"string","title":"Manufacturing Country"},"raw_materials_kg_co2e":{"type":"number","title":"Raw Materials Kg Co2E"},"manufacturing_kg_co2e":{"type":"number","title":"Manufacturing Kg Co2E"},"transport_kg_co2e":{"type":"number","title":"Transport Kg Co2E"},"eol_kg_co2e":{"type":"number","title":"Eol Kg Co2E"},"total_unit_kg_co2e":{"type":"number","title":"Total Unit Kg Co2E"},"total_line_kg_co2e":{"type":"number","title":"Total Line Kg Co2E"},"materials":{"items":{"$ref":"#/components/schemas/MaterialBreakdown"},"type":"array","title":"Materials"},"unknown_materials":{"items":{"type":"string"},"type":"array","title":"Unknown Materials"},"notes":{"items":{"type":"string"},"type":"array","title":"Notes"}},"type":"object","required":["name","category","quantity","unit_mass_kg","manufacturing_country","raw_materials_kg_co2e","manufacturing_kg_co2e","transport_kg_co2e","eol_kg_co2e","total_unit_kg_co2e","total_line_kg_co2e","materials","unknown_materials","notes"],"title":"Tm65ItemReport","description":"Computed TM65 numbers for a single BOM item."},"Tm65Report":{"properties":{"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"destination_country":{"type":"string","title":"Destination Country"},"summary":{"$ref":"#/components/schemas/Tm65Summary"},"items":{"items":{"$ref":"#/components/schemas/Tm65ItemReport"},"type":"array","title":"Items"},"methodology":{"type":"string","title":"Methodology","default":"CIBSE TM65 Level 2 (2021), simplified implementation"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"persisted":{"type":"boolean","title":"Persisted","default":true}},"type":"object","required":["destination_country","summary","items"],"title":"Tm65Report"},"Tm65Request":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Name"},"destination_country":{"type":"string","pattern":"^[A-Za-z]{2}$","title":"Destination Country","default":"GB"},"items":{"items":{"$ref":"#/components/schemas/BomItem"},"type":"array","maxItems":500,"minItems":1,"title":"Items"}},"type":"object","required":["items"],"title":"Tm65Request","description":"Full TM65 BOM request."},"Tm65Summary":{"properties":{"total_kg_co2e":{"type":"number","title":"Total Kg Co2E"},"total_tonnes_co2e":{"type":"number","title":"Total Tonnes Co2E"},"item_count":{"type":"integer","title":"Item Count"},"line_count":{"type":"integer","title":"Line Count"},"lines_with_unknown_materials":{"type":"integer","title":"Lines With Unknown Materials"},"breakdown_kg_co2e":{"additionalProperties":{"type":"number"},"type":"object","title":"Breakdown Kg Co2E"}},"type":"object","required":["total_kg_co2e","total_tonnes_co2e","item_count","line_count","lines_with_unknown_materials","breakdown_kg_co2e"],"title":"Tm65Summary"},"TotalLandedCost":{"properties":{"total":{"type":"number","title":"Total"},"currency":{"type":"string","title":"Currency","default":"GBP"},"components":{"$ref":"#/components/schemas/CostComponents"},"margin_of_error_pct":{"type":"number","title":"Margin Of Error Pct","description":"Confidence band (± %)","default":0},"co2":{"anyOf":[{"$ref":"#/components/schemas/CO2Breakdown"},{"type":"null"}],"description":"Total CO2 for this procurement option"}},"type":"object","required":["total","components"],"title":"TotalLandedCost","description":"Single headline number + breakdown."},"TrackResponse":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type","default":"Feature"},"geometry":{"additionalProperties":true,"type":"object","title":"Geometry"},"properties":{"additionalProperties":true,"type":"object","title":"Properties"},"source":{"type":"string","title":"Source","default":"OCEARCH"}},"type":"object","required":["name","geometry","properties"],"title":"TrackResponse"},"TrackedAnimal":{"properties":{"name":{"type":"string","title":"Name"},"species":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Species"},"length":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Length"},"weight":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Weight"},"last_ping":{"anyOf":[{"$ref":"#/components/schemas/LastPing"},{"type":"null"}]},"track_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Track Url"}},"type":"object","required":["name"],"title":"TrackedAnimal"},"TransportMode":{"type":"string","enum":["sea","air","rail","road"],"title":"TransportMode"},"UrlScanRequest":{"properties":{"url":{"type":"string","maxLength":4096,"minLength":1,"title":"Url","description":"URL to scan via VirusTotal"}},"type":"object","required":["url"],"title":"UrlScanRequest"},"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"},"WatchlistCreate":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"WatchlistCreate"},"WatchlistItemCreate":{"properties":{"entity_type":{"type":"string","title":"Entity Type"},"identifier":{"type":"string","title":"Identifier"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"alert_config":{"additionalProperties":true,"type":"object","title":"Alert Config","default":{}}},"type":"object","required":["entity_type","identifier"],"title":"WatchlistItemCreate"},"ZoneCreate":{"properties":{"name":{"type":"string","title":"Name"},"boundary":{"additionalProperties":true,"type":"object","title":"Boundary"},"alert_config":{"additionalProperties":true,"type":"object","title":"Alert Config","default":{}}},"type":"object","required":["name","boundary"],"title":"ZoneCreate"},"ZoneDefinition":{"properties":{"x":{"type":"number","title":"X","description":"Left edge in pixels"},"y":{"type":"number","title":"Y","description":"Top edge in pixels"},"width":{"type":"number","exclusiveMinimum":0.0,"title":"Width","description":"Width in pixels"},"height":{"type":"number","exclusiveMinimum":0.0,"title":"Height","description":"Height in pixels"},"density":{"$ref":"#/components/schemas/DensityClass"},"label":{"type":"string","maxLength":100,"title":"Label","default":""}},"type":"object","required":["x","y","width","height","density"],"title":"ZoneDefinition","description":"A rectangular zone drawn on the image."},"ZoneResult":{"properties":{"label":{"type":"string","title":"Label"},"density_class":{"type":"string","title":"Density Class"},"density_per_m2":{"type":"number","title":"Density Per M2"},"area_px":{"type":"number","title":"Area Px"},"area_m2":{"type":"number","title":"Area M2"},"estimated_people":{"type":"integer","title":"Estimated People"},"crush_risk":{"type":"boolean","title":"Crush Risk"}},"type":"object","required":["label","density_class","density_per_m2","area_px","area_m2","estimated_people","crush_risk"],"title":"ZoneResult"},"app__routers__crowd__SimulateRequest":{"properties":{"crowd_size":{"type":"integer","maximum":250000.0,"exclusiveMinimum":0.0,"title":"Crowd Size"},"grid_width":{"type":"integer","maximum":500.0,"exclusiveMinimum":0.0,"title":"Grid Width","description":"Grid width in cells (1m per cell)"},"grid_height":{"type":"integer","maximum":500.0,"exclusiveMinimum":0.0,"title":"Grid Height","description":"Grid height in cells (1m per cell)"},"obstacles":{"items":{"$ref":"#/components/schemas/Obstacle"},"type":"array","maxItems":200,"title":"Obstacles"},"venue_name":{"type":"string","maxLength":200,"title":"Venue Name","default":""},"venue_lat":{"anyOf":[{"type":"number","maximum":90.0,"minimum":-90.0},{"type":"null"}],"title":"Venue Lat"},"venue_lon":{"anyOf":[{"type":"number","maximum":180.0,"minimum":-180.0},{"type":"null"}],"title":"Venue Lon"},"max_ticks":{"type":"integer","maximum":1000.0,"exclusiveMinimum":0.0,"title":"Max Ticks","default":300},"snapshot_interval":{"type":"integer","maximum":100.0,"exclusiveMinimum":0.0,"title":"Snapshot Interval","description":"Ticks between snapshots","default":10}},"type":"object","required":["crowd_size","grid_width","grid_height"],"title":"SimulateRequest"},"app__routers__crowd__SimulationStatus":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"progress":{"type":"number","title":"Progress"},"venue_name":{"type":"string","title":"Venue Name"},"crowd_size":{"type":"integer","title":"Crowd Size"},"created_at":{"type":"string","title":"Created At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","status","progress","venue_name","crowd_size","created_at"],"title":"SimulationStatus"},"app__routers__flood__SimulateRequest":{"properties":{"center_lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Center Lat","description":"Center latitude"},"center_lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Center Lon","description":"Center longitude"},"location_name":{"type":"string","maxLength":200,"title":"Location Name","default":""},"scenario_type":{"$ref":"#/components/schemas/ScenarioType"},"rainfall_mm_hr":{"type":"number","maximum":200.0,"minimum":10.0,"title":"Rainfall Mm Hr","description":"Rainfall intensity in mm/hr"},"duration_hours":{"type":"number","maximum":72.0,"minimum":1.0,"title":"Duration Hours","description":"Simulation duration in hours"},"water_level_rise_m":{"type":"number","maximum":10.0,"minimum":0.0,"title":"Water Level Rise M","description":"Water level rise for river/tidal scenarios","default":0.0},"grid_resolution_m":{"$ref":"#/components/schemas/GridResolution","description":"Cell size in meters","default":30},"mannings_preset":{"$ref":"#/components/schemas/ManningsPreset","description":"Manning's roughness preset","default":"suburban"}},"type":"object","required":["center_lat","center_lon","scenario_type","rainfall_mm_hr","duration_hours"],"title":"SimulateRequest","description":"Configuration for a flood simulation run."},"app__routers__flood__SimulationStatus":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"progress":{"type":"number","title":"Progress"},"location_name":{"type":"string","title":"Location Name"},"scenario_type":{"type":"string","title":"Scenario Type"},"created_at":{"type":"string","title":"Created At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","status","progress","location_name","scenario_type","created_at"],"title":"SimulationStatus"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}