Skip to main content
An indicator of compromise (IoC) is an artifact observed on a network or in a system that, with high confidence, indicates a security breach has occurred or is occurring. CyberThreat AI accepts three categories of IoC as input: IP addresses, domain names, and file hashes.

Supported types

IP address

Both IPv4 and IPv6 addresses. Queried against VirusTotal and AbuseIPDB.

Domain

Fully qualified domain names. Queried against VirusTotal and Robtex.

Hash

MD5, SHA-1, or SHA-256 file digests. Queried against VirusTotal and PolySwarm.

Type reference

Display typeIoCType valueExample value
IPv4ip198.51.100.42
IPv6ip2001:db8::1
domaindomainmalicious-domain.example.com
hash/md5hashd41d8cd98f00b204e9800998ecf8427e
hash/sha1hashda39a3ee5e6b4b0d3255bfef95601890afd80709
hash/sha256hashe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
The IoCType union ('ip' | 'domain' | 'hash') is the internal routing key. The display type shown in the UI and included in the meta SSE event is more specific and derived after detection.

Auto-detection

When you submit a value without specifying its type, CyberThreat AI detects it automatically using Zod schema validation. Detection runs in a fixed priority order inside detectIocType (src/scripts/core/iocValidators.ts):
1

IP address check

The value is tested against z.union([z.ipv4(), z.ipv6()]). If it matches, detection stops and the type is 'ip'. The display subtype (IPv4 or IPv6) is resolved later by checking whether the normalized string contains a colon (:).
2

Domain check

The value is tested against z.hostname().regex(/\.[a-z]{2,}$/i). The regex requires at least one dot followed by a TLD of two or more letters, so bare hostnames without a TLD are rejected.
3

Hash check

The value is tested in order against z.hash('md5'), z.hash('sha1'), and z.hash('sha256'). The first match determines both the IoCType ('hash') and the HashAlgorithm ('md5' | 'sha1' | 'sha256'), which is used to build the display type hash/<algorithm>.
// src/scripts/core/iocValidators.ts
export function detectIocType(rawIoc: string): IoCType | null {
    const ioc = rawIoc.trim()

    if (IOC_IP_SCHEMA.safeParse(ioc).success) {
        return 'ip'
    }
    if (IOC_DOMAIN_SCHEMA.safeParse(ioc).success) {
        return 'domain'
    }
    if (IOC_HASH_SCHEMA.safeParse(ioc).success) {
        return 'hash'
    }

    return null
}
Input is trimmed before validation, so leading and trailing whitespace does not affect detection. Hash input is also lowercased before being matched.

Unrecognized values

If the submitted value does not pass any of the three schema checks, detectIocType returns null. The API responds with an error and no analysis is performed.
Values that look like IoCs but fail validation — for example, a hostname without a valid TLD, or a hex string that is neither 32, 40, nor 64 characters long — are treated as unrecognized and rejected.

Build docs developers (and LLMs) love