urx

Configuration

Set urx defaults in a TOML config file, and how those settings combine with command-line flags.

Configuration File

Urx supports loading settings from a TOML configuration file. This avoids repeating options on every command and lets you manage profiles for different scanning scenarios.

Loading a Config File

# Explicit path
urx -c /path/to/config.toml example.com

# Default location (auto-detected)
# ~/.config/urx/config.toml
urx example.com

Command-line flags always take precedence over config file values.

Full Configuration Reference

Below is a complete annotated configuration file. All sections and keys are optional.

# Targets are given on the command line, not here:
#   urx -c config.toml example.com

# ─── Output ──────────────────────────────────────────────
[output]
output = "results.txt"
format = "plain"           # plain, json, jsonl, csv, wordlist
merge_endpoint = false
dedup_similar = false      # Collapse URLs differing only in ids, hashes, dates, or query values
stream = false             # Write URLs as providers report them (unsorted, bypasses cache)

# ─── Providers ───────────────────────────────────────────
[provider]
providers = ["wayback", "cc", "otx"] # also available keyless: "arquivo", "urlscan" (anonymous)
subs = false                          # Include subdomains
cc_index = "CC-MAIN-2026-17"         # Common Crawl index (or "latest" to auto-resolve via collinfo.json)
cdx_endpoint = []                     # Extra CDX index servers, e.g. ["https://vefsafn.is/cdx"] (ids: cdx:<host>)
cdx_dialect = ""                      # "pywb" or "classic" for those servers; empty = probe once, pywb fallback
from = ""                             # Restrict CDX providers to captures >= this date (YYYY/YYYYMM/YYYYMMDD)
to = ""                               # Restrict CDX providers to captures <= this date
archive_status = []                   # Keep only captures the archive recorded with these status codes
archive_exclude_status = []           # Drop captures with these recorded status codes
archive_mime = []                     # Keep only captures with these recorded MIME types
archive_exclude_mime = []             # Drop captures with these recorded MIME types
vt_api_key = ""                       # VirusTotal API key
urlscan_api_key = ""                  # URLScan API key (optional; urlscan also works anonymously)
zoomeye_api_key = ""                  # ZoomEye API key
github_api_key = ""                   # GitHub Code Search personal access token
bevigil_api_key = ""                  # BeVigil API key (URLs from unpacked Android apps)
exclude_robots = false                # Skip robots.txt discovery
exclude_sitemap = false               # Skip sitemap.xml discovery
archived_discovery = false            # Also read archived robots.txt / sitemap versions
archived_discovery_limit = 50         # Documents fetched per domain by each archived provider

# ─── Filters ─────────────────────────────────────────────
[filter]
preset = ["no-resources", "no-images"]
extensions = ["js", "php", "aspx"]
exclude_extensions = ["html", "txt"]
patterns = ["admin", "api"]
exclude_patterns = ["logout", "static"]
match_regex = ["/api/v[0-9]+/"]   # Repeatable regexes, ORed, case-sensitive
filter_regex = ["/(assets|static)/"]
show_only_host = false
show_only_path = false
show_only_param = false
min_length = 10
max_length = 500
scope_file = ["scope.txt"]        # Bug-bounty scope files; repeatable, unioned, `!` excludes
meta_first_seen_after = ""        # Keep URLs first archived on or after this date (YYYY/YYYYMM/YYYYMMDD)
meta_first_seen_before = ""       # ...on or before
meta_last_seen_after = ""         # Keep URLs last archived on or after this date ("still alive as of")
meta_last_seen_before = ""        # ...on or before ("dead since")
meta_mime = []                    # Keep only these archived MIME types ("image/*" matches any subtype)
meta_exclude_mime = []            # Drop these archived MIME types
meta_status = []                  # Keep only these archived status codes ("20x" / "5xx" patterns)
meta_exclude_status = []          # Drop these archived status codes

# ─── Network ─────────────────────────────────────────────
[network]
network_scope = "all"                  # all, providers, testers, or providers,testers
proxy = "http://proxy.example.com:8080"
proxy_auth = "username:password"
insecure = false
random_agent = true
timeout = 30
retries = 3
parallel = 5
rate_limit = 10

# ─── Testing ─────────────────────────────────────────────
[testing]
check_status = false
include_status = ["200", "30x"]
exclude_status = ["404", "50x"]
extract_links = false
extract_js_endpoints = false   # Mine collected JavaScript for endpoints
max_js_files = 500             # Cap on files --extract-js-endpoints fetches (0 = unlimited)
archive_body = false                   # Mine the archived bodies of collected URLs
archive_body_limit = 500               # Distinct bodies fetched per run (duplicates never count)
expand_specs = false                   # Expand collected OpenAPI/Swagger/GraphQL documents into routes
max_spec_files = 50                    # Cap on specification documents fetched (0 = unlimited)

# ─── Cache ────────────────────────────────────────────────
[cache]
incremental = false
cache_type = "sqlite"                  # sqlite or redis
cache_path = "~/.urx/cache.db"
redis_url = "redis://localhost:6379"
cache_ttl = 86400                      # 24 hours
no_cache = false

# ─── Notify ──────────────────────────────────────────────
[notify]
# url = "https://hooks.slack.com/services/..."   # or a list; the URL is a secret —
#                                                 # prefer URX_NOTIFY_URL or the
#                                                 # provider-config file's notify_url
on = "new"                             # new, always, or never
format = "json"                        # json, slack, or discord

Minimal Config Examples

Bug bounty profile:

[provider]
providers = ["wayback", "cc", "otx", "vt"]
vt_api_key = "YOUR_KEY"
subs = true

[filter]
preset = ["no-resources"]
patterns = ["api", "admin", "login"]
scope_file = ["~/programs/example/scope.txt"]  # the program's own scope, verbatim

[cache]
incremental = true

API-focused discovery:

[provider]
providers = ["wayback", "cc", "otx", "vt", "urlscan", "zoomeye", "bevigil"]
vt_api_key = "YOUR_VT_KEY"
urlscan_api_key = "YOUR_URLSCAN_KEY"
zoomeye_api_key = "YOUR_ZOOMEYE_KEY"
bevigil_api_key = "YOUR_BEVIGIL_KEY"
subs = true

[filter]
patterns = ["api", "graphql", "rest", "v1", "v2"]
extensions = ["json", "xml"]

[testing]
expand_specs = true          # open the OpenAPI/Swagger/GraphQL documents this finds
max_spec_files = 25

[network]
parallel = 10
timeout = 60

Monitoring with Redis:

[provider]
providers = ["wayback", "cc", "otx"]

[cache]
incremental = true
cache_type = "redis"
redis_url = "redis://cache-server:6379"
cache_ttl = 43200

Run this with --silent on the command line — display flags such as --silent, --verbose, and --no-progress, along with host-validation flags (--strict / --no-strict), are CLI-only and have no config file equivalent. So are the output views (--params, --params-by-endpoint, --fuzz-placeholder) and --check-title: they change what a single run prints rather than how the tool is set up.

Config File Location

The default config file location is ~/.config/urx/config.toml. You can override this with the -c / --config flag.

Tips

  • Start with a minimal config and add sections as needed.
  • Use environment variables for sensitive API keys instead of storing them in the config file. See Environment Variables.
  • Create multiple config files for different scanning profiles and switch with -c.