Skip to main content

Scanners

Scanners let you monitor for newly indexed stealer or breach results and receive notifications through email, Discord webhooks, or custom HTTP webhooks.

What Scanners Actually Monitor

Scanners are incremental monitors. They only look for data indexed after the current scanner baseline.
  • scanners run on an hourly schedule
  • the window is based on indexed_at, not pwned_at
  • historical data is not replayed when you create a scanner
  • material query changes reset the baseline and begin monitoring from the update time
Use the regular search endpoints when you need to investigate historical data.

Scanner Types

Query Config Rules

query_config is close to the live v2 search filters, but it is not a raw request replay.
  • allowed flat filters depend on scanner_type
  • filter and filter_id are supported
  • canonical JSON keys such as domain, email_domain, dbname, and username are preferred
  • bracketed variants such as domain[] are also accepted
  • runtime-only parameters are rejected because scanners manage them automatically:
    • from
    • to
    • cursor
    • page_size
    • format
    • debug
    • search_id
  • scanners always search with date_field=indexed_at
  • scanner configs must contain a durable search anchor, such as a concrete domain, email domain, dbname, username, password hash, log ID, or structured filter leaf
  • wildcard-only, filter_id-only, or extra_params-only configs are rejected because they are not stable enough for hourly monitoring
Simple rule:
  • if the scanner can be described with exact-match fields, keep query_config flat
  • if the scanner needs or, contains, exists, ranges, or nested groups, use query_config.filter
See Structured Filters for the shared filter grammar, step-by-step examples, and filter_id behavior.

Notifications

Webhook Security Modes

  • signed_json Default mode for new custom webhook scanners. OathNet signs the raw request body with the shared secret.
  • signed_encrypted Signed and encrypted delivery for custom webhook scanners. OathNet signs the encrypted body and includes key metadata in headers.
  • api_key Available only on existing scanners. New scanners should use signed delivery.
Webhook URLs are validated aggressively:
  • only http and https are allowed
  • IP addresses are rejected
  • localhost and private-network hostnames are rejected
  • Discord scanners must use a Discord webhook URL

Creating a Scanner

Create scanners with a normalized query_config and delivery target. The create request should describe what to monitor and where to send notifications; OathNet owns scheduling, baselines, and run windows. Required fields are name, scanner_type, query_config, and notification_type. webhook_url is also required for webhook and discord notifications.
Before saving a webhook or Discord scanner, validate delivery so bad URLs or rejected signatures do not create a monitor that immediately fails.

Delivery Payload

Webhook and Discord notifications include scanner and run metadata plus a sample of matching results. The exact results.sample shape depends on scanner_type.
Use the webhook-security read operation to inspect the configured verification method and delivery headers for a saved scanner. Common webhook headers include a delivery ID, timestamp, signature, security mode, key ID, and encryption metadata when signed_encrypted is enabled. Verify signatures against the exact raw request body before parsing JSON.

Verifying Webhook Signatures

For signed_json and signed_encrypted, never rebuild the JSON before verification. Read the exact raw HTTP body bytes, then verify the X-OathNet-Signature header with HMAC-SHA256. Signature inputs: The signed message is:
The expected header value is:

Python Receiver Example

Node.js Receiver Example

For signed_encrypted, first verify the signature against the raw encrypted envelope body. Then decrypt the JSON envelope with AES-256-GCM using HKDF-SHA256(secret, info="oathnet-scanner-encryption-v1"). The envelope contains alg, iv, ciphertext, and kid; ciphertext is base64 encoded and already includes the GCM tag.
Store the webhook secret immediately. rotate_webhook_secret returns the new secret once, and later security reads only show a preview. Reject old timestamps and store delivery_id values you have processed to prevent replay.

Management Operations

Scanner management is exposed through the public API, but the important product concepts are simple:
  • quota tells you how many scanners the account can still create
  • test delivery sends a sample notification without waiting for the schedule
  • manual trigger queues a real run for an active scanner
  • pause stops scheduling without deleting the scanner
  • resume restarts a paused or disabled scanner after the issue is fixed
  • run history shows recent execution and notification outcomes
  • run detail explains one specific run and its delivery attempts
Use the OpenAPI reference for the exact scanner paths, parameters, statuses, and playground requests.

Troubleshooting

No results found

  • scanners only look for newly indexed data after the current baseline
  • use regular search endpoints to inspect historical data
  • verify that query_config contains valid filters for the scanner type
  • verify that structured filters target allowed fields for that scanner type

Not receiving notifications

  • run a delivery test before waiting for the hourly schedule
  • check the saved webhook security configuration
  • inspect run history for delivery failures
  • verify the webhook target returns a 2xx response

Scanner disabled

  • scanners are auto-disabled after repeated failures
  • fix the delivery or query issue, then resume the scanner
  • check quota and plan access if creation or execution is blocked

Scanner Management

Scanner management is available today through the public API. This guide explains the workflow and behavior; use the OpenAPI reference for the exact scanner operations, schemas, and playground requests.