API reference
Plain REST over HTTPS, JSON by default. Base URL https://isipsafe.com/api/v1. There is also an OpenAPI 3.1 spec if you would rather generate a client.
Authentication
Lookups (check, reports, check-block) work without a key, up to 400 per 24 hours per client address. Reporting, bulk uploads, the blocklist and clearing reports need a key, and a free account's key raises lookups to 10,000 per 24 hours (no limit on Enterprise). Sign in to get one (free), then add it to the URL as key:
https://isipsafe.com/api/v1/blocklist?key=sl_your_key_here&format=txt
If you prefer to keep it out of URLs (and out of proxy logs), send it as a header instead. Both work on every endpoint:
Authorization: Bearer sl_your_key_here
A wrong key returns 401 instead of quietly falling back to the anonymous allowance, so typos are obvious. The examples below assume export ISIPSAFE_KEY=sl_your_key_here.
Licence. Data from the API and the blocklist may be used to protect your own systems. Reselling it, redistributing it or building products and services on it, directly or indirectly, needs written authorisation. See the EULA and contact us for a commercial licence.
Responses and errors
Successful responses wrap the payload in data. Errors look like this, with a matching HTTP status:
{ "errors": [ { "detail": "ip: that is not a valid IPv4 or IPv6 address", "status": 422 } ] }
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 also has Retry-After in seconds. Limits are on the pricing page.
/check
Everything we know about one address.
| Parameter | Description |
|---|---|
| ip | IPv4 or IPv6 address. Required. |
| maxAgeInDays | Count reports from the last N days, 1 to 365. Default 30. The score itself always uses 30. |
| verbose | Include up to 100 of the reports themselves. |
curl -s "https://isipsafe.com/api/v1/check?ip=203.0.113.50&verbose&key=$ISIPSAFE_KEY"
{
"data": {
"ipAddress": "203.0.113.50",
"isPublic": true,
"isWhitelisted": false,
"isTor": false,
"hostnames": ["scanner-7.example.net"],
"ipVersion": 4,
"abuseConfidenceScore": 86,
"confidenceBand": "High",
"totalReports": 41,
"numDistinctUsers": 6,
"firstReportedAt": "2026-10-02T08:14:11Z",
"lastReportedAt": "2026-10-25T03:12:40Z",
"categories": ["port-scan", "brute-force", "ssh"],
"categoryIds": [14, 18, 22],
"countryCode": "NL",
"countryName": "Netherlands",
"region": "North Holland",
"city": "Amsterdam",
"asn": 64496,
"isp": "Example Hosting B.V.",
"link": "https://isipsafe.com/ip/203.0.113.50",
"reports": [ { "reportedAt": "...", "comment": "...", "categories": ["ssh", "brute-force"], "reporterType": "verified", "reporterCountryCode": "DE" } ]
}
}
/report
key requiredReport one address. Send form fields or JSON. Without a key the API answers 401.
| Field | Description |
|---|---|
| ip | The address, or a network in CIDR notation (up to a /16 or /48; network is accepted as an alias). Required. Private and reserved ranges are rejected. A network report gives each address inside it the report's weight divided by half the network size. |
| categories | Comma separated category codes, e.g. ssh,brute-force. Required. Up to 12. JSON may send an array. Numeric IDs (22,18) are accepted too, for older scripts. |
| comment | Up to 1,024 characters. Public, so leave out anything personal. |
| timestamp | When it happened, RFC 3339. Optional, defaults to now. |
curl -s "https://isipsafe.com/api/v1/report?key=$ISIPSAFE_KEY" \
-d ip=203.0.113.50 -d categories=ssh,brute-force -d comment="sshd: 212 failed logins"
curl -s https://isipsafe.com/api/v1/report -H "Content-Type: application/json" \
-d '{"ip":"2001:db8::7","categories":["web-app-attack","sql-injection"],"comment":"UNION SELECT in ?id="}'
{ "data": { "ipAddress": "203.0.113.50", "abuseConfidenceScore": 87, "link": "https://isipsafe.com/ip/203.0.113.50" } }
The same reporter can report the same address once per 15 minutes. A repeat returns 429; treat it as success. Reporting 127.0.0.2 always returns a 429, so you can test how your script handles it. Allowlisted addresses (public DNS resolvers and the like) are rejected with 422.
/bulk-report
key requiredUp to 10,000 reports in one CSV. Columns IP,Categories,ReportDate,Comment, header row optional. Send it as the csv field of a multipart form, or as the raw body.
curl -s "https://isipsafe.com/api/v1/bulk-report?key=$ISIPSAFE_KEY" -F [email protected]
{ "data": { "savedReports": 812, "invalidReports": [ { "error": "unknown category \"99\"", "input": "198.51.100.4", "rowNumber": 14 } ] } }
/reports
Reports for one address, newest first, paginated.
| Parameter | Description |
|---|---|
| ip | Required. |
| maxAgeInDays | 1 to 365, default 30. |
| page, perPage | Default 1 and 25. perPage up to 100. |
The response includes total, lastPage, nextPageUrl and previousPageUrl.
/check-block
All reported addresses inside a network. IPv4 blocks up to a /16, IPv6 up to a /48.
curl -s "https://isipsafe.com/api/v1/check-block?network=203.0.113.0/24&maxAgeInDays=60"
/blocklist
key requiredThe addresses with the highest confidence, ready for a firewall. /blacklist is an alias for tools that expect that name.
| Parameter | Description |
|---|---|
| format | json (default), txt, csv, stix (STIX 2.1 bundle), ipset, nftables, nginx, apache, mikrotik. plaintext or Accept: text/plain also give txt. |
| confidenceMinimum | 1 to 100, default 75. |
| days | Only addresses reported in the last N days, 1 to 90. Default 30. |
| limit | Up to 500,000. Default 10,000. Highest scores first. |
| ipVersion | 4 or 6. Default both. |
| onlyCountries | ISO 3166 codes, e.g. CN,RU. |
| exceptCountries | ISO 3166 codes to leave out, e.g. GB,IE. |
| download | Adds a Content-Disposition header so browsers save a file. |
curl -s "https://isipsafe.com/api/v1/blocklist?key=$ISIPSAFE_KEY&format=txt&confidenceMinimum=90&exceptCountries=GB"
/clear-address
key requiredDeletes every report you (this key's account) filed against an address. Use it when you reported something by mistake.
curl -s -X DELETE "https://isipsafe.com/api/v1/clear-address?key=$ISIPSAFE_KEY&ip=203.0.113.50"
/categories
All categories with their code (slug), name, group, description and legacy numeric ID. Also on the categories page.
Coming from another service?
Field names (ip, categories, comment, maxAgeInDays, confidenceMinimum), the response fields (abuseConfidenceScore, totalReports, numDistinctUsers, lastReportedAt) and category numbers 1 to 23 follow the conventions most abuse databases use. In most scripts, changing the base URL and the key is enough.