Repository navigation
07 Report Anatomy
What exactly is sent to AbuseIPDB, how it is built, and what is deliberately left out.
POST https://api.abuseipdb.com/api/v2/report with headers Key: <api key>,
Accept: application/json and a form body:
| Field | Value |
|---|---|
ip |
the banned address (IPv4 or IPv6), validated before queueing |
categories |
union of the jail category map; 16 added when SQL injection is detected |
timestamp |
time of the first queued ban for that IP, ISO-8601 with the local offset |
comment |
≤1000 bytes; generated, PII-free, attribution footer last |
Free plan constraints: 1000 reports + checks per day, one report per IP per 15 minutes; a comment longer than 1024 bytes is truncated by the API. The reporter stays inside these limits with 900/day, 20 min/IP and 1000-byte comments.
AbuseIPDB category IDs used by default (see https://www.abuseipdb.com/categories):
| ID | Title | Default jails |
|---|---|---|
| 5 | FTP Brute-Force | proftpd |
| 11 | Email Spam | exim-isp |
| 15 | Hacking | nginx-php-probe |
| 16 | SQL Injection | automatic on SQLi patterns |
| 18 | Brute-Force |
sshd, proftpd, exim-auth-fail, nginx-wp-login
|
| 19 | Bad Web Bot | nginx-attack-scan |
| 21 | Web App Attack | all web jails |
| 22 | SSH | sshd |
The map is configurable per jail; see Configuration.
Automated fail2ban report from server 203.0.113.10.
Attack type: SSH brute-force (jails: sshd).
Observed: 2026-01-02T03:04:05+00:00.
Detections: 1 ban event(s), 4 failed attempts.
Ban duration: 4d.
Patterns: PAM authentication failures; root password attempts; invalid usernames tried.
Log evidence:
sshd-session[123]: pam_unix(sshd:auth): authentication failure; ... rhost=198.51.100.7
sshd-session[123]: Failed password for root from 198.51.100.7 port 22 ssh2
No personal data included.
--
Reported via Fail2Ban_AbuseIPDB Monitor: https://github.com/paulmann/Fail2Ban_AbuseIPDB
Web example:
Automated fail2ban report from server 203.0.113.10.
Attack type: web application vulnerability scanning/exploitation attempts (jails: nginx-attack-scan).
Observed: 2026-01-02T03:04:05+00:00.
Detections: 1 ban event(s), 5 failed attempts.
Ban duration: 1d.
Sample requests/indicators:
GET /.env -> 404
GET /.git/config -> 404
GET /wp-admin/install.php?step=1 -> 404
GET /api/v1/items?id=1%20UNION%20SELECT%20@@version -> 404
No personal data included.
--
Reported via Fail2Ban_AbuseIPDB Monitor: https://github.com/paulmann/Fail2Ban_AbuseIPDB
Fields:
-
attack type — human description per jail (
JAIL_DESCRIPTIONS); - jails — every jail that contributed events for this IP;
- observed — first..last ban timestamp;
-
detections — number of queued ban events and sum of
failures; -
ban duration — from the events (
1h,1d, ...); - patterns — generic failure kinds (SSH/FTP/mail), never usernames;
- sample requests/indicators — for web jails, the attacker's own URLs and HTTP status;
- log evidence — fallback for web jails when URL extraction is not possible;
- attribution footer — configurable, appended after truncation, never cut off.
| Data | Sent? | Why |
|---|---|---|
| Attacker IP | yes | the purpose of the report |
| Jail name, counters, ban time | yes | factual context |
| Attacker's request URLs (web) | yes | useful to other AbuseIPDB users |
| Attempted usernames (SSH/FTP/SMTP) | no | attacker-chosen strings, no analytical value |
| Mail content, sender/recipient | no | third-party PII |
| Client domains / site names | no | not needed for an IP reputation report |
| API key, server path, config | no | never leaves the host |
If you need fully neutral reports, set attribution = no; the report then contains only
evidence.
The provided timestamp is the first queued ban for that IP. If an event stayed in the
queue for more than 23 hours (API outage, exhausted daily budget), the reporter sends the current
time instead, so AbuseIPDB never receives a stale timestamp.
- Same IP within 15 minutes → the API returns
429; the reporter defers the event and retries later (default throttle: 20 minutes). - Same IP with the same comment within 24 hours → AbuseIPDB updates the timestamp of the existing report instead of creating a new one. This is platform behaviour, not a project feature.
# our local journal (no API call)
/usr/local/sbin/abuseipdb-report --stats
# what would be sent now
/usr/local/sbin/abuseipdb-report --dry-run
# AbuseIPDB's own view of an address (one check request)
curl -s -G "https://api.abuseipdb.com/api/v2/check" \
--data-urlencode "ipAddress=198.51.100.7" -d maxAgeInDays=1 -d verbose \
-H "Key: $(cat /etc/abuseipdb/.abuseipdb.key)" -H "Accept: application/json"In the verbose response, reports[].comment contains the exact text that was sent — including the
attribution footer, if enabled.
Next: Fail2Ban Fundamentals · Configuration · FAQ
Fail2Ban_AbuseIPDB · repository · releases · issues · MIT