IrisQL 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.
Using IrisQL
Section titled “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
Section titled “Getting started”Endpoint
Section titled “Endpoint”POST https://api.domaintools.com/v1/iris-investigate/Authentication
Section titled “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
Section titled “Request format”Basic structure
Section titled “Basic structure”Send your IrisQL query as the request body:
curl -X POST 'https://api.domaintools.com/v1/iris-investigate/' \ -H "X-Api-Key: $DOMAINTOOLS_API_KEY" \ --data-binary @- << EOF# IrisQL-1.0DOMAIN CONTAINS "example"ANDRISK_SCORE GREATER_THAN 70EOFVersion comment
Section titled “Version comment”IrisQL queries must begin with the version comment:
This comment identifies the query as IrisQL and specifies the syntax version.
Query parameters
Section titled “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: $DOMAINTOOLS_API_KEY" \ --data-binary @- << EOF# IrisQL-1.0DOMAIN CONTAINS "spam"ANDRISK_SCORE GREATER_THAN 75ANDCREATE_DATE WITHIN "The last 30 days"EOFQuery parameters:
IrisQL supports standard query parameters for the Iris Investigate API. These parameters control pagination, sorting, formatting, and more. See the Iris Investigate API pagination guide for the complete list of available parameters.
Response format
Section titled “Response format”Response structure
Section titled “Response structure”IrisQL responses use the identical structure as the Iris Investigate API. See the Query Limits and Pagination guide for details on response fields like limit_exceeded, has_more_results, and position:
{ "response": { "results": [ { "domain": "example.com", "domain_risk": { "risk_score": 85, "components": [] }, "create_date": { "value": "2020-01-15", "count": 42 }, ... } ], "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 documentation.
Examples
Section titled “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
Section titled “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: $DOMAINTOOLS_API_KEY" \ --data-binary @- << EOF# IrisQL-1.0DOMAIN CONTAINS "phishing"DOMAIN CONTAINS "malware"ANDRISK_SCORE GREATER_THAN 85EOFComplex query with multiple conditions
Section titled “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: $DOMAINTOOLS_API_KEY" \ --data-binary @- << EOF# IrisQL-1.0DOMAIN CONTAINS "bank"DOMAIN CONTAINS "finance"ANDCREATE_DATE WITHIN "The last 30 days"ANDTLD IN ["com", "net", "org"]ANDRISK_SCORE GREATER_THAN 75EOFQuery with sorting and pagination
Section titled “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: $DOMAINTOOLS_API_KEY" \ --data-binary @- << EOF# IrisQL-1.0DOMAIN CONTAINS "phishing"ANDRISK_SCORE GREATER_THAN 85EOFQuery with XML response format
Section titled “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: $DOMAINTOOLS_API_KEY" \ --data-binary @- << EOF# IrisQL-1.0DOMAIN MATCHES "example.com"EOFIrisQL syntax reference
Section titled “IrisQL syntax reference”Query structure
Section titled “Query structure”Each IrisQL query consists of:
- Version comment (required):
# IrisQL-1.0 - Field conditions: Field name, operator, and value
- Logical operators: AND to combine conditions
- 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.
- Separate a field name from its operator with a single space.
- Write each condition on a single line.
Field names and API parameters
Section titled “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 Iris Investigate search parameters.
Supported fields
Section titled “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 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
Section titled “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
Section titled “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" |
| Exactly Matches | EXACTLY_MATCH | ISP_NAME EXACTLY_MATCH "Cloudflare, Inc." |
| 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", "example.net"] |
| Not Exactly In | NOT_EXACTLY_IN | DOMAIN NOT_EXACTLY_IN ["example.net", "example.org"] |
| 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 | RISK_SCORE LESS_THAN 30 |
| Less Than or Equal To | LESS_THAN_OR_EQUAL_TO | RISK_SCORE LESS_THAN_OR_EQUAL_TO 50 |
| Within | WITHIN | FIRST_SEEN WITHIN "The last 7 months" |
Not every field accepts every operator. Host-based fields such as NAMESERVER_HOST, NAMESERVER_DOMAIN, MAILSERVER_HOST, and MAILSERVER_DOMAIN support only a limited set (for example, NAMESERVER_HOST accepts MATCHES, DOES_NOT_MATCH, and EXISTS, but not CONTAINS). Using an unsupported operator returns a 400 error. For the accepted operators per field, see the Iris Investigate search reference.
Match a name server or mail server by its fully-qualified hostname (NAMESERVER_HOST, MAILSERVER_HOST) or by its registered domain portion (NAMESERVER_DOMAIN, MAILSERVER_DOMAIN):
NAMESERVER_HOST MATCHES "ns1.example.com"ANDMAILSERVER_DOMAIN MATCHES "example.com"MAILSERVER_DOMAIN and NAMESERVER_DOMAIN also accept BEGINS_WITH. To exclude a provider, use DOES_NOT_MATCH; to find domains that have any name server, use NAMESERVER_HOST EXISTS true.
IrisQL operators correspond to match operations in Advanced Search. See Match operations in Advanced Search for details.
Searching by field presence vs. specific values
Section titled “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 valueEXISTS false- Finds records where the field has no value
EMAIL EXISTS true # Finds records with any email addressEMAIL EXISTS false # Finds records without an email addressSSL_HASH EXISTS true # Finds records with any SSL certificateFACEBOOK EXISTS true # Finds records with Facebook trackingGOOGLE_ANALYTICS EXISTS false # Finds records without Google AnalyticsSee the Web analytics and tracking section for the complete list of tracker fields.
Logical operators
Section titled “Logical operators”Use logical operators to combine multiple search conditions. Write exactly one condition, or the AND keyword, per line. Combining more than one on the same line returns a 400 error.
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"ANDRISK_SCORE GREATER_THAN 70ANDTLD MATCHES "com"Putting AND on the same line as a condition (for example, DOMAIN MATCHES "example.com" AND RISK_SCORE GREATER_THAN 70) returns a 400 error.
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:
DOMAIN CONTAINS "bank"DOMAIN CONTAINS "finance"ANDCREATE_DATE WITHIN "The last 1 month"This query finds domains that contain “bank” OR “finance”, AND were created in the last month. Putting both OR conditions on the same line (for example, DOMAIN CONTAINS "bank" DOMAIN CONTAINS "finance") returns a 400 error — each condition still needs its own line.
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 "example.net"# Use:DOMAIN IN ["example.com", "example.net"]When to use each approach:
- Multi-line pattern: When you need different operators (e.g.,
CONTAINSandBEGINS_WITH) or complex OR conditions - IN operator: When matching multiple specific values with the same matching logic
Registration data sources
Section titled “Registration data sources”By default, IrisQL searches use registration data, which is populated from a single per-domain source (WHOIS or RDAP) selected by collection recency and field count. You can also search specifically against RDAP or WHOIS data using prefix syntax.
RDAP-specific search:
parsed_domain_rdap:ADMIN_CONTACT_EMAIL MATCHES "admin@example.com"WHOIS-specific search:
parsed_whois:REGISTRANT MATCHES "John Smith"Default behavior (registration data):
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
Section titled “Historical search syntax”IrisQL uses the HISTORICAL_ prefix to access historical data:
HISTORICAL_EMAIL- Search historical email addressesHISTORICAL_REGISTRANT- Search historical registrant names (supportsMATCHESoperator only, notCONTAINS)HISTORICAL_FREE_TEXT- Search historical free text
Example:
HISTORICAL_EMAIL MATCHES "admin@example.com"ANDRISK_SCORE GREATER_THAN 70Certain fields support historical search. See Historical search settings in the Iris Investigate User Guide for details.
Data types
Section titled “Data types”IrisQL supports several data types for query values. Understanding these types helps you write correct queries.
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 90Booleans:
Boolean values (true or false) don’t use quotes:
ACTIVE MATCHES trueFor 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 "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
Section titled “Rate limits”IrisQL requests are subject to the same rate limits as the Iris Investigate API. See Rate Limits for details.