Usage Examples
Basic Usage
urx example.com
urx example.com example.org
cat domains.txt | urx
# domain list files; repeatable, merged with domains on the command line
urx --domain-list domains.txt
urx --dL program-a.txt --dL program-b.txt
# only URLs under /shop
urx example.com/shop
File Input
# text, WARC or compressed files; space-separated or repeated
urx --files urls.txt archive.warc data.gz
urx --files urls.txt --files archive.warc
# with filters
urx --files data.txt --patterns api,admin -f json
Output Formats
urx example.com -o results.txt
urx example.com -f json -o results.json
urx example.com -f csv -o results.csv
# one JSON object per line
urx example.com -f jsonl | jq -r '.url'
One File per Host
# out/example.com.json, out/example.org.json, ... plus the combined all.json
urx example.com example.org -f json --output-dir out/ -o all.json
Each host gets its own file, so www.example.com and every subdomain (under
--subs) are split out. Output that is not URLs (--show-only-host,
--show-only-path, --show-only-param, --params) goes to _unknown.<ext>.
Streaming Output
# write URLs as each provider reports them
urx example.com --stream | httpx -silent
--stream output is unsorted, skips the cache, and supports plain, jsonl
and csv only. It rejects options that need the full result set:
--incremental, --check-status / --include-status / --exclude-status /
--check-title, the extractors, --archive-body, --expand-specs,
--merge-endpoint, --dedup-similar, --show-sources, --show-meta,
--output-dir, the parameter views, the --meta-* filters and --files.
Provenance and Run Statistics
# providers that returned each URL
urx example.com --show-sources
# archive capture metadata in plain text
urx example.com --providers wayback --show-meta
# per-provider counts, errors and timings on stderr
urx example.com --stats
A repeat run served from the cache has no sources or archive metadata, and
--stats prints nothing. If the target was scanned within --cache-ttl, add
--no-cache here and to the --meta-* and --archive-body examples below.
Wordlist
# path segments and parameter names, deduplicated and sorted
# (segments that look like ids, hashes or dates are left out)
urx example.com --subs -f wordlist -o words.txt
ffuf -w words.txt -u https://example.com/FUZZ
Parameter Inventory
# every query parameter name, once each
urx example.com --params
# grouped by endpoint
urx example.com --params-by-endpoint
# one URL per parameter signature, values replaced
urx example.com --fuzz-placeholder FUZZ | ffuf -w - -u FUZZ
Filtering Examples
Extensions and Patterns
urx example.com -e js,php,aspx
urx example.com --exclude-extensions html,txt
urx example.com --patterns api,v1,graphql
urx example.com --exclude-patterns static,images
urx example.com --patterns api --exclude-patterns test,dev
# URL length
urx example.com --min-length 50 --max-length 200
Using Presets
urx example.com -p no-images
urx example.com -p no-resources
urx example.com -p only-js
Scope Files
# scope.txt
# *.example.com
# !admin.example.com
urx example.com --subs --scope-file scope.txt
# several files are unioned; exclusions always win
urx --domain-list targets.txt --subs --scope-file scope-a.txt --scope-file scope-b.txt
Archive Metadata Filtering
Runs after collection, on the metadata the archives recorded:
# still captured since 2024, no HTML or images
urx example.com --providers wayback --meta-last-seen-after 2024 --meta-exclude-mime 'text/html,image/*'
# nothing captured since 2019
urx example.com --providers wayback --meta-last-seen-before 2019
# JSON the archive got with a 200
urx example.com --providers wayback --meta-mime application/json --meta-status 200
# last captured during 2020 (Wayback reports only its newest capture, so
# first_seen there is the same date)
urx example.com --providers wayback --meta-last-seen-after 2020 --meta-last-seen-before 2020
Regular Expressions
# keep versioned API paths (case-insensitive); repeat the flag to OR patterns
urx example.com --match-regex '(?i)/api/v[0-9]+/'
# drop static asset directories
urx example.com --filter-regex '/(assets|static)/'
Collapsing Near-Duplicates
# /post/1, /post/2 and /post/99999 become one line
urx example.com --dedup-similar
Archive-Side Filters
Applied by the CDX index itself (wayback, cc, arquivo, --cdx-endpoint), so
less is fetched:
# captures from 2023 on, recorded as 200
urx example.com --from 2023 --archive-status 200
# served as JSON, even without a .json extension
urx example.com --archive-mime application/json
# skip error pages and HTML
urx example.com --archive-exclude-status 404,500 --archive-exclude-mime text/html
Provider Selection
urx example.com --providers wayback,otx
# all keyless sources (urlscan works without a key)
urx example.com --providers wayback,cc,otx,arquivo,urlscan
# every provider; vt, zoomeye, github and bevigil error without a key
urx example.com --providers wayback,cc,otx,arquivo,vt,urlscan,zoomeye,github,bevigil
# same, but keyed providers run only when a key is set
urx example.com --all-providers
# everything except OTX
urx example.com --all-providers --exclude-providers otx
# any other CDX server (here the Icelandic web archive), id cdx:vefsafn.is
urx example.is --cdx-endpoint https://vefsafn.is/cdx --rate-limit-by cdx:vefsafn.is=1
# two Common Crawl indexes in parallel
urx example.com --providers cc --cc-index CC-MAIN-2026-17,CC-MAIN-2025-51
# list providers and which need a key
urx --list-providers
--providers also runs the live robots.txt / sitemap.xml probes, and any keyed
provider whose URX_*_API_KEY is set. Drop them with --exclude-robots,
--exclude-sitemap or --exclude-providers.
Using a Config File
# profile plus a separate file holding only the API keys
urx -c ~/.config/urx/bugbounty.toml --provider-config ~/.config/urx/keys.toml example.com
See Configuration for every key.
With API Keys
urx example.com --vt-api-key=YOUR_KEY --urlscan-api-key=YOUR_KEY
urx example.com --zoomeye-api-key=YOUR_KEY --providers zoomeye
# or via environment; a set key also enables its provider
export URX_VT_API_KEY=YOUR_KEY
export URX_URLSCAN_API_KEY=YOUR_KEY
export URX_ZOOMEYE_API_KEY=YOUR_KEY
export URX_GITHUB_API_KEY=YOUR_TOKEN
export URX_BEVIGIL_API_KEY=YOUR_KEY
urx example.com --providers=vt,urlscan,zoomeye,github,bevigil
# key rotation: repeat the flag, or comma-separate the env var
urx example.com --vt-api-key=key1 --vt-api-key=key2 --vt-api-key=key3
URX_VT_API_KEY=key1,key2,key3 urx example.com
Discovery Options
# skip robots.txt and/or sitemap.xml
urx example.com --exclude-robots --exclude-sitemap
# also read every archived version of robots.txt and sitemap.xml
urx example.com --archived-discovery
# see which URLs came from an old version
urx example.com --archived-discovery --show-sources
# robots.txt only, versions captured 2014 to 2016
urx example.com --archived-discovery --from 2014 --to 2016 --exclude-sitemap
# at most 10 documents per domain, newest first (default 50)
urx example.com --archived-discovery --archived-discovery-limit 10
Testing & Validation
# include subdomains
urx example.com --subs
# check HTTP status
urx example.com --check-status
Extract Links
urx example.com --extract-links
Re-fetches each surviving URL and reads every URL-bearing tag: <a href>,
<script src>, <link href>, <form action>, <iframe src>, <img src>,
<source src>, <object data>, <embed src> and <meta http-equiv="refresh">.
Relative URLs resolve against the page (and <base href>), and duplicates are
collapsed.
Filters and host validation run twice: on the collected URLs before any page is
fetched, and on the discovered links. So -e js would drop the HTML pages before they are read.
Filter the output instead:
# JS URLs, collected or referenced by the pages
urx example.com --extract-links | grep -E '\.js(\?|$)'
Extract Endpoints from JavaScript
urx example.com --extract-js-endpoints
# cap the scripts fetched (default 500)
urx example.com --extract-js-endpoints --max-js-files 100
# scripts found by --extract-links are not mined in the same run; chain two runs
urx example.com --extract-links | grep -E '\.js(\?|$)' > bundles.txt
urx --files bundles.txt --extract-js-endpoints --max-js-files 100
# API-looking paths (--patterns would drop the bundles before they are read)
urx example.com --extract-js-endpoints | grep -E 'api|graphql'
Fetches each collected URL that looks like a script and pulls paths and URLs
from its string literals: fetch("/api/v2/users"), axios.post("/graphql"),
the static prefix of `/api/orders/${id}`, chunk imports. Noise (MIME
types, module specifiers, base64, CSS values, regex fragments) is dropped; see
the CLI options guide for
the full policy. Bodies are capped at 10 MiB.
- Discovered endpoints pass through your filters and host validation, so leave
-e jsoff or only the.jsfiles survive. - Discovered endpoints are not status-checked;
--check-statuscovers the collected URLs only.
Mine Archived Bodies
# extract links from the bodies the Wayback Machine stored
urx example.com --archive-body
# fewer bodies (default 500), paced
urx example.com --archive-body --archive-body-limit 200 --rate-limit 5
# JS URLs, collected or referenced by the archived pages
urx example.com --archive-body --no-cache | grep -E '\.js(\?|$)'
Works for pages that no longer exist. URLs whose captures share a content
digest are fetched once, and --archive-body-limit counts distinct bodies.
Expand API Specifications
# expand every route in the collected OpenAPI, Swagger and GraphQL documents
urx example.com --expand-specs
# fewer documents (default 50), paced
urx example.com --expand-specs --max-spec-files 10 --rate-limit 2
# use the archived copy when the live host no longer serves it
urx example.com --archive-body --expand-specs
JSON and YAML are both read. Filters and presets also apply to the expanded
routes, so --preset only-api would drop /users or /orders/{id}. No preset
is needed to find the documents.
Record Response Titles
# --check-title implies --check-status; --show-meta prints the response-head fields
urx example.com --check-title --show-meta
# response-head fields as JSON Lines
urx example.com --check-status -f jsonl | jq -r '[.url, .status, .content_type] | @tsv'
Status Filtering
urx example.com --check-status --include-status 200
urx example.com --check-status --include-status 200,30x
urx example.com --check-status --exclude-status 404,50x
With both set, --include-status decides and --exclude-status is ignored. A
URL whose check failed outright (refused, timed out) prints as
[Status check failed] unless --include-status is set.
Network Configuration
urx example.com --proxy http://localhost:8080
urx example.com --proxy http://localhost:8080 --proxy-auth username:password
urx example.com --timeout 60 --parallel 10 --retries 5
urx example.com --insecure
urx example.com --random-agent
Authenticated and Custom Requests
Headers go only to the target (status checks, extractors, robots/sitemap), never to the archives:
urx example.com --check-status \
-H "Authorization: Bearer $TOKEN" \
--cookie "session=abc" \
--user-agent "acme-security-scan/1.0"
Rate Limits and Time Budget
# 10 req/s per provider, 1 req/s for VirusTotal, stop collecting after 10 minutes
urx example.com --rate-limit 10 --rate-limit-by vt=1 --max-time 600
URL Normalization
urx example.com --normalize-url
urx example.com --normalize-url --merge-endpoint
# only hosts, paths or query strings
urx example.com --subs --show-only-host
urx example.com --show-only-path
urx example.com --show-only-param
# keep URLs on any host a provider returned (a path-scoped target still applies)
urx example.com --no-strict
Caching & Incremental Scanning
# SQLite (default)
urx example.com --cache-type sqlite --cache-path ~/.urx/cache.db
# Redis; needs a build with: cargo install urx --features redis-cache
urx example.com --cache-type redis --redis-url redis://localhost:6379
# TTL of 12 hours (default 24)
urx example.com --cache-ttl 43200
# no cache
urx example.com --no-cache
Incremental Mode
# only URLs not seen before
urx example.com --incremental
# post to Slack only when something new turned up
urx example.com --incremental --silent --notify "$SLACK_HOOK" --notify-format slack
Inspect and Prune the Cache
urx cache stats
urx cache list --domain '*.example.com'
# rescan one target from scratch
urx cache drop example.com
urx cache prune
urx cache clear --yes
Pipeline Integration
echo "example.com" | urx | grep "login" > targets.txt
urx example.com | httpx -silent
urx example.com | gf xss
urx example.com -e js | nuclei -t xss
More in Integration.
Complex Scenarios
Complete Bug Bounty Workflow
urx target.com \
--subs \
-e js,json,xml \
--patterns api,v1,v2,admin,panel \
--exclude-patterns cdn,static \
--check-status \
--include-status 200,30x \
--incremental \
--parallel 15 \
-o results.txt
API Endpoint Discovery
urx example.com \
--patterns api,graphql,rest,v1,v2,v3 \
-e json,xml \
--exclude-patterns test,staging \
-f json \
-o api-endpoints.json
API Surface from Specifications
urx target.com \
--subs \
--expand-specs \
--max-spec-files 25 \
--check-status \
--include-status 200 \
-f jsonl \
-o api-surface.jsonl
Expanded routes are not status-checked. --include-status 200 keeps only the
collected URLs (including the spec documents) that returned 200; every expanded
route is added unchecked, path templates like /orders/{id} included.
JavaScript Analysis Pipeline
urx target.com \
-p only-js \
--check-status \
--include-status 200 \
-f jsonl \
| jq -r .url \
| tee js-files.txt \
| nuclei -t exposures/