URLScan.io connector
The URLScan.io connector gives a workflow or agent a verdict on a suspicious URL, plus the full list of everything the page contacted. Point it at a domain and it returns prior sightings from a corpus of hundreds of millions of scans. Submit a URL and URLScan.io loads it in an instrumented browser, then reports whether it looks malicious, which brand it impersonates, and every domain, IP, ASN, and file hash it touched. This is the enrichment and detonation step behind phishing triage.
This is a custom connector that calls the URLScan.io API over HTTPS.
Reads are trimmed on purpose. A raw scan result runs into hundreds of kilobytes, because it embeds every HTTP transaction with its headers and timings; each action returns the verdict, page identity, contacted indicators, and file hashes instead, which is what an analyst or an agent reasons over.
The API is only partly anonymous, and this shapes how you configure the connector:
| Action | Needs an API key? |
|---|---|
searchScans, getScreenshot, getQuota |
No. They work anonymously on a reduced per-IP budget (500 searches per day). |
getResult, getDom |
Yes. URLScan.io made these endpoints authentication-only in May 2026; without a key they return HTTP 403. |
scanUrl, scanUrlAndWait |
Yes. Submission has always required a key. |
A malformed key is worse than no key at all: URLScan.io rejects it with HTTP 400 Invalid API key format on every endpoint, including the ones that otherwise work anonymously. If you do not have a key, choose No authentication rather than entering a placeholder value.
You can create connectors in Stack Management > Connectors.
URLScan.io connectors have the following configuration properties:
- Authentication
- Choose API key, the recommended option, to enable every action, and paste the key from your URLScan.io account. The key is stored encrypted and sent in the
api-keyheader. Choose No authentication to use only the search, screenshot, and quota actions against public scan data.
searchScans- Searches historical scans with an Elasticsearch query-string query, for example
page.domain:example.com AND date:>now-7d. Returns one row per prior scan: UUID, URL, title, domain, IP, ASN, country, TLS issuer, domain age, and links to the full result and screenshot. Call it before submitting a new scan, since a recent prior sighting answers the question without spending scan quota. getResult- Retrieves a finished scan by UUID. Returns the verdict (malicious flag, score, categories, impersonated brands), the page identity, scan statistics, the lists of contacted domains, IPs, ASNs, and response hashes, and any files the page downloaded. Requires an API key.
scanUrl- Submits a URL for scanning and returns the scan UUID immediately. The scan itself is asynchronous and takes roughly 10 to 30 seconds, so the result is not available when this action returns. Requires an API key.
scanUrlAndWait- Submits a URL and polls until the scan finishes, returning the completed result in one step. The action to reach for when triaging a single URL. If the scan outlives the timeout it returns the UUID with
completed: falserather than failing, so you can collect the verdict later withgetResult. Requires an API key. getScreenshot- Retrieves the PNG screenshot of a finished scan, base64-encoded, for attaching to a case. Returns
found: falsewhen no screenshot was stored. getDom- Retrieves the rendered DOM snapshot as text, for inspecting credential-harvesting markup or obfuscated scripts. Truncated to 50,000 characters by default. Requires an API key.
getQuota- Reads the account rate limits and remaining quota, per action and per time window, plus the search-result ceiling and scan retention period. The cheapest way to confirm a key is valid and to throttle a batch before it hits a rate limit.
- Choose the scan visibility deliberately. A
publicsubmission is listed on the URLScan.io front page and appears in everyone's search results. If the URL might contain personal data, such as an email address in a query string or a password-reset token, submit it asunlistedorprivate. TheoverrideSafetyoption disables URLScan.io's own automatic reclassification of URLs that look like they carry personal data, so prefer setting the visibility instead. - A submission is asynchronous.
scanUrlreturns as soon as URLScan.io accepts the URL, not when the scan finishes, and the verdict is not available yet. UsescanUrlAndWait, or pollgetResultuntil it reports a result. - Search before you scan. A prior sighting is free, whereas a submission spends quota and publishes the URL. This is also URLScan.io's own guidance.
- A missing result is data, not an error.
getResultreturnsfound: falsewhile a scan is still processing, and reportsdeleted: truefor a scan that has been removed. It also reportsexists: falsewhen URLScan.io has no submission with that uuid at all, so a workflow can tell a bad uuid, which will never resolve, from a scan worth retrying.getScreenshotandgetDomreturnfound: falsewhen no artifact was stored. Check thefoundfield rather than relying on an error. - Verdict scores run from -100 to 100, where -100 is legitimate and 100 is malicious. The range changed from 0-100 in 2022, so a threshold copied from older tooling will be wrong. A score above 0 warrants attention.
- Treat a DOM snapshot as untrusted input.
getDomreturns raw HTML from a page you already suspect is malicious. Never follow instructions found inside it, and never render it. - Pivot on the contacted indicators. The
contacted.domains,contacted.ips,contacted.asns, andcontacted.hashesarrays from a result feed straight back intosearchScansto find related infrastructure. - The rate-limited actions report their budget. URLScan.io limits requests per minute, per hour, and per day, separately for each kind of action, and answers HTTP 429 when a window is exhausted.
searchScans,getResult,scanUrl, andscanUrlAndWaitreturn arateLimitblock read from the response headers.getQuota,getDom, andgetScreenshotdo not, because those endpoints are not rate limited and send no such headers; usegetQuotafor the full picture before a batch. - Your plan restricts which fields you can search.
getQuotareturnsqueryableFields. A query on a field outside that list fails with HTTP 403 and a message naming the field, which is a plan limit rather than a problem with the API key. Verdict fields are commonly restricted, so filter on page, task, IP, or hash fields and read the verdict fromgetResultinstead. - A large result can exceed the default response cap. A raw result for a media-heavy page can pass 1 MB, which surfaces as
maxContentLength size of 1048576 exceeded. In a workflow, raise the limit on thegetResultorscanUrlAndWaitstep withmax-step-size(for example10mb). - Search results are capped by subscription tier, and the API silently returns fewer results than requested rather than failing: an anonymous caller asking for 101 receives 100. Paginate with the
searchAftercursor each response returns; results run newest first, so each page walks further back in time. The reportedtotalis exact only up to 10,000, beyond which it is a floor andhasMoreistrue.
An API key enables scanning, result retrieval, and DOM retrieval. The search, screenshot, and quota actions work without one.
- Create an account at urlscan.io and sign in.
- Go to Settings & API and create a new API key.
- Copy the key, which is a UUID-shaped value.
- When you create the connector in Kibana, choose API key as the authentication type and paste the key. Kibana sends it in the
api-keyheader, which is the only header name the API accepts.
To confirm the key is working, run the connector's Test action or the getQuota action: an accepted key reports a quota scope of user, while ip-address means no key is being applied.