> For the complete documentation index see https://domscan.net/llms.txt. Markdown versions of every docs page are available by appending .md to the page URL.

Source: https://domscan.net/docs/reputation

# Domain Reputation

Get a reputation score (0-100) for any domain based on multiple security and trust signals.

Get a reputation score (0-100) for any domain based on multiple security and trust signals. The API checks DNS security configuration, SSL certificates, blacklists (Spamhaus, SURBL), threat intelligence (URLhaus), email authentication, and web presence to calculate a weighted score with actionable recommendations.

GET /v1/reputation Credits: 3

#### Query parameters

| Parameter | Type | required |
| --- | --- | --- |
| domain | string | required |

#### Response fields

| Field | Type |
| --- | --- |
| `domain` | string |
| `reputation_score` | integer |
| `grade` | string |
| `risk_level` | string |
| `reputation_score_confidence` | string |
| `grade_capped_by_parking` | boolean |
| `factors` | object |
| `factors.age` | object |
| `factors.dns_security` | object |
| `factors.ssl_certificate` | object |
| `factors.hosting` | object |
| `factors.web_presence` | object |
| `factors.blacklists` | object |
| `factors.email_config` | object |
| `recommendations[]` | object[] |
| `recommendations[]` | object |
| `recommendations[].priority` | string |
| `recommendations[].category` | string |
| `recommendations[].action` | string |
| `recommendations[].impact` | string |
| `evidence_summary` | object |
| `evidence_summary.checks_performed` | integer |
| `evidence_summary.cache_status` | string |
| `evidence_summary.confidence` | string |
| `evidence_summary.risk_level` | string |
| `evidence_summary.factor_count` | integer |
| `evidence_summary.scored_factor_count` | integer |
| `evidence_summary.passing_factor_count` | integer |
| `evidence_summary.warning_factor_count` | integer |
| `evidence_summary.failing_factor_count` | integer |
| `evidence_summary.lowest_scoring_factors[]` | object[] |
| `evidence_summary.lowest_scoring_factors[]` | object |
| `evidence_summary.lowest_scoring_factors[].name` | string |
| `evidence_summary.lowest_scoring_factors[].score` | number \| null |
| `evidence_summary.lowest_scoring_factors[].weight` | number \| null |
| `evidence_summary.blacklist_listed_count` | integer |
| `evidence_summary.recommendation_count` | integer |
| `evidence_summary.high_priority_recommendation_count` | integer |
| `evidence_summary.grade_capped_by_parking` | boolean |
| `meta` | object |
| `meta.query_time_ms` | integer |
| `meta.checks_performed` | integer |
| `meta.cached` | boolean |
| `meta.served_by` | string |

#### Example request

```bash
curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/reputation?domain=example.com"
```

```javascript
const response = await fetch("https://domscan.net/v1/reputation?domain=example.com", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
```

```python
import os
import requests

response = requests.get(
    "https://domscan.net/v1/reputation?domain=example.com",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/reputation?domain=example.com", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
```

```ruby
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/reputation?domain=example.com")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))
```

#### Example response

```json
{
  "domain": "example.com",
  "reputation_score": 69,
  "grade": "C",
  "risk_level": "medium",
  "reputation_score_confidence": "high",
  "grade_capped_by_parking": true,
  "factors": {
    "age": {
      "score": 84,
      "weight": 0.1,
      "details": {
        "age_days": 5840
      }
    },
    "dns_security": {
      "score": 80,
      "weight": 0.2,
      "details": {
        "dnssec": false,
        "spf": true,
        "dmarc": true,
        "dmarc_policy": "reject"
      }
    },
    "ssl_certificate": {
      "score": 92,
      "weight": 0.2,
      "details": {
        "valid": true,
        "error": null,
        "grade": "A",
        "chain_valid": true,
        "min_tls_version": "TLSv1.3"
      }
    },
    "hosting": {
      "score": 35,
      "weight": 0.1,
      "details": {
        "has_a_records": true,
        "a_record_count": 2,
        "parked": true
      }
    },
    "web_presence": {
      "score": 20,
      "weight": 0.15,
      "details": {
        "has_website": true,
        "redirects_to_https": true,
        "response_time_ms": 87,
        "parked": true,
        "for_sale": false,
        "parking_provider": "Example Parking"
      }
    },
    "blacklists": {
      "score": 100,
      "weight": 0.1,
      "details": {
        "listed": false,
        "threat_level": "none",
        "domain_sources": [],
        "ip_sources": []
      }
    },
    "email_config": {
      "score": 100,
      "weight": 0.15,
      "details": {
        "has_mx": true,
        "has_spf": true,
        "has_dmarc": true,
        "mx_count": 2
      }
    }
  },
  "recommendations": [
    {
      "priority": "high",
      "category": "web_presence",
      "action": "Move the domain off parking if it is intended for customer traffic.",
      "impact": "+10 points"
    }
  ],
  "meta": {
    "query_time_ms": 187,
    "checks_performed": 7,
    "cached": false,
    "served_by": "pop=MAD country=ES"
  }
}
```

#### HTTP status codes

- `200` OK
- `400` Bad Request
- `401` Unauthorized
- `402` Payment Required
- `429` Too Many Requests

POST /v1/reputation/bulk

#### Request body

| Field | Type | Description |
| --- | --- | --- |
| domains required | string[] | Array of full domain names to check |

Use POST /v1/reputation/bulk to score multiple domains in one request. Send a JSON body with a domains array. Supports up to 3 domains per request because each lookup fans out across several security checks.

#### Example request

```bash
curl -H "X-API-Key: your-api-key" -X POST "https://domscan.net/v1/reputation/bulk"   -H "Content-Type: application/json"   -d '{
    "domains": ["stripe.com", "cloudflare.com", "example.com"]
  }'
```

#### Example response

```json
{
  "results": [
    {
      "domain": "stripe.com",
      "reputation_score": 92,
      "grade": "A+",
      "risk_level": "low",
      "factors": {
        "dns_security": { "score": 100, "weight": 0.2 },
        "ssl_certificate": { "score": 100, "weight": 0.2 }
      },
      "recommendations": [],
      "meta": {
        "query_time_ms": 1250,
        "checks_performed": 7,
        "cached": false
      }
    },
    {
      "domain": "not a domain",
      "error": {
        "code": "INVALID_DOMAIN",
        "message": "Invalid domain format"
      }
    }
  ],
  "summary": {
    "total": 2,
    "successful": 1,
    "failed": 1,
    "cached": 0,
    "query_time_ms": 1310
  },
  "meta": {
    "served_by": "pop=MAD country=ES"
  }
}
```

#### Response fields

| Field | Type |
| --- | --- |
| `results[]` | object[] |
| `results[]` | object |
| `results[].domain` | string |
| `results[].reputation_score` | integer |
| `results[].grade` | string |
| `results[].risk_level` | string |
| `results[].reputation_score_confidence` | string |
| `results[].grade_capped_by_parking` | boolean |
| `results[].factors` | object |
| `results[].evidence_summary` | object |
| `results[].evidence_summary.checks_performed` | integer |
| `results[].evidence_summary.cache_status` | string |
| `results[].evidence_summary.confidence` | string |
| `results[].evidence_summary.risk_level` | string |
| `results[].evidence_summary.factor_count` | integer |
| `results[].evidence_summary.scored_factor_count` | integer |
| `results[].evidence_summary.passing_factor_count` | integer |
| `results[].evidence_summary.warning_factor_count` | integer |
| `results[].evidence_summary.failing_factor_count` | integer |
| `results[].evidence_summary.lowest_scoring_factors[]` | object[] |
| `results[].evidence_summary.lowest_scoring_factors[]` | object |
| `results[].evidence_summary.lowest_scoring_factors[].name` | string |
| `results[].evidence_summary.lowest_scoring_factors[].score` | number \| null |
| `results[].evidence_summary.lowest_scoring_factors[].weight` | number \| null |
| `results[].evidence_summary.blacklist_listed_count` | integer |
| `results[].evidence_summary.recommendation_count` | integer |
| `results[].evidence_summary.high_priority_recommendation_count` | integer |
| `results[].evidence_summary.grade_capped_by_parking` | boolean |
| `results[].recommendations[]` | object[] |
| `results[].recommendations[]` | object |
| `results[].meta` | object |
| `results[].error` | object |
| `results[].error.code` | string |
| `results[].error.message` | string |
| `summary` | object |
| `summary.total` | integer |
| `summary.successful` | integer |
| `summary.failed` | integer |
| `summary.cached` | integer |
| `summary.query_time_ms` | integer |
| `meta` | object |
| `meta.served_by` | string |
