Skip to content

IrisQL: Iris Query Language for API

IrisQL is a text-based query language for the Iris Investigate API that enables complex domain searches with advanced filtering, OR (logical OR) logic, and nested conditions.

Technology Preview

This is a preview release. Features may evolve with customer feedback. Report issues and suggestions to your DomainTools contact.

Using IrisQL

Use IrisQL for:

  • Complex OR logic - Search for domains matching multiple conditions across different fields
  • Programmatic query building - Dynamically construct queries in your application
  • Reusing UI (user interface) queries - Export queries from Iris Investigate UI and use them in your API calls
  • Advanced filtering - Combine multiple operators and conditions in a single request
  • Nested conditions - Build queries with complex AND (logical AND)/OR combinations

Getting started

Endpoint

POST https://api.domaintools.com/v1/iris-investigate/

Authentication

Use Header Authentication by passing your API key in the X-Api-Key header. See Authentication for details on other authentication methods.

Request format

Basic structure

Send your IrisQL query as the request body:

curl -X POST 'https://api.domaintools.com/v1/iris-investigate/' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  --data-binary @- << IRISQL
# IrisQL-1.0
DOMAIN CONTAINS "example"
AND
RISK_SCORE GREATER_THAN 70
IRISQL

Version comment

IrisQL queries must begin with the version comment:

# IrisQL-1.0

This comment identifies the query as IrisQL and specifies the syntax version.

Query parameters

IrisQL works alongside standard query parameters for the Iris Investigate API:

curl -X POST 'https://api.domaintools.com/v1/iris-investigate/?page_size=50&sort_by=risk_score' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  --data-binary @- << IRISQL
# IrisQL-1.0
DOMAIN CONTAINS "spam"
AND
RISK_SCORE GREATER_THAN 75
AND
CREATE_DATE WITHIN "The last 30 days"
IRISQL

Query parameters:

IrisQL supports standard query parameters for the Iris Investigate API. These parameters control pagination, sorting, formatting, and more. See the Iris Investigate API Guide for the complete list of available parameters.

Response format

Response structure

IrisQL responses use the identical structure as the Iris Investigate API. See the Query Limits & Pagination section of the Iris Investigate API Guide for details on response fields like limit_exceeded, has_more_results, and position:

{
  "response": {
    "results": [
      {
        "domain": "example.com",
        "risk_score": 85,
        "create_date": "2020-01-15",
        ...
      }
    ],
    "results_count": 50,
    "total_count": 1250,
    "has_more_results": true,
    "limit_exceeded": false,
    "message": "There is more data for you to enjoy.",
    "missing_domains": []
  }
}

All domain attributes include pivot counts showing how many domains have each value. For complete response field documentation, see the Iris Investigate API Guide.

Examples

All IrisQL queries use the POST method to send the query as the request body. Use the X-Api-Key header for authentication.

Basic query

Search for domains containing "phishing" or "malware" with a high risk score:

curl -X POST 'https://api.domaintools.com/v1/iris-investigate/' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  --data-binary @- << IRISQL
# IrisQL-1.0
DOMAIN CONTAINS "phishing"
DOMAIN CONTAINS "malware"
AND
RISK_SCORE GREATER_THAN 85
IRISQL

Complex query with multiple conditions

Search for high-risk domains created in the last 30 days with specific top-level domains:

curl -X POST 'https://api.domaintools.com/v1/iris-investigate/?page_size=100' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  --data-binary @- << IRISQL
# IrisQL-1.0
DOMAIN CONTAINS "bank"
DOMAIN CONTAINS "finance"
AND
CREATE_DATE WITHIN "The last 30 days"
AND
TLD IN ["com", "net", "org"]
AND
RISK_SCORE GREATER_THAN 75
IRISQL

Query with sorting and pagination

Retrieve results sorted by risk score with pagination:

curl -X POST 'https://api.domaintools.com/v1/iris-investigate/?page_size=50&sort_by=risk_score&position=0' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  --data-binary @- << IRISQL
# IrisQL-1.0
DOMAIN CONTAINS "phishing"
AND
RISK_SCORE GREATER_THAN 85
IRISQL

Query with XML response format

Request results in XML format:

curl -X POST 'https://api.domaintools.com/v1/iris-investigate/?format=xml' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  --data-binary @- << IRISQL
# IrisQL-1.0
DOMAIN MATCHES "example.com"
IRISQL

IrisQL syntax reference

Query structure

Each IrisQL query consists of:

  1. Version comment (required): # IrisQL-1.0
  2. Field conditions: Field name, operator, and value
  3. Logical operators: AND to combine conditions
  4. Values: Must be valid JSON primitives - strings in double quotes, numbers without quotes, booleans (true/false), and arrays with square brackets (e.g., ["value1", "value2"])

Syntax notes:

  • IrisQL is case-insensitive for field names and operators.
  • Extra whitespace between tokens is normalized and doesn't affect query parsing.
  • Write each condition on a single line.
  • Don't add leading whitespace before conditions.

Field names and API parameters

IrisQL field names correspond to the parameter names used in the Iris Investigate API. These parameter names may differ from the labels shown in the Advanced Search user interface. For example:

  • UI label: "Name Server" → IrisQL field: NAMESERVER_HOST → API parameter: nameserver_host
  • UI label: "Admin Contact Email" → IrisQL field: ADMIN_CONTACT_EMAIL → API parameter: admin_contact_email
  • UI label: "IP ASN" → IrisQL field: ASN → API parameter: asn

For the complete mapping between API parameters and their data sources, see the search parameters in the Iris Investigate API Guide.

Supported fields

Field names use uppercase with underscores. Fields are organized by category for easier reference.

Domain and risk:

Advanced Search Field IrisQL Field Name
Domain Name DOMAIN
Risk Score RISK_SCORE
First Seen FIRST_SEEN
TLD TLD
Create Date CREATE_DATE
Expiration Date EXPIRATION_DATE
Active / Status ACTIVE
Rank / Popularity Rank RANK

Registration and WHOIS:

Advanced Search Field IrisQL Field Name
Registrant REGISTRANT
Registrant Organisation REGISTRANT_ORG
Registrar REGISTRAR
WHOIS Record WHOIS

Contact information:

Advanced Search Field IrisQL Field Name
Contact Name CONTACT_NAME
Contact Street CONTACT_STREET
Contact Phone CONTACT_PHONE

Email:

Advanced Search Field IrisQL Field Name
Email EMAIL
Email Domain EMAIL_DOMAIN
Email DNS/SOA EMAIL_DNS_SOA

Email (by contact type):

Contact-specific email fields target particular contact roles in registration data.

Advanced Search Field IrisQL Field Name
Admin Contact Email ADMIN_CONTACT_EMAIL
Billing Contact Email BILLING_CONTACT_EMAIL
Registrant Contact Email REGISTRANT_CONTACT_EMAIL
Technical Contact Email TECHNICAL_CONTACT_EMAIL
WHOIS Email MISC_EMAIL

Infrastructure:

Advanced Search Field IrisQL Field Name Notes
IP IP
IP ASN ASN
IP Country Code IP_COUNTRY_CODE
IP ISP ISP_NAME Requires EXACTLY_MATCH for exact value matching
Server Type SERVER_TYPE
Name Server NAMESERVER_HOST Fully-qualified hostname
Name Server Domain NAMESERVER_DOMAIN Registered domain portion only
Name Server IP NAMESERVER_IP
Mail Server MAILSERVER_HOST Fully-qualified hostname
Mail Server Domain MAILSERVER_DOMAIN Registered domain portion only
Mail Server IP MAILSERVER_IP

SSL/TLS certificates:

Advanced Search Field IrisQL Field Name Notes
SSL Hash SSL_HASH SHA-1 hash
SSL Email SSL_EMAIL
SSL Subject / SSL Subject Common Name SSL_SUBJECT
SSL Organization / SSL Subject Organization Name SSL_ORG Requires EXACTLY_MATCH for exact value matching
SSL Issuer Common Name SSL_ISSUER_COMMON_NAME
SSL Alt Names SSL_ALT_NAMES
SSL Duration SSL_DURATION Values must be strings
SSL Not After SSL_NOT_AFTER
SSL Not Before SSL_NOT_BEFORE

Web content:

Advanced Search Field IrisQL Field Name
Website Title WEBSITE_TITLE
Redirect Domain REDIRECT_DOMAIN

Web analytics and tracking: {#web-analytics-and-tracking}

All tracker fields use the EXISTS true or EXISTS false pattern to check for presence or absence of tracking codes, or MATCHES "" to search for specific tracking code values.

Advanced Search Field IrisQL Field Name
Facebook (Meta Pixel) FACEBOOK
Google Analytics GOOGLE_ANALYTICS
Google Analytics 4 GA4
Adsense ADSENSE
Google Tag Manager GOOGLE_TAG_MANAGER
Hotjar HOTJAR
Matomo MATOMO
Baidu Analytics BAIDU_ANALYTICS
Yandex Metrica YANDEX_METRICA
Statcounter Project STATCOUNTER_PROJECT
Statcounter Security STATCOUNTER_SECURITY

Metadata:

Advanced Search Field IrisQL Field Name Notes
Tags TAGS Requires array syntax with CONTAINS: TAGS CONTAINS ["value"]

Historical search:

Advanced Search Field IrisQL Field Name Notes
Email (Historical) HISTORICAL_EMAIL
Registrant (Historical) HISTORICAL_REGISTRANT Only supports MATCHES
Free Text (Historical) / WHOIS (Historical) HISTORICAL_FREE_TEXT Searches historical WHOIS records

Operators

Advanced Search Operator IrisQL Operator Example
Begins With BEGINS_WITH DOMAIN BEGINS_WITH "test"
Ends With ENDS_WITH DOMAIN ENDS_WITH ".com"
Contains CONTAINS DOMAIN CONTAINS "test"
Contains All CONTAINS_ALL REGISTRANT CONTAINS_ALL "John Smith"
Doesn't Contain DOES_NOT_CONTAIN REGISTRANT DOES_NOT_CONTAIN "privacy"
Doesn't Contain All DOES_NOT_CONTAIN_ALL REGISTRANT DOES_NOT_CONTAIN_ALL "privacy protection"
Matches MATCHES DOMAIN MATCHES "example.com"
Doesn't Match DOES_NOT_MATCH DOMAIN DOES_NOT_MATCH "test"
In IN TLD IN ["com","net","org"]
Not In NOT_IN TLD NOT_IN ["xyz", "top"]
Exactly In EXACTLY_IN DOMAIN EXACTLY_IN ["example.com", "test.com"]
Not Exactly In NOT_EXACTLY_IN DOMAIN NOT_EXACTLY_IN ["spam.com", "malware.com"]
Exists EXISTS EMAIL EXISTS true - See Searching by field presence
Greater Than GREATER_THAN RISK_SCORE GREATER_THAN 70
Greater Than or Equal To GREATER_THAN_OR_EQUAL RISK_SCORE GREATER_THAN_OR_EQUAL 70
Less Than LESS_THAN or LOWER_THAN RISK_SCORE LESS_THAN 30
Less Than or Equal To LESS_THAN_OR_EQUAL_TO or LOWER_THAN_OR_EQUAL RISK_SCORE LESS_THAN_OR_EQUAL_TO 50
Within WITHIN FIRST_SEEN WITHIN "The last 7 months"

IrisQL operators correspond to match operations in Advanced Search. See Match operations in Advanced Search for details.

Searching by field presence vs. specific values

Some searches need to find records where a field has any value (presence), rather than matching a specific value. IrisQL provides two methods depending on the field type.

Using the EXISTS operator:

The EXISTS operator always requires a boolean value (true or false):

  • EXISTS true - Finds records where the field has any value
  • EXISTS false - Finds records where the field has no value
EMAIL EXISTS true               # Finds records with any email address
EMAIL EXISTS false              # Finds records without an email address
SSL_HASH EXISTS true            # Finds records with any SSL certificate
FACEBOOK EXISTS true            # Finds records with Facebook tracking
GOOGLE_ANALYTICS EXISTS false   # Finds records without Google Analytics

See the Web analytics and tracking section for the complete list of tracker fields.

Logical operators

Use logical operators to combine multiple search conditions.

AND operator (logical AND):

The AND operator combines multiple conditions. All conditions must be true for a domain to match. Each condition appears on its own line, with AND on a separate line between them:

DOMAIN MATCHES "example.com"
AND
RISK_SCORE GREATER_THAN 70
AND
TLD MATCHES "com"

OR operator (logical OR):

Use the logical OR operation in two ways:

Multi-line OR pattern:

When you write multiple conditions for the same field without AND between them, they work as OR logic. This pattern is useful when you need different operators or want to combine OR conditions with other AND conditions:

# IrisQL-1.0
DOMAIN CONTAINS "bank"
DOMAIN CONTAINS "finance"
AND
CREATE_DATE WITHIN "The last 1 month"

This query finds domains that contain "bank" OR "finance", AND were created in the last month.

IN operator for OR logic:

For cleaner syntax when matching multiple specific values with the same operator, use the IN operator with array syntax:

# Instead of multiple lines:
# DOMAIN MATCHES "example.com"
# DOMAIN MATCHES "test.com"
# Use:
DOMAIN IN ["example.com", "test.com"]

When to use each approach:

  • Multi-line pattern: When you need different operators (e.g., CONTAINS and BEGINS_WITH) or complex OR conditions
  • IN operator: When matching multiple specific values with the same matching logic

Registration data sources

By default, IrisQL searches use registration data, which automatically selects the most appropriate RDAP or WHOIS record. You can also search specifically against RDAP or WHOIS data using prefix syntax.

RDAP-specific search:

# IrisQL-1.0
parsed_domain_rdap:ADMIN_CONTACT_EMAIL MATCHES "admin@example.com"

WHOIS-specific search:

# IrisQL-1.0
parsed_whois:REGISTRANT MATCHES "John Smith"

Default behavior (registration data):

# IrisQL-1.0
EMAIL MATCHES "admin@example.com"

For more information about RDAP (Registration Data Access Protocol) and WHOIS data, see RDAP and WHOIS data in search in the Iris Investigate User Guide.

Historical search syntax

IrisQL uses the HISTORICAL_ prefix to access historical data:

  • HISTORICAL_EMAIL - Search historical email addresses
  • HISTORICAL_REGISTRANT - Search historical registrant names (supports MATCHES operator only, not CONTAINS)
  • HISTORICAL_FREE_TEXT - Search historical free text

Example:

# IrisQL-1.0
HISTORICAL_EMAIL MATCHES "admin@example.com"
AND
RISK_SCORE GREATER_THAN 70

Certain fields support historical search. See Historical search settings in the Iris Investigate User Guide for details.

Data types

IrisQL supports several data types for query values. Understanding these types helps you write correct queries.

JSON format requirement

All IrisQL values must be valid JSON primitives. This means strings must use double quotes (not single quotes), numbers must be valid JSON numbers, and arrays must use proper JSON array syntax with square brackets.

Strings:

Text values always use double quotes:

DOMAIN MATCHES "domaintools.com"
EMAIL MATCHES "admin@example.com"
REGISTRANT CONTAINS "John Smith"

To include a double quote character in a string, escape it with a backslash:

REGISTRANT CONTAINS "\"quoted text\""

Numbers:

Numeric values don't use quotes:

RISK_SCORE GREATER_THAN 90

Booleans:

Boolean values (true or false) don't use quotes:

ACTIVE MATCHES true

For web analytics/tracker fields, see the Web analytics and tracking section for the EXISTS true/false pattern.

Dates and times:

Relative dates:

Use the WITHIN operator with the pattern: "The last {N} {unit}"

Supported time units: day, week, month, year (singular or plural)

FIRST_SEEN WITHIN "The last 7 months"
FIRST_SEEN WITHIN "The last 1 day"
CREATE_DATE WITHIN "The last 30 days"
EXPIRATION_DATE WITHIN "The last 1 year"

Absolute dates:

Use comparison operators with ISO 8601 date format (YYYY-MM-DD):

FIRST_SEEN GREATER_THAN "2024-01-01"
CREATE_DATE LESS_THAN "2025-01-01"
EXPIRATION_DATE GREATER_THAN_OR_EQUAL_TO "2026-01-01"

Note on timezones: The system interprets dates without times as midnight Coordinated Universal Time (UTC). The UI displays dates in your local timezone, which may show a different date. For example, "2024-01-01" (midnight UTC) displays as 2023-12-31 in US Eastern timezone (UTC-5).

IP addresses:

IP addresses are represented as quoted strings:

IP MATCHES "192.168.1.1"
IP GREATER_THAN "192.168.1.0"
IP LESS_THAN "192.168.2.0"

For Classless Inter-Domain Routing (CIDR) ranges, use the IN operator with array syntax:

IP IN ["192.168.1.0/24"]

Arrays:

Some operators and fields require array values. Arrays use square brackets with comma-separated values (JSON array format):

IN operator:

Always requires an array:

TLD IN ["com","net","org"]
DOMAIN IN ["example.com", "test.com"]

CONTAINS operator with TAGS field:

Requires an array:

TAGS CONTAINS ["malicious"]
TAGS CONTAINS ["malicious", "phishing"]

Array syntax rules:

  • Use square brackets: [...]
  • Quote string values: ["value1", "value2"]
  • Separate values with commas
  • No quotes around numbers in arrays (if applicable)

Rate limits

IrisQL requests are subject to the same rate limits as the Iris Investigate API. See Rate Limits for details.

See also