# ContrastAPI — Full API Reference > Security intelligence API. 53 MCP tools. Base URL: https://api.contrastcyber.com > Auth: None required (100 req/hr). Pro: Authorization: Bearer cc_xxx (1000 req/hr). > All responses JSON with a "summary" field optimized for LLM consumption. > OpenAPI spec: https://api.contrastcyber.com/openapi.json ## CVE Intelligence GET /v1/cve/{cve_id} — Full CVE details with EPSS + KEV + CVSS breakdown. Response keys: cve_id, summary, description, severity, cvss_v3, cvss_breakdown, cwe_id, epss:{score,percentile}, kev:{in_kev,date_added}, affected_products, published, modified, references Errors: 400, 404 GET /v1/cve/{cve_id}/risk_score — Composite risk score (CVSS×0.20 + EPSS×0.35 + KEV×0.30 + PoC×0.15) with multiplicative boosters (KEV+PoC ×1.15, CVSS≥9 AND EPSS>0.7 ×1.10, <7d ×1.05). Score clamped to [0,100]. Response keys: cve_id, score, label (CRITICAL|HIGH|MEDIUM|LOW), urgency, has_public_poc, components:{cvss_v3,epss_score,in_kev,has_public_poc,weighted_breakdown}, boosters_applied, recommendation, summary Errors: 400, 404 GET /v1/cvss/details?vector= — Parse a CVSS v3.0 or v3.1 vector string into per-metric breakdown + recomputed base score. Response keys: version, vector, base_score, base_severity, metrics:{attack_vector,attack_complexity,privileges_required,user_interaction,scope,confidentiality_impact,integrity_impact,availability_impact}, temporal_score, environmental_score, summary Errors: 400 (v2 vectors and malformed strings rejected) GET /v1/cves?product=&severity=&published_after=&published_before=&kev=&epss_min=&sort=&offset= — Search CVEs (paginated): filter by product, severity, YYYY-MM-DD date range, KEV-only, min EPSS score, sort, offset. Response keys: count, summary, results GET /v1/exploit/{cve_id} — Public exploits (GitHub Advisory + Shodan CVEDB refs + ExploitDB CSV). Response keys: cve_id, exploits_found, sources:{github:{found,count,advisories},shodan_refs:{found,count,results}}, exploits:[{edb_id,...}], has_public_exploit, summary GET /v1/kev/{cve_id} — CISA KEV detail (federal patch deadline, required action, ransomware association, CWE list). Response keys: cve_id, in_kev, vendor_project, product, vulnerability_name, date_added, due_date, days_remaining, required_action, known_ransomware_use, cwe_list, summary GET /v1/cwe/{cwe_id} — MITRE CWE catalog entry. Accepts "CWE-79" or just "79". Response keys: cwe_id, name, abstraction, summary, description, mitigations, parent_chain, child_chain, related_cves_count GET /v1/cve/leading — CVEs indexed before NVD (MITRE/GHSA-only feed, freshly published). Response keys: count, summary, results:[{cve_id, source, severity, ...}] POST /v1/cves/bulk — Bulk CVE lookup. Body: {"cve_ids":["CVE-2024-1234",...]} (max 10 free, 50 pro). Response keys: results:[{cve_id,status,cve,error}], total, successful, failed, summary ## Domain Intelligence GET /v1/domain/{domain} — Full domain report (DNS+WHOIS+SSL+subdomains+WAF+email+threat+risk). Supports ?lite=true. Response keys: domain, summary, dns, reverse_dns, whois, ssl, email_security, subdomains, certificates, waf, threat, risk:{score,grade,factors} GET /v1/audit/{domain} — Orchestrated audit: full domain report + tech fingerprint + live HTTP headers in one call. Response keys: domain, report (full domain intel), technologies:{technologies,categories,count,summary}, live_headers, summary GET /v1/threat-report/{ip} — Orchestrated IP threat report: Shodan InternetDB + AbuseIPDB + Shodan full + ASN. No private IPs. Response keys: ip, enrichment:{ports,hostnames,vulns,cpes,tags}, abuseipdb, shodan, asn:{asn,prefix}, threat_level, summary GET /v1/dns/{domain} — DNS records (A, AAAA, MX, NS, TXT, CNAME, SOA). Response keys: domain, records:{a,aaaa,mx,ns,txt,cname,soa}, summary GET /v1/whois/{domain} — WHOIS registration data. Response keys: domain, whois:{registrar,creation_date,expiry_date,name_servers}, summary GET /v1/ssl/{domain} — SSL/TLS certificate analysis. Response keys: domain, valid, issuer, subject, not_before, not_after, days_remaining, san, protocol, cipher:{name,bits}, chain, grade, summary GET /v1/subdomains/{domain} — Subdomain enumeration (DNS brute + CT logs). Response keys: domain, subdomains, count, summary GET /v1/certs/{domain} — Certificate Transparency log entries. Response keys: domain, total_certificates, certificates:[{issuer,not_before,not_after,common_name}], summary GET /v1/ip/{ip} — IP intelligence (Shodan InternetDB). No private/reserved IPs. Response keys: ip, ptr, ports, hostnames, vulns, cpes, tags, summary GET /v1/asn/{target} — ASN lookup. Accepts domain or IP. Response keys: target, resolved_ip, asn, asn_name, ipv4_prefixes, ipv6_prefixes, ipv4_count, ipv6_count, summary GET /v1/threat/{domain} — Threat intelligence (URLhaus). Response keys: domain, urlhaus_status, urls_online, url_count, threat_types, tags, urls, summary GET /v1/tech/{domain} — Technology fingerprinting (CMS, frameworks, CDN). Response keys: domain, technologies:[{name,category,source,version}], categories, count, summary GET /v1/scan/headers/{domain} — Live HTTP security header scan. Response keys: domain, status_code, url, score, grade, findings, headers_present, headers_missing, summary GET /v1/email/mx/{domain} — Email MX analysis (provider + SPF/DMARC/DKIM). Response keys: domain, mx_records, mail_provider, email_security:{spf,dmarc,dkim_selectors,dkim_status,grade,issues}, summary GET /v1/email/disposable/{email} — Disposable email check. Response keys: email, domain, disposable, provider, mx_disposable, risk_level, summary GET /v1/email/verify/{email} — Combined email validation: syntax + MX + disposable + role + free-provider. NO SMTP RCPT TO probing (ethical declined — Hunter.io grey area). Response keys: email, domain, syntax_valid, mx_records, disposable, disposable_provider, role_address, role_type, free_provider, summary GET /v1/phone/{number} — Phone validation. Include country code (e.g. +14155551234). Response keys: valid, number, format:{e164,international,national}, country_code, country_name, type, carrier, timezone, summary GET /v1/username/{username} — Username OSINT across 16 platforms (3-39 chars). Response keys: username, found_count, checked_count, results:[{platform,url,status}], summary, verdict:{sources_queried,sources_unavailable,completeness} GET /v1/archive/{domain} — Wayback Machine history. Response keys: domain, status, total_snapshots, first_seen, last_seen, years_online, snapshots, archive_url, summary, warnings. status='unavailable' (cdx_timeout/cdx_rate_limited/cdx_unavailable/cdx_error/cdx_parse_error/cdx_body_too_large) → total_snapshots OMITTED (unknown, not zero). ## Threat Intelligence / IOC GET /v1/ioc/{indicator} — Unified IOC enrichment. Auto-detects IP/domain/URL/hash. Response keys: indicator, type, threat_level, sources:{threatfox,feodo,urlhaus}, summary GET /v1/hash/{file_hash} — Malware hash (MalwareBazaar). MD5/SHA1/SHA256. Response keys: hash, hash_type, found, malware_family, file_type, file_size, first_seen, tags, file_name, summary GET /v1/password/{sha1_hash} — Password breach check (HIBP k-anonymity). Full SHA1 hash. Response keys: hash_prefix, found, breach_count, summary GET /v1/phishing/{url} — Phishing/malware URL check (URLhaus). Must start with http(s)://. Response keys: url, host, is_malicious, urlhaus_host:{found,urls_online,url_count}, urlhaus_url:{found,threat,tags}, threat_level, summary POST /v1/iocs/bulk — Bulk IOC enrichment. Body: {"indicators":["8.8.8.8","evil.com",...]} (max 10 free, 50 pro). Response keys: results:[{indicator,status,ioc:{type,threat_level,sources},error}], total, successful, failed, timed_out, partial, summary ## MITRE ATLAS (AI/ML Threats) GET /v1/atlas/{technique_id} — Lookup ATLAS technique (AML.T#### or AML.T####.###). Sub-techniques inherit parent tactics; `inherited_tactics` flag surfaces this. Response keys: technique_id, name, description, tactics, inherited_tactics, maturity, attack_reference_id, attack_reference_url, subtechnique_of, created_date, modified_date, verdict, next_calls GET /v1/atlas/techniques?keyword=&tactic=&maturity=&exclude_id=&include= — Search ATLAS techniques (~167 entries). Slim default; ?include=full for verbose narrative. Response keys: count, summary, results:[{technique_id, name, tactics, maturity, ...}] POST /v1/atlas/techniques/bulk — Bulk lookup up to 50 ATLAS technique ids in one call (drill case-study `techniques_used` in one request). Response keys: results:[{technique_id, status, technique, error}], total, successful, failed, not_found, summary GET /v1/atlas/case-studies/{case_study_id} — Lookup ATLAS case study (AML.CS####). ?include=full for full narrative. Response keys: case_study_id, name, summary, target, actor, techniques_used, references, pivot_hints GET /v1/atlas/case-studies?keyword=&technique_id= — Search ATLAS case studies (~57 entries). Filter by referenced technique. Response keys: count, summary, results ## MITRE D3FEND (Defense Mapping) GET /v1/d3fend/{defense_id} — Lookup D3FEND defense by slug (e.g. TokenBinding, ContentFiltering). Response keys: defense_id, label, uri, parent_label, description, tactic, artifact, attack_techniques, verdict, next_calls GET /v1/d3fend/defenses?keyword=&tactic=&artifact=&include=&exclude_id= — Search defenses (~149 entries, 7 D3FEND tactics). Slim-default uri-drop; ?include=full restores. Response keys: count, summary, results GET /v1/d3fend/attack/{attack_technique_id} — Reverse: ATT&CK T-code → mitigating D3FEND defenses (e.g. T1059, T1550.001). Response keys: attack_technique_id, count, summary, defenses:[{defense_id, name, tactic, artifact}] 200 with empty list when no mapping exists; the gap is the signal. POST /v1/d3fend/coverage — Batch coverage breakdown for a list of ATT&CK T-codes (max 500). Identifies undefended techniques. Body: {"attack_techniques":["T1059","T1190","T1550.001"]} Response keys: total, count_by_tactic, undefended, summary, coverage:[{attack_technique_id, defense_count, defenses}] ## Web Intelligence (v1.25.0) Single-page audits with explicit ethical floor: per-target eTLD+1 throttle (60/min), self-identifying UA `ContrastAPI/ (+https://contrastcyber.com/bot)`, robots.txt respected (Disallow `/` for our UA → 403, no fetch), Cache-Control honoured (no-store/private skips cache write), no SMTP probing. GET /v1/robots/{domain} — Fetch + parse target's robots.txt (RFC 9309). Sitemaps, per-User-agent allow/disallow blocks, crawl-delay, Host directive. Response keys: domain, fetched_url, status_code, sitemaps, user_agents:{ua:{allow,disallow,crawl_delay}}, host, truncated, summary status_code=404 → no robots.txt = implicit allow-all. 502 on hard fetch failure (DNS/TCP/TLS). GET /v1/redirect/{url:path} — Walk a URL's HTTP redirect chain hop-by-hop. SSRF-guarded at every hop (private IPs and non-HTTP schemes rejected). Up to 10 hops. Response keys: start_url, final_url, hops:[{url, status_code, location, latency_ms}], hop_count, final_status, loop_detected, truncated, summary Per-target throttle consumed once for start host AND once per new host reached. 502 on hard fetch failure. GET /v1/email/verify/{email} — Combined email validation: syntax + MX + disposable + role + free-provider. Replaces email_mx + email_disposable + manual role parse with one call. Response keys: email, domain, syntax_valid, mx_records, disposable, disposable_provider, role_address, role_type, free_provider, summary Deliberately does NOT do SMTP RCPT TO probing (Hunter.io / NeverBounce-style mailbox enumeration is an ethical grey area we declined). GET /v1/brand/{domain} — Scrape homepage for public brand assets [cost: 2]. Strictly homepage-only; we do NOT crawl. Response keys: domain, fetched_url, status_code, favicon_url_untrusted, og_image_url_untrusted, theme_color, site_name_untrusted, logo_url_untrusted, cache_respected, summary All target-derived URLs are absolute and `_untrusted` (DO NOT execute or shell-out). 403 with `error.code = robots_txt_disallow` when target opted out. GET /v1/seo/{domain} — One-page SEO audit + 0-100 composite score [cost: 2]. 10 rules x 10 pts each. Response keys: domain, fetched_url, status_code, title_untrusted, meta_description_untrusted, canonical_url, h1_untrusted, h1_count, h2_count, h3_count, images_total, images_missing_alt, internal_link_count, external_link_count, og_tags, json_ld_present, score, missing_signals, cache_respected, summary Score rules: title present, title length 30-60, meta desc present, meta desc length 50-160, single H1, canonical, ≥3 OG tags, JSON-LD present, image alt coverage (proportional), HTTPS. ## Code Security POST /v1/check/secrets — Detect hardcoded secrets (14 patterns). Body: {"code":"...","language":"python"} Response keys: findings:[{type,severity,line,match,description,remediation}], total, by_severity, summary POST /v1/check/injection — SQL/command/path injection. Body: {"code":"...","language":"python"} Response keys: findings:[{type,severity,line,match,description,remediation}], total, by_severity, summary POST /v1/check/headers — Validate security headers. Body: {"headers":{"header-name":"value"}} Response keys: findings, total, by_severity, score, grade, headers_present:[], headers_missing:[], summary POST /v1/check/dependencies — Check packages for CVEs. Body: {"packages":[{"name":"...","version":"..."}]} Response keys: findings:[{package,version,cve_id,severity,cvss_v3,epss_score,in_kev,remediation}], total, by_severity, summary ## Meta GET /v1/status — Health check. Response: {status, version, data_sources} GET /v1/usage — Pro key stats (requires auth). Response: {total_requests, last_24h, last_1h, hourly_limit, hourly_remaining, top_endpoints} GET /v1/privacy/my-data — GDPR transparency. Returns every row the DB has about the caller — hashed IP, 24h endpoint usage (normalized, no query params), Pro key record if any. Free and Pro tier both supported. No auth required. Response: {tier, rate_limit, client_ip_hash, api_key_record, usage_last_24h:{total_requests,by_endpoint}, not_stored, source_code, privacy_policy} ## MCP ContrastAPI is also exposed as an MCP server with 53 tools, 7 Resources, 3 Prompts. Resources (no rate limit, browse-only): atlas://catalog, atlas://technique/{id}, atlas://case-study/{id}, d3fend://catalog, d3fend://defense/{id}, cwe://catalog, cwe://weakness/{id}. Prompts: contrast_triage(target, perspective='red'|'blue'), security_audit(domain), vulnerability_check(product). Transports: HTTP `POST https://api.contrastcyber.com/mcp/` (Streamable HTTP, JSON-RPC 2.0), or stdio via mcp_server.py. ## Example: CVE Lookup GET /v1/cve/CVE-2024-3094 → {"cve_id":"CVE-2024-3094", "summary":"CRITICAL — xz/liblzma backdoor. CVSS 10.0. CISA KEV. EPSS 93%.", "severity":"CRITICAL", "cvss_v3":10.0, "epss":{"score":0.93}, "kev":{"in_kev":true}} ## Example: Domain Report GET /v1/domain/example.com → {"domain":"example.com", "summary":"Grade B (72/100). SSL A (DigiCert, TLSv1.3). 3 subdomains. No threats.", "risk":{"score":72,"grade":"B"}, "ssl":{"grade":"A","days_remaining":120}} ## Example: SEO Audit GET /v1/seo/example.com → {"domain":"example.com", "score":85, "missing_signals":["meta_description_length_off","images_missing_alt"], "h1_count":1, "json_ld_present":true, "summary":"example.com score=85/100 — missing:meta_description_length_off,images_missing_alt"} ## Rate Limits & Data Sources Keyless: 100 req/hr per IP. Pro: 1000 req/hr. Headers: X-RateLimit-{Limit,Remaining,Reset,Cost,Tier}, X-Request-ID. Credit costs: most endpoints = 1, /v1/audit and /v1/threat-report = 4, /v1/brand and /v1/seo = 2, bulk endpoints = N (one per item). Data: NVD (340K+ CVEs), EPSS (323K+), CISA KEV (1500+), MITRE CWE (944), MITRE ATLAS (~167 techniques + ~57 case studies), MITRE D3FEND (~149 defenses), Shodan, URLhaus, ThreatFox, MalwareBazaar, GitHub Advisory DB, HIBP, Wayback Machine, crt.sh. CVE/EPSS/KEV synced every 2h. Others live.