Overt is a signal-intelligence platform for people who sell security and infrastructure. It watches what companies visibly do on the public internet and turns each observation into a timestamped, evidence-backed buying signal — with the source attached.
Observed, not inferred.
Most "intent" tools sell a probability — this account is 73% in-market — derived from content consumption you can't see or check. Overt sells the opposite: a thing the company verifiably did, carrying the DNS record, response header, or job posting that proves it happened. Every signal can be re-derived from public data. Nothing is a black box.
The problem it solves
A rep selling a WAF, a CDN, an identity product, or an MSSP service spends most of their day guessing: which accounts are worth a call this week, and what do I open with? The honest answers are written all over a company's public surface — the CDN they just switched to, the WAF they dropped, the admin panel they left exposed, the DMARC record they let rot, the security engineer they just posted a job for. That evidence exists, but it's scattered across DNS, TLS logs, HTTP headers, and job boards, and it goes stale the moment you write it down.
Overt maintains a continuously re-scanned corpus of company domains, detects what each one runs and exposes, and emits a signal the moment something changes — paired with the play a rep should run on it. The result is a worklist ordered by genuine, checkable buying relevance instead of a vendor's opaque score.
What it observes
Stack
CDN, WAF, bot defence, DDoS scrubbing, hosting, identity/SSO, MDM, email security, and the SaaS a company runs — detected from its public surface.
Changes
A continuously updated feed of genuine stack movements: a CDN swapped, a WAF added or dropped, a new identity provider stood up.
Posture
An A–F grade for email auth (SPF/DMARC/DKIM), transport security (HSTS/TLS), security headers, DNSSEC/CAA, and disclosure hygiene.
Security- and infrastructure-relevant roles a company is hiring for, mirrored from public ATS job boards.
Account context
Firmographics, decision-maker geography, and pipeline status — so a signal lands as a worklist item, not a curiosity.
Who it's for
Overt is built for revenue teams at cybersecurity resellers, MSSPs, and vendor channel organisations — AEs, SEs, and SDRs doing the prospecting, and the sales leadership who set the territory. It assumes a security-literate user who will fact-check a claim before they act on it, which is exactly why every signal ships its evidence.
New to Overt?
Read How Overt works for the architecture, then Quickstart to run your first scan and signal query. The Signals & evidence concept page is the single most important idea in the product.
Overt is a single Cloudflare Worker backed by a Cloudflare D1 database. There is no build step, no separate backend, and no client framework — the edge runtime is the application.
The shape of the system
Three things run continuously and feed each other:
Detection. Given a hostname, Overt fetches its public surface (HTTP response, DNS records, TLS metadata) and identifies the technologies, security controls, and exposures it can observe — each with the evidence that pointed at it.
The corpus & the re-scan loop. A scheduled job (a Cloudflare Cron Trigger) re-detects domains from a maintained corpus on a tight cycle. When a domain's stack genuinely changes, the change is logged to a long-lived feed.
Fusion & serving. Detection output is fused with account firmographics, hiring intent, decision-maker geography, and pipeline state, then scored and served — to the web app, the API, and the Chrome extension.
A scan, end to end
When a rep analyses example.com in full-footprint mode:
Validation. The target is checked as a public, registrable hostname. Private, loopback, link-local and reserved addresses are refused — both before and after DNS resolution. See Security model.
Cache. A recent result (within the cache window) is returned immediately unless the caller forces a fresh scan.
Subdomain discovery. Hostnames are enumerated from public Certificate Transparency logs, de-duplicated, and capped.
Per-host detection. Each host is fetched and analysed in parallel — CDN/WAF/bot, technology fingerprints, cookie hygiene, and dangling-CNAME takeover candidates.
Domain intel. One pass over the apex resolves mail, SPF/verification records, the DNS provider, and probes for trust-center, identity, MDM and self-hosted-Git surfaces.
Posture. Email auth, transport security, security headers, DNSSEC/CAA, and the current certificate are graded.
Origin exposure. Only when a CDN or WAF is present, Overt looks for an origin server reachable directly — a confirmed CDN bypass.
Fusion & scoring. Findings are mapped to plays, an attack-surface summary and a priority score are computed, a quality gate runs, and the account is matched to firmographics.
Persistence. Results, any genuine stack changes, and metadata are written back; a change triggers the outbound webhook.
A single-host analysis is the same minus subdomain discovery.
What we don't document here
The detection rule sets, the exact scoring weights, the corpus contents, and the data partnerships are Overt's product moat. This documentation describes the method and the interfaces — enough to build on Overt and operate it — but not the rules themselves. See Detection layers for where that line sits.
Why this architecture
It runs where the requests are. Running on Cloudflare's edge means low-latency outbound lookups (DNS-over-HTTPS, CT logs, origin fetches) and a generous subrequest budget per invocation.
One artefact. The Worker ships the API, the cron, and the inline single-page UI. There are no third-party runtime libraries, so there is effectively no supply-chain surface to audit beyond Overt's own code.
The database is the product. D1 holds the corpus, the deduped current stack per domain, and the change history — the "what was used, when" record that compounds in value over time.
Surfaces
Web app
A single-page UI served inline by the Worker — Analyze, Explorer, Signals, Lists and Pipeline.
HTTP API
The same data the UI uses, available to integrations. See the API reference.
Chrome extension
Shows the live stack and plays for the tab you're on, and can keep the corpus current as your team browses.
Webhook
Genuine stack changes are pushed to a chat/CRM webhook in real time.
Get started › Quickstart
Quickstart
Run your first detection, read its evidence, and build a target list — first in the web app, then over the API.
1 · Analyze a company
Open the web app, go to Analyze, enter a company's domain (e.g. example.com), and choose single-host or full-footprint. Overt returns:
a headline — priority score and the single biggest opening;
the detected stack, each item carrying its evidence ("how we know");
the posture grade and the attack-surface summary;
the matched account (firmographics) and any pipeline status.
2 · Read the evidence
Click any finding to see exactly what pointed at it — the header, CNAME, cookie, MX, or endpoint, plus a confidence level. This is the heart of Overt: a claim you can verify in a terminal before you put it in an email. See Signals & evidence.
3 · Build a target list
Go to Signals and combine conditions to describe an audience — for example "companies on a competing WAF, with good firmographic quality, not yet contacted." Save the result as a List, or export it as CSV for your CRM. See the Signals module.
4 · Do it over the API
Everything the UI does is available programmatically. Detection:
# Full detection for one host
curl -H "X-API-Key: $OVERT_KEY" \
"https://your-overt-host/api/detect?host=example.com"
A displacement list — everyone on product X who is not on product Y:
Replace your-overt-host with your deployment origin. How you authenticate depends on whether Overt is fronted by Cloudflare Access — see Authentication.
The sales angle attached to a finding — how it maps to your portfolio and what to open with.
Priority score
A 0–100 ranking of how worth-a-call an account is, weighting findings by confidence and relevance.
Quality gate
A filter that suppresses low-value or noise accounts so worklists stay actionable.
Buying geography
Where a company's IT/security decision-makers actually sit — the decision locus.
Displacement list
Accounts on a competing product but not yours — the highest-intent prospecting cut.
Core concepts › Signals & evidence
Signals & evidence
A signal is the atom of Overt. Everything else — lists, scores, the feed, the pipeline — is built from signals. Understanding what one is, and what it deliberately is not, is the key to using the product.
Observed, not inferred
There are two ways to tell a rep an account is worth a call:
Inferred intent — a model says "this account is probably researching your category." You can't see the inputs and you can't check the output. It might be right.
Observed events — the company demonstrably did something: switched CDN, dropped a WAF, exposed an admin panel, posted a security-engineer role. You can re-derive it yourself.
Overt only emits the second kind. Every signal answers a rep's two real questions — is this real? and what do I say? — because it carries both its proof and its play.
The anatomy of a signal
A finding is a small, consistent record. Conceptually:
{
"name": "Akamai", // what was detected"category": "CDN", // how it's classified"source": "cname", // the kind of evidence"evidence": "www → e1.akamaiedge.net", // the exact observable"confidence": "high"// how strongly it's supported
}
The evidence string is what makes a signal a signal rather than an assertion. It's surfaced in the UI as "how we know" and is meant to be copy-pasteable into a terminal: a CNAME you can dig, a header you can curl, a job posting you can open.
When a site runs on a hosted site builder (Wix, Shopify, Squarespace…) that itself sits behind a CDN, Overt records the CDN as "(via {platform})" and never attributes it to the company as their own choice. This prevents the most common false signal in technographics: crediting a company for infrastructure decisions their website builder made for them.
If a rep ever asks "are you sure?", the answer is in the evidence string. Train the team to read it — it's what separates Overt from a guess.
Core concepts › Confidence model
Confidence model
Not all evidence is equal. A delegation CNAME is near-certain; a substring in a page's HTML is suggestive. Overt grades every finding so the strength of a claim travels with it.
Three levels
Confidence
What earns it
Why
high
Delegation CNAMEs, MX hosts, the DNS provider — evidence that means the service is actually in the path.
You can't accidentally point your CNAME at a vendor's edge; mail can't flow through an MX you don't use.
medium
Origin ASN ownership and similar network-level signals.
Strong, but transit and shared infrastructure can occasionally mislabel.
low
HTML/CSP substrings and other body fingerprints.
A third-party script on a page doesn't prove the company is a customer of that vendor.
Why it matters downstream
Confidence isn't decorative. It feeds the priority score and the leaderboard, so a high-confidence displacement opportunity outranks a low-confidence one. It also lets you filter: in the Signals builder you can prefer high-confidence findings when a worklist needs to be airtight (e.g. an executive territory review) and relax it when you want breadth.
Stale-include caveat
Some signals (an SPF include or verification TXT a vendor left behind after a trial) are real records but may reflect a past relationship, not a current one. Overt surfaces them with appropriate confidence and lets you filter them out — but read the evidence before you assume "current customer."
Core concepts › Detection layers
Detection layers
How Overt turns a hostname into a stack. This page describes the method — the rule sets that drive it are not published.
Where the line is
Overt's detection is driven by curated rule tables — which headers map to which CDN, which CNAME suffixes mean which vendor, which ASNs belong to whom, and so on. Those tables, their coverage, and their tuning are the product's accuracy moat and are deliberately not documented. What follows is the architecture they plug into.
CDN detection: three layers, first hit wins
For each hostname Overt runs three CDN detection layers in priority order and takes the first confident answer:
Response headers. Fetch the host and inspect CDN-identifying headers. Because Overt itself runs on Cloudflare, Cloudflare's own headers are ignored — it's identified by ASN/CNAME instead, so the platform never mistakes itself for the target's choice.
CNAME chain. Resolve over DNS-over-HTTPS and match delegation domains. This is the highest-confidence layer — you can't be on a vendor's edge without pointing at it.
Origin ASN. Resolve the IP and map its ASN to a provider. General cloud ASNs (AWS/Azure/GCP) are deliberately not mapped to a CDN — they surface as hosting, not as a CDN choice.
Independent passes
Alongside CDN detection, several passes run independently:
Pass
What it inspects
WAF / bot
Response headers and security-cookie names.
Technology
HTML & CSP fingerprints, header tech, and classified CNAMEs.
DNS intel
MX, SPF, verification TXT, the NS → DNS-provider mapping, and trust-center / IdP / MDM / self-hosted-Git probes.
Posture
SPF/DMARC/DKIM, HSTS & transport, security headers, DNSSEC/CAA, certificate. See Posture.
Precision over recall. Where a rule would over-count (a CNAME that ships with standard onboarding, a broad substring), it's either excluded or down-weighted. A wrong signal costs a rep credibility; a missing one costs nothing they didn't already lack.
Evidence at the point of detection. A finding is never recorded without the observable that produced it. See Signals & evidence.
No retries, fail-open. A failed lookup yields an empty result and the scan continues — a slow third party degrades coverage, never the whole scan.
Detection runs the same way in three contexts: on demand (Analyze / the API), continuously (the re-scan loop), and live (the Chrome extension).
Core concepts › The change feed
The change feed
A stack you detected once is technographics. A stack you watch over time is intent. The change feed is where Overt's continuously re-scanned corpus turns into timed buying signals.
What gets logged
Every re-scan compares the freshly detected stack against the stored one. Only a genuine movement is recorded:
a product or control added — a new WAF, a new identity provider, a CDN where there was none;
a product or control removed — a WAF dropped, a CDN swapped out.
Re-scans that find no change add nothing to the feed. This keeps the feed high signal — every entry is something that actually happened, with a timestamp and the before/after.
Why "added a WAF" and "dropped a WAF" both sell
A company that just added a competitor's WAF is in-market for the category and worth a competitive displacement play later. A company that just dropped one is exposed right now and worth an immediate call. The same observation, opposite plays — and the feed gives you both, dated.
Consuming it
In the app — the Explorer's Changes view, filterable by category and domain.
Over the API — GET /api/changes, filterable by domain, category, and since.
Pushed — to a chat/CRM webhook the moment a change is detected, de-duplicated so it never spams.
The change history is kept long-term. It's the "what was used when" record — the dataset that compounds and that a one-off scan can't reproduce.
Core concepts › Corpus & freshness
Corpus & freshness
Overt doesn't wait for you to ask about a company — it already watches a maintained set of them. That set is the corpus, and a continuous re-scan loop keeps it fresh.
The re-scan loop
A Cloudflare Cron Trigger drives a scheduled job that re-detects a batch of corpus domains every tick. The batch is split between two pools:
a coverage pool that prioritises never-scanned domains, so new corpus entries get a first reading quickly;
a reserved re-scan pool of the stalest established domains, so the change feed keeps producing signal on accounts you already know.
Within a tick the batch is processed with bounded concurrency so it finishes inside the schedule window. Per-scan snapshots are written only when the stack changed, so unchanged re-scans cost nothing in storage.
What stays, what's pruned
The deduped current stack per domain is always kept — it's what Explorer, the leaderboard, and Signals query.
The change history is kept long-term — it's the irreplaceable record.
Per-scan snapshots are written only on change, keeping the working set lean.
Corpus composition
What's in the corpus, how it's sourced and curated, and how it's segmented are not published — the corpus and the freshness it carries are core to the product. Overt can also be pointed at an arbitrary hostname on demand without it being in the corpus.
On-demand vs. corpus
Any hostname can be analysed on demand via Analyze or the API — it doesn't need to be in the corpus. When it is, results are served from the continuously refreshed store, and a recent cache short-circuits redundant work. Force a fresh read with ?fresh=1.
Core concepts › Posture & attack surface
Posture & attack surface
Two of Overt's signal families are about what a company got wrong, not what it bought. Both are openings for a security seller.
Security posture (A–F)
The posture pass grades a domain's externally observable security hygiene and rolls it into a letter grade:
HSTS, redirect-to-HTTPS, TLS posture, current certificate.
Headers
Security response headers and information disclosure.
DNS trust
DNSSEC, CAA, and security.txt presence.
Grades read at a glance:
ABCDF.
A weak grade is itself a signal — "your DMARC is at p=none" is a concrete, evidence-backed opener.
Attack surface
The attack-surface pass surfaces externally observable exposures:
Exposure
What it means
Subdomain takeover candidate
A dangling CNAME pointing at an unclaimed service — claimable by an attacker.
Confirmed origin exposure
An origin server reachable directly, bypassing the CDN/WAF in front of it. Only reported when confirmed.
Exposed admin surface
Admin/management hostnames observable on the public surface.
Insecure cookies
Session cookies missing Secure/HttpOnly.
EOL software
End-of-life server software disclosed in headers.
Overt only reports what it can observe from outside, with evidence. It does not exploit, brute-force, or attempt to access anything — the origin-exposure check confirms reachability, nothing more. Use these signals to open a conversation, not as a pentest.
Core concepts › Plays & portfolio mapping
Plays & portfolio mapping
A signal a rep can't act on is trivia. Overt maps each finding to your portfolio so every signal arrives with a play attached.
How mapping works
Each detected product or control is classified against your portfolio as one of:
Ours — the company already runs something you sell or partner on (expansion, renewal-risk, or reference angle);
Competes — the company runs a competitor's product (displacement angle);
Adjacent / context — neither, but it colours the account (e.g. they're on a hyperscaler, they run a particular identity stack).
From that classification Overt frames the opening: a competing WAF becomes a displacement play; a weak posture grade becomes a remediation play; a fresh "added X" change becomes a timing play.
Displacement, the highest-intent cut
The most actionable list in Overt is "on a competitor, not on us." The /api/by-product?product=X&without=Y endpoint and the Signals builder both produce it directly. Pair it with the change feed and you get displacement targets ordered by recency.
Portfolio is configuration
The portfolio map — which products are "ours," which "compete," and the exact play wording — is specific to your business and is a tuned asset. The mechanism is documented; the contents are yours.
Core concepts › Priority & quality
Priority & quality
Overt orders accounts so a rep can work top-down. Two mechanisms do this: a priority score that ranks opportunity, and a quality gate that suppresses noise.
Priority score (0–100)
Each account gets a sales-priority score that blends signal-driven inputs:
What was found and how it maps to your portfolio (a competing product outranks a neutral one);
Confidence — high-confidence findings weigh more than low (see Confidence model);
Recency — a fresh change is hotter than a long-standing state;
Account fit — firmographic quality and segment relevance;
Exposure — posture and attack-surface openings.
The score drives the leaderboard ("hottest accounts") and the default sort in lists.
The quality gate
Not every domain is worth a rep's attention — parked domains, microsites, and dead pages add noise. The quality gate flags low-value records so they can be filtered out of worklists by default while remaining queryable when you want the long tail.
Weights are not published
The exact inputs, weights, and thresholds behind the priority score and the quality gate are tuned and proprietary. This page describes what they consider and why; the formula is the moat.
Core concepts › Accounts & firmographics
Accounts & firmographics
A signal lands better when the rep knows who they're calling. Overt joins each domain to account context so a stack change reads as a qualified opportunity.
What's joined
Firmographics — company identity, revenue/employee bands, region, and sector classification.
Sector & registry context — segment tags that let you slice the corpus by industry or regulatory category in the Signals builder.
Decision-maker context — contacts and the buying geography for the account.
These come from a mix of registry data and enrichment providers and are matched to the domain so a single /api/company?domain= call returns the firmographic picture.
Personal data
Contact and buying-geography data is personal data. It's handled under a B2B legitimate-interest basis and is subject to the privacy controls in Data & privacy — it must never sit on a public URL.
Core concepts › Buying & hiring geography
Buying & hiring geography
Knowing a company is in-market is half the answer. Knowing where the decision actually sits is the other half — especially for multinationals whose security buying isn't at the registered HQ.
Buying geography
Overt derives a decision locus for an account — where its senior IT/security/engineering staff actually sit — so a rep targets the right office and the right region, not just the legal address. This is enrichment-backed and surfaced per domain.
Hiring geography
The same question, answered for free from public job postings: where a company is hiring security and infrastructure roles is a strong, no-cost proxy for where the relevant team lives — and the roles themselves are a hiring-intent signal.
Both are available as conditions in the Signals builder — e.g. "decision-makers in DACH."
Buying-geography records are personal data and are subject to retention and access controls — see Data & privacy.
Modules › Analyze
Analyze
Point Overt at one company and get its complete, evidence-backed picture in a single view.
What you get
Headline — the priority score and the single biggest opening.
Stack — every detected product and control, grouped by category, each expandable to its evidence.
Posture — the A–F grade with its component breakdown.
Attack surface — observable exposures.
Intel — DNS, mail, and identity surface.
Account — firmographics, buying/hiring geography, and pipeline status.
Modes
Single host — one hostname, fast. Best for a quick check before a call.
Full footprint — enumerates subdomains and detects each. Best for a territory or account review.
Under the hood this is /api/detect and /api/scan. Results are cached briefly; force fresh with the re-scan control.
Modules › Explorer
Explorer
Browse the whole corpus three ways: by product, by hottest accounts, and by what just changed.
Products
Every detected product across the corpus with its distinct-domain count. Drill into any product to see who runs it — and combine "uses X, not Y" for instant displacement lists.
Hottest accounts
The leaderboard, ordered by priority score, filterable by segment and quality. This is the "who do I call this week" view.
Changes
The change feed as a browsable timeline, filterable by category and domain — the timing layer over the corpus.
Modules › Signals (query builder)
Signals — the query builder
Describe an audience as a set of conditions and Overt returns the matching accounts. This is how you turn the corpus into a campaign-ready list.
Combining conditions
Conditions are ANDed together. You can mix any of these dimensions:
Dimension
Example conditions
Stack
uses product X, runs CDN Y, on DNS provider Z
Category
has a WAF / has no WAF, runs an identity provider
Firmographics
revenue band, employee band, region
Sector / registry
industry or regulatory-category tags
Quality & priority
minimum quality, minimum priority score
Attack surface
origin exposed, takeover candidate, exposed admin
Geography
buying-team region, hiring region
Pipeline
status (prospect / contacted / …), owner
Recency
changed recently in a given category
From query to action
Save as a List — share a static cut with the team (see Lists).
Export CSV — CRM-import-ready.
Call the API — the same query runs at POST /api/signal; fetch the available fields/operators from GET /api/signal-options.
Field and operator names shown are illustrative — query /api/signal-options for the exact set your deployment supports.
Modules › Lists
Lists
A saved set of accounts, shared across the team.
Lists turn a one-time query into a working artefact. Build a cut in Signals, save it as a List, and the whole team works the same set. Lists are team-shared within your tenant and back the /api/lists and /api/list endpoints.
Typical uses
A campaign target list ("Q3 WAF displacement — DACH").
A named-account watchlist for a strategic rep.
A hand-off from sales-ops to the team after a territory carve-up.
Modules › Pipeline
Pipeline
A lightweight CRM-lite layer so Overt knows what's already in motion — and signals arrive as worklist items, not duplicates.
Account status
Each account can carry a stage (prospect → contacted → qualified → won / lost), an owner, and free-text notes. The pipeline board groups accounts by stage; status is also a condition in the Signals builder, so you can always exclude what's already being worked.
API
Read and set status at /api/account-status. Export the pipeline as CSV for your system of record. Overt is a prospecting layer, not a replacement CRM — wire it to your CRM via the webhook and CSV exports.
Modules › Chrome extension
Chrome extension
See any company's live signals on the site you're already looking at — and turn every site your team visits into a watched account.
What it does
On any tab, shows the detected stack and the plays for the current company.
Optional auto-collect (default off) keeps the corpus current as your team browses — each visited apex is detected once, with a cooldown and a denylist.
How it's built
Manifest V3, no build step, load-unpacked.
Reaches the API via host permission, which bypasses CORS — so the web app itself stays same-origin-locked.
When Overt is behind Cloudflare Access, the extension authenticates with the same Access cookie (credentials: include).
Auto-collect is off by default and respects a cooldown and denylist — it's an opt-in way to grow coverage from real browsing, not a tracker.
API reference › Authentication
Authentication
How a request is authenticated depends on whether your Overt deployment is fronted by Cloudflare Access — which it should be in production.
Three callers, three paths
Caller
Auth
The web app (same-origin)
None — served from the same origin.
A person in a browser
Cloudflare Access SSO (handled transparently once configured).
A program / integration
A Cloudflare Access service token, or the Worker's X-API-Key (see below).
When Access fronts the Worker (recommended)
With an edge Access application in front of Overt, requests are intercepted before the Worker. Machines authenticate with a service token:
Create one in Zero Trust → Access → Service Auth → Service Tokens, then add it to the Access application's policy as an include → Service Token rule.
The Worker API key
The Worker also supports an X-API-Key header. It applies when Overt runs in its in-Worker Access mode, or when an Access Bypass policy for /api/* hands gating back to the Worker:
Every admin and mutating call — success or denied — is written to the audit log.
Stand up Access before exposing Overt
Some read endpoints have no in-code auth — they rely on the Access gate. Until Access is configured they'd be world-readable, and some return personal data. Lock down with Access first. See Security model.
API reference › Conventions
API conventions
Base URL, formats, rate limits, and errors — the things that hold across every endpoint.
Base URL
Your deployment origin, e.g. https://your-overt-host. A machine-readable contract is served at GET /api/openapi.json (OpenAPI 3.0).
Format
Requests that take a body are JSON (content-type: application/json). Responses are JSON unless a format=csv parameter is offered. All responses are same-origin only — there is no Access-Control-Allow-Origin: *.
Rate limits
The scan-path endpoints are rate-limited per IP with a fixed window. The expensive endpoints (/api/detect, /api/scan) have tighter budgets than the read/query endpoints. Caller-supplied ?limit= values are capped server-side. A throttled request returns 429.
Caching
Detection results are cached briefly per host. Add ?fresh=1 to /api/detect (and the scan path) to bypass the cache and force a live read.
Errors
Status
Meaning
400
Invalid input — e.g. a target that isn't a public registrable hostname.
401 / 403
Missing or rejected credentials (Access, API key, or admin token).
404
No record for the requested domain.
429
Rate limit exceeded — back off and retry.
503
Liveness failure (/api/healthz only) — the re-scan loop has stalled.
API reference › Detection endpoints
Detection endpoints
Turn a hostname into a stack, posture, and attack-surface picture — on demand.
GET/api/detecttarget-validated · rate-limited
Full detection for one host: stack, posture, attack surface, DNS intel, and account context.
Hottest accounts by priority score, filterable by segment and quality.
Param
Description
segment
Restrict to a segment.
crap
Include low-quality accounts (off by default).
API reference › Signals & changes
Signals & changes
The query builder and the change feed — the endpoints that turn the corpus into worklists and intent.
POST/api/signalread
The custom prospect query. ANDs a set of conditions over the corpus and returns matching accounts. See the Signals module for the dimensions you can combine.
Create and read team-shared Lists (/api/lists) and their items (/api/list). Scoped to your tenant.
API reference › Census & exports
Census & exports
Bulk, CRM-ready outputs.
GET/api/scrubbingread
An L3/L4 DDoS scrubbing census — accounts whose network-level routing indicates a scrubbing/Magic-Transit-style posture. Add ?format=csv for a spreadsheet.
Signals results and the Pipeline export to CSV directly from the UI — ready to import into your CRM. The scrubbing census is the same data over the API.
API reference › Webhooks & OpenAPI
Webhooks & the OpenAPI contract
Push signals out in real time, and integrate against a machine-readable spec.
Change webhook
When the re-scan loop detects a genuine stack change, Overt posts to a configured incoming webhook (Slack / Google Chat / Teams shape). Wire it into your CRM or alerting to get the moment-it-happens signal without polling. Alerts are de-duplicated so a flapping detection never spams the channel.
The Worker also posts operational alerts to the same channel on a real incident — a re-scan throughput collapse or a stale backup — not on routine activity.
OpenAPI
GET/api/openapi.jsonspec
An OpenAPI 3.0 description of the public API surface — point your client generator or API explorer at it. Behind Access, add a Bypass policy if a tool needs it unauthenticated.
Liveness
GET/api/healthzpublic
Returns 200 {"status":"ok"}, or 503 when the re-scan loop has stalled. Point an uptime monitor here. See Health & monitoring.
Operate › Security model
Security model
Overt fetches attacker-controlled content (the sites it scans) and may serve personal data. Its security model is built around both facts.
Anti-SSRF
User-supplied targets are validated as public, registrable hostnames. After DNS resolution, any private, loopback, link-local, or reserved IP is refused before any fetch. There is no way to point a scan at internal infrastructure.
Output safety
All scanned-site data is HTML-escaped before it reaches the DOM — the page renders attacker-controlled content, so this is load-bearing. The Content-Security-Policy uses a per-request nonce for the single inline script; there is no 'unsafe-inline'. X-Frame-Options: DENY, nosniff, HSTS and a strict Referrer-Policy are set.
Access control
Cloudflare Access — the recommended posture is an edge Access app fronting every route, so unauthenticated requests are redirected to SSO before reaching the Worker. See Authentication.
Admin token — all mutating/admin endpoints require a constant-time-compared bearer token, independent of Access.
Active probe — the optional active WAF probe requires authentication.
CORS — same-origin only; no wildcard origin.
Lock down before exposing
Several read endpoints rely on the Access gate rather than in-code auth. Until Access is configured they are world-readable — and some return personal data. Standing up Access is the single most important deployment action.
Durability & recovery
D1 point-in-time recovery (Time Travel) provides a rolling restore window.
A daily off-database backup of the irreplaceable subset is taken to a separate store, with an upsert-only restore that never deletes.
Audit
Every admin and mutating endpoint hit — success and denied — is appended to an audit log with actor and IP, readable at /api/admin/audit and tenant-scoped.
Operate › Data & privacy
Data & privacy
Most of what Overt stores is technical and public. Two endpoints return personal data, and they carry specific obligations.
Personal data
Buying geography — names, job titles, and work city/country of senior IT/security/dev staff.
Contacts — decision-maker names and titles.
Handling
The intended lawful basis is B2B legitimate interest — professional contact data used for B2B outreach. To stay defensible:
Never put it on a public URL — lock the deployment behind Access (this is the most important control).
Reveal contact details (email/phone) only when actually contacting someone; geography needs no reveal.
Honour erasure requests by deleting the relevant rows for a domain.
Personal-data tables are subject to a retention purge by the scheduled job.
The detection and posture data Overt stores about a company is derived entirely from its public surface — DNS, TLS logs, HTTP responses, and public job boards. Nothing is obtained by authenticating to, or attacking, a target.
Operate › Multi-tenancy
Multi-tenancy
Overt's workspace data is tenant-scoped, so the same deployment can host isolated teams.
How scoping works
The shared workspace tables — Lists, list items, account status, contacts, and the audit log — carry a tenant identifier. On every request the Worker derives the caller's tenant and scopes every read and write by it. Two intentional exceptions run without tenant context: the retention purge of personal data, and the whole-database disaster-recovery backup.
Modes
Single internal tenant (default) — behaviour-preserving; every row belongs to one internal tenant.
Per-tenant isolation — when identity gating is enabled per hostname, the same scoping becomes hard isolation between tenants, with the tenant derived from the verified identity claim.
Tenant scoping is wired on the read side today and dormant in single-tenant mode — it activates without behaviour change the moment identity gating is switched on. The detection corpus itself is shared infrastructure; tenancy applies to the workspace layer (your lists, pipeline, and contacts).
Operate › Health & monitoring
Health & monitoring
One public liveness probe, one rich admin view, and proactive alerting.
Liveness
Point any uptime monitor at the public liveness probe:
GET /api/healthz
→ 200 {"status":"ok"}
→ 503 {"status":"down"} # the re-scan loop has stalled
It returns no data, so it's safe to leave public (add an Access Bypass for the path if Access fronts everything).
Operator view
GET/api/admin/healthadmin token
The full ops picture: re-scan throughput, corpus size and backlog, change rate, backup age, and whether Access is enforced.
GET/api/admin/auditadmin token
The audit trail of every mutating admin action and denied attempt.
Alerting
The scheduled job posts to the configured webhook on a real incident — re-scan throughput collapse or a stale backup — de-duplicated so it never spams. Pair the external /api/healthz monitor with this for both outside-in and inside-out coverage.
Operate › Deployment
Deployment
Overt deploys as a single Cloudflare Worker with a D1 binding. No Node, no bundler, no wrangler required on the deploy machine.
What deploys
A deploy script uploads the Worker's ES modules via the Cloudflare REST API, binds D1, registers the re-scan cron, and injects configuration from the environment. Secrets are loaded at deploy time from gitignored files — never committed.
Configuration
Configuration is environment-driven. The categories you'll set:
Group
What it controls
Auth / lockdown
The admin token; the Cloudflare Access team domain and audience (the lockdown).
Enrichment keys
Optional provider keys that unlock contacts, buying geography, the CT-log token, and the LLM classifier — each degrades gracefully if unset.
Alerting
The change/incident webhook URL.
Scan budgets
Re-scan batch size, default and max deep-scan hosts, and per-IP rate limits.
Standing up Access
Before any external exposure, front Overt with a Cloudflare Access application on a custom domain tied to your IdP, set the team domain + audience, and remove the open workers.dev route. Full runbook lives with the deployment. See Security model and Authentication.
Tests before deploy
A dependency-free smoke runner catches the failures that actually happen — a module that won't parse, a broken inline script, a regressed normalisation helper. Run it before every deploy; because the deploy re-uploads all modules, a parse error is a live outage, and this is the cheap guard against it.
The single artefact (one Worker + one database) is the operational point: there's one thing to deploy, one thing to monitor, and effectively no third-party runtime dependencies to keep patched.