Back to Help Center
GETTING STARTED August 27, 2026 · 10 min read

DomainScan API Quickstart

DomainScan's API gives programmatic access to all 50+ tools including cryptographic hashing (MD5, SHA family, BLAKE2, RIPEMD-160) and password hashing (bcrypt, Argon2). This quickstart covers authentication, making your first call, the full endpoint reference, and code examples in JavaScript, Python, and curl.

The DomainScan API gives you programmatic access to the same data powering 50+ web tools — domain lookups, DNS queries, IP intelligence, SSL checks, email authentication, and more. All responses are structured JSON, and most endpoints return results in under 2 seconds.

Base URL

https://api.domainscan.in/api/v1

All endpoints are HTTPS only. HTTP requests are redirected.

Authentication

Include your API key in every request as a header:

X-API-Key: your_api_key_here

Get your API key from your DomainScan account dashboard → Profile → API Keys.

Your First Request

curl

curl -X GET \
  "https://api.domainscan.in/api/v1/domain/lookup?domain=example.com" \
  -H "X-API-Key: your_api_key_here"

JavaScript (fetch)

const response = await fetch(
  'https://api.domainscan.in/api/v1/domain/lookup?domain=example.com',
  {
    headers: {
      'X-API-Key': 'your_api_key_here',
    },
  }
);
const { data } = await response.json();
console.log(data.domain, data.registrar, data.expiryDate);

Python

import requests

API_KEY = 'your_api_key_here'
BASE_URL = 'https://api.domainscan.in/api/v1'

def lookup_domain(domain):
    resp = requests.get(
        f'{BASE_URL}/domain/lookup',
        params={'domain': domain},
        headers={'X-API-Key': API_KEY},
        timeout=10
    )
    resp.raise_for_status()
    return resp.json()['data']

info = lookup_domain('example.com')
print(info['registrar'], info['expiryDate'])

Response Structure

All responses use this envelope:

{
  "success": true,
  "data": {
    // endpoint-specific payload
  }
}

Error responses:

{
  "success": false,
  "message": "Domain not found or invalid",
  "code": "DOMAIN_NOT_FOUND"
}

Always check success before accessing data.

Core Endpoints

Domain Lookup (WHOIS / RDAP)

GET /domain/lookup?domain={domain}

Returns ownership, registration dates, registrar, nameservers, domain age, and Trust Score.

{
  "success": true,
  "data": {
    "domain": "example.com",
    "registrar": "ICANN Accredited Registrar",
    "registeredOn": "1995-08-14T00:00:00Z",
    "expiresOn": "2026-08-13T00:00:00Z",
    "updatedOn": "2024-08-14T00:00:00Z",
    "domainAge": "29 years",
    "nameservers": ["a.iana-servers.net", "b.iana-servers.net"],
    "status": ["clientDeleteProhibited", "clientTransferProhibited"],
    "trustScore": 92
  }
}

DNS Query

GET /domain/dns?domain={domain}&type={type}

type can be: A, AAAA, MX, TXT, CNAME, NS, SOA, CAA, SRV, or ALL

{
  "success": true,
  "data": {
    "domain": "example.com",
    "records": {
      "A": [{ "value": "93.184.216.34", "ttl": 3600 }],
      "MX": [{ "value": "mail.example.com", "priority": 10, "ttl": 3600 }]
    }
  }
}

IP Lookup

GET /ip/lookup?ip={ip}

Returns geolocation, ISP, ASN, hostname, reverse DNS, and Trust Score for any IPv4 or IPv6 address.

{
  "success": true,
  "data": {
    "ip": "8.8.8.8",
    "hostname": "dns.google",
    "org": "GOOGLE",
    "asn": "AS15169",
    "country": "United States",
    "city": "Mountain View",
    "lat": 37.386,
    "lon": -122.0838,
    "trustScore": 98
  }
}

SSL Certificate Check

GET /security/ssl-info?domain={domain}

Returns certificate details, validity, trust chain, grade, and security configuration.

{
  "success": true,
  "data": {
    "domain": "example.com",
    "valid": true,
    "expiresOn": "2026-11-01T00:00:00Z",
    "daysUntilExpiry": 72,
    "issuer": "DigiCert Inc",
    "certType": "OV",
    "grade": "A+",
    "protocols": ["TLSv1.2", "TLSv1.3"],
    "hsts": true
  }
}

Email Authentication Check

GET /security/email?domain={domain}

Returns SPF, DKIM, DMARC, BIMI, MTA-STS, TLS-RPT analysis and a composite deliverability score.

{
  "success": true,
  "data": {
    "domain": "example.com",
    "deliverabilityScore": 87,
    "spf": {
      "present": true,
      "valid": true,
      "policy": "~all",
      "lookupCount": 4
    },
    "dmarc": {
      "present": true,
      "policy": "reject",
      "pct": 100,
      "rua": "dmarc@example.com"
    },
    "dkim": {
      "present": true,
      "selectors": ["google", "s1"]
    }
  }
}

Domain Trust Score

GET /domain/trust?domain={domain}

Comprehensive domain health check — blacklists, DNS, SSL, email auth, traffic signals — returns a 0–100 Trust Score with per-category breakdown and AI recommendations.

IP Blacklist Check

GET /ip/blacklist?ip={ip}

Checks IP against 130+ DNSBL and reputation databases. Returns listed/clean status per list with impact level.

DNS Propagation

GET /domain/propagation?domain={domain}&type={type}

Checks DNS propagation from resolvers worldwide. Returns per-resolver results, global propagation percentage, and average response times.

Nameserver Lookup

GET /domain/ns?domain={domain}

Returns authoritative nameservers with health scores, response times, and propagation status.

Hash Generator

POST /developer/hash
Content-Type: application/json

{
  "input":  "hello world",
  "algo":   "sha256",
  "output": "hex",
  "salt":   "",
  "hmac":   ""
}

Computes a cryptographic hash for input using one of 11 server-side algorithms: md5, sha1, sha256, sha384, sha512, sha3-224, sha3-256, sha3-384, sha3-512, blake2b, blake2s, ripemd160. output is hex (default), base64, or binary. Setting hmac switches to HMAC mode with that key. salt is appended to input before hashing.

CRC32 is client-side only and has no server endpoint. SHA-1/256/384/512 and HMAC-SHA-* are also available in-browser via the Hash Generator UI — no upload needed.

{
  "success": true,
  "data": {
    "success": true,
    "hash": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
    "algorithm": "sha256",
    "outputFormat": "hex",
    "salt": null,
    "hmac": null,
    "time": 1
  }
}

Password Hash

POST /developer/hash-password
Content-Type: application/json

{
  "input":       "correct horse battery staple",
  "algo":        "argon2id",
  "iterations":  3,
  "memoryKb":    65536,
  "parallelism": 4,
  "hashLength":  32
}

Hashes a password with bcrypt, argon2id, argon2i, or argon2d. For bcrypt use cost (4–14) instead of the Argon2 params. Output is a self-contained PHC / MCF string that embeds salt + parameters — safe to store directly in a database column.

Server-side bounds (rejected outside range): bcrypt cost 4–14 · Argon2 iterations 1–6, memoryKb 8–262144 (KiB), parallelism 1–8, hashLength 16–64.

{
  "success": true,
  "data": {
    "success": true,
    "algorithm": "argon2id",
    "encoded": "$argon2id$v=19$m=65536,t=3,p=4$w9KLuqzivGvqfMYefUg9ZA$BMld9qceYn8woJsFqQQOfYvL90vCOFBIsB69hdBmS+A",
    "params": { "iterations": 3, "memoryKb": 65536, "parallelism": 4, "hashLength": 32 },
    "time": 16
  }
}

PBKDF2 is client-side only — use the browser tool or crypto.subtle.deriveBits() directly. No server endpoint for PBKDF2 because its parameters have to live in the encoded string.

Password Verify

POST /developer/verify-password
Content-Type: application/json

{
  "password": "correct horse battery staple",
  "encoded":  "$argon2id$v=19$m=65536,t=3,p=4$...$..."
}

Verifies a plain-text password against a bcrypt or Argon2 PHC/MCF string. Algorithm is auto-detected from the prefix ($2[abxy]$ → bcrypt · $argon2(id|i|d)$ → argon2). Uses the underlying library’s constant-time comparison.

{
  "success": true,
  "data": {
    "success": true,
    "matched": true,
    "algorithm": "argon2id",
    "time": 7
  }
}

PBKDF2 strings ($pbkdf2-…$…) are rejected — verify PBKDF2 in the browser instead.

Endpoint Reference

CategoryEndpointQuery Param
Domain LookupGET /domain/lookupdomain
DNS QueryGET /domain/dnsdomain, type
DNS PropagationGET /domain/propagationdomain, type
NameserversGET /domain/nsdomain
Trust ScoreGET /domain/trustdomain
SPF CheckGET /domain/spfdomain
DMARC CheckGET /domain/dmarcdomain
DKIM CheckGET /domain/dkimdomain, selector
AI SEO ReadinessGET /domain/ai-readydomain
IP LookupGET /ip/lookupip
My IPGET /ip/myip
IP BlacklistGET /ip/blacklistip
PingGET /ip/pinghost
TracerouteGET /ip/traceroutehost
Reverse IPGET /ip/reverseip
Port ScanGET /ip/porthost, port
Subnet CalculatorGET /ip/subnetip, mask
SSL InfoGET /security/ssl-infodomain
Security HeadersGET /security/headersdomain
Email AuthGET /security/emaildomain
MAC LookupGET /security/mac-infomac
Hash GeneratorPOST /developer/hashbody: input, algo, output, salt?, hmac?
Password HashPOST /developer/hash-passwordbody: input, algo, cost? (bcrypt) or iterations/memoryKb/parallelism/hashLength (argon2)
Password VerifyPOST /developer/verify-passwordbody: password, encoded

Error Codes

HTTP StatusCodeMeaning
400INVALID_INPUTMissing or malformed query parameter
401UNAUTHORIZEDMissing or invalid API key
404NOT_FOUNDDomain/IP doesn’t exist or can’t be resolved
429RATE_LIMITEDToo many requests — check Retry-After header
500INTERNAL_ERRORServer-side error — retry after a moment
503SERVICE_UNAVAILABLEUpstream resolver unavailable — retry

Rate Limits

Rate limits are applied per API key. Headers on every response tell you your current status:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1724234400

On 429, implement exponential backoff:

async function fetchWithBackoff(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const res = await fetch(url, options);
    if (res.status !== 429) return res;
    const retryAfter = parseInt(res.headers.get('Retry-After') || '1', 10);
    await new Promise(r => setTimeout(r, retryAfter * 1000 * Math.pow(2, i)));
  }
  throw new Error('Rate limit retries exhausted');
}

Quick Integration Patterns

Check domain health before sending email

async function isDomainHealthy(domain) {
  const res = await fetch(
    `https://api.domainscan.in/api/v1/domain/trust?domain=${domain}`,
    { headers: { 'X-API-Key': API_KEY } }
  );
  const { data } = await res.json();
  return data.trustScore >= 70;
}

Monitor SSL expiry across multiple domains

import requests
from datetime import datetime, timezone

def check_ssl_expiry(domains, api_key, warn_days=30):
    alerts = []
    for domain in domains:
        resp = requests.get(
            f'https://api.domainscan.in/api/v1/security/ssl-info',
            params={'domain': domain},
            headers={'X-API-Key': api_key}
        )
        data = resp.json().get('data', {})
        days = data.get('daysUntilExpiry', 999)
        if days < warn_days:
            alerts.append({'domain': domain, 'daysLeft': days})
    return alerts

Validate email sender domain

async function validateSenderDomain(domain) {
  const res = await fetch(
    `https://api.domainscan.in/api/v1/security/email?domain=${domain}`,
    { headers: { 'X-API-Key': API_KEY } }
  );
  const { data } = await res.json();
  return {
    valid: data.deliverabilityScore >= 60,
    score: data.deliverabilityScore,
    hasDmarc: data.dmarc?.present,
    dmarcPolicy: data.dmarc?.policy,
  };
}

For questions or higher-volume access, contact DomainScan.

Read the full API + MCP developer guide, follow the MCP quickstart for Claude Code and Cursor, or browse every major DNS record type to know what data the API returns.

Common Questions

01

Is the API free to use?

DomainScan's core tools are free — no account required for basic usage via the web UI. The API requires an account and API key. Free tier API access includes rate-limited calls to most endpoints. Check your account dashboard for your current usage and limits.

02

What format do API responses use?

All responses are JSON. Successful responses follow the envelope format: { success: true, data: { ... } }. Error responses include a message field explaining what went wrong. All timestamps are ISO 8601. IP addresses are returned as strings.

03

How do I handle rate limits?

The API returns HTTP 429 when rate limits are exceeded. The response includes Retry-After and X-RateLimit-Reset headers telling you when the limit resets. Implement exponential backoff: wait 1s after first 429, 2s after second, 4s after third, etc. Batch lookups into single requests where the endpoint supports it.

04

Can I use the API to check multiple domains at once?

Most endpoints accept a single domain per request. For bulk operations, make parallel requests — the API handles concurrent calls well within rate limits. For very high volume (thousands of lookups), contact DomainScan about enterprise access.

05

Which developer tools are exposed via the API?

Cryptographic hashing (POST /developer/hash) supports MD5, SHA-1, SHA-256, SHA-384, SHA-512, SHA-3 (224/256/384/512), BLAKE2b, BLAKE2s and RIPEMD-160 with optional HMAC and salt. Password hashing (POST /developer/hash-password) supports bcrypt, Argon2id, Argon2i and Argon2d and returns a self-contained PHC/MCF string. Password verification (POST /developer/verify-password) auto-detects the algorithm from the encoded prefix. CRC32 and PBKDF2 are client-side only — use the browser UI or Web Crypto API directly.

06

What are the recommended parameters for Argon2id password hashing?

OWASP 2023 defaults: iterations (t) 3, memoryKb (m) 65536 (64 MiB), parallelism (p) 4, hashLength 32. These give ~50 ms per hash on modern hardware — slow enough to make brute-force expensive, fast enough not to impact real users. The API enforces bounds (t 1–6, m 8 KiB–256 MiB, p 1–8, hashLength 16–64) so requests outside range are rejected before compute. Never reuse salts — the tool generates a random 16-byte salt per request.