{"components":{"parameters":{"FeedSince":{"description":"Return IOCs added on or after this RFC3339 timestamp","in":"query","name":"since","schema":{"format":"date-time","type":"string"}},"FeedSlug":{"description":"Threat feed slug","in":"path","name":"slug","required":true,"schema":{"type":"string"}},"FeedWindow":{"description":"Sliding time window shorthand (overridden by `since` if both provided)","in":"query","name":"window","schema":{"enum":["1h","24h","7d","30d"],"type":"string"}},"Page":{"description":"Page number","in":"query","name":"page","schema":{"default":1,"minimum":1,"type":"integer"}},"PerPage":{"description":"Items per page (max 100)","in":"query","name":"per_page","schema":{"default":25,"maximum":100,"minimum":1,"type":"integer"}},"ReportId":{"description":"Report UUID","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}},"responses":{"BadRequest":{"content":{"application/json":{"example":{"error":{"code":"VALIDATION_ERROR","details":null,"message":"ioc_value is required"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Validation error or malformed request"},"Conflict":{"content":{"application/json":{"example":{"error":{"code":"CONFLICT","details":null,"message":"email already registered"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Conflict — resource already exists or duplicate action"},"Forbidden":{"content":{"application/json":{"example":{"error":{"code":"FORBIDDEN","details":null,"message":"admin scope required"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Authenticated but insufficient permissions"},"NotFound":{"content":{"application/json":{"example":{"error":{"code":"NOT_FOUND","details":null,"message":"report not found"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Resource not found"},"TooManyRequests":{"content":{"application/json":{"example":{"error":{"code":"RATE_LIMITED","details":null,"message":"anonymous submission limit: 10 per hour"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Rate limit exceeded"},"Unauthorized":{"content":{"application/json":{"example":{"error":{"code":"UNAUTHORIZED","details":null,"message":"invalid or expired token"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Missing or invalid authentication credentials"}},"schemas":{"APIKeyListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKeyResponse"},"type":"array"}},"required":["data"],"type":"object"},"APIKeyResponse":{"properties":{"commercial_tier":{"enum":["community","pro","enterprise"],"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"is_active":{"type":"boolean"},"key_prefix":{"description":"First 8 characters of the key for identification","example":"vsp_abc1","type":"string"},"label":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"rate_limit_tier":{"description":"Applied rate limit tier","type":"string"},"scopes":{"items":{"enum":["read","write","admin"],"type":"string"},"type":"array"}},"required":["id","label","key_prefix","scopes","rate_limit_tier","commercial_tier","is_active","created_at"],"type":"object"},"AbuseNotificationEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/AbuseNotificationResponse"}},"required":["data"],"type":"object"},"AbuseNotificationListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/AbuseNotificationResponse"},"type":"array"}},"required":["data"],"type":"object"},"AbuseNotificationResponse":{"properties":{"abuse_email":{"format":"email","type":"string"},"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"email_body":{"type":["string","null"]},"email_subject":{"type":["string","null"]},"error":{"type":["string","null"]},"id":{"format":"uuid","type":"string"},"provider_id":{"format":"uuid","type":"string"},"provider_name":{"type":"string"},"report_id":{"format":"uuid","type":"string"},"sent_at":{"format":"date-time","type":"string"},"status":{"enum":["pending","approved","sent","failed","skipped"],"type":"string"},"takedown_detected_at":{"format":"date-time","type":"string"},"time_to_takedown_hours":{"format":"float","type":"number"}},"required":["id","report_id","provider_name","abuse_email","status","created_at"],"type":"object"},"AbuseStatsEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/AbuseStatsResponse"}},"required":["data"],"type":"object"},"AbuseStatsResponse":{"properties":{"avg_takedown_hours":{"format":"float","type":"number"},"bounce_rate":{"format":"float","type":"number"},"pending_review":{"type":"integer"},"takedown_rate":{"description":"Fraction of notifications resulting in takedown (0.0–1.0)","format":"float","type":"number"},"total_sent":{"type":"integer"},"total_takedowns":{"type":"integer"}},"required":["total_sent","total_takedowns","avg_takedown_hours","takedown_rate","pending_review","bounce_rate"],"type":"object"},"AuditLogEntry":{"description":"An entry in the admin audit log","properties":{"action":{"description":"Action performed (e.g. update_report_status, delete_report)","type":"string"},"actor_id":{"description":"Reporter/admin who performed the action","format":"uuid","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"target_id":{"format":"uuid","type":"string"},"target_type":{"description":"Entity type affected","type":"string"}},"type":"object"},"BlockListResultResponse":{"properties":{"checked_at":{"format":"date-time","type":"string"},"confidence":{"type":"string"},"listed":{"type":"boolean"},"name":{"example":"vspam reports","type":"string"},"reason":{"type":"string"},"status":{"type":"string"}},"required":["name","listed","status"],"type":"object"},"BrandDetailEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/BrandDetailResponse"}},"required":["data"],"type":"object"},"BrandDetailResponse":{"allOf":[{"$ref":"#/components/schemas/BrandResponse"},{"properties":{"categories":{"description":"Categories of phishing activity targeting this brand","items":{"type":"string"},"type":"array"},"top_ioc_types":{"items":{"type":"string"},"type":"array"},"trend":{"items":{"description":"Time-series report count per day/week","type":"object"},"type":"array"}},"type":"object"}]},"BrandListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/BrandResponse"},"type":"array"},"meta":{"$ref":"#/components/schemas/BrandListMeta"}},"required":["data","meta"],"type":"object"},"BrandListMeta":{"allOf":[{"$ref":"#/components/schemas/Meta"},{"properties":{"summary":{"$ref":"#/components/schemas/BrandListSummary"}},"type":"object"}],"description":"Standard pagination meta plus a summary computed across all brands in the window. Nested here (rather than beside data/meta) because the web client's list-fetch helper only forwards the data and meta fields."},"BrandListSummary":{"description":"Metrics computed across every brand in the window, not just the current page — a paginated brand list can't derive these on its own.","properties":{"attributed_reports":{"description":"All brand-attributed reports in the window. top10_reports / attributed_reports is the top-10 concentration share.","type":"integer"},"new_entrants":{"description":"Brands whose first-ever report (all time) falls inside the selected window","type":"integer"},"top10_reports":{"description":"Reports attributed to the 10 highest-volume brands in the window","type":"integer"}},"type":"object"},"BrandResponse":{"description":"Summary of a brand targeted by phishing","properties":{"kit_count":{"type":"integer"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"report_count":{"type":"integer"}},"type":"object"},"BulkCreateReportRequest":{"properties":{"reports":{"items":{"$ref":"#/components/schemas/CreateReportRequest"},"maxItems":100,"minItems":1,"type":"array"}},"required":["reports"],"type":"object"},"BulkResultEnvelope":{"properties":{"data":{"properties":{"created":{"type":"integer"},"results":{"items":{"$ref":"#/components/schemas/BulkResultItem"},"type":"array"},"total":{"type":"integer"}},"required":["total","created","results"],"type":"object"}},"required":["data"],"type":"object"},"BulkResultItem":{"properties":{"error":{"type":["string","null"]},"index":{"description":"Zero-based index in the submitted array","type":"integer"},"ioc_value":{"type":"string"},"report_id":{"format":"uuid","type":"string"},"status":{"enum":["created","duplicate","error"],"type":"string"}},"required":["index","status","ioc_value"],"type":"object"},"CastVoteRequest":{"properties":{"vote_type":{"enum":["confirm","reject"],"type":"string"}},"required":["vote_type"],"type":"object"},"ContentDetailsResponse":{"properties":{"content_type":{"type":"string"},"error":{"type":"string"},"final_url":{"type":"string"},"reachable":{"type":"boolean"},"server":{"type":"string"},"skipped_reason":{"type":"string"},"status_code":{"type":"integer"},"title":{"type":"string"},"url":{"type":"string"}},"required":["reachable"],"type":"object"},"CreateAuthReportRequest":{"properties":{"category":{"maxLength":64,"type":"string"},"evidence":{"maxLength":4096,"type":"string"},"ioc_type":{"enum":["url","email","domain","ip"],"type":"string"},"ioc_value":{"maxLength":2048,"minLength":3,"type":"string"},"screenshot_keys":{"description":"S3/object-storage keys for screenshot attachments","items":{"maxLength":512,"type":"string"},"maxItems":3,"type":"array"},"threat_feed_slug":{"description":"Associate report with a specific named threat feed","maxLength":100,"type":"string"}},"required":["ioc_type","ioc_value"],"type":"object"},"CreateIOCRequestRequest":{"properties":{"bounty":{"description":"Optional bounty in community credits","maximum":1000,"minimum":0,"type":"integer"},"description":{"maxLength":1024,"minLength":10,"type":"string"},"duration_days":{"default":30,"description":"How long the bounty stays open before it expires. Defaults to 30 days.","enum":[7,14,30],"type":"integer"},"ioc_type":{"enum":["url","email","domain","ip"],"type":"string"},"ioc_value":{"maxLength":2048,"minLength":3,"type":"string"}},"required":["ioc_type","ioc_value","description"],"type":"object"},"CreateKeyRequest":{"properties":{"label":{"maxLength":64,"minLength":1,"type":"string"},"scopes":{"items":{"enum":["read","write","admin"],"type":"string"},"minItems":1,"type":"array"}},"required":["label","scopes"],"type":"object"},"CreateReportRequest":{"properties":{"category":{"maxLength":64,"type":"string"},"evidence":{"maxLength":4096,"type":"string"},"ioc_type":{"enum":["url","email","domain","ip"],"type":"string"},"ioc_value":{"maxLength":2048,"minLength":3,"type":"string"}},"required":["ioc_type","ioc_value"],"type":"object"},"CreateThreatFeedRequest":{"properties":{"artifact_scopes":{"description":"Optional stored artifact-scope override; derived when omitted.","items":{"enum":["domain","ipv4","ipv6","asn","prefix","ip","identity"],"type":"string"},"minItems":1,"type":"array"},"auto_confirm":{"default":false,"type":"boolean"},"categories":{"description":"IOC categories this feed covers","items":{"type":"string"},"minItems":1,"type":"array"},"description":{"maxLength":1024,"type":"string"},"dnsbl_zone":{"description":"DNS zone name for DNSBL publishing","maxLength":255,"type":"string"},"enterprise_only":{"default":false,"type":"boolean"},"feed_kind":{"description":"Optional stored taxonomy override; derived from categories and IOC types when omitted.","enum":["threat","policy","context","reputation"],"type":"string"},"ioc_types":{"items":{"enum":["url","domain","ip","email","network","asn"],"type":"string"},"minItems":1,"type":"array"},"methodology_summary":{"maxLength":2048,"type":"string"},"name":{"maxLength":255,"minLength":2,"type":"string"},"operator_intent":{"description":"Optional stored operator-action intent override.","enum":["direct_block","watch","context","policy"],"type":"string"},"primary_focus":{"description":"Optional public focus label shown in the feed catalog.","maxLength":120,"type":"string"},"publication_mode":{"description":"Optional stored publication-mode override.","enum":["shadow_gated","aggregate_derived","policy_curated","contextual","effective_read_filtered","legacy_confirmed","unknown"],"type":"string"},"publication_thresholds":{"maxLength":2048,"type":"string"},"recommended_action":{"maxLength":2048,"type":"string"},"selection_logic":{"maxLength":2048,"type":"string"},"slug":{"description":"URL-safe identifier, unique per platform","maxLength":100,"minLength":2,"type":"string"},"source_url":{"format":"uri","maxLength":2048,"type":"string"},"update_frequency":{"enum":["hourly","daily","weekly"],"type":"string"}},"required":["slug","name","categories","ioc_types"],"type":"object"},"CreateWatchlistRequest":{"properties":{"match_type":{"enum":["contains","exact","domain","ip"],"type":"string"},"notify_email":{"default":false,"type":"boolean"},"notify_webhook":{"default":false,"type":"boolean"},"pattern":{"maxLength":512,"minLength":2,"type":"string"}},"required":["pattern","match_type"],"type":"object"},"CreateWebhookRequest":{"properties":{"events":{"items":{"enum":["report_confirmed","report_submitted","vote_cast"],"type":"string"},"minItems":1,"type":"array"},"secret":{"description":"HMAC-SHA256 signing secret (optional)","maxLength":128,"type":"string"},"url":{"format":"uri","maxLength":2048,"type":"string"}},"required":["url","events"],"type":"object"},"CreatedKeyEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/CreatedKeyResponse"}},"required":["data"],"type":"object"},"CreatedKeyResponse":{"allOf":[{"$ref":"#/components/schemas/APIKeyResponse"},{"properties":{"key":{"description":"Full raw API key — shown ONCE at creation, not stored","type":"string"}},"required":["key"],"type":"object"}]},"CreditListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CreditResponse"},"type":"array"}},"required":["data"],"type":"object"},"CreditResponse":{"description":"Credit transaction record","properties":{"amount":{"description":"Credit delta (positive = earned, negative = spent)","type":"integer"},"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"reason":{"description":"Human-readable reason for the credit change","type":"string"},"reference_id":{"description":"Related entity ID (report_id, request_id, etc.)","format":"uuid","type":"string"}},"type":"object"},"DNSDetailsResponse":{"properties":{"a":{"items":{"type":"string"},"type":"array"},"aaaa":{"items":{"type":"string"},"type":"array"},"cname":{"type":"string"},"dmarc":{"items":{"type":"string"},"type":"array"},"errors":{"additionalProperties":{"type":"string"},"type":"object"},"mx":{"items":{"$ref":"#/components/schemas/MXRecordResponse"},"type":"array"},"ns":{"items":{"type":"string"},"type":"array"},"txt":{"items":{"type":"string"},"type":"array"}},"type":"object"},"EffectiveDecisionResponse":{"properties":{"listed":{"type":"boolean"},"rationale":{"type":"string"},"source":{"example":"shadow_v2","type":"string"},"verdict":{"enum":["malicious","suspicious","manual_review","unknown","benign"],"type":"string"}},"required":["source","verdict","listed","rationale"],"type":"object"},"ErrorDetail":{"description":"Structured error body","properties":{"code":{"description":"Machine-readable error code","example":"NOT_FOUND","type":"string"},"details":{"description":"Additional error details (nullable)"},"message":{"description":"Human-readable error message","example":"report not found","type":"string"}},"required":["code","message"],"type":"object"},"ErrorEnvelope":{"properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}},"required":["error"],"type":"object"},"FeedIOCRecord":{"description":"One indicator in the JSON feed. verdict and score report what the scoring engine made of the indicator; they describe it rather than decide whether it appears, so nothing is withheld on their account and a client wanting a narrower set can filter on them. Both are omitted for an indicator that has not been scored, which is distinct from one scored zero.\n","properties":{"category":{"type":"string"},"confidence":{"description":"Fixed-point 0.0000-1.0000.","type":"string"},"confirmed_at":{"format":"date-time","type":"string"},"ioc_type":{"enum":["url","email","domain","ip","network","asn"],"type":"string"},"ioc_value":{"type":"string"},"score":{"description":"0-100, from the same run as verdict.","format":"double","type":"number"},"verdict":{"enum":["malicious","manual_review","suspicious","unknown","benign"],"type":"string"}},"required":["ioc_type","ioc_value","confidence"],"type":"object"},"FeedPublicationDailyCount":{"properties":{"date":{"format":"date","type":"string"},"published":{"type":"integer"},"suppressed":{"type":"integer"}},"required":["date","published","suppressed"],"type":"object"},"FeedPublicationDailyCountListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/FeedPublicationDailyCount"},"type":"array"}},"required":["data"],"type":"object"},"FeedPublicationEvent":{"properties":{"artifact_type":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"feed_slug":{"type":"string"},"ioc_value":{"type":"string"},"publication_mode":{"type":"string"},"report_id":{"type":"string"},"state":{"type":"string"}},"required":["feed_slug","artifact_type","ioc_value","state","created_at"],"type":"object"},"FeedPublicationEventListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/FeedPublicationEvent"},"type":"array"}},"required":["data"],"type":"object"},"FulfillIOCRequestRequest":{"properties":{"report_id":{"format":"uuid","type":"string"}},"required":["report_id"],"type":"object"},"GenerateAbuseNotificationRequest":{"properties":{"report_id":{"format":"uuid","type":"string"}},"required":["report_id"],"type":"object"},"HostInfoResponse":{"properties":{"asn":{"type":"string"},"domain":{"type":"string"},"has_private_resolution":{"type":"boolean"},"ip":{"type":"string"},"resolved_ips":{"items":{"type":"string"},"type":"array"}},"required":["has_private_resolution"],"type":"object"},"IOCRequestEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/IOCRequestResponse"}},"required":["data"],"type":"object"},"IOCRequestListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/IOCRequestResponse"},"type":"array"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"],"type":"object"},"IOCRequestResponse":{"properties":{"bounty":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"expires_at":{"description":"When an open request moves to 'expired' if nobody fulfils it.","format":"date-time","type":"string"},"fulfilled_by":{"description":"Reporter ID who fulfilled this request","format":"uuid","type":"string"},"id":{"format":"uuid","type":"string"},"ioc_type":{"enum":["url","email","domain","ip"],"type":"string"},"ioc_value":{"type":"string"},"report_id":{"format":"uuid","type":"string"},"requester_id":{"format":"uuid","type":"string"},"status":{"enum":["open","fulfilled","closed","expired"],"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id","requester_id","ioc_type","ioc_value","description","bounty","status","expires_at","created_at","updated_at"],"type":"object"},"KitBadgeEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/KitBadgeResponse"}},"required":["data"],"type":"object"},"KitBadgeResponse":{"properties":{"brand_target":{"type":["string","null"]},"composite_hash":{"type":"string"},"kit_id":{"format":"uuid","type":"string"},"match_type":{"description":"How the kit was matched to this report","type":"string"},"report_count":{"type":"integer"}},"required":["kit_id","composite_hash","match_type","report_count"],"type":"object"},"KitDetailEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/KitDetailResponse"}},"required":["data"],"type":"object"},"KitDetailResponse":{"properties":{"brand_target":{"description":"Brand being impersonated","type":["string","null"]},"composite_hash":{"description":"SHA-256 composite hash of the kit","type":"string"},"first_seen_at":{"format":"date-time","type":"string"},"form_fields":{"description":"Extracted form field names/structure"},"form_hash":{"type":["string","null"]},"header_hash":{"type":["string","null"]},"id":{"format":"uuid","type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"page_title":{"type":["string","null"]},"report_count":{"type":"integer"},"resource_hash":{"type":["string","null"]},"structure_hash":{"type":["string","null"]}},"required":["id","composite_hash","first_seen_at","last_seen_at","report_count"],"type":"object"},"KitListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/KitDetailResponse"},"type":"array"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"],"type":"object"},"LeaderboardEntry":{"properties":{"display_name":{"type":"string"},"points_alltime":{"type":"integer"},"points_month":{"type":"integer"},"points_week":{"type":"integer"},"reporter_id":{"format":"uuid","type":"string"},"total_submissions":{"type":"integer"},"trust_tier":{"type":"integer"}},"required":["reporter_id","display_name","trust_tier","points_alltime","points_week","points_month","total_submissions"],"type":"object"},"LeaderboardEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array"}},"required":["data"],"type":"object"},"LoginRequest":{"properties":{"email":{"format":"email","type":"string"},"password":{"format":"password","type":"string"}},"required":["email","password"],"type":"object"},"LookupContextResponse":{"properties":{"artifact_label":{"type":"string"},"artifact_scope":{"type":"string"},"interpretation":{"type":"string"},"product_surface":{"type":"string"},"product_surface_path":{"example":"/domain-reputation","type":"string"},"recommended_action":{"type":"string"},"supporting_context":{"type":"string"},"workflow":{"type":"string"}},"required":["artifact_label","artifact_scope","workflow","interpretation","recommended_action","supporting_context","product_surface","product_surface_path"],"type":"object"},"MXRecordResponse":{"properties":{"host":{"type":"string"},"preference":{"type":"integer"}},"required":["host","preference"],"type":"object"},"MailDetailsResponse":{"properties":{"dmarc":{"items":{"type":"string"},"type":"array"},"mail_servers":{"items":{"$ref":"#/components/schemas/MXRecordResponse"},"type":"array"},"spf":{"items":{"type":"string"},"type":"array"}},"type":"object"},"Meta":{"description":"Pagination metadata for list responses","properties":{"page":{"example":1,"type":"integer"},"per_page":{"example":25,"type":"integer"},"total":{"example":100,"type":"integer"}},"required":["page","per_page","total"],"type":"object"},"OperatorLookupEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/OperatorLookupResponse"}},"required":["data"],"type":"object"},"OperatorLookupResponse":{"properties":{"effective_decision":{"$ref":"#/components/schemas/EffectiveDecisionResponse"},"listed":{"type":"boolean"},"lookup_context":{"$ref":"#/components/schemas/LookupContextResponse"},"lookup_type":{"enum":["domain","asn","ipv4","ipv6"],"type":"string"},"normalized_value":{"type":"string"},"rbl":{"$ref":"#/components/schemas/RBLCheckResponse"},"report":{"$ref":"#/components/schemas/PublicLookupResponse"},"source":{"example":"report_db","type":"string"}},"required":["lookup_type","source","normalized_value","listed"],"type":"object"},"PTRRecordResponse":{"properties":{"error":{"type":"string"},"ip":{"type":"string"},"records":{"items":{"type":"string"},"type":"array"}},"required":["ip","records"],"type":"object"},"PivotResult":{"description":"A report or IOC related to the pivot target","properties":{"confidence":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"ioc_hash":{"type":"string"},"ioc_type":{"enum":["url","email","domain","ip"],"type":"string"},"ioc_value":{"type":"string"},"pivot_field":{"description":"The field that matched the pivot value (e.g. resolving_ip, nameserver)","type":"string"},"report_id":{"format":"uuid","type":"string"},"status":{"type":"string"}},"type":"object"},"PreferencesEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/PreferencesResponse"}},"required":["data"],"type":"object"},"PreferencesResponse":{"properties":{"leaderboard_opt_out":{"description":"Whether this reporter is hidden from the public leaderboard. Kept out of the public reporter profile: the choice is the reporter's business, not a visitor's.","type":"boolean"}},"required":["leaderboard_opt_out"],"type":"object"},"ProviderListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ProviderResponse"},"type":"array"}},"required":["data"],"type":"object"},"ProviderResponse":{"properties":{"abuse_email":{"format":"email","type":"string"},"abuse_url":{"format":"uri","type":"string"},"id":{"format":"uuid","type":"string"},"name":{"type":"string"},"supports_xarf":{"type":"boolean"},"unsubscribed":{"type":"boolean"}},"required":["id","name","abuse_email","supports_xarf","unsubscribed"],"type":"object"},"PublicLookupEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/PublicLookupResponse"}},"required":["data"],"type":"object"},"PublicLookupResponse":{"properties":{"category":{"type":["string","null"]},"confidence":{"example":"92.5000","type":"string"},"confirmed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"effective_decision":{"$ref":"#/components/schemas/EffectiveDecisionResponse"},"ioc_hash":{"type":"string"},"ioc_type":{"enum":["url","email","domain","ip","network","asn"],"type":"string"},"lookup_context":{"$ref":"#/components/schemas/LookupContextResponse"},"report_id":{"format":"uuid","type":"string"},"scoring":{"$ref":"#/components/schemas/ScoringSummaryResponse"},"status":{"enum":["submitted","under_review","confirmed","false_positive"],"type":"string"}},"required":["status","ioc_type","ioc_hash","confidence","report_id","created_at"],"type":"object"},"RBLCheckEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/RBLCheckResponse"}},"required":["data"],"type":"object"},"RBLCheckResponse":{"properties":{"checked_at":{"format":"date-time","type":"string"},"effective_decision":{"$ref":"#/components/schemas/EffectiveDecisionResponse"},"ip":{"example":"203.0.113.42","type":"string"},"listed":{"type":"boolean"},"lookup_context":{"$ref":"#/components/schemas/LookupContextResponse"},"match":{"$ref":"#/components/schemas/RBLMatchDetail"},"scoring":{"$ref":"#/components/schemas/ScoringSummaryResponse"}},"required":["listed","ip","checked_at"],"type":"object"},"RBLMatchDetail":{"properties":{"confidence":{"example":"95.0000","type":"string"},"first_seen_at":{"format":"date-time","type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"list_class":{"description":"RBL list classification","type":"string"},"prefix":{"description":"CIDR prefix matched","example":"203.0.113.0/24","type":"string"},"reason":{"type":"string"},"report_count":{"type":"integer"},"report_ids":{"items":{"format":"uuid","type":"string"},"type":"array"}},"type":"object"},"RDAPDetailsResponse":{"properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"handle":{"type":"string"},"name":{"type":"string"},"rdap_url":{"type":"string"},"registrar":{"type":"string"},"status":{"items":{"type":"string"},"type":"array"},"updated_at":{"type":"string"}},"type":"object"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string"}},"required":["refresh_token"],"type":"object"},"RegisterRequest":{"properties":{"display_name":{"maxLength":64,"minLength":2,"type":"string"},"email":{"description":"Valid email address (max 254 chars)","format":"email","maxLength":254,"type":"string"},"password":{"format":"password","maxLength":128,"minLength":8,"type":"string"}},"required":["email","display_name","password"],"type":"object"},"ReportEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/ReportResponse"}},"required":["data"],"type":"object"},"ReportListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ReportResponse"},"type":"array"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"],"type":"object"},"ReportResponse":{"properties":{"category":{"type":["string","null"]},"confidence":{"description":"Confidence score as decimal string (4 decimal places)","example":"92.5000","type":"string"},"confirmed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"effective_decision":{"$ref":"#/components/schemas/EffectiveDecisionResponse"},"evidence":{"type":["string","null"]},"evidence_screenshots":{"items":{"type":"string"},"type":"array"},"id":{"format":"uuid","type":"string"},"ioc_hash":{"description":"SHA-256 hash of the canonical IOC value","type":"string"},"ioc_type":{"enum":["url","email","domain","ip","network","asn"],"type":"string"},"ioc_value":{"description":"Normalized/defanged IOC value","type":"string"},"ioc_value_original":{"description":"Original submitted value before normalization","type":["string","null"]},"lookup_context":{"$ref":"#/components/schemas/LookupContextResponse"},"metadata":{"additionalProperties":true,"description":"Additional structured metadata attached to the report","type":["object","null"]},"reporter_id":{"format":"uuid","type":"string"},"scoring":{"$ref":"#/components/schemas/ScoringSummaryResponse"},"status":{"enum":["submitted","under_review","confirmed","false_positive"],"type":"string"},"time_to_consensus_seconds":{"description":"Seconds from report creation to the first transition into confirmed or false_positive (from verdict_events, falling back to confirmed_at for confirmed reports that predate verdict event history). The verdict may come from votes, an admin, a delist approval or auto-confirm on ingest. Still present if the report later changed status; absent when no verdict was ever recorded.","type":"integer"},"updated_at":{"format":"date-time","type":"string"}},"required":["id","reporter_id","ioc_type","ioc_value","ioc_hash","status","confidence","created_at","updated_at"],"type":"object"},"ReporterEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/ReporterResponse"}},"required":["data"],"type":"object"},"ReporterResponse":{"properties":{"accurate_reports":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email_verified":{"type":"boolean"},"id":{"format":"uuid","type":"string"},"reputation_score":{"description":"Decimal reputation score with 4 decimal places","example":"87.5000","type":"string"},"total_reports":{"type":"integer"},"trust_tier":{"description":"Numeric trust tier (0=community, 1=trusted, 2=verified)","example":1,"type":"integer"},"trust_tier_label":{"example":"trusted","type":"string"}},"required":["id","display_name","trust_tier","trust_tier_label","reputation_score","total_reports","accurate_reports","email_verified","created_at"],"type":"object"},"ReputationDetailsResponse":{"properties":{"category":{"type":"string"},"confidence":{"type":"string"},"report_id":{"type":"string"},"report_status":{"type":"string"},"source":{"example":"vspam","type":"string"}},"required":["source"],"type":"object"},"ReputationEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/ReputationResponse"}},"required":["data"],"type":"object"},"ReputationReportResponse":{"properties":{"category":{"type":"string"},"confidence":{"type":"string"},"confirmed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"ioc_type":{"enum":["url","email","domain","ip","network","asn"],"type":"string"},"report_id":{"format":"uuid","type":"string"},"status":{"enum":["submitted","under_review","confirmed","false_positive"],"type":"string"}},"required":["report_id","ioc_type","status","confidence","created_at"],"type":"object"},"ReputationResponse":{"properties":{"block_lists":{"items":{"$ref":"#/components/schemas/BlockListResultResponse"},"type":"array"},"cached":{"type":"boolean"},"collected_at":{"format":"date-time","type":"string"},"content":{"$ref":"#/components/schemas/ContentDetailsResponse"},"dns":{"$ref":"#/components/schemas/DNSDetailsResponse"},"host":{"$ref":"#/components/schemas/HostInfoResponse"},"input":{"type":"string"},"input_type":{"enum":["url","email","domain","ip","asn"],"type":"string"},"listed":{"type":"boolean"},"lookup_type":{"enum":["domain","ip","asn"],"type":"string"},"mail":{"$ref":"#/components/schemas/MailDetailsResponse"},"normalized_value":{"type":"string"},"rdap":{"$ref":"#/components/schemas/RDAPDetailsResponse"},"related_reports":{"items":{"$ref":"#/components/schemas/ReputationReportResponse"},"type":"array"},"reputation":{"$ref":"#/components/schemas/ReputationDetailsResponse"},"reverse_dns":{"items":{"$ref":"#/components/schemas/PTRRecordResponse"},"type":"array"},"scoring":{"$ref":"#/components/schemas/ScoringSummaryResponse"},"summary":{"type":"string"},"value_hash":{"type":"string"},"verdict":{"enum":["malicious","suspicious","unknown"],"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["input","input_type","lookup_type","normalized_value","verdict","listed","summary","cached","collected_at","reputation","block_lists"],"type":"object"},"STIXBundle":{"properties":{"id":{"description":"STIX bundle identifier (bundle--UUID)","example":"bundle--a47c8a56-7eab-4c26-9b37-fc3f4c88b44b","type":"string"},"objects":{"items":{"description":"STIX 2.1 domain objects (indicators, reports, etc.)","type":"object"},"type":"array"},"spec_version":{"enum":["2.1"],"type":"string"},"type":{"enum":["bundle"],"type":"string"}},"required":["type","id","spec_version","objects"],"type":"object"},"ScoringReasonResponse":{"properties":{"code":{"type":"string"},"reason":{"type":["string","null"]},"weight":{"example":"18.0000","type":"string"}},"required":["code","weight"],"type":"object"},"ScoringSummaryResponse":{"properties":{"confidence":{"example":"0.7300","type":"string"},"generated_at":{"format":"date-time","type":"string"},"methodology":{"type":"string"},"model_version":{"example":"deterministic-hybrid","type":"string"},"needs_manual_review":{"type":"boolean"},"reason_summary":{"type":["string","null"]},"score":{"example":"84.5000","type":"string"},"source":{"example":"shadow_v2","type":"string"},"top_reasons":{"items":{"$ref":"#/components/schemas/ScoringReasonResponse"},"type":"array"},"verdict":{"enum":["malicious","suspicious","manual_review","unknown","benign"],"type":"string"}},"required":["source","model_version","verdict","score","confidence","needs_manual_review","methodology","generated_at"],"type":"object"},"StatsEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/StatsResponse"}},"required":["data"],"type":"object"},"StatsResponse":{"properties":{"active_asns_30d":{"type":"integer"},"active_reporters":{"type":"integer"},"approved_delists_30d":{"type":"integer"},"avg_delist_review_hours_30d":{"format":"float","type":"number"},"confirmed_today":{"type":"integer"},"confirmed_total":{"description":"All-time confirmed report count, unlike confirmed_today.","type":"integer"},"current_feed_publications":{"type":"integer"},"dnsbl_domains":{"type":"integer"},"false_positive_reports":{"type":"integer"},"feed_published_30d":{"type":"integer"},"feed_suppressed_30d":{"type":"integer"},"ipv6_exact_hosts_tracked":{"type":"integer"},"ipv6_watch_prefixes_30d":{"type":"integer"},"ipv6_watch_prefixes_48_30d":{"description":"Same 30-day watch count as ipv6_watch_prefixes_30d, filtered to /48 prefixes.","type":"integer"},"ipv6_watch_prefixes_56_30d":{"description":"Same 30-day watch count as ipv6_watch_prefixes_30d, filtered to /56 prefixes.","type":"integer"},"ipv6_watch_prefixes_64_30d":{"description":"Same 30-day watch count as ipv6_watch_prefixes_30d, filtered to /64 prefixes.","type":"integer"},"pending_delists":{"type":"integer"},"phishing_domains_tracked":{"type":"integer"},"rbl_listed_ips":{"type":"integer"},"threat_intel_total":{"type":"integer"},"total_reports":{"type":"integer"},"votes_today":{"type":"integer"}},"required":["total_reports","confirmed_today","active_reporters","votes_today","dnsbl_domains","rbl_listed_ips"],"type":"object"},"StatusHistoryCheck":{"properties":{"check":{"example":"postgres","type":"string"},"days":{"items":{"$ref":"#/components/schemas/StatusHistoryDay"},"type":"array"}},"required":["check","days"],"type":"object"},"StatusHistoryDay":{"properties":{"date":{"description":"UTC calendar day.","format":"date","type":"string"},"failures":{"type":"integer"},"probes":{"description":"Probes recorded for this day. Zero means no data, not 100% uptime.","type":"integer"}},"required":["date","probes","failures"],"type":"object"},"StatusHistoryEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/StatusHistoryResponse"}},"required":["data"],"type":"object"},"StatusHistoryFailure":{"properties":{"check":{"type":"string"},"error":{"description":"A generic message (e.g. \"postgres unreachable\"), never driver detail.","type":"string"},"probed_at":{"format":"date-time","type":"string"}},"required":["probed_at","check","error"],"type":"object"},"StatusHistoryResponse":{"properties":{"checks":{"items":{"$ref":"#/components/schemas/StatusHistoryCheck"},"type":"array"},"recent_failures":{"items":{"$ref":"#/components/schemas/StatusHistoryFailure"},"type":"array"}},"required":["checks","recent_failures"],"type":"object"},"TAXIIAPIRoot":{"properties":{"description":{"type":["string","null"]},"max_content_length":{"description":"Maximum content length in bytes for POST requests","type":"integer"},"title":{"type":"string"},"versions":{"example":["taxii-2.1"],"items":{"type":"string"},"type":"array"}},"required":["title","versions","max_content_length"],"type":"object"},"TAXIICollection":{"properties":{"can_read":{"type":"boolean"},"can_write":{"type":"boolean"},"description":{"type":["string","null"]},"id":{"description":"Collection identifier (UUID or slug)","type":"string"},"media_types":{"example":["application/stix+json;version=2.1"],"items":{"type":"string"},"type":"array"},"title":{"type":"string"}},"required":["id","title","can_read","can_write"],"type":"object"},"TAXIICollectionsEnvelope":{"properties":{"collections":{"items":{"$ref":"#/components/schemas/TAXIICollection"},"type":"array"}},"required":["collections"],"type":"object"},"TAXIIDiscovery":{"properties":{"api_roots":{"description":"List of available API root URLs","items":{"format":"uri","type":"string"},"type":"array"},"default":{"description":"URL of the default API root","format":"uri","type":"string"},"description":{"type":["string","null"]},"title":{"example":"vspam.org TAXII","type":"string"}},"required":["title","api_roots"],"type":"object"},"TAXIIManifest":{"properties":{"objects":{"items":{"$ref":"#/components/schemas/TAXIIManifestEntry"},"type":"array"}},"required":["objects"],"type":"object"},"TAXIIManifestEntry":{"properties":{"date_added":{"format":"date-time","type":"string"},"id":{"description":"STIX object ID","type":"string"},"media_type":{"type":["string","null"]},"version":{"description":"Last-modified timestamp used as version","format":"date-time","type":"string"}},"required":["id","date_added","version"],"type":"object"},"ThreatFeedEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/ThreatFeedResponse"}},"required":["data"],"type":"object"},"ThreatFeedListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ThreatFeedResponse"},"type":"array"}},"required":["data"],"type":"object"},"ThreatFeedResponse":{"properties":{"artifact_scopes":{"items":{"type":"string"},"type":"array"},"auto_confirm":{"type":"boolean"},"categories":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":["string","null"]},"dnsbl_zone":{"type":["string","null"]},"enterprise_only":{"type":"boolean"},"feed_kind":{"type":"string"},"has_snapshot_history":{"description":"True when snapshot-format publication history exists, false when its absence is confirmed, and null when summary availability prevents a reliable answer.","type":["boolean","null"]},"id":{"format":"uuid","type":"string"},"ioc_types":{"items":{"enum":["url","domain","ip","email","network","asn"],"type":"string"},"type":"array"},"is_active":{"type":"boolean"},"last_updated":{"format":"date-time","type":"string"},"methodology_summary":{"type":"string"},"name":{"type":"string"},"operator_intent":{"enum":["direct_block","watch","context","policy"],"type":"string"},"primary_focus":{"type":"string"},"publication_mode":{"type":"string"},"publication_thresholds":{"type":"string"},"recommended_action":{"type":"string"},"regeneration_interval_seconds":{"description":"How often, in seconds, exported feed data can change — the feed worker's cache-bound regeneration cadence, which applies uniformly to every feed regardless of update_frequency (nothing reads update_frequency at generation or export time).","type":"integer"},"report_count":{"type":"integer"},"selection_logic":{"type":"string"},"slug":{"type":"string"},"source_url":{"format":"uri","type":"string"},"update_frequency":{"enum":["hourly","daily","weekly"],"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id","slug","name","categories","ioc_types","is_active","auto_confirm","feed_kind","primary_focus","artifact_scopes","publication_mode","operator_intent","report_count","has_snapshot_history","regeneration_interval_seconds","created_at","updated_at"],"type":"object"},"TokenEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/TokenResponse"}},"required":["data"],"type":"object"},"TokenResponse":{"properties":{"access_token":{"description":"JWT access token","type":"string"},"expires_in":{"description":"Token TTL in seconds","example":3600,"type":"integer"},"refresh_token":{"description":"JWT refresh token (not included in /auth/refresh responses)","type":"string"},"token_type":{"enum":["Bearer"],"example":"Bearer","type":"string"}},"required":["access_token","expires_in","token_type"],"type":"object"},"UpdateCommercialTierRequest":{"properties":{"commercial_tier":{"enum":["community","pro","enterprise"],"type":"string"}},"required":["commercial_tier"],"type":"object"},"UpdateStatusRequest":{"properties":{"status":{"enum":["submitted","under_review","confirmed","false_positive"],"type":"string"}},"required":["status"],"type":"object"},"UpdateThreatFeedRequest":{"description":"All fields optional — only provided fields are updated","properties":{"artifact_scopes":{"items":{"enum":["domain","ipv4","ipv6","asn","prefix","ip","identity"],"type":"string"},"minItems":1,"type":"array"},"auto_confirm":{"type":"boolean"},"categories":{"items":{"type":"string"},"minItems":1,"type":"array"},"description":{"maxLength":1024,"type":"string"},"dnsbl_zone":{"maxLength":255,"type":"string"},"enterprise_only":{"type":"boolean"},"feed_kind":{"description":"Optional stored taxonomy override; omitted fields keep the current value.","enum":["threat","policy","context","reputation"],"type":"string"},"ioc_types":{"items":{"enum":["url","domain","ip","email","network","asn"],"type":"string"},"minItems":1,"type":"array"},"methodology_summary":{"maxLength":2048,"type":"string"},"name":{"maxLength":255,"minLength":2,"type":"string"},"operator_intent":{"enum":["direct_block","watch","context","policy"],"type":"string"},"primary_focus":{"maxLength":120,"type":"string"},"publication_mode":{"enum":["shadow_gated","aggregate_derived","policy_curated","contextual","effective_read_filtered","legacy_confirmed","unknown"],"type":"string"},"publication_thresholds":{"maxLength":2048,"type":"string"},"recommended_action":{"maxLength":2048,"type":"string"},"selection_logic":{"maxLength":2048,"type":"string"},"source_url":{"format":"uri","maxLength":2048,"type":"string"},"update_frequency":{"enum":["hourly","daily","weekly"],"type":"string"}},"type":"object"},"UpdateTierRequest":{"properties":{"trust_tier":{"maximum":2,"minimum":0,"type":"integer"}},"required":["trust_tier"],"type":"object"},"VerifyEmailRequest":{"properties":{"token":{"maxLength":64,"minLength":64,"type":"string"}},"required":["token"],"type":"object"},"VoteEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/VoteResponse"}},"required":["data"],"type":"object"},"VoteListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/VoteResponse"},"type":"array"}},"required":["data"],"type":"object"},"VoteResponse":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"report_id":{"format":"uuid","type":"string"},"vote_type":{"enum":["confirm","reject"],"type":"string"},"voter_id":{"format":"uuid","type":"string"},"voter_trust_tier":{"description":"Trust tier of the voter at time of vote","type":"integer"}},"required":["id","report_id","voter_id","vote_type","voter_trust_tier","created_at"],"type":"object"},"WatchlistEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/WatchlistResponse"}},"required":["data"],"type":"object"},"WatchlistListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WatchlistResponse"},"type":"array"}},"required":["data"],"type":"object"},"WatchlistResponse":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"is_active":{"type":"boolean"},"last_matched_at":{"format":"date-time","type":"string"},"match_count":{"type":"integer"},"match_type":{"enum":["contains","exact","domain","ip"],"type":"string"},"notify_email":{"type":"boolean"},"notify_webhook":{"type":"boolean"},"pattern":{"type":"string"}},"required":["id","pattern","match_type","notify_email","notify_webhook","is_active","match_count","created_at"],"type":"object"},"WebhookEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/WebhookResponse"}},"required":["data"],"type":"object"},"WebhookListEnvelope":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WebhookResponse"},"type":"array"}},"required":["data"],"type":"object"},"WebhookResponse":{"properties":{"created_at":{"format":"date-time","type":"string"},"events":{"items":{"enum":["report_confirmed","report_submitted","vote_cast"],"type":"string"},"type":"array"},"failure_count":{"type":"integer"},"id":{"format":"uuid","type":"string"},"is_active":{"type":"boolean"},"last_sent_at":{"format":"date-time","type":"string"},"signed":{"description":"Deliveries carry an X-Webhook-Signature HMAC-SHA256 header. The secret itself is never returned.","type":"boolean"},"url":{"format":"uri","type":"string"}},"required":["id","url","events","is_active","failure_count","signed","created_at"],"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"description":"API key created via /api/v1/keys. Any key can read (GET); POST, PUT, PATCH and DELETE need the write scope, otherwise 403.","in":"header","name":"X-API-Key","type":"apiKey"},"BearerAuth":{"bearerFormat":"JWT","description":"JWT access token obtained from /api/v1/auth/login","scheme":"bearer","type":"http"}}},"info":{"contact":{"name":"vspam.org Support","url":"https://vspam.org"},"description":"REST API for vspam.org — a community-driven phishing intelligence platform.\nProvides IOC (Indicator of Compromise) reporting, lookup, voting, feeds, and TAXII 2.1 endpoints.\n\n## Authentication\nMost endpoints accept either a **Bearer JWT** or an **X-API-Key** header.\nPublic endpoints require no authentication.\n\n## Response Envelope\nAll responses use a consistent envelope:\n- **Single item success**: `{ \"data\": { ...object } }`\n- **List success**: `{ \"data\": [ ...array ], \"meta\": { \"page\": 1, \"per_page\": 25, \"total\": 100 } }`\n- **Error**: `{ \"error\": { \"code\": \"NOT_FOUND\", \"message\": \"...\", \"details\": null } }`\n\n## Rate Limits\n- Anonymous report submissions: 10 per hour per IP\n- Authenticated endpoints: varies by commercial tier\n","title":"vspam.org Phishing Intelligence API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/api/v1/abuse/generate":{"post":{"operationId":"generateAbuseNotification","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAbuseNotificationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationEnvelope"}}},"description":"Abuse notification generated"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Generate an abuse notification for a report (requires admin scope)","tags":["Admin"]}},"/api/v1/abuse/notifications":{"get":{"operationId":"listAbuseNotifications","parameters":[{"in":"query","name":"status","schema":{"enum":["pending","approved","sent","failed","skipped"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationListEnvelope"}}},"description":"Abuse notifications"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"List abuse notifications with optional status filter (requires admin scope)","tags":["Admin"]}},"/api/v1/abuse/notifications/{id}":{"get":{"operationId":"getAbuseNotification","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationEnvelope"}}},"description":"Abuse notification"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get a single abuse notification (requires admin scope)","tags":["Admin"]}},"/api/v1/abuse/notifications/{id}/approve":{"post":{"operationId":"approveAbuseNotification","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationEnvelope"}}},"description":"Abuse notification approved and sent"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Approve and send an abuse notification (requires admin scope)","tags":["Admin"]}},"/api/v1/abuse/notifications/{id}/skip":{"post":{"operationId":"skipAbuseNotification","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationEnvelope"}}},"description":"Abuse notification skipped"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Skip an abuse notification (requires admin scope)","tags":["Admin"]}},"/api/v1/abuse/queue":{"get":{"operationId":"getAbuseQueue","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationListEnvelope"}}},"description":"Abuse notification queue"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get pending abuse notification queue (requires admin scope)","tags":["Admin"]}},"/api/v1/abuse/unsubscribe":{"get":{"operationId":"abuseUnsubscribe","parameters":[{"description":"Unsubscribe token from email","in":"query","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"message":{"example":"unsubscribed","type":"string"}},"type":"object"}},"type":"object"}}},"description":"Unsubscribed"},"400":{"$ref":"#/components/responses/BadRequest"}},"security":[],"summary":"Unsubscribe from abuse notifications via token","tags":["Admin"]}},"/api/v1/audit-log":{"get":{"operationId":"getAuditLog","parameters":[{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditLogEntry"},"type":"array"},"meta":{"$ref":"#/components/schemas/Meta"}},"type":"object"}}},"description":"Audit log entries"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get audit log (requires admin scope)","tags":["Admin"]}},"/api/v1/auth/login":{"post":{"operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenEnvelope"}}},"description":"Tokens issued"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[],"summary":"Login and obtain JWT tokens","tags":["Authentication"]}},"/api/v1/auth/refresh":{"post":{"operationId":"refreshToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenEnvelope"}}},"description":"New access token issued (no new refresh_token in response)"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[],"summary":"Refresh access token","tags":["Authentication"]}},"/api/v1/auth/register":{"post":{"operationId":"register","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReporterEnvelope"}}},"description":"Account created"},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Conflict"}},"security":[],"summary":"Register a new reporter account","tags":["Authentication"]}},"/api/v1/auth/resend-verification":{"post":{"operationId":"resendVerification","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"message":{"example":"verification email sent","type":"string"}},"type":"object"}},"type":"object"}}},"description":"Verification email sent"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Resend email verification","tags":["Authentication"]}},"/api/v1/auth/verify":{"post":{"operationId":"verifyEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"message":{"example":"email verified","type":"string"}},"type":"object"}},"type":"object"}}},"description":"Email verified"},"400":{"$ref":"#/components/responses/BadRequest"}},"security":[],"summary":"Verify email address with token","tags":["Authentication"]}},"/api/v1/badge/protected.svg":{"get":{"description":"An SVG badge for a site or README. Carries no data and touches no database. Cached for an hour.","operationId":"getProtectedBadge","responses":{"200":{"content":{"image/svg+xml":{"schema":{"type":"string"}}},"description":"SVG badge"}},"security":[],"summary":"Embeddable \"protected by vspam.org\" badge","tags":["Profile"]}},"/api/v1/badge/reporter/{id}":{"get":{"description":"Everything on the badge is already served by the public reporter profile. An unknown id returns 404 with a grey \"unknown\" badge rather than an error page, so an embedded image still renders something.","operationId":"getReporterBadge","parameters":[{"description":"Reporter ID. A trailing .svg is accepted and ignored.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"image/svg+xml":{"schema":{"type":"string"}}},"description":"SVG badge"},"404":{"content":{"image/svg+xml":{"schema":{"type":"string"}}},"description":"SVG badge reading \"unknown\""}},"security":[],"summary":"Embeddable badge showing a reporter's confirmed count","tags":["Profile"]}},"/api/v1/events":{"get":{"description":"Opens a persistent SSE stream. Authenticate via a `token` query param (JWT), a\nstandard `Authorization: Bearer` header, or an `X-API-Key` header — all three\nresolve to the same scopes. The query param exists only for browser\nEventSource clients, which cannot set request headers.\nEach event is `event: \u003ctype\u003e` (`report:new`, `report:status`, or `vote:new`)\nfollowed by a `data:` line of JSON with `type`, `report_id`, `ioc_type`,\n`ioc_value`, `status`, `category`, `actor_name`, `vote_type`, and `timestamp`.\n","operationId":"subscribeEvents","parameters":[{"description":"JWT token (alternative to Bearer header for SSE clients)","in":"query","name":"token","schema":{"type":"string"}}],"responses":{"200":{"content":{"text/event-stream":{"schema":{"description":"Stream of server-sent events","type":"string"}}},"description":"SSE stream established"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Subscribe to real-time events via Server-Sent Events","tags":["Events"]}},"/api/v1/feeds":{"post":{"operationId":"createThreatFeed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThreatFeedRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreatFeedEnvelope"}}},"description":"Threat feed created"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Create a threat feed (requires admin scope)","tags":["Admin"]}},"/api/v1/feeds/csv":{"get":{"operationId":"getFeedCSV","parameters":[{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"text/csv":{"schema":{"type":"string"}}},"description":"CSV feed"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download confirmed IOC feed as CSV","tags":["Feeds"]}},"/api/v1/feeds/json":{"get":{"operationId":"getFeedJSON","parameters":[{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/FeedIOCRecord"},"type":"array"}}},"description":"JSON feed"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download confirmed IOC feed as JSON array","tags":["Feeds"]}},"/api/v1/feeds/misp":{"get":{"operationId":"getFeedMISP","parameters":[{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"application/json":{"schema":{"description":"MISP event object","type":"object"}}},"description":"MISP format feed"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Enterprise tier required"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download confirmed IOC feed in MISP format (enterprise tier required)","tags":["Feeds"]}},"/api/v1/feeds/stix":{"get":{"operationId":"getFeedSTIX","parameters":[{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"application/stix+json":{"schema":{"description":"STIX 2.1 Bundle object","type":"object"}}},"description":"STIX 2.1 bundle"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Enterprise tier required"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download confirmed IOC feed as STIX 2.1 bundle (enterprise tier required)","tags":["Feeds"]}},"/api/v1/feeds/txt":{"get":{"operationId":"getFeedTXT","parameters":[{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"text/plain":{"schema":{"type":"string"}}},"description":"Plain text feed"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download confirmed IOC feed as plain text (one per line)","tags":["Feeds"]}},"/api/v1/feeds/{id}":{"delete":{"operationId":"deleteThreatFeed","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Threat feed deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Delete a threat feed (requires admin scope)","tags":["Admin"]},"patch":{"operationId":"updateThreatFeed","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateThreatFeedRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreatFeedEnvelope"}}},"description":"Threat feed updated"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Update a threat feed (requires admin scope)","tags":["Admin"]}},"/api/v1/feeds/{slug}/csv":{"get":{"operationId":"getNamedFeedCSV","parameters":[{"$ref":"#/components/parameters/FeedSlug"},{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"text/csv":{"schema":{"type":"string"}}},"description":"CSV feed"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download named feed as CSV","tags":["Named Feeds"]}},"/api/v1/feeds/{slug}/json":{"get":{"operationId":"getNamedFeedJSON","parameters":[{"$ref":"#/components/parameters/FeedSlug"},{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array"}}},"description":"JSON feed"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download named feed as JSON array","tags":["Named Feeds"]}},"/api/v1/feeds/{slug}/misp":{"get":{"operationId":"getNamedFeedMISP","parameters":[{"$ref":"#/components/parameters/FeedSlug"},{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"MISP format feed"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Enterprise tier required"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download named feed in MISP format (enterprise tier required)","tags":["Named Feeds"]}},"/api/v1/feeds/{slug}/stix":{"get":{"operationId":"getNamedFeedSTIX","parameters":[{"$ref":"#/components/parameters/FeedSlug"},{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"application/stix+json":{"schema":{"type":"object"}}},"description":"STIX 2.1 bundle"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Enterprise tier required"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download named feed as STIX 2.1 bundle (enterprise tier required)","tags":["Named Feeds"]}},"/api/v1/feeds/{slug}/txt":{"get":{"operationId":"getNamedFeedTXT","parameters":[{"$ref":"#/components/parameters/FeedSlug"},{"$ref":"#/components/parameters/FeedSince"},{"$ref":"#/components/parameters/FeedWindow"}],"responses":{"200":{"content":{"text/plain":{"schema":{"type":"string"}}},"description":"Plain text feed"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Download named feed as plain text","tags":["Named Feeds"]}},"/api/v1/keys":{"get":{"description":"Needs a signed-in session; an API key gets 403.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"List of API keys"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]}],"summary":"List API keys for the authenticated reporter","tags":["API Keys"]},"post":{"description":"Needs a signed-in session; an API key cannot create, list or revoke keys (403).","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedKeyEnvelope"}}},"description":"API key created — raw key shown once"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]}],"summary":"Create an API key","tags":["API Keys"]}},"/api/v1/keys/{id}":{"delete":{"description":"Needs a signed-in session; an API key gets 403.","operationId":"deleteAPIKey","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Key revoked"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]}],"summary":"Revoke an API key","tags":["API Keys"]}},"/api/v1/keys/{id}/commercial-tier":{"put":{"operationId":"updateKeyCommercialTier","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommercialTierRequest"}}},"required":true},"responses":{"200":{"description":"Commercial tier updated"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Update commercial tier for an API key (requires admin scope)","tags":["Admin"]}},"/api/v1/leaderboard":{"get":{"operationId":"getLeaderboard","parameters":[{"description":"Optional period filter (e.g. week, month, alltime)","in":"query","name":"period","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaderboardEnvelope"}}},"description":"Leaderboard entries"}},"security":[],"summary":"Get reporter leaderboard","tags":["Profile"]}},"/api/v1/lookup/{ioc_hash}":{"get":{"operationId":"authenticatedLookup","parameters":[{"description":"SHA-256 hash of the IOC value","in":"path","name":"ioc_hash","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportEnvelope"}}},"description":"Full report details"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Authenticated IOC lookup — returns full report","tags":["Lookup"]}},"/api/v1/me":{"get":{"operationId":"getProfile","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReporterEnvelope"}}},"description":"Reporter profile"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get authenticated reporter profile","tags":["Profile"]}},"/api/v1/me/credits":{"get":{"operationId":"getCredits","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditListEnvelope"}}},"description":"Credit history"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get credits for the authenticated reporter","tags":["Profile"]}},"/api/v1/me/preferences":{"get":{"operationId":"getPreferences","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesEnvelope"}}},"description":"Preferences"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get the authenticated reporter's own preferences","tags":["Profile"]},"patch":{"description":"Partial update. A field omitted from the body is left unchanged, so a client that knows about one preference cannot reset another it has never heard of.","operationId":"updatePreferences","requestBody":{"content":{"application/json":{"schema":{"properties":{"leaderboard_opt_out":{"description":"Hide this reporter from the public leaderboard","type":"boolean"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesEnvelope"}}},"description":"Preferences after the update"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Update the authenticated reporter's own preferences","tags":["Profile"]}},"/api/v1/providers":{"get":{"operationId":"listProviders","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderListEnvelope"}}},"description":"Provider list"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"List abuse contact providers (requires admin scope)","tags":["Admin"]}},"/api/v1/public/brands":{"get":{"operationId":"listBrands","parameters":[{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandListEnvelope"}}},"description":"Paginated brand list"}},"security":[],"summary":"List brands targeted by phishing campaigns","tags":["Reports"]}},"/api/v1/public/brands/{name}":{"get":{"operationId":"getBrand","parameters":[{"in":"path","name":"name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandDetailEnvelope"}}},"description":"Brand detail"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get brand detail by name","tags":["Reports"]}},"/api/v1/public/feeds":{"get":{"operationId":"listPublicFeeds","parameters":[{"description":"Filter feeds by intended operator use.","in":"query","name":"operator_intent","required":false,"schema":{"enum":["direct_block","watch","context","policy"],"type":"string"}},{"description":"Filter feeds by artifact family covered by the feed.","in":"query","name":"artifact_scope","required":false,"schema":{"enum":["domain","ipv4","ipv6","asn","prefix","ip","identity"],"type":"string"}},{"description":"Filter feeds by publication decision model.","in":"query","name":"publication_mode","required":false,"schema":{"enum":["shadow_gated","aggregate_derived","policy_curated","contextual","effective_read_filtered","legacy_confirmed","unknown"],"type":"string"}},{"description":"Filter feeds by broad feed family.","in":"query","name":"feed_kind","required":false,"schema":{"enum":["threat","policy","context","reputation"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreatFeedListEnvelope"}}},"description":"List of threat feeds"}},"security":[],"summary":"List all public threat feeds","tags":["Feeds"]}},"/api/v1/public/feeds/{slug}":{"get":{"operationId":"getPublicFeed","parameters":[{"$ref":"#/components/parameters/FeedSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreatFeedEnvelope"}}},"description":"Threat feed details"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get a public threat feed by slug","tags":["Feeds"]}},"/api/v1/public/feeds/{slug}/publications":{"get":{"description":"Daily published vs suppressed publication transition counts for one feed over the trailing 30 days, zero-filled for days with no transitions. Aggregates only — never artifact values, suppression reasons, or reporter data.","operationId":"getPublicFeedPublicationHistory","parameters":[{"$ref":"#/components/parameters/FeedSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedPublicationDailyCountListEnvelope"}}},"description":"Daily publication history"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get daily publication history for a feed","tags":["Feeds"]}},"/api/v1/public/kits":{"get":{"operationId":"listKits","parameters":[{"description":"Filter by brand target","in":"query","name":"brand","schema":{"type":"string"}},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KitListEnvelope"}}},"description":"Paginated list of phishing kits"}},"security":[],"summary":"List phishing kits","tags":["Reports"]}},"/api/v1/public/kits/{id}":{"get":{"operationId":"getKit","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KitDetailEnvelope"}}},"description":"Phishing kit details"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get a phishing kit by ID","tags":["Reports"]}},"/api/v1/public/kits/{id}/reports":{"get":{"operationId":"getKitReports","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportListEnvelope"}}},"description":"Reports for this kit"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get reports associated with a phishing kit","tags":["Reports"]}},"/api/v1/public/lookup/{ioc_hash}":{"get":{"operationId":"publicLookup","parameters":[{"description":"SHA-256 hash of the IOC value","in":"path","name":"ioc_hash","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicLookupEnvelope"}}},"description":"Lookup result"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Public IOC lookup by SHA-256 hash","tags":["Lookup"]}},"/api/v1/public/operator-lookup":{"get":{"operationId":"operatorLookup","parameters":[{"description":"Lookup type","in":"query","name":"type","required":true,"schema":{"enum":["domain","asn","ipv4","ipv6"],"type":"string"}},{"description":"Raw operator input. Domains, ASNs, and IPs are normalized server-side.","in":"query","name":"value","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatorLookupEnvelope"}}},"description":"Unified operator lookup result"},"400":{"$ref":"#/components/responses/BadRequest"}},"security":[],"summary":"Server-normalized operator lookup","tags":["Lookup"]}},"/api/v1/public/pivot":{"get":{"operationId":"pivot","parameters":[{"in":"query","name":"type","required":true,"schema":{"enum":["ip","domain","nameserver"],"type":"string"}},{"in":"query","name":"value","required":true,"schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"default":20,"maximum":50,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PivotResult"},"type":"array"}},"type":"object"}}},"description":"Pivot results"}},"security":[],"summary":"Pivot from an IP, domain, or nameserver to related reports","tags":["Pivot Search"]}},"/api/v1/public/reporters/{id}":{"get":{"operationId":"getPublicReporter","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReporterEnvelope"}}},"description":"Reporter profile"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get a public reporter profile by ID","tags":["Profile"]}},"/api/v1/public/reports":{"get":{"operationId":"listPublicReports","parameters":[{"description":"Free-text search query","in":"query","name":"q","schema":{"type":"string"}},{"in":"query","name":"ioc_type","schema":{"enum":["url","domain","email","ip","network","asn"],"type":"string"}},{"in":"query","name":"status","schema":{"enum":["submitted","under_review","confirmed","false_positive"],"type":"string"}},{"in":"query","name":"category","schema":{"type":"string"}},{"in":"query","name":"shadow_verdict","schema":{"enum":["benign","unknown","suspicious","malicious","manual_review"],"type":"string"}},{"in":"query","name":"effective_verdict","schema":{"enum":["benign","unknown","suspicious","malicious","manual_review"],"type":"string"}},{"in":"query","name":"score_min","schema":{"type":"number"}},{"in":"query","name":"score_max","schema":{"type":"number"}},{"in":"query","name":"needs_manual_review","schema":{"type":"boolean"}},{"in":"query","name":"effective_listed","schema":{"type":"boolean"}},{"in":"query","name":"date_from","schema":{"format":"date-time","type":"string"}},{"in":"query","name":"date_to","schema":{"format":"date-time","type":"string"}},{"in":"query","name":"sort","schema":{"enum":["oldest","confidence","shadow_score","shadow_confidence","effective_verdict"],"type":"string"}},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportListEnvelope"}}},"description":"Paginated list of reports"}},"security":[],"summary":"List public reports","tags":["Reports"]},"post":{"operationId":"createPublicReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportEnvelope"}}},"description":"Report created"},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"security":[],"summary":"Submit a report anonymously (rate limited 10/hour/IP)","tags":["Reports"]}},"/api/v1/public/reports/{id}":{"get":{"operationId":"getPublicReport","parameters":[{"$ref":"#/components/parameters/ReportId"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportEnvelope"}}},"description":"Report details"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get a public report by ID","tags":["Reports"]}},"/api/v1/public/reports/{id}/kit":{"get":{"operationId":"getReportKitBadge","parameters":[{"$ref":"#/components/parameters/ReportId"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KitBadgeEnvelope"}}},"description":"Kit badge info"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get phishing kit badge for a report","tags":["Reports"]}},"/api/v1/public/reports/{id}/votes":{"get":{"operationId":"getPublicReportVotes","parameters":[{"$ref":"#/components/parameters/ReportId"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteListEnvelope"}}},"description":"List of votes"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get votes for a public report","tags":["Votes"]}},"/api/v1/public/reputation":{"get":{"description":"Normalizes the input server-side, collects DNS/RDAP/content/block-list signals, and attaches the shadow-scoring summary for the best-matching report when one exists. Results are cached for 15 minutes; uncached lookups may require a Turnstile token.","operationId":"publicReputation","parameters":[{"description":"Raw artifact to look up. Alias `q` is also accepted.","in":"query","name":"value","required":true,"schema":{"type":"string"}},{"description":"Input type hint. Defaults to auto-detection.","in":"query","name":"type","required":false,"schema":{"enum":["domain","ip","ipv4","ipv6","asn","url","email","auto"],"type":"string"}},{"description":"Bypass the cache and re-collect signals. May require turnstile_token.","in":"query","name":"refresh","required":false,"schema":{"type":"boolean"}},{"description":"Cloudflare Turnstile token, required for uncached lookups when captcha is enabled.","in":"query","name":"turnstile_token","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReputationEnvelope"}}},"description":"Reputation lookup result"},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"CAPTCHA_REQUIRED","details":{"cached":false},"message":"complete captcha to refresh this reputation lookup"}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Captcha verification required to refresh this lookup"}},"security":[],"summary":"Public reputation lookup — domain, IP, ASN, URL, or email","tags":["Lookup"]}},"/api/v1/public/requests":{"get":{"operationId":"listPublicIOCRequests","parameters":[{"in":"query","name":"status","schema":{"enum":["open","fulfilled","closed","expired"],"type":"string"}},{"$ref":"#/components/parameters/Page"},{"in":"query","name":"per_page","schema":{"default":20,"maximum":50,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IOCRequestListEnvelope"}}},"description":"Paginated list of IOC requests"}},"security":[],"summary":"List public IOC requests","tags":["IOC Requests"]}},"/api/v1/public/requests/{id}":{"get":{"operationId":"getPublicIOCRequest","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IOCRequestEnvelope"}}},"description":"IOC request details"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get a public IOC request by ID","tags":["IOC Requests"]}},"/api/v1/public/status/history":{"get":{"description":"Per-UTC-day probe and failure counts for each dependency GET /health/ready checks, plus the most recently failed probes. Recorded by a background worker every 5 minutes; a day with zero recorded probes means the API itself was not running to check, and is reported as zero probes rather than 100% uptime.","operationId":"getStatusHistory","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusHistoryEnvelope"}}},"description":"Readiness probe history"}},"security":[],"summary":"Get 90-day history of the API's own readiness probe","tags":["Statistics"]}},"/api/v1/rbl/check":{"get":{"operationId":"rblCheck","parameters":[{"description":"IPv4 or IPv6 address to check","in":"query","name":"ip","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RBLCheckEnvelope"}}},"description":"RBL check result"},"400":{"$ref":"#/components/responses/BadRequest"}},"security":[],"summary":"Check if an IP is listed in the RBL","tags":["IP RBL"]}},"/api/v1/reporters/{id}/tier":{"patch":{"operationId":"updateReporterTier","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTierRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReporterEnvelope"}}},"description":"Reporter updated"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Update reporter trust tier (requires admin scope)","tags":["Admin"]}},"/api/v1/reports":{"post":{"operationId":"createReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAuthReportRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportEnvelope"}}},"description":"Report created"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Submit a report (authenticated)","tags":["Reports"]}},"/api/v1/reports/bulk":{"post":{"operationId":"bulkCreateReports","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkCreateReportRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkResultEnvelope"}}},"description":"Bulk operation result"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Bulk submit reports (authenticated)","tags":["Reports"]}},"/api/v1/reports/{id}":{"delete":{"operationId":"deleteReport","parameters":[{"$ref":"#/components/parameters/ReportId"}],"responses":{"204":{"description":"Report deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Delete a report (requires admin scope)","tags":["Admin"]}},"/api/v1/reports/{id}/abuse":{"get":{"operationId":"getReportAbuseNotifications","parameters":[{"$ref":"#/components/parameters/ReportId"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseNotificationListEnvelope"}}},"description":"Abuse notifications for report"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get abuse notifications for a report (requires admin scope)","tags":["Admin"]}},"/api/v1/reports/{id}/status":{"patch":{"operationId":"updateReportStatus","parameters":[{"$ref":"#/components/parameters/ReportId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatusRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportEnvelope"}}},"description":"Report updated"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Update report status (requires admin scope)","tags":["Admin"]}},"/api/v1/reports/{id}/votes":{"get":{"operationId":"getReportVotes","parameters":[{"$ref":"#/components/parameters/ReportId"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteListEnvelope"}}},"description":"List of votes"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get votes for a report (authenticated)","tags":["Votes"]},"post":{"operationId":"castVote","parameters":[{"$ref":"#/components/parameters/ReportId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CastVoteRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteEnvelope"}}},"description":"Vote recorded"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Cast a vote on a report","tags":["Votes"]}},"/api/v1/requests":{"post":{"operationId":"createIOCRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIOCRequestRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IOCRequestEnvelope"}}},"description":"IOC request created"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Create an IOC request (authenticated)","tags":["IOC Requests"]}},"/api/v1/requests/{id}":{"delete":{"operationId":"deleteIOCRequest","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Delete an IOC request","tags":["IOC Requests"]}},"/api/v1/requests/{id}/fulfill":{"post":{"operationId":"fulfillIOCRequest","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FulfillIOCRequestRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IOCRequestEnvelope"}}},"description":"IOC request fulfilled"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Fulfill an IOC request with a report","tags":["IOC Requests"]}},"/api/v1/stats":{"get":{"operationId":"getStats","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsEnvelope"}}},"description":"Platform statistics"}},"security":[],"summary":"Get platform statistics","tags":["Statistics"]}},"/api/v1/stats/abuse":{"get":{"operationId":"getStatsAbuse","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbuseStatsEnvelope"}}},"description":"Abuse stats"}},"security":[],"summary":"Get abuse notification statistics","tags":["Statistics"]}},"/api/v1/stats/abuse/providers":{"get":{"operationId":"getStatsAbuseProviders","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"description":"ProviderStats — provider name, takedown counts, timing","type":"object"},"type":"array"}},"type":"object"}}},"description":"Provider stats array"}},"security":[],"summary":"Get per-provider abuse statistics","tags":["Statistics"]}},"/api/v1/stats/activity":{"get":{"operationId":"getStatsActivity","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"description":"ActivityItem","type":"object"},"type":"array"}},"type":"object"}}},"description":"Activity items"}},"security":[],"summary":"Get recent activity items","tags":["Statistics"]}},"/api/v1/stats/feed-publications":{"get":{"operationId":"getFeedPublications","parameters":[{"in":"query","name":"state","required":false,"schema":{"enum":["published","suppressed"],"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"maximum":200,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedPublicationEventListEnvelope"}}},"description":"Recent publication transitions"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get recent broad-feed publication transitions","tags":["Admin"]}},"/api/v1/stats/geo":{"get":{"operationId":"getStatsGeo","responses":{"200":{"content":{"application/json":{"schema":{"description":"GeoData","properties":{"data":{"description":"GeoData — country/region breakdown of IOCs","type":"object"}},"type":"object"}}},"description":"Geographic distribution"}},"security":[],"summary":"Get geographic distribution data","tags":["Statistics"]}},"/api/v1/stats/health":{"get":{"operationId":"getSystemHealth","responses":{"200":{"content":{"application/json":{"schema":{"description":"SystemHealth","properties":{"data":{"description":"SystemHealth — DB, Redis, worker status","type":"object"}},"type":"object"}}},"description":"System health"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get system health (requires admin scope)","tags":["Admin"]}},"/api/v1/stats/threat-intel":{"get":{"operationId":"getStatsThreatIntel","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"description":"ThreatIntelStats","type":"object"}},"type":"object"}}},"description":"Threat intel stats"}},"security":[],"summary":"Get threat intelligence statistics","tags":["Statistics"]}},"/api/v1/stats/trends":{"get":{"operationId":"getStatsTrends","responses":{"200":{"content":{"application/json":{"schema":{"description":"Trend data object","properties":{"data":{"description":"TrendData — time-series arrays of report/vote counts","type":"object"}},"type":"object"}}},"description":"Trend data"}},"security":[],"summary":"Get trend data","tags":["Statistics"]}},"/api/v1/usage":{"get":{"operationId":"getUsageSummary","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"description":"UsageSummary per API key","type":"object"},"type":"array"}},"type":"object"}}},"description":"Usage summary list"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get usage summary for all keys (requires admin scope)","tags":["Admin"]}},"/api/v1/usage/{key_id}":{"get":{"operationId":"getUsageHistory","parameters":[{"in":"path","name":"key_id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"description":"UsageHistory entry","type":"object"},"type":"array"}},"type":"object"}}},"description":"Usage history"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Get usage history for a specific API key (requires admin scope)","tags":["Admin"]}},"/api/v1/watchlist":{"get":{"operationId":"listWatchlist","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistListEnvelope"}}},"description":"Watchlist entries"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"List watchlist entries for the authenticated reporter","tags":["Watchlist"]},"post":{"operationId":"createWatchlist","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWatchlistRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistEnvelope"}}},"description":"Watchlist entry created"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Add a watchlist entry","tags":["Watchlist"]}},"/api/v1/watchlist/{id}":{"delete":{"operationId":"deleteWatchlist","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Watchlist entry deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Delete a watchlist entry","tags":["Watchlist"]}},"/api/v1/webhooks":{"get":{"operationId":"listWebhooks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListEnvelope"}}},"description":"Webhook list"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"List webhooks for the authenticated reporter","tags":["Webhooks"]},"post":{"operationId":"createWebhook","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEnvelope"}}},"description":"Webhook created"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Create a webhook subscription","tags":["Webhooks"]}},"/api/v1/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Webhook deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"summary":"Delete a webhook","tags":["Webhooks"]}},"/health":{"get":{"operationId":"healthCheck","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"service":{"example":"vspam-api","type":"string"},"status":{"example":"ok","type":"string"}},"type":"object"}}},"description":"Service is healthy"}},"security":[],"summary":"Health check","tags":["Authentication"]}},"/taxii2/":{"get":{"operationId":"taxiiDiscovery","responses":{"200":{"content":{"application/taxii+json;version=2.1":{"schema":{"$ref":"#/components/schemas/TAXIIDiscovery"}}},"description":"TAXII Discovery object"}},"security":[],"summary":"TAXII Discovery endpoint","tags":["TAXII 2.1"]}},"/taxii2/api/":{"get":{"operationId":"taxiiAPIRoot","responses":{"200":{"content":{"application/taxii+json;version=2.1":{"schema":{"$ref":"#/components/schemas/TAXIIAPIRoot"}}},"description":"TAXII API Root object"}},"security":[],"summary":"TAXII API Root information","tags":["TAXII 2.1"]}},"/taxii2/api/collections/":{"get":{"operationId":"taxiiListCollections","responses":{"200":{"content":{"application/taxii+json;version=2.1":{"schema":{"$ref":"#/components/schemas/TAXIICollectionsEnvelope"}}},"description":"Collections list"}},"security":[],"summary":"List TAXII collections","tags":["TAXII 2.1"]}},"/taxii2/api/collections/{id}/":{"get":{"operationId":"taxiiGetCollection","parameters":[{"description":"TAXII collection ID","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/taxii+json;version=2.1":{"schema":{"$ref":"#/components/schemas/TAXIICollection"}}},"description":"TAXII Collection object"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get a TAXII collection by ID","tags":["TAXII 2.1"]}},"/taxii2/api/collections/{id}/manifest/":{"get":{"operationId":"taxiiGetManifest","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/taxii+json;version=2.1":{"schema":{"$ref":"#/components/schemas/TAXIIManifest"}}},"description":"TAXII Manifest"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get manifest for a TAXII collection","tags":["TAXII 2.1"]}},"/taxii2/api/collections/{id}/objects/":{"get":{"operationId":"taxiiGetObjects","parameters":[{"description":"TAXII collection ID","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"Only return objects added after this timestamp (RFC3339)","in":"query","name":"added_after","schema":{"format":"date-time","type":"string"}},{"description":"Filter expression (e.g. match[type]=indicator)","in":"query","name":"match","schema":{"type":"string"}},{"description":"Maximum number of objects to return","in":"query","name":"limit","schema":{"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/stix+json;version=2.1":{"schema":{"$ref":"#/components/schemas/STIXBundle"}}},"description":"STIX 2.1 Bundle"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[],"summary":"Get STIX objects from a TAXII collection","tags":["TAXII 2.1"]}}},"servers":[{"description":"Production","url":"https://api.vspam.org"},{"description":"Development","url":"http://localhost:8080"}],"tags":[{"description":"Register, login, token refresh, and email verification","name":"Authentication"},{"description":"Submit and retrieve phishing IOC reports","name":"Reports"},{"description":"Operator and hash-based IOC lookup","name":"Lookup"},{"description":"Community requests for specific IOC intelligence","name":"IOC Requests"},{"description":"Pivot from an IP, domain, or nameserver to related reports","name":"Pivot Search"},{"description":"Real-time IP blocklist check","name":"IP RBL"},{"description":"Community voting on report accuracy","name":"Votes"},{"description":"Manage API keys for programmatic access","name":"API Keys"},{"description":"Reporter profile and leaderboard","name":"Profile"},{"description":"Platform-wide statistics and trends","name":"Statistics"},{"description":"Webhook subscriptions for real-time events","name":"Webhooks"},{"description":"Pattern-based IOC watchlist with notifications","name":"Watchlist"},{"description":"Server-Sent Events (SSE) real-time stream","name":"Events"},{"description":"Threat feed downloads scoped to a named feed slug","name":"Named Feeds"},{"description":"Bulk threat feed downloads in various formats","name":"Feeds"},{"description":"TAXII 2.1 compatible endpoints for STIX bundle delivery","name":"TAXII 2.1"},{"description":"Administrative endpoints — requires admin scope","name":"Admin"}]}