check

Full Threat Analysis

Changed on

Comprehensive threat intelligence check for IPs, domains, URLs, file hashes, email addresses and phone numbers.

An email address or a phone number is recognised automatically and answered from the dataset only, at every enrichment level: verdict (malicious | suspicious | unknown, never clean), recommendedAction (block | review | unverified) and reasons. Pass country for a phone number in national format.

Enrichment Levels:

  • basic - Malicious status, reputation counters, sources, blocklist counters, plus whatever the dataset holds (geo, whois, certificates, vulnerabilities, dns, …). No risk score.
  • standard (default) - Basic + risk score, classification, confidence, MITRE mapping, cross-correlation, ASN reputation, OTX context
  • full - Standard + detection timeline and related infrastructure
  • fast - Standard's evidence and scoring, read from the cache only: no live DNS, OTX or other upstream call before the answer. What the cache did not hold is listed in pending and fetched in the background, so a re-check a few seconds later is complete. A hash is looked up in the dataset, then on CIRCL for at most ~2.5 s (no OTX); a lookup still running then (or not started yet, every lookup slot busy) answers lookupStatus: "unknown" with pending: ["circl"], plus lookupQueued: false when not even a background slot was free to start it later — the next check starts it. Email addresses and phone numbers answer as at standard.

With no target parameter at all, answers a minimal 200 body (malicious: false + dataTrust/evidence) instead of an error.

get/check

Request

  • Base URL
    https://api.ismalicious.com
  • Auth
    • API key in header X-API-KEY
    • or HTTP bearer
    • or HTTP basic

Query parameters

querystring

IP address, domain, URL, file hash, email address or phone number to check. Supply this or one of the ip / domain / hash aliases. A phone number is best sent in E.164 (+33612345678), URL-encoded: an unencoded + reaches the server as a space.

ipstring

Alias for query restricted in intent to IP addresses

domainstring

Alias for query restricted in intent to domains

hashstring

Alias for query restricted in intent to file hashes (MD5/SHA1/SHA256)

enrichmentstring

Enrichment level: basic, standard, full, or fast. An unknown value reads as standard, so a client may send fast to a server that predates it

countrystring

ISO 3166-1 alpha-2 country for a phone number written in national format (06 12 34 56 78 with FR → +33612345678). Ignored for every other indicator, and for a number written internationally

Response

Threat analysis response. Field availability depends on the entity type, the enrichment level, and the dataset — see the schema description.

apiVersionstring required

API version

asnReputationobject nullable

ASN-level reputation (standard/full, when resolvable)

azureTenantobject nullable

Azure tenant details (cached enrichment)

blocklistHitsinteger nullable

Number of blocklist sources listing the entity

blocklistListedboolean nullable

Whether the entity appears on at least one enabled blocklist

categoriesstring[] nullable

Categories claimed by the threat listings (email and phone queries); hash documents pass their stored categories through

certificateFactsobject nullable

The certificate section, each part naming its source and time: status (found | none | unknown | pending | not_applicable), live (what our own TLS handshake on port 443 observed — read from the cache here, never probed by this endpoint) and ctHistory (crt.sh: status, via http|postgres|stored, fetchedAt, stale, counts, rows, error). none is only ever said for a registrable domain with no current certificate logged and nothing observed live; a source that did not answer reads unknown.

certificatesobject[] nullable

Certificate Transparency entries from crt.sh, in crt.sh's row shape (not_before / not_after without a timezone, UTC). Normalised: at most 10 current certificates, newest first, or the 10 most recent expired ones when none is current, with the precertificate/final duplicates removed — the full counts are in certificateFacts.ctHistory (currentCount, totalSeen). Never the live certificate, never set for an IP. Omitted while crt.sh is switched off.

confidenceScorenumber double nullable

Hash queries only: ingestion confidence from the feed document (0-100)

crossCorrelationobject nullable

Cross-correlation signals across data facets (standard/full)

delistedboolean nullable

Present and true when the entity was delisted after review

dnsobject nullable

Raw DNS snapshot (records, SPF/DMARC flags)

enrichmentLevelstring required

Enrichment level applied: basic | standard | full | fast

entitystring nullable

Email and phone queries only: what was looked up — the lowercased address, or the E.164 number (its digits when no country could be told)

firstSeenstring nullable

When the entity entered the dataset, or the feed's earliest observation of it — RFC 3339 UTC (2026-08-25T14:17:40Z). Present at every enrichment level; null when the stored document carries no stamp (an entity no feed has ever listed)

geoobject nullable

Raw geolocation payload (shape follows ip-api)

greynoiseobject nullable

GreyNoise Community context for an IPv4 (standard/full), present only when a report lookup has fetched it in the last three days — this endpoint reads that answer and never calls GreyNoise itself. { source, fetchedAt, classification: benign|malicious|unknown, noise, riot, name, link, lastSeen, tags }. riot: true (a known business service) and benign are context and never raise riskScore; malicious feeds its Context factor. Absent is "no answer", never a clean verdict

intelOwlobject nullable

IntelOwl analyzer output (cached enrichment)

knownGoodboolean nullable

Hash queries only: present and true when the hash is NSRL-listed known software

lastSeenstring nullable

Latest re-observation of the entity by a feed — RFC 3339 UTC. Present at every enrichment level; null when unknown

lastUpdatedstring nullable

Last full refresh of the stored document at ingest — RFC 3339 UTC. Present at every enrichment level; null when unknown

lookupQueuedboolean nullable

Hash queries only, next to pending: ["circl"]: false when nothing is running or queued for the hash — every background lookup slot was taken — so nothing completes it in the background: the next check starts the lookup. Absent otherwise (additive: a lookup is running, or queued to start once a slot frees)

lookupStatusstring nullable

Hash queries: known when a reputation source or NSRL match is available, otherwise unknown. Email and phone queries: found when the dataset holds a document for the address or number, otherwise unknown. Unknown is never positive evidence of safety.

maliciousboolean required

Explicit or scanner-derived malicious detection for IPs/domains; hashes also include malware-feed matches. false is not a safety verdict. Consult riskScore, evidence and blocklist fields for the overall assessment, and lookupStatus for unknown hashes.

microsoftTenantboolean nullable

Whether the domain maps to a Microsoft/Azure tenant

mitreobject nullable

MITRE ATT&CK mapping for the classified categories (standard/full)

otxobject nullable

AlienVault OTX pulse context (standard/full)

pendingstring[] nullable

fast only: the facets the cache did not hold for this answer and that are being fetched in the background — dns, whois, geo, certificates (the CT history of a public domain name), otx for an IP, a domain or a URL; circl for a hash whose lookup outlived the request deadline, or found every lookup slot busy until it and starts once one frees (lookupStatus then reads unknown for now, not a CIRCL miss) — unless lookupQueued is false. A re-check a few seconds later answers them from the cache. A facet no fetch can fill is not listed: one whose last fetch failed within the past five minutes, the geo and WHOIS of a private or reserved address. Absent when nothing is pending

processingTimeinteger nullable

Server-side processing time in milliseconds (absent on the minimal no-target response)

ransomwareobject nullable

Ransomware-group context, when the entity appears in ransomware feeds

reasonsstring[] nullable

Email and phone queries only: at most five short sentences stating the evidence behind verdict

recommendedActionstring nullable

Email and phone queries only: block (malicious) | review (suspicious) | unverified (unknown — nothing is known either way)

relatedInfrastructureobject nullable

Related infrastructure (full enrichment only)

reputationobject nullable

Aggregated detection counters (typically malicious / suspicious / harmless / undetected, sometimes timeout). May be null for unknown entities.

similar_domainsobject nullable

Lookalikes of the domain that the corpus lists — typosquats, homoglyphs, the name on other TLDs or wrapped in phishing words — best first: { keywords, hits, total_hits, truncated, matches: [{ domain, fuzzer, threatLevel }] }. hits holds the same names as matches.

sourcesobject[] nullable

Raw source rows from the feed corpus (name, url, category, … as ingested). Each row may carry threatClass (threat when absent, infrastructure, policy, allowlist) and fpRisk (low when absent, medium, high) copied from the feed registry

techStackobject nullable

Detected technology stack (cached enrichment)

timelineobject nullable

Detection timeline (full enrichment only)

typestring nullable

Email and phone queries only: email | phone

verdictstring nullable

Email and phone queries only: malicious | suspicious | unknown, never clean

vulnerabilitiesobject nullable

Raw open-port / CVE payload (shape follows Shodan InternetDB: cpes / hostnames / ip / ports / tags / vulns)

whoisobject nullable

Raw WHOIS payload (shape follows the WHOIS provider)

Example response

{
  "apiVersion": "v2",
  "classification": {
    "indicators": [
      {
        "category": "phishing",
        "type": "source_category"
      }
    ],
    "primary": "safe"
  },
  "confidence": {
    "factors": [
      {
        "name": "source_agreement"
      }
    ],
    "level": "high"
  },
  "dataTrust": {
    "certificates": {
      "source": "tls",
      "state": "found"
    }
  },
  "email": {
    "address": "billing@paypa1-secure.com",
    "domain": "paypa1-secure.com",
    "domainReputation": {
      "lookupStatus": "found"
    },
    "localPart": "billing"
  },
  "enrichmentLevel": "standard",
  "entity": "billing@paypa1-secure.com",
  "firstSeen": "2026-08-25T14:17:40Z",
  "hashInfo": {
    "hash": "44d88612fea8a8f36de82e1278abb02f",
    "hashType": "md5"
  },
  "infrastructure": {
    "attributes": [
      "cloud",
      "saas"
    ],
    "sources": [
      {
        "category": "infrastructure",
        "id": "azure-ip-ranges",
        "name": "Azure - Published IP Ranges",
        "threatClass": "infrastructure"
      }
    ]
  },
  "lastSeen": "2026-09-20T06:00:00Z",
  "lastUpdated": "2026-09-01T00:00:00Z",
  "lookupStatus": "unknown",
  "pending": [
    "dns",
    "otx"
  ],
  "phone": {
    "countryCallingCode": "33",
    "e164": "+33612345678",
    "input": "06 12 34 56 78",
    "resolvedWith": "country"
  },
  "pwnedPassword": {
    "corpusUpdatedAt": "2026-09-30T18:00:00+00:00",
    "count": 52256179,
    "hashType": "ntlm",
    "source": "Have I Been Pwned — Pwned Passwords",
    "sourceUrl": "https://haveibeenpwned.com/Passwords"
  },
  "recommendedAction": "block",
  "riskScore": {
    "factors": [
      {
        "name": "domain_age"
      }
    ],
    "level": "safe"
  },
  "type": "email",
  "verdict": "malicious"
}

Changes

    • breaking

      the response's property type changed from object null to array null for status

    • info

      added the optional property // to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property / to the response with the status