Response FormatΒΆ
Standard response format for all API endpoints.
OverviewΒΆ
All API responses follow a consistent structure, making it easy to parse and handle results programmatically.
Response TypesΒΆ
Success ResponsesΒΆ
All successful responses (HTTP 200-299) return JSON with endpoint-specific data and metadata.
Error ResponsesΒΆ
All error responses (HTTP 400-599) return a standardized error structure:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {}
},
"request_id": "req_abc123"
}
See Error Codes for complete error documentation.
Common Response FieldsΒΆ
These fields appear across multiple endpoints:
| Field | Type | Always Present | Description |
|---|---|---|---|
domain |
string | Yes | Domain that was checked |
score |
integer | Yes* | Mailflow Security Score (0-100) |
meta |
object | Yes | Response metadata |
timestamp |
string | In meta |
ISO 8601 timestamp |
*Not present in error responses
Metadata ObjectΒΆ
Every success response includes a meta object with performance and caching information:
{
"meta": {
"version": "1.0.0",
"latency_ms": 450,
"timestamp": "2025-10-21T10:30:00Z",
"cached": false
}
}
Metadata FieldsΒΆ
| Field | Type | Description |
|---|---|---|
version |
string | API version used |
latency_ms |
integer | Request processing time in milliseconds |
timestamp |
string | When response was generated (ISO 8601) |
cached |
boolean | Whether result was served from cache |
Endpoint Response FormatsΒΆ
GET /api/v1/checkΒΆ
Full validation response with detailed results:
{
"domain": "example.com",
"score": 75,
"score_breakdown": {
"current_score": 75,
"max_score": 100,
"total_deductions": 25,
"potential_score_if_fixed": 90,
"issues_by_severity": {
"critical": 0,
"high": 1,
"medium": 2,
"low": 1
},
"total_issues": 4
},
"spf": {
"present": true,
"record": "v=spf1 include:_spf.google.com ~all",
"dns_lookups": 2,
"flattening_needed": false,
"syntax_ok": true,
"qualifier": "~all",
"issues": []
},
"dkim": {
"discovered_selectors": ["google", "default"],
"keys": [
{
"selector": "google",
"present": true,
"key_algo": "rsa",
"key_bits": 2048,
"revoked": false,
"issues": []
}
],
"issues": []
},
"dmarc": {
"present": true,
"record": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com",
"policy": "quarantine",
"subdomain_policy": "none",
"aspf": "r",
"adkim": "r",
"pct": 100,
"rua": ["mailto:dmarc@example.com"],
"ruf": [],
"issues": []
},
"alignment": {
"spf_aligned": "pass",
"dkim_aligned": "pass",
"pass_likelihood": "high"
},
"issues": [
{
"code": "DMARC_POLICY_WEAK",
"category": "dmarc",
"severity": "high",
"points_deducted": 10,
"score_gain_if_fixed": 10,
"title": "DMARC Policy Too Permissive",
"description": "DMARC policy is set to 'quarantine' instead of 'reject'",
"remediation": "Update DMARC policy from 'quarantine' to 'reject' for maximum protection",
"dns_snippet": {
"generic": "_dmarc.example.com. IN TXT \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"",
"route53": null
}
}
],
"top_issues": [
{
"code": "DMARC_POLICY_WEAK",
"category": "dmarc",
"severity": "high",
"points_deducted": 10,
"score_gain_if_fixed": 10,
"title": "DMARC Policy Too Permissive",
"description": "DMARC policy is set to 'quarantine' instead of 'reject'",
"remediation": "Update DMARC policy from 'quarantine' to 'reject' for maximum protection",
"dns_snippet": {
"generic": "_dmarc.example.com. IN TXT \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"",
"route53": null
}
}
],
"meta": {
"version": "1.0.0",
"latency_ms": 450,
"timestamp": "2025-10-21T10:30:00Z",
"cached": false
}
}
GET /api/v1/scoreΒΆ
Lightweight score response:
{
"domain": "example.com",
"score": 75,
"score_breakdown": {
"current_score": 75,
"max_score": 100,
"total_deductions": 25,
"potential_score_if_fixed": 90,
"issues_by_severity": {
"critical": 0,
"high": 1,
"medium": 2,
"low": 1
},
"total_issues": 4
},
"top_issues": [
{
"code": "DMARC_POLICY_WEAK",
"category": "dmarc",
"severity": "high",
"points_deducted": 10,
"score_gain_if_fixed": 10,
"title": "DMARC Policy Too Permissive",
"description": "DMARC policy is set to 'quarantine' instead of 'reject'",
"remediation": "Update DMARC policy from 'quarantine' to 'reject' for maximum protection",
"dns_snippet": {
"generic": "_dmarc.example.com. IN TXT \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"",
"route53": null
}
}
],
"meta": {
"version": "1.0.0",
"latency_ms": 180,
"timestamp": "2025-10-21T10:30:00Z",
"cached": true
}
}
POST /api/v1/recommendationsΒΆ
Recommendations response:
{
"domain": "example.com",
"current_score": 75,
"potential_score": 90,
"recommendations": [
{
"priority": 1,
"issue_code": "DMARC_POLICY_WEAK",
"category": "dmarc",
"severity": "high",
"score_gain": 10,
"action": "Update DMARC policy from 'quarantine' to 'reject' for maximum protection",
"dns_snippet": {
"generic": "_dmarc.example.com. IN TXT \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"",
"route53": null
},
"verification": "Run /api/v1/check?domain=example.com to verify the fix"
},
{
"priority": 2,
"issue_code": "SPF_SOFTFAIL",
"category": "spf",
"severity": "medium",
"score_gain": 8,
"action": "Change SPF qualifier from '~all' (softfail) to '-all' (hardfail)",
"dns_snippet": {
"generic": "example.com. IN TXT \"v=spf1 include:_spf.google.com -all\"",
"route53": null
},
"verification": "Run /api/v1/check?domain=example.com to verify the fix"
}
],
"meta": {
"version": "1.0.0",
"latency_ms": 520,
"timestamp": "2025-10-21T10:30:00Z",
"cached": false
}
}
GET /api/v1/historyΒΆ
Historical snapshots response:
{
"domain": "example.com",
"snapshots": [
{
"timestamp": "2025-10-21T10:30:00Z",
"score": 75,
"spf_present": true,
"dkim_present": true,
"dmarc_present": true,
"dmarc_policy": "quarantine",
"critical_issues": 0,
"high_issues": 1
},
{
"timestamp": "2025-10-20T10:30:00Z",
"score": 65,
"spf_present": true,
"dkim_present": false,
"dmarc_present": true,
"dmarc_policy": "none",
"critical_issues": 1,
"high_issues": 2
}
],
"total_snapshots": 45,
"date_range": {
"first": "2025-09-15T10:30:00Z",
"last": "2025-10-21T10:30:00Z"
},
"meta": {
"version": "1.0.0",
"latency_ms": 120,
"timestamp": "2025-10-21T10:30:00Z",
"cached": false
}
}
Nested Object SchemasΒΆ
Score Breakdown ObjectΒΆ
{
"current_score": 75,
"max_score": 100,
"total_deductions": 25,
"potential_score_if_fixed": 90,
"issues_by_severity": {
"critical": 0,
"high": 1,
"medium": 2,
"low": 1,
"info": 0
},
"total_issues": 4
}
Fields:
| Field | Type | Description |
|---|---|---|
current_score |
integer | Current Mailflow Security Score (0-100) |
max_score |
integer | Maximum possible score (always 100) |
total_deductions |
integer | Total points deducted from max score |
potential_score_if_fixed |
integer | Score if all issues are resolved |
issues_by_severity |
object | Count of issues by severity level |
total_issues |
integer | Total number of issues found |
SPF Result ObjectΒΆ
{
"present": true,
"record": "v=spf1 include:_spf.google.com ~all",
"dns_lookups": 2,
"flattening_needed": false,
"syntax_ok": true,
"qualifier": "~all",
"issues": []
}
Fields:
| Field | Type | Description |
|---|---|---|
present |
boolean | Whether SPF record exists |
record |
string | Raw SPF record (null if not present) |
dns_lookups |
integer | Number of DNS lookups required (max 10) |
flattening_needed |
boolean | Whether SPF flattening is recommended |
syntax_ok |
boolean | Whether SPF syntax is valid |
qualifier |
string | Final SPF qualifier (+all, -all, ~all, ?all) |
issues |
array | List of SPF-specific issues |
DKIM Result ObjectΒΆ
{
"discovered_selectors": ["google", "default"],
"keys": [
{
"selector": "google",
"present": true,
"key_algo": "rsa",
"key_bits": 2048,
"revoked": false,
"issues": []
}
],
"issues": []
}
Fields:
| Field | Type | Description |
|---|---|---|
discovered_selectors |
array | DKIM selectors found via BIMI/discovery |
keys |
array | Validation results for each DKIM key |
issues |
array | General DKIM issues |
DKIM Key Fields:
| Field | Type | Description |
|---|---|---|
selector |
string | DKIM selector name |
present |
boolean | Whether DKIM key exists |
key_algo |
string | Key algorithm (rsa/ed25519) |
key_bits |
integer | Key length in bits |
revoked |
boolean | Whether key is revoked |
issues |
array | Issues specific to this key |
DMARC Result ObjectΒΆ
{
"present": true,
"record": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com",
"policy": "quarantine",
"subdomain_policy": "none",
"aspf": "r",
"adkim": "r",
"pct": 100,
"rua": ["mailto:dmarc@example.com"],
"ruf": [],
"issues": []
}
Fields:
| Field | Type | Description |
|---|---|---|
present |
boolean | Whether DMARC record exists |
record |
string | Raw DMARC record (null if not present) |
policy |
string | DMARC policy: none, quarantine, or reject |
subdomain_policy |
string | Subdomain policy (sp tag) |
aspf |
string | SPF alignment mode: r (relaxed) or s (strict) |
adkim |
string | DKIM alignment mode: r (relaxed) or s (strict) |
pct |
integer | Percentage of messages to filter (0-100) |
rua |
array | Aggregate report URIs |
ruf |
array | Forensic report URIs |
issues |
array | DMARC-specific issues |
Security Issue ObjectΒΆ
{
"code": "DMARC_POLICY_WEAK",
"category": "dmarc",
"severity": "high",
"points_deducted": 10,
"score_gain_if_fixed": 10,
"title": "DMARC Policy Too Permissive",
"description": "DMARC policy is set to 'quarantine' instead of 'reject'",
"remediation": "Update DMARC policy from 'quarantine' to 'reject' for maximum protection",
"dns_snippet": {
"generic": "_dmarc.example.com. IN TXT \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"",
"route53": null
}
}
Fields:
| Field | Type | Description |
|---|---|---|
code |
string | Unique issue code (e.g., DMARC_POLICY_WEAK) |
category |
string | Issue category: spf, dkim, dmarc, or dns |
severity |
string | Severity: critical, high, medium, low, or info |
points_deducted |
integer | Points deducted from score |
score_gain_if_fixed |
integer | Points gained if issue is resolved |
title |
string | Short issue title |
description |
string | Detailed issue description |
remediation |
string | Step-by-step fix instructions |
dns_snippet |
object | DNS configuration to fix the issue |
DNS Snippet ObjectΒΆ
{
"generic": "_dmarc.example.com. IN TXT \"v=DMARC1; p=reject; rua=mailto:dmarc@example.com\"",
"route53": null
}
Fields:
| Field | Type | Description |
|---|---|---|
generic |
string | BIND-style DNS record (universal format) |
route53 |
string | AWS Route53 JSON snippet (when applicable) |
Alignment Result ObjectΒΆ
Fields:
| Field | Type | Description |
|---|---|---|
spf_aligned |
string | SPF alignment status: pass, fail, or unknown |
dkim_aligned |
string | DKIM alignment status: pass, fail, or unknown |
pass_likelihood |
string | DMARC pass likelihood: high, medium, or low |
PaginationΒΆ
For endpoints that return lists (like /api/v1/history), pagination is handled via query parameters:
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 30 | Number of items to return (max varies by endpoint) |
offset |
integer | 0 | Number of items to skip |
Response includes:
CachingΒΆ
Responses include caching information in the meta object:
Cache Behavior:
- Results are cached for 15 minutes by default
- Use
?refresh=trueto bypass cache - Check
meta.cachedto see if result was served from cache - Cached results are still accurate but may not reflect very recent DNS changes
Cache Headers:
Cache-Control: public, max-age=900
ETag: "abc123def456"
Last-Modified: Mon, 21 Oct 2025 10:30:00 GMT
Response TimesΒΆ
Expected latency by endpoint:
| Endpoint | Cached | Uncached | Notes |
|---|---|---|---|
/api/v1/check |
100-200ms | 400-700ms | Full validation with DNS queries |
/api/v1/score |
50-100ms | 150-300ms | Lightweight, faster than /check |
/api/v1/recommendations |
150-250ms | 500-800ms | Includes validation + recommendation logic |
/api/v1/history |
50-150ms | N/A | Database query, no DNS lookups |
Parsing ExamplesΒΆ
PythonΒΆ
import requests
response = requests.get(
"https://api.reputeapi.com/api/v1/check",
params={"domain": "example.com"},
headers={"X-API-Key": "your-api-key"}
)
if response.status_code == 200:
data = response.json()
# Access common fields
domain = data['domain']
score = data['score']
cached = data['meta']['cached']
latency = data['meta']['latency_ms']
# Access nested data
spf_present = data['spf']['present']
dmarc_policy = data['dmarc']['policy']
# Iterate issues
for issue in data['issues']:
print(f"[{issue['severity']}] {issue['title']}")
print(f" Fix: {issue['remediation']}")
if issue['dns_snippet']:
print(f" DNS: {issue['dns_snippet']['generic']}")
else:
error = response.json()
print(f"Error: {error['error']['code']}")
print(f"Message: {error['error']['message']}")
JavaScriptΒΆ
const response = await fetch(
'https://api.reputeapi.com/api/v1/check?domain=example.com',
{
headers: { 'X-API-Key': 'your-api-key' }
}
);
if (response.ok) {
const data = await response.json();
// Access common fields
const { domain, score, meta } = data;
console.log(`${domain}: ${score}/100`);
console.log(`Cached: ${meta.cached}, Latency: ${meta.latency_ms}ms`);
// Access nested data
const { spf, dkim, dmarc } = data;
console.log(`SPF: ${spf.present ? 'Present' : 'Missing'}`);
console.log(`DMARC Policy: ${dmarc.policy || 'None'}`);
// Iterate issues
data.issues.forEach(issue => {
console.log(`[${issue.severity}] ${issue.title}`);
});
} else {
const error = await response.json();
console.error(`Error ${error.error.code}: ${error.error.message}`);
}
Best PracticesΒΆ
1. Always Check HTTP StatusΒΆ
if response.status_code == 200:
# Success path
data = response.json()
else:
# Error path
error = response.json()
2. Use Type Hints (Python)ΒΆ
from typing import Dict, Any
def process_check_response(data: Dict[str, Any]) -> None:
domain: str = data['domain']
score: int = data['score']
meta: Dict[str, Any] = data['meta']
3. Handle Optional FieldsΒΆ
# Some fields may be null
dmarc_policy = data['dmarc'].get('policy', 'none')
dns_snippet = issue.get('dns_snippet', {}).get('generic')
if dns_snippet:
print(f"Apply this DNS record: {dns_snippet}")
4. Leverage MetadataΒΆ
# Check if result is cached
if data['meta']['cached']:
print("Result served from cache")
# Monitor performance
latency = data['meta']['latency_ms']
if latency > 1000:
print(f"Slow response: {latency}ms")
Related DocumentationΒΆ
- Error Codes - Complete error reference
- GET /api/v1/check - Full validation endpoint
- GET /api/v1/score - Quick score endpoint
- POST /api/v1/recommendations - Recommendations endpoint
- GET /api/v1/history - Historical data endpoint