Troubleshooting GuideΒΆ
Common issues and their solutions when integrating with ReputeAPI.
Authentication IssuesΒΆ
401 Unauthorized - Invalid API KeyΒΆ
Symptoms:
Common Causes:
- Missing API key header
- Incorrect header name
- API key has wrong prefix/format
- API key has been revoked
Solutions:
Python:
# β Wrong - Missing header
response = requests.get(f"{BASE_URL}/api/v1/check?domain=example.com")
# β Wrong - Incorrect header name
response = requests.get(
f"{BASE_URL}/api/v1/check?domain=example.com",
headers={"Authorization": f"Bearer {API_KEY}"}
)
# β
Correct
response = requests.get(
f"{BASE_URL}/api/v1/check?domain=example.com",
headers={"X-API-Key": API_KEY}
)
JavaScript:
// β Wrong
fetch(url) // No headers
// β
Correct
fetch(url, {
headers: {
'X-API-Key': API_KEY
}
})
cURL:
# β Wrong
curl "https://api.reputeapi.com/api/v1/check?domain=example.com"
# β
Correct
curl "https://api.reputeapi.com/api/v1/check?domain=example.com" \
-H "X-API-Key: your-api-key"
Verification:
# Test your API key
import requests
API_KEY = "your-api-key-here"
BASE_URL = "https://api.reputeapi.com"
response = requests.get(
f"{BASE_URL}/api/v1/usage",
headers={"X-API-Key": API_KEY}
)
if response.status_code == 200:
print("β
API key is valid")
print(f"Your plan: {response.json()['plan']}")
else:
print(f"β API key error: {response.status_code}")
print(response.json())
Rate Limiting IssuesΒΆ
429 Too Many RequestsΒΆ
Symptoms:
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Please try again later.",
"retry_after": 60,
"status": 429
}
Rate Limits by Tier:
| Tier | Per Minute | Per Day |
|---|---|---|
| Free | 10 | 1,000 |
| Basic | 60 | 10,000 |
| Premium | 120 | 50,000 |
Solutions:
1. Add Delay Between RequestsΒΆ
import time
domains = ["example1.com", "example2.com", "example3.com"]
for domain in domains:
result = check_domain(domain)
print(f"{domain}: {result['score']}/100")
# Add 1 second delay to respect rate limits
time.sleep(1)
2. Implement Retry Logic with Exponential BackoffΒΆ
import time
import requests
def check_domain_with_retry(domain: str, max_retries: int = 3):
"""Check domain with automatic retry on rate limit"""
retries = 0
delay = 1
while retries < max_retries:
try:
response = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": domain},
headers={"X-API-Key": API_KEY},
timeout=10
)
if response.status_code == 429:
# Rate limited
retry_after = int(response.headers.get('Retry-After', delay))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
retries += 1
delay *= 2 # Exponential backoff
continue
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code != 429:
raise
retries += 1
raise Exception(f"Max retries ({max_retries}) exceeded")
# Usage
result = check_domain_with_retry("example.com")
3. Use Bulk Endpoint for Multiple DomainsΒΆ
# β Bad - Multiple individual requests
for domain in domains:
check_domain(domain) # Will hit rate limit
# β
Good - Single bulk request
bulk_validate(domains) # Validates all at once
4. Implement Request QueueΒΆ
import queue
import threading
import time
class RateLimitedQueue:
"""Queue with rate limiting"""
def __init__(self, requests_per_minute: int = 10):
self.queue = queue.Queue()
self.requests_per_minute = requests_per_minute
self.delay = 60.0 / requests_per_minute
def add_domain(self, domain: str):
"""Add domain to queue"""
self.queue.put(domain)
def process_queue(self):
"""Process queue with rate limiting"""
while not self.queue.empty():
domain = self.queue.get()
try:
result = check_domain(domain)
print(f"{domain}: {result['score']}/100")
except Exception as e:
print(f"Error for {domain}: {e}")
# Rate limiting delay
time.sleep(self.delay)
# Usage
rate_queue = RateLimitedQueue(requests_per_minute=10)
for domain in large_domain_list:
rate_queue.add_domain(domain)
rate_queue.process_queue()
Request IssuesΒΆ
400 Bad Request - Invalid DomainΒΆ
Symptoms:
Common Causes:
# β Wrong - Including protocol
check_domain("https://example.com")
# β Wrong - Including path
check_domain("example.com/page")
# β Wrong - Including port
check_domain("example.com:443")
# β Wrong - Email address
check_domain("user@example.com")
# β
Correct - Domain only
check_domain("example.com")
Solution - Domain Validation:
import re
from urllib.parse import urlparse
def validate_domain(input_string: str) -> str:
"""
Validate and clean domain input
Args:
input_string: User input (might include protocol, path, etc.)
Returns:
Clean domain name
Raises:
ValueError: If domain is invalid
"""
# Remove whitespace
domain = input_string.strip()
# Remove protocol if present
if '://' in domain:
domain = urlparse(domain).netloc
# Remove path if present
domain = domain.split('/')[0]
# Remove port if present
domain = domain.split(':')[0]
# Extract domain from email if needed
if '@' in domain:
domain = domain.split('@')[1]
# Validate domain format
domain_pattern = r'^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'
if not re.match(domain_pattern, domain):
raise ValueError(f"Invalid domain format: {domain}")
return domain.lower()
# Usage
try:
domain = validate_domain("https://example.com/path")
print(f"Clean domain: {domain}") # Output: example.com
result = check_domain(domain)
except ValueError as e:
print(f"Validation error: {e}")
Request TimeoutΒΆ
Symptoms:
requests.exceptions.Timeout: HTTPConnectionPool(host='api.reputeapi.com', port=443): Read timed out.
Solutions:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_session_with_retries(timeout: int = 10):
"""Create session with timeouts and retries"""
session = requests.Session()
# Configure retry strategy
retry_strategy = Retry(
total=3,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["GET", "POST"],
backoff_factor=1 # Wait 1, 2, 4 seconds between retries
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
# Usage
session = create_session_with_retries(timeout=15)
session.headers.update({"X-API-Key": API_KEY})
try:
response = session.get(
f"{BASE_URL}/api/v1/check",
params={"domain": "example.com"},
timeout=15 # 15 second timeout
)
result = response.json()
except requests.exceptions.Timeout:
print("Request timed out after 15 seconds")
except Exception as e:
print(f"Error: {e}")
Response IssuesΒΆ
Unexpected Response FormatΒΆ
Symptoms:
Cause: Assuming response structure without validation
Solution - Safe Response Parsing:
def safe_get_score(domain: str) -> dict:
"""
Safely get domain score with validation
Returns:
Dict with score and status, never raises exceptions
"""
try:
response = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": domain},
headers={"X-API-Key": API_KEY},
timeout=10
)
# Check HTTP status
if not response.ok:
return {
"domain": domain,
"status": "error",
"error": f"HTTP {response.status_code}",
"score": None
}
# Parse JSON
try:
result = response.json()
except ValueError:
return {
"domain": domain,
"status": "error",
"error": "Invalid JSON response",
"score": None
}
# Validate response structure
if not isinstance(result, dict):
return {
"domain": domain,
"status": "error",
"error": "Unexpected response format",
"score": None
}
# Extract score safely
score = result.get('score')
if score is None:
return {
"domain": domain,
"status": "error",
"error": "Score not in response",
"score": None
}
return {
"domain": domain,
"status": "success",
"score": score,
"grade": result.get('grade', 'Unknown'),
"data": result
}
except requests.exceptions.RequestException as e:
return {
"domain": domain,
"status": "error",
"error": str(e),
"score": None
}
# Usage
result = safe_get_score("example.com")
if result["status"] == "success":
print(f"Score: {result['score']}/100")
else:
print(f"Error: {result['error']}")
DNS Resolution IssuesΒΆ
Domain Not FoundΒΆ
Symptoms:
{
"error": "Domain not found",
"message": "Unable to resolve DNS records for domain",
"code": "DNS_RESOLUTION_FAILED"
}
Possible Causes:
- Domain doesn't exist
- DNS servers are unreachable
- Domain recently registered (DNS not propagated)
- Typo in domain name
Solutions:
import socket
import dns.resolver
def verify_domain_exists(domain: str) -> tuple[bool, str]:
"""
Verify domain exists before API call
Returns:
Tuple of (exists, message)
"""
try:
# Try to resolve A record
answers = dns.resolver.resolve(domain, 'A')
return True, f"Domain exists with {len(answers)} A records"
except dns.resolver.NXDOMAIN:
return False, "Domain does not exist"
except dns.resolver.NoAnswer:
return False, "Domain exists but has no A records"
except dns.resolver.Timeout:
return False, "DNS query timed out"
except Exception as e:
return False, f"DNS error: {str(e)}"
# Usage
domain = "example.com"
exists, message = verify_domain_exists(domain)
if exists:
print(f"β
{message}")
result = check_domain(domain)
else:
print(f"β {message}")
print("Cannot validate domain that doesn't exist")
Connection IssuesΒΆ
SSL Certificate Verification FailedΒΆ
Symptoms:
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.reputeapi.com', port=443): Max retries exceeded with url: ...
Causes: - Outdated SSL certificates on your system - Corporate firewall/proxy interfering - System clock incorrect
Solutions:
1. Update CA CertificatesΒΆ
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install ca-certificates
# macOS
brew install ca-certificates
# Python - Update certifi
pip install --upgrade certifi
2. Use System CertificatesΒΆ
import requests
import certifi
response = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": "example.com"},
headers={"X-API-Key": API_KEY},
verify=certifi.where() # Use certifi's CA bundle
)
3. For Corporate ProxiesΒΆ
import requests
proxies = {
'http': 'http://proxy.company.com:8080',
'https': 'http://proxy.company.com:8080',
}
response = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": "example.com"},
headers={"X-API-Key": API_KEY},
proxies=proxies,
verify='/path/to/corporate-ca-bundle.crt'
)
Performance IssuesΒΆ
Slow Response TimesΒΆ
Symptoms: Requests taking 10+ seconds
Solutions:
1. Use Score Endpoint for Quick ChecksΒΆ
# β Slow - Full check with all details
response = requests.get(f"{BASE_URL}/api/v1/check?domain=example.com")
# Takes ~2-5 seconds
# β
Fast - Score only
response = requests.get(f"{BASE_URL}/api/v1/score?domain=example.com")
# Takes ~0.5-1 second
2. Enable CachingΒΆ
from functools import lru_cache
import time
@lru_cache(maxsize=128)
def check_domain_cached(domain: str) -> dict:
"""Check domain with local caching"""
response = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": domain},
headers={"X-API-Key": API_KEY}
)
return response.json()
# First call - hits API
start = time.time()
result1 = check_domain_cached("example.com")
print(f"First call: {time.time() - start:.2f}s")
# Second call - from cache
start = time.time()
result2 = check_domain_cached("example.com")
print(f"Second call: {time.time() - start:.2f}s")
3. Use Async for Multiple DomainsΒΆ
import asyncio
import httpx
async def check_domains_async(domains: list) -> list:
"""Check multiple domains concurrently"""
async with httpx.AsyncClient() as client:
tasks = [
client.get(
f"{BASE_URL}/api/v1/check",
params={"domain": domain},
headers={"X-API-Key": API_KEY}
)
for domain in domains
]
responses = await asyncio.gather(*tasks)
return [r.json() for r in responses]
# Usage
domains = ["example1.com", "example2.com", "example3.com"]
results = asyncio.run(check_domains_async(domains))
# Much faster than sequential calls
Data IssuesΒΆ
Missing DKIM SelectorsΒΆ
Symptoms: DKIM validation fails even though DKIM is configured
Solution: Provide DKIM selectors explicitly
# β Without selectors - may miss DKIM keys
result = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": "example.com"},
headers={"X-API-Key": API_KEY}
).json()
# β
With selectors - finds DKIM keys
result = requests.get(
f"{BASE_URL}/api/v1/check",
params={
"domain": "example.com",
"selectors": "default,google,k1,selector1"
},
headers={"X-API-Key": API_KEY}
).json()
Finding DKIM Selectors:
import dns.resolver
def find_common_selectors(domain: str) -> list:
"""Try common DKIM selectors"""
common_selectors = [
"default", "google", "k1", "k2", "k3",
"selector1", "selector2", "dkim", "mail",
"smtp", "email", "s1", "s2"
]
found = []
for selector in common_selectors:
try:
record_name = f"{selector}._domainkey.{domain}"
answers = dns.resolver.resolve(record_name, 'TXT')
if answers:
found.append(selector)
print(f"β Found: {selector}")
except:
pass
return found
# Usage
selectors = find_common_selectors("example.com")
if selectors:
print(f"\nFound selectors: {', '.join(selectors)}")
else:
print("No common selectors found")
Debugging ChecklistΒΆ
When troubleshooting issues, check:
1. API KeyΒΆ
# Verify API key
print(f"API Key: {API_KEY[:10]}...") # Don't print full key
print(f"Key length: {len(API_KEY)}")
print(f"Key starts with: {API_KEY[:3]}")
2. Network ConnectivityΒΆ
import requests
try:
response = requests.get("https://api.reputeapi.com/health", timeout=5)
print(f"β
API is reachable: {response.status_code}")
except Exception as e:
print(f"β Cannot reach API: {e}")
3. Request DetailsΒΆ
import requests
# Enable debug logging
import logging
import http.client as http_client
http_client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
# Make request
response = requests.get(
f"{BASE_URL}/api/v1/check",
params={"domain": "example.com"},
headers={"X-API-Key": API_KEY}
)
4. Response InspectionΒΆ
response = requests.get(url, headers=headers)
print(f"Status Code: {response.status_code}")
print(f"Headers: {dict(response.headers)}")
print(f"Response Time: {response.elapsed.total_seconds()}s")
print(f"Response Body: {response.text[:500]}") # First 500 chars
Getting HelpΒΆ
Still stuck? Here's how to get help:
1. Check DocumentationΒΆ
2. Search FAQΒΆ
3. Contact SupportΒΆ
When contacting support, include:
import sys
import requests
# Diagnostic information
print("=== Diagnostic Information ===")
print(f"Python version: {sys.version}")
print(f"requests version: {requests.__version__}")
print(f"Operating System: {sys.platform}")
print(f"API endpoint: {BASE_URL}")
print(f"Domain being checked: example.com")
print(f"Error message: [paste error here]")
print(f"Full traceback: [paste traceback here]")
Send to: support@reputeapi.com