{"openapi":"3.1.0","info":{"title":"AbuseTrack API","version":"1.0.0","description":"Community-driven IP abuse-reporting and threat intelligence. Look up what the community has reported on an IPv4 or IPv6 address, and submit your own reports, for example straight from a fail2ban sensor.\n\nAuthenticated endpoints require an API key. Create one in your account under **API keys** and send it as a bearer token:\n\n`Authorization: Bearer at_your_api_key_here`\n\n(The `x-api-key: <key>` and AbuseIPDB-style `Key: <key>` headers are also accepted.) Each authenticated call counts against your plan's request limit.\n\n**Without an account:** `/api/v1/lookup` and `/api/v1/blocklist.txt` also answer without a key, rate-limited per client IP (lookups show the latest 10 reports; the blocklist is the delayed community feed).\n\n**AbuseIPDB compatible:** `/api/v2/check`, `/api/v2/report` and `/api/v2/blacklist` accept AbuseIPDB's parameters and return its response format. Existing tools such as fail2ban's `abuseipdb` action work by changing the base URL to this instance and using an AbuseTrack key.","contact":{"name":"AbuseTrack","url":"https://abusetrack.io"}},"servers":[{"url":"https://abusetrack.io","description":"This instance"}],"tags":[{"name":"Lookup","description":"Query community threat data"},{"name":"Blocklist","description":"Plain-text IP blocklist feed"},{"name":"Reports","description":"Submit new abuse reports"},{"name":"Stats","description":"Public live statistics"},{"name":"AbuseIPDB compatible","description":"Drop-in endpoints for tools written against AbuseIPDB API v2"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your API key as a bearer token, e.g. `Authorization: Bearer at_…`."},"keyHeader":{"type":"apiKey","in":"header","name":"Key","description":"AbuseIPDB-style header, e.g. `Key: at_…`."},"keyQuery":{"type":"apiKey","in":"query","name":"key","description":"Read-only list endpoints only, for firewalls that can load a URL but not send headers (pfSense, OPNsense, MikroTik)."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"Usage":{"type":"object","description":"Your account-wide API usage for the current day after this call. The quota is a single daily pool shared by all your keys and resets at 00:00 UTC.","properties":{"used":{"type":"integer","example":42},"limit":{"type":"integer","example":3000},"resetsAt":{"type":"string","format":"date-time","description":"When the daily quota next resets (UTC).","example":"2026-06-16T00:00:00.000Z"}}},"LookupHit":{"type":"object","properties":{"type":{"type":"string","enum":["ip"],"example":"ip"},"value":{"type":"string","example":"203.0.113.10"},"threatType":{"type":"string","example":"Brute Force"},"reportedAt":{"type":"string","format":"date-time","example":"2026-06-14T20:41:55.000Z"}}},"LookupResponse":{"type":"object","properties":{"value":{"type":"string","example":"203.0.113.10"},"reported":{"type":"boolean","example":true},"count":{"type":"integer","example":3},"results":{"type":"array","items":{"$ref":"#/components/schemas/LookupHit"}},"usage":{"$ref":"#/components/schemas/Usage"}}},"ReportRequest":{"type":"object","required":["type","value","threatType"],"properties":{"type":{"type":"string","enum":["ip"],"description":"The kind of entity you are reporting (IP only).","example":"ip"},"value":{"type":"string","description":"The entity itself. Must be valid for the given type. Private, loopback and reserved IP ranges are rejected.","example":"203.0.113.10"},"threatType":{"type":"string","description":"What the entity did, e.g. \"Brute Force\", \"Phishing\", \"Spam\".","example":"Brute Force"},"comment":{"type":"string","maxLength":1000,"description":"Optional free-text note describing the incident (AbuseIPDB-style).","example":"SSH brute-force: 8 failed logins on sshd"},"additionalFields":{"type":"object","additionalProperties":true,"description":"Optional structured metadata to attach to the report."}}},"ReportResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"},"usage":{"$ref":"#/components/schemas/Usage"}}},"StatsResponse":{"type":"object","properties":{"counts":{"type":"object","properties":{"ip":{"type":"integer","example":1380}}},"total":{"type":"integer","example":1380},"threats":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","example":"Brute Force"},"count":{"type":"integer","example":1290}}}},"recent":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","example":"ip"},"value":{"type":"string","example":"203.0.113.10"},"threatType":{"type":"string","example":"Brute Force"},"country":{"type":["string","null"],"example":"US"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"paths":{"/api/v1/lookup":{"get":{"tags":["Lookup"],"summary":"Look up an entity","description":"Return every community report matching an IPv4 or IPv6 address. With a key it counts against your usage limit. Without a key it is limited to 60 calls per hour per client IP and returns the latest 10 reports.","security":[{},{"bearerAuth":[]},{"keyHeader":[]}],"parameters":[{"name":"value","in":"query","required":true,"description":"The entity to look up.","schema":{"type":"string"},"example":"203.0.113.10"}],"responses":{"200":{"description":"Lookup result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupResponse"}}}},"400":{"description":"The `value` query parameter is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Usage limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/blocklist.txt":{"get":{"tags":["Blocklist"],"summary":"Community blocklist feed","description":"Plain-text list of abusive IP addresses, one per line (lines starting with `#` are comments). Built for firewall feeds such as CrowdSec, ipset/iptables or any tool that ingests a blocklist URL. Without a key it serves the community feed (capped, new IPs delayed), 12 calls per hour per client IP. With a key (header, or `?key=` for URL-only firewalls) it counts as one API call per refresh, and accounts that report get the full real-time feed. Poll it every 15-30 minutes.","security":[{},{"bearerAuth":[]},{"keyHeader":[]},{"keyQuery":[]}],"parameters":[{"name":"score","in":"query","required":false,"description":"Minimum community risk score, 0-100. Default 25 (Medium and up).","schema":{"type":"integer","minimum":0,"maximum":100,"default":25}},{"name":"reporters","in":"query","required":false,"description":"Minimum number of distinct reporters required. Default 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"since","in":"query","required":false,"description":"Only include IPs reported within the last N days. Omit for all-time.","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"description":"Maximum number of IPs to return. Default 10000.","schema":{"type":"integer","minimum":1,"maximum":200000,"default":10000}},{"name":"comments","in":"query","required":false,"description":"Set to `0` for pure IPs with no `#` header (for strict parsers like CrowdSec's `cscli decisions import`). Default includes comments.","schema":{"type":"string","enum":["0","1"],"default":"1"}}],"responses":{"200":{"description":"The blocklist, as plain text.","content":{"text/plain":{"schema":{"type":"string"},"example":"# AbuseTrack community blocklist\n203.0.113.10\n198.51.100.7\n"}}},"401":{"description":"Missing or invalid API key.","content":{"text/plain":{"schema":{"type":"string"}}}},"429":{"description":"Usage limit reached or too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reports":{"post":{"tags":["Reports"],"summary":"Submit a report","description":"Submit a new abuse report. Used by integrations such as the fail2ban reporter to push abusive IPs in real time. Counts against your usage limit.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"}}}},"responses":{"200":{"description":"The report was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportResponse"}}}},"400":{"description":"Invalid type, value or missing threatType.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The value has been blocked by an administrator.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Usage limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/check":{"get":{"tags":["AbuseIPDB compatible"],"summary":"Check an IP (AbuseIPDB format)","description":"AbuseIPDB API v2 `check`. `abuseConfidenceScore` is the AbuseTrack community risk score (0-100). Fields AbuseTrack has no data for (usageType, domain, isTor) are returned empty.","security":[{"keyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"ipAddress","in":"query","required":true,"schema":{"type":"string"}},{"name":"maxAgeInDays","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":365,"default":30}},{"name":"verbose","in":"query","required":false,"description":"Flag: include the individual reports (up to 100).","schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: { ipAddress, abuseConfidenceScore, totalReports, ... } }`"},"401":{"description":"Missing or invalid key (AbuseIPDB error format)."},"422":{"description":"Invalid IP address."}}}},"/api/v2/report":{"post":{"tags":["AbuseIPDB compatible"],"summary":"Report an IP (AbuseIPDB format)","description":"AbuseIPDB API v2 `report`. Parameters as form fields, JSON or query string. Categories are AbuseIPDB category ids (e.g. `18,22` for SSH brute force). The same IP can be reported by one account once per 15 minutes.","security":[{"keyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"ip","in":"query","required":true,"schema":{"type":"string"}},{"name":"categories","in":"query","required":true,"description":"Comma-separated AbuseIPDB category ids (1-23).","schema":{"type":"string","example":"18,22"}},{"name":"comment","in":"query","required":false,"schema":{"type":"string"}},{"name":"timestamp","in":"query","required":false,"description":"ISO 8601 time of the attack (stored with the report).","schema":{"type":"string"}}],"responses":{"200":{"description":"`{ data: { ipAddress, abuseConfidenceScore } }`"},"422":{"description":"Invalid IP or categories."},"429":{"description":"Same IP reported by this account within 15 minutes, or daily quota used up."}}}},"/api/v2/blacklist":{"get":{"tags":["AbuseIPDB compatible"],"summary":"Blocklist (AbuseIPDB format)","description":"AbuseIPDB API v2 `blacklist`. JSON by default; one IP per line with `plaintext` or `Accept: text/plain`. The give-to-get policy applies as on /api/v1/blocklist.txt. `confidenceMinimum` defaults to 75 (AbuseIPDB: 100) because AbuseTrack scores are calibrated differently.","security":[{"keyHeader":[]},{"bearerAuth":[]},{"keyQuery":[]}],"parameters":[{"name":"confidenceMinimum","in":"query","required":false,"schema":{"type":"integer","minimum":25,"maximum":100,"default":75}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200000,"default":10000}},{"name":"plaintext","in":"query","required":false,"schema":{"type":"string"}},{"name":"ipVersion","in":"query","required":false,"schema":{"type":"string","enum":["4","6"]}},{"name":"onlyCountries","in":"query","required":false,"description":"Comma-separated ISO country codes.","schema":{"type":"string"}},{"name":"exceptCountries","in":"query","required":false,"description":"Comma-separated ISO country codes.","schema":{"type":"string"}}],"responses":{"200":{"description":"`{ meta: { generatedAt }, data: [{ ipAddress, countryCode, abuseConfidenceScore, lastReportedAt }] }`"}}}},"/api/stats":{"get":{"tags":["Stats"],"summary":"Live statistics","description":"Public, unauthenticated live statistics: counts per category, the threat-type distribution and the latest reports.","responses":{"200":{"description":"Current statistics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}}}}}}