Overview
Structured filters are the shared language for searches that need more than simple exact-match query parameters. They power breach search, stealer search, victim search, investigation fanout, AI-generated filters, and savedquery_config values for exports, bulk search, and scanners.
Use this guide to understand what filter, filter_id, operators, merge order,
and validation errors mean. Use the OpenAPI reference when you need the exact
request schema for one API operation.
Start Here
Use the simplest option that fits your case:- If you only need simple exact filters like email, domain, country, or db name, use normal query params.
- If you need
or,in,not_in,contains,starts_with,ends_with,wildcard, range filters, orexists, use a structuredfilter. - If you want to type plain English like “US gmail users older than 18”, use the AI filter endpoint and then search with
filter_id. - If you are saving a search for scanners, bulk search, or exports, use
query_config.
- keep simple exact rules as normal flat params
- switch to a structured
filterwhen flat params are no longer enough - keep
filter_idonly when there is no real filter to send yet
1. Simple Search: Use Normal Query Params
This is the easiest option. Use it when every condition is a simple exact match.- breach:
email[],email_domain[],username[],name[],full_name[],first_name[],last_name[],country[],city[],state[],postal_code[],address[],dbname[],phone[],ip[],discord[],discord_id[],social[],financial[],gaming[],iban[],ssn[],date_birth_from,date_birth_to - stealer credentials:
domain[],subdomain[],path[],username[],password[],email[],email_domain[],ip[],hwid[],discord_id[],log_id,has_log_id,source_type[],password_hash[],archive_hash[],canonical_credential_id[] - victims:
username[],email[],email_domain[],ip[],hwid[],discord_id[],country[],city[],os[],service[],steam_id[],steam_name[],phone[],domain[],subdomain[],identity_state[],victim_ip[],antivirus[],infection_path[],total_docs_min,total_docs_max,service_count_min,service_count_max,view=enriched - investigation evidence:
property_type,service,identity_kind,account_id,username,display_name,value,domain,active,source_type,confidence,confidence_min,include_cookie_evidence,exclude_cookie_evidence - investigation files:
name,folder,kind,ext,size_min,size_max
2. Complex Search: Use filter
Use a structured filter when normal query params are not enough.
Good examples:
country is US OR CAemail ends with @gmail.comage is at least 18instagram exists(country is US AND dbname is linkedin.com) OR password contains hunter
filter in two ways.
Option A: GET with filter in the query string
Pass filter as a JSON-encoded string:
Option B: POST to the same search route with a JSON body
Use this form for complex filters. The response shape is the same asGET /search.
filterfilter_id
page_size, cursor, sort, from, to, and date_field can stay in the query string.
Investigation Section Filters
Investigation search accepts section-specific filters so one request can return a combined investigation workspace.links in the response to explain why records from different sections are related.
3. Natural Language: Use AI Filter Then Search
Step 1: Ask the AI filter endpoint to build the filter
Step 2: Search with the returned filter_id
Step 3: Optional: edit the filter and send your own filter
If you want to change the AI result before searching, send a real filter instead of relying only on the stored context.
4. Saved Jobs: Use query_config
query_config is the JSON version of a search. It is used by:
- scanners
- bulk search
- exports
extra_params, which are flattened into the eventual request when supported.
Simple query_config
For JSON
query_config objects, prefer canonical keys such as domain, email_domain, and dbname. Bracketed variants such as domain[] are still accepted for parity with query-string filters.Complex query_config
When the logic is too complex for simple flat keys, put a real structured filter inside query_config.filter.
Filter Grammar
Every filter is built from just three shapes:- a leaf rule with
field - an
andgroup - an
orgroup
Leaf node
AND group
OR group
Nested example
Merge Order
Requests support this merge order:filter_idloads a stored transient filter context when it still exists.- An explicit
filterreplaces that stored filter. - Flat filters such as
email[],domain[],dbname[], orlog_idare merged on top. - Pagination and sort settings such as
cursor,page_size,fields[],from,to, andsortstill apply normally.
- start from a saved or AI-generated
filter_id - send your own
filterif you want to take control - still add normal query params if needed
Operator Guide In Plain Language
Quick examples
Common Cases
Pattern searches
contains,ends_with, andwildcardrequire at least2non-wildcard characters- patterns like
"*","*a*", or"?"are rejected with400 starts_withuses prefix semantics
Exists / missing checks
Numeric and date ranges
Use string values that match the public field format:- numeric-style fields such as
ageshould use numeric strings like"18" - date-style fields such as
date_birthshould use ISO-style dates like"1990-01-01" - datetime fields such as
indexed_atshould use RFC3339 timestamps like"2026-04-18T00:00:00Z"
in and not_in
Use arrays when you already know multiple values:
Domain-only email filters
When you already know the mail domain, prefer the dedicated public field:Step-By-Step Examples
Example: exact filters only
Example: one structured rule
Example: AND two rules together
Example: OR two rules together
Example: nested logic
Example: send the filter with POST
Example: filter_id plus your own exact params
This is valid:
Example: filter_id plus a replacement filter
This is also valid:
Choosing Fields
Field availability is endpoint-specific. A field accepted by breach search is not automatically valid for stealer or victims.- breach search commonly uses fields such as
email,email_domain,username,country,city,dbname,date_birth, andage - stealer search commonly uses fields such as
domain,subdomain,path,username,password,email,ip,hwid,discord_id, andlog_id - victims search commonly uses fields such as
username,email,ip,hwid,discord_id,log_id, andtotal_docs
Scanners, Exports, And Bulk Search
query_config reuses the same filter system, with a few extra rules:
filtercan be a JSON object or a JSON string- flat filters can be sent with canonical JSON keys such as
domain,email_domain, ordbname - bracketed keys such as
domain[]are also accepted - scanners reject runtime-only keys such as
from,to,cursor,page_size,format,debug, andsearch_id - scanners always monitor on
indexed_at - exports and bulk search allow
from,to,date_field, andsortbecause those jobs serialize full searches
- start flat when the saved search is simple
- switch to
query_config.filterwhen the saved search becomes complex
Limits
filter_idmust be a 24-character hex string- maximum nesting depth is
2 - maximum leaf conditions is
50 valueis required for every operator exceptexistsinandnot_inrequire arrays
Common 400 Errors
Typical structured-filter validation failures include:- malformed JSON in
filter - a node that mixes
fieldwithandoror - invalid operator names
- disallowed fields for the selected endpoint
contains,ends_with, orwildcardpatterns that are too short- using pattern operators on date or IP fields
- nesting deeper than two levels
- more than fifty leaf rules
Recommended Client Pattern
Use three practical rules when building an API client:- If a filter can be represented as normal exact-match params, keep it simple and send flat params.
- If the filter needs nested logic or advanced operators, send a real structured
filter. - If both
filter_idand a real filter are available for a saved config, prefer the real filter as the canonical version.
Related Guides
Breach Search
Search breach data with structured filters
Stealer Search
Search stealer records with flat or structured filters
Victim Workflows
Search victim summaries using the same filter grammar
API Reference
Use OpenAPI for exact filter request fields and playground examples