{"openapi":"3.1.0","info":{"title":"antiphish-api","description":"Modulares Anti-Phishing/Anti-Spam-Backend — Heuristik + LLM-Deep-Mode.","version":"0.2.0"},"paths":{"/scan/url":{"post":{"tags":["scan"],"summary":"Scan Url","operationId":"scan_url_scan_url_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/scan/email":{"post":{"tags":["scan"],"summary":"Scan Email","operationId":"scan_email_scan_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/unsubscribe/extract":{"post":{"tags":["unsubscribe"],"summary":"Extract","operationId":"extract_unsubscribe_extract_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeExtractResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/unsubscribe/execute":{"post":{"tags":["unsubscribe"],"summary":"Execute","operationId":"execute_unsubscribe_execute_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeExecuteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeExecuteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/unsubscribe/status/{message_id}":{"get":{"tags":["unsubscribe"],"summary":"Status","description":"Liefert den aktuellen Zustellstatus inklusive evtl. spaeter eingetroffener DSN.\n\n`message_id` kann mit oder ohne <...> uebergeben werden.","operationId":"status_unsubscribe_status__message_id__get","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/discover/imap":{"post":{"tags":["discover"],"summary":"Discover Imap","description":"Fragt das LLM, ob es die IMAP-Settings einer Domain kennt.\nPrivacy-Hinweis: NUR die Domain wird an die LLM-Cloud übermittelt,\nkeine Mailadresse, keine Mail-Inhalte. Caller (MailGuard-Plugin) cached\ndie Antwort 7 Tage in einem WP-Transient.","operationId":"discover_imap_discover_imap_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoverRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoverResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Health","description":"Liveness + optionaler Ollama-Ping. Ollama-Ausfall macht den Endpoint\nNICHT unhealthy — der API-Service selbst läuft ja.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Health Get"}}}}}}}},"components":{"schemas":{"DiscoverRequest":{"properties":{"domain":{"type":"string","maxLength":253,"minLength":3,"title":"Domain"}},"type":"object","required":["domain"],"title":"DiscoverRequest"},"DiscoverResponse":{"properties":{"found":{"type":"boolean","title":"Found"},"host":{"type":"string","title":"Host","default":""},"port":{"type":"integer","title":"Port","default":0},"encryption":{"type":"string","title":"Encryption","default":""},"confidence":{"type":"number","title":"Confidence","default":0.0},"note":{"type":"string","title":"Note","default":""},"source":{"type":"string","title":"Source","default":"llm"}},"type":"object","required":["found"],"title":"DiscoverResponse"},"EmailScanRequest":{"properties":{"subject":{"type":"string","maxLength":4096,"title":"Subject","default":""},"body":{"type":"string","maxLength":200000,"title":"Body","default":""},"from_addr":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"title":"From Addr"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers","description":"Optionale Mail-Header (z.B. 'List-Unsubscribe'). Keys werden case-insensitive ausgewertet."},"deep":{"type":"boolean","title":"Deep","description":"True erzwingt den LLM-Deep-Mode. Sonst läuft der LLM nur, wenn der Heuristik-Score im unklaren Mittelband (DEEP_MIN..DEEP_MAX) liegt.","default":false}},"type":"object","title":"EmailScanRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Reason":{"properties":{"rule":{"type":"string","title":"Rule","description":"Stabiler Regel-ID-String, z. B. 'url.ip_host'."},"description":{"type":"string","title":"Description","description":"Menschlich lesbare Erklärung."},"score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Score","description":"Teilscore dieser Regel."}},"type":"object","required":["rule","description","score"],"title":"Reason"},"ScanResult":{"properties":{"verdict":{"$ref":"#/components/schemas/Verdict"},"score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Score"},"reasons":{"items":{"$ref":"#/components/schemas/Reason"},"type":"array","title":"Reasons"}},"type":"object","required":["verdict","score"],"title":"ScanResult"},"UnsubscribeExecuteRequest":{"properties":{"email":{"$ref":"#/components/schemas/EmailScanRequest"},"option":{"$ref":"#/components/schemas/UnsubscribeOption"}},"type":"object","required":["email","option"],"title":"UnsubscribeExecuteRequest","description":"Execute fuehrt eine konkrete UnsubscribeOption aus.\n\nDie ursprueengliche Mail wird mitgegeben, damit der Phishing-Scan\nVOR dem Abmelden laufen kann (Schutz vor Tracking-Pixel-Effekt bei\nPhishing-Mails)."},"UnsubscribeExecuteResponse":{"properties":{"status":{"type":"string","title":"Status","description":"'unsubscribed' | 'needs_manual' | 'blocked' | 'smtp_not_configured' | 'failed'"},"detail":{"type":"string","title":"Detail"},"http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Http Status"},"scan":{"anyOf":[{"$ref":"#/components/schemas/ScanResult"},{"type":"null"}]},"option":{"anyOf":[{"$ref":"#/components/schemas/UnsubscribeOption"},{"type":"null"}]},"manual_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manual Url","description":"Bei status='needs_manual': URL, die der Nutzer im Browser oeffnen muss (z.B. wenn der Provider One-Click-POST als 404 abweist und statt dessen nur einen GET-Endpoint mit User-Facing-Formular anbietet)."},"message_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Id","description":"Message-ID der von uns versendeten mailto-Abmeldung (nur fuer Mailto-Optionen)."},"queue_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Queue Id","description":"Postfix-Queue-ID, falls die Abmeldung lokal eingespeist wurde."},"postfix_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postfix Status","description":"Echtes Postfix-Ergebnis: 'sent' | 'bounced' | 'deferred' | 'queued'."},"bounce_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bounce Reason","description":"Bei postfix_status='bounced': SMTP-Fehler-Text des Remote-Servers, sofern aus dem Journal extrahierbar."}},"type":"object","required":["status","detail"],"title":"UnsubscribeExecuteResponse"},"UnsubscribeExtractResponse":{"properties":{"found":{"type":"boolean","title":"Found"},"options":{"items":{"$ref":"#/components/schemas/UnsubscribeOption"},"type":"array","title":"Options"}},"type":"object","required":["found"],"title":"UnsubscribeExtractResponse"},"UnsubscribeKind":{"type":"string","enum":["http","mailto"],"title":"UnsubscribeKind"},"UnsubscribeOption":{"properties":{"kind":{"$ref":"#/components/schemas/UnsubscribeKind"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"one_click":{"type":"boolean","title":"One Click","description":"True wenn RFC 8058 One-Click signalisiert ist (Header List-Unsubscribe-Post: List-Unsubscribe=One-Click).","default":false},"mailto_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailto To"},"mailto_subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailto Subject"},"mailto_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailto Body"}},"type":"object","required":["kind"],"title":"UnsubscribeOption"},"UnsubscribeStatusResponse":{"properties":{"message_id":{"type":"string","title":"Message Id"},"found":{"type":"boolean","title":"Found"},"queue_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Queue Id"},"sent_at":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sent At"},"from_addr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Addr"},"to_addr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Addr"},"smtp_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smtp Status"},"smtp_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smtp Detail"},"dsn_received_at":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dsn Received At"},"dsn_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dsn Action","description":"RFC-3464 Action: 'failed' | 'delayed' | 'delivered' | 'relayed' | 'expanded'."},"dsn_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dsn Status","description":"RFC-3464 Status, z.B. '5.1.1'."},"dsn_diagnostic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dsn Diagnostic"},"dsn_remote_mta":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dsn Remote Mta"}},"type":"object","required":["message_id","found"],"title":"UnsubscribeStatusResponse","description":"Aktueller Zustellstatus einer fruher abgesetzten mailto-Abmeldung.\n\nWird vom DeliveryStore gelesen; bei spaeten Remote-DSN-Mails sind die\ndsn_*-Felder gefuellt."},"UrlScanRequest":{"properties":{"url":{"type":"string","maxLength":4096,"minLength":1,"title":"Url"}},"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"},"Verdict":{"type":"string","enum":["clean","suspicious","dangerous"],"title":"Verdict"}}}}