Email Reputation
The Email Reputation endpoints provide sending IP reputation scoring based on trap hits, blocklist status, telemetry signals, and behavioral analysis. Scores range from 0 (worst) to 100 (best). Single-IP and batch reputation routes are anonymous, expose only LimesIndex-owned evidence, and share a 60 requests/minute per-client-IP limit.
Single IP Reputation
GET/v1/email/ip/{ip}/reputation
Get the full sending reputation for an IP, including contributing factors, 30-day history, and subnet context.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ip | string | Yes | IPv4 or IPv6 address |
Response (200)
{
"data": {
"ip": "198.51.100.25",
"score": 71,
"level": "neutral",
"factors": [
{
"name": "ip_age_days",
"impact": 6,
"detail": "Observed sending for 95 days (+2 per 30 days, capped at +20)"
},
{
"name": "neighbor_reputation",
"impact": 10,
"detail": "Subnet 198.51.100.0/24 is clean — no active listings"
},
{
"name": "datacenter_type",
"impact": 5,
"detail": "Active dataset classifies this IP as a datacenter with no negative reputation signals"
}
],
"history": [
{
"score": 75,
"level": "good",
"computed_at": "2026-04-12T00:00:00Z"
},
{
"score": 72,
"level": "good",
"computed_at": "2026-04-11T00:00:00Z"
}
],
"subnet": {
"subnet": "198.51.100.0/24",
"total_ips_seen": 12,
"listed_count": 0,
"avg_reputation": 71,
"worst_score": 71,
"contamination_level": "clean"
},
"blocklist": {
"listed": false
},
"fcrdns": {
"ip": "198.51.100.25",
"ptr_hostname": "mail.example.net",
"forward_match": true,
"forward_ips": ["198.51.100.25"],
"last_checked_at": "2026-04-12T00:00:00Z",
"last_observed_at": "2026-04-12T00:00:00Z"
}
},
"meta": {
"processing_time_ms": 12
}
}
Response Fields
Data Object
| Field | Type | Description |
|---|---|---|
ip | string | The queried IP address (normalized) |
score | integer | Reputation score (0-100) |
level | string | Human-readable level |
factors | array | Factors contributing to the score |
history | array | 30-day score history |
subnet | object | Subnet reputation context |
blocklist | object | LimesIndex-owned blocklist status |
fcrdns | object | Latest FCrDNS status, when available |
Factor Object
| Field | Type | Description |
|---|---|---|
name | string | Factor identifier |
impact | integer | Positive or negative impact on the score |
detail | string | Human-readable explanation |
History Point
| Field | Type | Description |
|---|---|---|
score | integer | Score at that point |
level | string | Level at that point |
computed_at | string | ISO 8601 timestamp |
Score Ranges
| Score | Level | Description |
|---|---|---|
| 80-100 | good | Healthy sender reputation |
| 60-79 | neutral | Some risk signals detected |
| 40-59 | poor | Multiple negative signals |
| 0-39 | bad | Severe reputation issues |
Scoring model
The scorer is deterministic and starts at 50 (neutral/unknown). Each returned factor explains its exact contribution; the final score is clamped to 0–100.
The production factors are:
- active blocklist listing: −40;
- pristine trap hits: −15 per hit, capped at −45;
- recycled/typo trap hits: −5 per hit, capped at −20;
- SMTP honeypot activity: −15;
- cross-signal corroboration: −10 per additional signal type, capped at −30;
telemetry_bounce_rateabove 5%: −25;telemetry_complaint_rateabove 0.1%: −30;- a clean /24 subnet: +10;
- repeated historical listings (three or more in 30 days): −10;
- geo instability: −10 for one or two changes, −20 for three or more;
- failed FCrDNS: −15;
- earliest production observation age: +2 per 30 full days, capped at +20;
- active datacenter classification: +5 only when no negative reputation signal is present.
The neighbor_reputation factor feeds back the subnet result for IPv4
addresses: clean is +10, light contamination is 0, moderate is
−5, and heavy is −15. The neighbors endpoint reports clean for zero
active listings, light for 1–2, moderate for 3–5, and heavy for 6 or more.
An absent age or datacenter classification is unknown and contributes no bonus. Synthetic trap observations are excluded from the age anchor and all production reputation evidence. Evidence read failures are returned as an unavailable error rather than converted into a neutral or clean score.
Batch Reputation
POST/v1/email/reputation/batch
Get reputation scores for multiple IPs in a single request. Returns score and level for each IP.
Request Body
{
"ips": ["198.51.100.25", "203.0.113.50"]
}
Maximum 100 IPs per request.
Response (200)
{
"data": [
{
"ip": "198.51.100.25",
"score": 78,
"level": "good"
},
{
"ip": "203.0.113.50",
"score": 50,
"level": "neutral"
}
],
"meta": {
"processing_time_ms": 20
}
}
Limits
- Maximum 100 IPs per request
- Invalid or non-public IPs are rejected with
400 Bad Request. - If reputation evidence is unavailable for an IP, the request returns
503rather than synthesizing a neutral score.
Subnet Neighbors
GET/v1/email/ip/{ip}/neighbors
Analyze the /24 subnet reputation around an IP address. Shows how many neighbors are listed and the overall contamination level. Useful for understanding whether an IP is in a "bad neighborhood."
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ip | string | Yes | Public IPv4 address |
Response (200)
{
"data": {
"subnet": "198.51.100.0/24",
"total_ips_seen": 12,
"listed_count": 1,
"avg_reputation": 65,
"worst_score": 30,
"contamination_level": "light"
},
"meta": {
"processing_time_ms": 8
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
subnet | string | The /24 subnet in CIDR notation |
total_ips_seen | integer | Total IPs observed in this subnet |
listed_count | integer | Number of active blocklist listings in this subnet |
avg_reputation | integer | Average reputation score in the subnet |
worst_score | integer | Lowest reputation score in the subnet |
contamination_level | string | Overall level: clean, light, moderate, heavy |
Contamination Levels
| Level | Description |
|---|---|
| clean | No blocklisted IPs in the subnet |
| light | 1-2 listed IPs, low risk to neighbors |
| moderate | Multiple listed IPs, some risk of guilt-by-association |
| heavy | Many listed IPs, significant shared-IP risk |
Error Responses
400 Bad Request
{
"data": {
"error": "invalid IP address",
"code": "INVALID_IP"
},
"meta": {
"processing_time_ms": 0
}
}
Code Examples
cURL
# Single IP reputation (anonymous; 60 requests/minute per client IP)
curl "https://api.limesindex.com/v1/email/ip/198.51.100.25/reputation"
# Batch reputation (anonymous; shares the same 60 requests/minute budget)
curl -X POST "https://api.limesindex.com/v1/email/reputation/batch" \
-H "Content-Type: application/json" \
-d '{"ips": ["198.51.100.25", "203.0.113.50"]}'
# Subnet neighbors
curl -X GET "https://api.limesindex.com/v1/email/ip/198.51.100.25/neighbors" \
-H "X-API-Key: YOUR_API_KEY"
Python
import requests
BASE_URL = "https://api.limesindex.com"
# Get reputation for an IP
resp = requests.get(
f"{BASE_URL}/v1/email/ip/198.51.100.25/reputation"
)
data = resp.json()["data"]
print(f"Score: {data['score']} ({data['level']})")
for factor in data["factors"]:
sign = "+" if factor["impact"] > 0 else ""
print(f" {sign}{factor['impact']} {factor['name']}: {factor['detail']}")
# Check subnet health
resp = requests.get(
f"{BASE_URL}/v1/email/ip/198.51.100.25/neighbors",
headers={"X-API-Key": "YOUR_API_KEY"}
)
subnet = resp.json()["data"]
print(f"Subnet: {subnet['subnet']}")
print(f"Contamination: {subnet['contamination_level']}")
print(f"Listed neighbors: {subnet['listed_count']}/{subnet['total_ips_seen']}")
Use Cases
- Pre-campaign assessment: Check your sending IPs' reputation before a campaign
- IP rotation decisions: Identify which IPs in your pool need rest or removal
- Subnet risk: Understand shared-IP contamination risk before purchasing new IPs
- Trend monitoring: Track reputation history to detect degradation early
Related Endpoints
- Blocklist - Direct blocklist status checks
- Warmup - Warm-up guidance based on reputation
- Email Domain DNS - Domain authentication analysis