JavaScript Integration GuideΒΆ
Complete guide to integrating ReputeAPI with JavaScript and Node.js applications.
InstallationΒΆ
ReputeAPI works with any HTTP client. Here are the most popular options:
fetch (Built-in):
axios:
node-fetch:
Quick StartΒΆ
Browser (Fetch API)ΒΆ
const API_KEY = 'your-api-key-here';
const BASE_URL = 'https://api.reputeapi.com';
async function checkDomain(domain) {
const response = await fetch(
`${BASE_URL}/api/v1/check?domain=${domain}`,
{
headers: {
'X-API-Key': API_KEY
}
}
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const result = await response.json();
return result;
}
// Usage
checkDomain('example.com')
.then(result => {
console.log(`Score: ${result.score}/100`);
console.log(`Grade: ${result.grade}`);
})
.catch(error => {
console.error('Error:', error);
});
Node.js (Axios)ΒΆ
const axios = require('axios');
const API_KEY = process.env.REPUTE_API_KEY;
const BASE_URL = 'https://api.reputeapi.com';
async function checkDomain(domain) {
try {
const response = await axios.get(`${BASE_URL}/api/v1/check`, {
params: { domain },
headers: { 'X-API-Key': API_KEY }
});
return response.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
throw error;
}
}
// Usage
checkDomain('example.com')
.then(result => {
console.log(`Score: ${result.score}/100`);
});
Environment VariablesΒΆ
Create a .env file:
Load it using dotenv:
require('dotenv').config();
const API_KEY = process.env.REPUTE_API_KEY;
const BASE_URL = process.env.REPUTE_API_URL || 'https://api.reputeapi.com';
Client ClassΒΆ
Create a reusable client for your application:
class ReputeAPIClient {
constructor(apiKey, baseUrl = 'https://api.reputeapi.com') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
/**
* Run complete mailflow security check
* @param {string} domain - Domain to check
* @param {Object} options - Optional parameters
* @returns {Promise<Object>} Validation results
*/
async checkDomain(domain, options = {}) {
const params = new URLSearchParams({
domain,
...options
});
if (options.selectors && Array.isArray(options.selectors)) {
params.set('selectors', options.selectors.join(','));
}
const response = await fetch(
`${this.baseUrl}/api/v1/check?${params}`,
{
headers: { 'X-API-Key': this.apiKey }
}
);
if (!response.ok) {
throw await this._handleError(response);
}
return response.json();
}
/**
* Get quick score check (faster)
* @param {string} domain - Domain to check
* @param {boolean} refresh - Bypass cache
* @returns {Promise<Object>} Score and top issues
*/
async getScore(domain, refresh = false) {
const params = new URLSearchParams({ domain, refresh });
const response = await fetch(
`${this.baseUrl}/api/v1/score?${params}`,
{
headers: { 'X-API-Key': this.apiKey }
}
);
if (!response.ok) {
throw await this._handleError(response);
}
return response.json();
}
/**
* Get prioritized recommendations
* @param {string} domain - Domain to get recommendations for
* @param {string} severity - Filter by severity
* @returns {Promise<Object>} Recommendations
*/
async getRecommendations(domain, severity = null) {
const body = { domain };
if (severity) body.severity = severity;
const response = await fetch(
`${this.baseUrl}/api/v1/recommendations`,
{
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
if (!response.ok) {
throw await this._handleError(response);
}
return response.json();
}
/**
* Get historical validation data
* @param {string} domain - Domain to get history for
* @param {Object} options - Date range options
* @returns {Promise<Object>} Historical snapshots
*/
async getHistory(domain, options = {}) {
const params = new URLSearchParams({ domain });
if (options.days) {
params.set('days', options.days);
} else if (options.startDate && options.endDate) {
params.set('start_date', options.startDate.toISOString());
params.set('end_date', options.endDate.toISOString());
} else {
params.set('days', 30);
}
const response = await fetch(
`${this.baseUrl}/api/v1/history?${params}`,
{
headers: { 'X-API-Key': this.apiKey }
}
);
if (!response.ok) {
throw await this._handleError(response);
}
return response.json();
}
/**
* Get API usage statistics
* @returns {Promise<Object>} Usage stats
*/
async getUsage() {
const response = await fetch(
`${this.baseUrl}/api/v1/usage`,
{
headers: { 'X-API-Key': this.apiKey }
}
);
if (!response.ok) {
throw await this._handleError(response);
}
return response.json();
}
/**
* Validate multiple domains (legacy endpoint)
* @param {string[]} domains - List of domains
* @returns {Promise<Object>} Results for all domains
*/
async bulkValidate(domains) {
const response = await fetch(
`${this.baseUrl}/v1/bulk-validate`,
{
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({ domains })
}
);
if (!response.ok) {
throw await this._handleError(response);
}
return response.json();
}
/**
* Handle API errors
* @private
*/
async _handleError(response) {
let errorData;
try {
errorData = await response.json();
} catch {
errorData = { message: response.statusText };
}
const error = new Error(errorData.message || 'API request failed');
error.status = response.status;
error.data = errorData;
return error;
}
}
// Export for Node.js
if (typeof module !== 'undefined' && module.exports) {
module.exports = ReputeAPIClient;
}
// Usage
const client = new ReputeAPIClient(API_KEY);
client.checkDomain('example.com')
.then(result => {
console.log(`Score: ${result.score}/100`);
})
.catch(error => {
console.error('Error:', error.message);
});
Error HandlingΒΆ
Comprehensive Error HandlingΒΆ
class ReputeAPIError extends Error {
constructor(message, status, data) {
super(message);
this.name = 'ReputeAPIError';
this.status = status;
this.data = data;
}
}
class AuthenticationError extends ReputeAPIError {
constructor(message, data) {
super(message, 401, data);
this.name = 'AuthenticationError';
}
}
class RateLimitError extends ReputeAPIError {
constructor(message, retryAfter, data) {
super(message, 429, data);
this.name = 'RateLimitError';
this.retryAfter = retryAfter;
}
}
class ValidationError extends ReputeAPIError {
constructor(message, data) {
super(message, 400, data);
this.name = 'ValidationError';
}
}
async function checkDomainSafe(domain) {
try {
const response = await fetch(
`${BASE_URL}/api/v1/check?domain=${domain}`,
{
headers: { 'X-API-Key': API_KEY },
signal: AbortSignal.timeout(10000) // 10 second timeout
}
);
// Handle specific error codes
if (response.status === 401) {
throw new AuthenticationError('Invalid or missing API key');
}
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
throw new RateLimitError(
'Rate limit exceeded',
parseInt(retryAfter)
);
}
if (response.status === 400) {
const errorData = await response.json();
throw new ValidationError(errorData.message);
}
if (response.status >= 500) {
throw new ReputeAPIError(
`Server error: ${response.status}`,
response.status
);
}
if (!response.ok) {
throw new ReputeAPIError(
`Request failed: ${response.status}`,
response.status
);
}
return await response.json();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication error:', error.message);
console.error('Please check your API key');
} else if (error instanceof RateLimitError) {
console.error(`Rate limit exceeded. Retry after ${error.retryAfter} seconds`);
} else if (error instanceof ValidationError) {
console.error('Validation error:', error.message);
} else if (error.name === 'AbortError') {
console.error('Request timed out');
} else if (error.name === 'TypeError') {
console.error('Network error:', error.message);
} else {
console.error('Error:', error.message);
}
return null;
}
}
// Usage
const result = await checkDomainSafe('example.com');
if (result) {
console.log(`Score: ${result.score}/100`);
}
Retry Logic with Exponential BackoffΒΆ
/**
* Retry function with exponential backoff
* @param {Function} fn - Async function to retry
* @param {Object} options - Retry options
* @returns {Promise} Result of function
*/
async function retryWithBackoff(
fn,
options = {}
) {
const {
maxRetries = 3,
baseDelay = 1000,
maxDelay = 60000
} = options;
let retries = 0;
let delay = baseDelay;
while (retries < maxRetries) {
try {
return await fn();
} catch (error) {
retries++;
// Don't retry on authentication or validation errors
if (error instanceof AuthenticationError ||
error instanceof ValidationError) {
throw error;
}
// Handle rate limit with server-provided delay
if (error instanceof RateLimitError) {
delay = error.retryAfter * 1000;
}
if (retries >= maxRetries) {
throw new Error(`Max retries (${maxRetries}) exceeded: ${error.message}`);
}
console.log(`Retry ${retries}/${maxRetries} after ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
// Exponential backoff
delay = Math.min(delay * 2, maxDelay);
}
}
}
// Usage
const result = await retryWithBackoff(
() => checkDomainSafe('example.com'),
{ maxRetries: 3, baseDelay: 2000 }
);
Axios-based ClientΒΆ
Alternative implementation using Axios:
const axios = require('axios');
class AxiosReputeAPIClient {
constructor(apiKey, baseUrl = 'https://api.reputeapi.com') {
this.client = axios.create({
baseURL: baseUrl,
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json'
},
timeout: 10000
});
// Add response interceptor for error handling
this.client.interceptors.response.use(
response => response,
error => this._handleError(error)
);
}
async checkDomain(domain, options = {}) {
const response = await this.client.get('/api/v1/check', {
params: {
domain,
...options,
selectors: options.selectors?.join(',')
}
});
return response.data;
}
async getScore(domain, refresh = false) {
const response = await this.client.get('/api/v1/score', {
params: { domain, refresh }
});
return response.data;
}
async getRecommendations(domain, severity = null) {
const response = await this.client.post('/api/v1/recommendations', {
domain,
...(severity && { severity })
});
return response.data;
}
async getHistory(domain, options = {}) {
const params = { domain };
if (options.days) {
params.days = options.days;
} else if (options.startDate && options.endDate) {
params.start_date = options.startDate.toISOString();
params.end_date = options.endDate.toISOString();
} else {
params.days = 30;
}
const response = await this.client.get('/api/v1/history', { params });
return response.data;
}
async getUsage() {
const response = await this.client.get('/api/v1/usage');
return response.data;
}
async bulkValidate(domains) {
const response = await this.client.post('/v1/bulk-validate', {
domains
});
return response.data;
}
_handleError(error) {
if (error.response) {
// Server responded with error status
const { status, data } = error.response;
if (status === 401) {
throw new AuthenticationError(
data.message || 'Invalid API key',
data
);
}
if (status === 429) {
const retryAfter = error.response.headers['retry-after'] || 60;
throw new RateLimitError(
data.message || 'Rate limit exceeded',
parseInt(retryAfter),
data
);
}
if (status === 400) {
throw new ValidationError(
data.message || 'Invalid request',
data
);
}
throw new ReputeAPIError(
data.message || 'API request failed',
status,
data
);
} else if (error.request) {
// Request made but no response
throw new Error('No response from server');
} else {
// Error in request setup
throw error;
}
}
}
module.exports = AxiosReputeAPIClient;
Common Use CasesΒΆ
1. React Component IntegrationΒΆ
import React, { useState, useEffect } from 'react';
function DomainSecurityScore({ domain }) {
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const checkDomain = async () => {
setLoading(true);
setError(null);
try {
const client = new ReputeAPIClient(process.env.REACT_APP_API_KEY);
const data = await client.getScore(domain);
setResult(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
if (domain) {
checkDomain();
}
}, [domain]);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!result) return null;
return (
<div className="domain-score">
<h2>{domain}</h2>
<div className="score">
<span className="score-value">{result.score}</span>
<span className="score-max">/100</span>
</div>
<div className={`grade grade-${result.grade.toLowerCase()}`}>
{result.grade}
</div>
{result.top_issues && result.top_issues.length > 0 && (
<div className="issues">
<h3>Top Issues:</h3>
<ul>
{result.top_issues.map((issue, index) => (
<li key={index} className={`severity-${issue.severity}`}>
{issue.message}
</li>
))}
</ul>
</div>
)}
</div>
);
}
export default DomainSecurityScore;
2. Express.js API ServerΒΆ
const express = require('express');
const ReputeAPIClient = require('./ReputeAPIClient');
const app = express();
const client = new ReputeAPIClient(process.env.REPUTE_API_KEY);
app.use(express.json());
// Check domain endpoint
app.get('/api/check/:domain', async (req, res) => {
try {
const { domain } = req.params;
const result = await client.checkDomain(domain);
res.json(result);
} catch (error) {
res.status(error.status || 500).json({
error: error.message
});
}
});
// Get score endpoint
app.get('/api/score/:domain', async (req, res) => {
try {
const { domain } = req.params;
const result = await client.getScore(domain);
res.json(result);
} catch (error) {
res.status(error.status || 500).json({
error: error.message
});
}
});
// Bulk check endpoint
app.post('/api/bulk-check', async (req, res) => {
try {
const { domains } = req.body;
if (!Array.isArray(domains)) {
return res.status(400).json({
error: 'domains must be an array'
});
}
// Check domains concurrently
const results = await Promise.allSettled(
domains.map(domain => client.getScore(domain))
);
const response = results.map((result, index) => ({
domain: domains[index],
...(result.status === 'fulfilled'
? { success: true, data: result.value }
: { success: false, error: result.reason.message }
)
}));
res.json({ results: response });
} catch (error) {
res.status(500).json({
error: error.message
});
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
3. Batch Domain Checker (Node.js)ΒΆ
const fs = require('fs');
const { createObjectCsvWriter } = require('csv-writer');
async function auditDomainsBatch(domains, outputFile = 'audit_results.csv') {
const client = new ReputeAPIClient(process.env.REPUTE_API_KEY);
const results = [];
console.log(`Auditing ${domains.length} domains...`);
for (let i = 0; i < domains.length; i++) {
const domain = domains[i];
process.stdout.write(`[${i + 1}/${domains.length}] ${domain}... `);
try {
const result = await client.getScore(domain);
const auditResult = {
domain,
score: result.score,
grade: result.grade,
timestamp: new Date().toISOString(),
status: 'success'
};
// Count issues by severity
const topIssues = result.top_issues || [];
auditResult.critical_count = topIssues.filter(
i => i.severity === 'critical'
).length;
auditResult.high_count = topIssues.filter(
i => i.severity === 'high'
).length;
results.push(auditResult);
console.log(`Score: ${result.score}/100`);
} catch (error) {
results.push({
domain,
score: 0,
grade: 'Error',
timestamp: new Date().toISOString(),
status: `error: ${error.message}`,
critical_count: 0,
high_count: 0
});
console.log(`Error: ${error.message}`);
}
// Rate limiting: wait between requests
if (i < domains.length - 1) {
await new Promise(resolve => setTimeout(resolve, 500));
}
}
// Save to CSV
const csvWriter = createObjectCsvWriter({
path: outputFile,
header: [
{ id: 'domain', title: 'Domain' },
{ id: 'score', title: 'Score' },
{ id: 'grade', title: 'Grade' },
{ id: 'critical_count', title: 'Critical Issues' },
{ id: 'high_count', title: 'High Issues' },
{ id: 'status', title: 'Status' },
{ id: 'timestamp', title: 'Timestamp' }
]
});
await csvWriter.writeRecords(results);
console.log(`\nResults saved to ${outputFile}`);
// Summary
const totalDomains = results.length;
const passingDomains = results.filter(r => r.score >= 80).length;
console.log(`\nSummary: ${passingDomains}/${totalDomains} domains passing (80+)`);
return results;
}
// Usage
const domains = ['example.com', 'test.com', 'demo.com'];
auditDomainsBatch(domains);
4. Monitoring Script with AlertsΒΆ
const schedule = require('node-schedule');
const nodemailer = require('nodemailer');
class DomainMonitor {
constructor(apiKey, alertThreshold = 70) {
this.client = new ReputeAPIClient(apiKey);
this.alertThreshold = alertThreshold;
this.previousScores = new Map();
// Configure email alerts
this.mailer = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS
}
});
}
async checkDomain(domain) {
try {
const result = await this.client.getScore(domain);
const currentScore = result.score;
const previousScore = this.previousScores.get(domain);
console.log(`[${new Date().toISOString()}] ${domain}: ${currentScore}/100`);
// Alert if score below threshold
if (currentScore < this.alertThreshold) {
await this.sendAlert(
domain,
`Score below threshold: ${currentScore} < ${this.alertThreshold}`
);
}
// Alert if score dropped significantly
if (previousScore && currentScore < previousScore - 10) {
await this.sendAlert(
domain,
`Score dropped from ${previousScore} to ${currentScore}`
);
}
this.previousScores.set(domain, currentScore);
} catch (error) {
console.error(`Error checking ${domain}:`, error.message);
await this.sendAlert(domain, `Check failed: ${error.message}`);
}
}
async sendAlert(domain, message) {
console.log(`ALERT for ${domain}: ${message}`);
// Send email alert
try {
await this.mailer.sendMail({
from: process.env.EMAIL_USER,
to: process.env.ALERT_EMAIL,
subject: `ReputeAPI Alert: ${domain}`,
text: `Alert for ${domain}:\n\n${message}\n\nTime: ${new Date().toISOString()}`
});
} catch (error) {
console.error('Failed to send email alert:', error.message);
}
}
async monitorDomains(domains) {
for (const domain of domains) {
await this.checkDomain(domain);
}
}
scheduleMonitoring(domains, cronExpression = '0 * * * *') {
// Default: every hour
schedule.scheduleJob(cronExpression, async () => {
await this.monitorDomains(domains);
});
console.log(`Monitoring scheduled: ${cronExpression}`);
console.log(`Watching domains: ${domains.join(', ')}`);
}
}
// Usage
const monitor = new DomainMonitor(process.env.REPUTE_API_KEY, 75);
const domains = ['example.com', 'test.com'];
// Run initial check
monitor.monitorDomains(domains);
// Schedule hourly checks
monitor.scheduleMonitoring(domains, '0 * * * *');
5. Vue.js Dashboard ComponentΒΆ
<template>
<div class="domain-dashboard">
<h1>Domain Security Dashboard</h1>
<div class="domain-input">
<input
v-model="newDomain"
@keyup.enter="addDomain"
placeholder="Enter domain to check"
/>
<button @click="addDomain">Add Domain</button>
</div>
<div class="domains-grid">
<div
v-for="domain in domains"
:key="domain.name"
class="domain-card"
:class="`grade-${domain.grade?.toLowerCase()}`"
>
<h3>{{ domain.name }}</h3>
<div v-if="domain.loading" class="loading">
Loading...
</div>
<div v-else-if="domain.error" class="error">
Error: {{ domain.error }}
</div>
<div v-else-if="domain.score !== null" class="domain-info">
<div class="score">{{ domain.score }}/100</div>
<div class="grade">{{ domain.grade }}</div>
<div v-if="domain.topIssues?.length" class="issues">
<h4>Top Issues:</h4>
<ul>
<li
v-for="(issue, index) in domain.topIssues"
:key="index"
:class="`severity-${issue.severity}`"
>
{{ issue.message }}
</li>
</ul>
</div>
</div>
<button @click="refreshDomain(domain.name)" class="refresh-btn">
Refresh
</button>
<button @click="removeDomain(domain.name)" class="remove-btn">
Remove
</button>
</div>
</div>
</div>
</template>
<script>
import ReputeAPIClient from './ReputeAPIClient';
export default {
name: 'DomainDashboard',
data() {
return {
domains: [],
newDomain: '',
client: null
};
},
created() {
this.client = new ReputeAPIClient(process.env.VUE_APP_API_KEY);
},
methods: {
async addDomain() {
const domain = this.newDomain.trim();
if (!domain) return;
// Check if domain already exists
if (this.domains.find(d => d.name === domain)) {
alert('Domain already added');
return;
}
this.domains.push({
name: domain,
loading: true,
score: null,
grade: null,
topIssues: [],
error: null
});
this.newDomain = '';
await this.checkDomain(domain);
},
async checkDomain(domainName) {
const domain = this.domains.find(d => d.name === domainName);
if (!domain) return;
domain.loading = true;
domain.error = null;
try {
const result = await this.client.getScore(domainName);
domain.score = result.score;
domain.grade = result.grade;
domain.topIssues = result.top_issues || [];
} catch (error) {
domain.error = error.message;
} finally {
domain.loading = false;
}
},
async refreshDomain(domainName) {
await this.checkDomain(domainName);
},
removeDomain(domainName) {
this.domains = this.domains.filter(d => d.name !== domainName);
}
}
};
</script>
<style scoped>
.domain-dashboard {
padding: 20px;
}
.domains-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin-top: 20px;
}
.domain-card {
border: 2px solid #ddd;
border-radius: 8px;
padding: 20px;
background: white;
}
.domain-card.grade-excellent {
border-color: #22c55e;
}
.domain-card.grade-good {
border-color: #3b82f6;
}
.domain-card.grade-fair {
border-color: #f59e0b;
}
.domain-card.grade-poor {
border-color: #ef4444;
}
.score {
font-size: 48px;
font-weight: bold;
text-align: center;
}
.grade {
text-align: center;
font-size: 24px;
margin: 10px 0;
}
</style>
Performance TipsΒΆ
1. Request CachingΒΆ
class CachedReputeAPIClient extends ReputeAPIClient {
constructor(apiKey, baseUrl, cacheTtl = 900000) { // 15 minutes
super(apiKey, baseUrl);
this.cache = new Map();
this.cacheTtl = cacheTtl;
}
_getCacheKey(endpoint, params) {
return `${endpoint}:${JSON.stringify(params)}`;
}
_getFromCache(key) {
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < this.cacheTtl) {
return cached.data;
}
return null;
}
_setCache(key, data) {
this.cache.set(key, {
data,
timestamp: Date.now()
});
}
async checkDomain(domain, options = {}) {
const cacheKey = this._getCacheKey('check', { domain, ...options });
// Try cache first
if (!options.refresh) {
const cached = this._getFromCache(cacheKey);
if (cached) return cached;
}
// Fetch from API
const result = await super.checkDomain(domain, options);
// Cache result
this._setCache(cacheKey, result);
return result;
}
}
2. Concurrent Requests with Rate LimitingΒΆ
class RateLimitedQueue {
constructor(maxConcurrent = 5, minInterval = 200) {
this.maxConcurrent = maxConcurrent;
this.minInterval = minInterval;
this.queue = [];
this.running = 0;
this.lastRun = 0;
}
async add(fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject });
this._process();
});
}
async _process() {
if (this.running >= this.maxConcurrent || this.queue.length === 0) {
return;
}
// Rate limiting: ensure minimum interval between requests
const now = Date.now();
const timeSinceLastRun = now - this.lastRun;
if (timeSinceLastRun < this.minInterval) {
setTimeout(() => this._process(), this.minInterval - timeSinceLastRun);
return;
}
const { fn, resolve, reject } = this.queue.shift();
this.running++;
this.lastRun = Date.now();
try {
const result = await fn();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running--;
this._process();
}
}
}
// Usage
const queue = new RateLimitedQueue(5, 200); // Max 5 concurrent, 200ms between
const client = new ReputeAPIClient(API_KEY);
async function checkDomainsWithRateLimit(domains) {
const results = await Promise.all(
domains.map(domain =>
queue.add(() => client.getScore(domain))
)
);
return results;
}
TestingΒΆ
Jest Unit TestsΒΆ
const ReputeAPIClient = require('./ReputeAPIClient');
// Mock fetch
global.fetch = jest.fn();
describe('ReputeAPIClient', () => {
let client;
beforeEach(() => {
client = new ReputeAPIClient('test-api-key');
fetch.mockClear();
});
test('checkDomain returns result', async () => {
const mockResponse = {
domain: 'example.com',
score: 85,
grade: 'Good'
};
fetch.mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
});
const result = await client.checkDomain('example.com');
expect(result).toEqual(mockResponse);
expect(fetch).toHaveBeenCalledWith(
expect.stringContaining('/api/v1/check?domain=example.com'),
expect.objectContaining({
headers: { 'X-API-Key': 'test-api-key' }
})
);
});
test('handles authentication error', async () => {
fetch.mockResolvedValueOnce({
ok: false,
status: 401,
json: async () => ({ message: 'Invalid API key' })
});
await expect(client.checkDomain('example.com'))
.rejects
.toThrow('Invalid API key');
});
test('handles rate limit error', async () => {
fetch.mockResolvedValueOnce({
ok: false,
status: 429,
headers: {
get: () => '60'
},
json: async () => ({ message: 'Rate limit exceeded' })
});
await expect(client.checkDomain('example.com'))
.rejects
.toThrow('Rate limit exceeded');
});
});
Next StepsΒΆ
- Python Guide - Python integration
- cURL Examples - Command-line usage
- Integration Patterns - Architecture patterns
- Best Practices - Optimization tips
- API Reference - Complete API documentation
Additional ResourcesΒΆ
SupportΒΆ
Need help with JavaScript integration?