Passive OSINT & Recon API

Map an attack surface without sending it a single packet

The Passive OSINT & Recon API returns passive subdomain and infrastructure discovery as clean JSON.

no credit card1,000 free credits · instant API key · live in 10 seconds
Missing a Passive OSINT & Recon endpoint, or need a source we don't have yet?Contact us real people · same-day reply.
P
/passive-osint/v1

4 active endpoints, on 1, 2 and 3 credit tiers.

  • POST/passive-osint/v1/subdomains
  • POST/passive-osint/v1/domain
  • POST/passive-osint/v1/ip
  • POST/passive-osint/v1/batch

What Passive OSINT & Recon endpoints does ReefAPI ship?

4 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.

4 endpoints

subdomains

2 cr

Passive subdomain discovery across crt.sh + certspotter + OTX + hackertarget + Wayback, dedup…

required
domain
optional
sources

domain

3 cr

One-call unified passive report.

required
domain
optional
sources, include_pii

ip

1 cr

Passive IP enrichment.

required
ip
optional
include_pii

batch

3 cr

Compact passive report (subdomain count+list, DNS, threat, archive-first-seen) across up to 1…

required
domains
optional

Every parameter, every allowed value →

Passive OSINT & Recon API

3 of 4 endpoints, ready to run

View docs ↗

Every subdomain the public sources know about, plus a matrix showing which source found each one and a per-source status.

2 credits1 required · 1 optional
POST/passive-osint/v1/subdomains
ok18031 ms · 11 records · sample
{
  "ok": true,
  "meta": {
    "api": "passive-osint",
    "endpoint": "subdomains",
    "mode": "live",
    "latency_ms": 18031.3,
    "record_count": 11,
    "cache_hit": false
  },
  "data": {
    "domain": "hackerone.com",
    "subdomains": [
      "a.ns.hackerone.com",
      "api.hackerone.com",
      "b.ns.hackerone.com"
    ],
    "count": 11,
    "source_matrix": {
      "docs.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "gslink.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "mta-sts.forwarding.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "support.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "www.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "mta-sts.managed.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "mta-sts.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "api.hackerone.com": [
        "certspotter",
        "hackertarget"
      ],
      "hackerone.com": [
        "certspotter"
      ],
      "b.ns.hackerone.com": [
        "hackertarget"
      ],
      "a.ns.hackerone.com": [
        "hackertarget"
      ]
    },
    "sources": {
      "crtsh": {
        "ok": false,
        "count": 0,
        "note": "crt.sh HTTP 404 (flaky CT endpoint) — degraded"
      },
      "certspotter": {
        "ok": true,
        "count": 9,
        "note": null
      },
      "otx": {
        "ok": false,
        "count": 0,
        "note": "source timed out after 18s (slow upstream — partial result returned)"
      },
      "hackertarget": {
        "ok": true,
        "count": 10,
        "note": null
      },
      "wayback": {
        "ok": false,
        "count": 0,
        "note": "source timed out after 18s (slow upstream — partial result returned)"
      }
    },
    "coverage_note": "Passive discovery aggregates public CT logs, passive-DNS and archive indexes. It is inherently PARTIAL and the passive ecosystem is FRAGMENTED — each source samples a different slice (live measurement: independent aggregators and our sources overlap only partially), so aggregating many sources maximises coverage but CANNOT claim a complete inventory. Active brute-force/zone-transfer would be needed for completeness and is out of scope. Sources that returned data: certspotter, hackertarget."
  }
}
Real response, fetched from the live endpoint with the parameters on the left — trimmed to the first few rows, with seller names left out. Press Try it for the untrimmed response.

How the Passive OSINT & Recon API works

Passive OSINT & Recon is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.

01
Authenticate
x-api-key header

No OAuth app, no request signing, no per-site account. One key covers all 184 engines.

02
Call
POST /passive-osint/v1/…

Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.

03
Pay
1 or 2 or 3 credits per call

Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.

04
Read
{ ok, data, meta, error }

One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.

Scoping an engagement before you are allowed to scan

Authorisation usually arrives after scoping, which means the first pass has to be built entirely from records other people already published.

01subdomains
POST/passive-osint/v1/subdomains
{"domain": "hackerone.com"}

Aggregates several public sources and returns the union along with a matrix of which source produced each name.

02Read the source matrix before you trust a name.
POSTRead the source matrix before you trust a name.

A host seen by one source and no others is frequently a certificate that was issued and never used. Corroboration across sources is the useful signal.

Nothing here touches the target. Every record already exists in certificate-transparency logs, passive DNS or the archive, which is what makes this usable before an authorisation letter arrives.

request
curl -X POST https://api.reefapi.com/passive-osint/v1/subdomains \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"domain":"hackerone.com"}'
response envelope
{
  "ok": true,
  "data": { … },
  "meta": {
    "api": "passive-osint",
    "endpoint": "subdomains",
    "mode": "live",
    "latency_ms": …,
    "record_count": …
  },
  "error": null
}

Five sources, wildly uneven yield, and the matrix that shows it

The subdomain list is a union of five independent public indexes, and they do not contribute equally. Every response carries sources{} with a per-source ok flag, count and note, plus source_matrix{} mapping each hostname to the sources that saw it, so you can tell a well-corroborated host from one that a single archive remembers. The numbers below are a single measured run against hackerone.com.

SourceWhat it indexesMeasured yield on hackerone.com
otxAlienVault/LevelBlue OTX passive DNS plus its URL list82 of the 82 hosts in the union
hackertargethostsearch, free tier10 hosts; a repeat run minutes later returned 11
certspotterCert Spotter certificate-transparency issuances9 hosts
waybackWayback Machine archived-host index2 hosts
crtshcrt.sh certificate-transparency logs0, with ok:false and note "crt.sh HTTP 502 (flaky CT endpoint) - degraded"
uniondeduplicated and sortedcount 82, matching the returned subdomains array length
confidencea word, not a number"high" on dns and ssl, "medium" on subdomains_passive, archive, threat_flags, dns_history and associated_domains
meta.sectionsper-section status on the domain actionok for six sections, "empty" for associated_domains, so a blank section is labelled rather than silent

Restricting sources is a good way to get nothing. A run with sources=crtsh alone returned ok:true, count 0, an empty subdomains array and an empty source_matrix, because the one source selected was the one that was degraded that day. Unless you have a reason, leave sources at its default of all five and read the sources{} block to see which ones actually answered.

What passive means, and what it costs

Measured on a large, well-known security domain. Both the strength and the two weaknesses are structural.

Nothing is sent to the target

Every name comes from records third parties have already published — certificate-transparency logs, passive DNS collections and archive crawls. No probe, no resolution attempt against their infrastructure, nothing in their logs. That is the entire point of the endpoint, and it is why it can run before an engagement is signed.

The source matrix is returned, not just the union

Each discovered host lists which sources reported it, and each source reports its own status. A name found by four independent sources and a name found by one are very different claims, and merging them into a flat list throws that away.

Against us: passive means stale as well as safe

A certificate issued in 2019 for a host that was decommissioned in 2020 is still in the transparency log forever. Some fraction of any passive result no longer resolves. The endpoint tells you what was published, not what is live — resolving the list is a separate, active step you take once you are allowed to.

Against us: it is slow, because it fans out

A large domain took the better part of twenty seconds, because several public sources are queried and some of them are themselves slow or rate-limited. Treat this as a background job. The response includes a coverage note describing what the aggregation does and does not include.

Personal data stays out unless asked for

Registration and contact details are excluded by default. Passive reconnaissance sits close enough to personal data that the conservative default is the correct one, and turning it off is a deliberate act rather than something you get by accident.

What people build with Passive OSINT & Recon

The jobs this data is most often used for.

4

endpoints

1/2/3

credits per call

01

Security teams call subdomains to map an organization's external attack surface passively.

02

Recon workflows use domain and ip to enrich a target with infrastructure context.

03

Threat-intel tools use batch to run passive discovery across many domains at once.

What Passive OSINT & Recon data costs

The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.

Full pricing →
$0.67–$1.50 / 1,000 credits
  • 1,000 free credits on signup, no card
  • One key, all 184 APIs, one credit pool
  • Failed and blocked calls are never charged
  • Credits roll over and never expire

Call it in two lines

Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.

curl
curl -X POST https://api.reefapi.com/passive-osint/v1/subdomains \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"domain":"hackerone.com"}'
python
import requests

r = requests.post(
    "https://api.reefapi.com/passive-osint/v1/subdomains",
    headers={"x-api-key": REEF_KEY},
    json={
  "domain": "hackerone.com"
},
)
print(r.json()["data"])
FAQ

Have a question? We got answers.

The questions people actually ask before wiring up Passive OSINT & Recon.

Get a free key →
Why is batch so much shallower than the single-domain call?

Because it queries fewer sources. In back-to-back measurements the subdomains action returned 82 hosts for hackerone.com while the batch action returned subdomain_count 11 for the same domain, with sources_succeeded listing only certspotter and hackertarget. batch also returned archive_first_seen null where the domain action returned 2005-02-09T16:19:15Z. batch is a compact triage pass over up to 10 domains, not a cheaper way to run the same query. Do not compare a batch count against a single-domain count.

One source produced all 82 hosts. Should I just use that one?

No, because which source carries a domain is not predictable. On hackerone.com otx returned all 82 while certspotter returned 9, hackertarget 10 and wayback 2, and crt.sh was down entirely. On another domain the shape will differ, and certificate-transparency sources see hosts that passive DNS never resolved. Read source_matrix per host instead: a hostname listed by certspotter, otx and hackertarget is far better corroborated than one seen only by wayback, which may be an archived host that no longer exists.

What does this engine refuse to do?

Person OSINT, explicitly and at the parameter level. Passing an email alongside a domain returned ok:false with error.code INVALID_PARAM and the message "'email' is out of scope: passive-osint is domain/IP-only and deliberately does NOT do person OSINT (email/phone/username/social). Use a domain or ip parameter." It also does no active scanning: no brute force, no zone transfer, no port scan. Everything comes from public indexes that already hold the data, which is why it is safe to run against a target you do not own.

How complete is the subdomain list?

Not complete, and the response says so in coverage_note rather than in the docs alone. The note describes the passive ecosystem as fragmented, states that aggregating many sources maximises coverage but cannot claim a complete inventory, and points out that active brute force or a zone transfer would be needed for completeness and is out of scope. The batch action carries a blunter version: roughly 60 to 90 percent of live inventory per domain. Treat the output as an attack-surface starting point, not an asset register.

What does the ip action add that a WHOIS lookup does not?

Neighbours and history. A measured 8.8.8.8 lookup returned rdns.ptr ["dns.google"], network {asn 15169, as_name "GOOGLE - Google LLC, US", bgp_prefix 8.8.8.0/24, country US, registry arin, network_name GOGL, org "Google LLC"}, clean threat_flags across feodo, sslbl and spamhaus_drop, and a shared_host block with shown 200, approx_total 500 and is_shared true. The note on that block is the important part: a shared or CDN IP lists many unrelated domains and that is not an ownership link.

Why do two identical calls return slightly different data?

Because the upstream indexes are live and unordered. Two runs on hackerone.com minutes apart returned hackertarget counts of 10 and then 11, and the dns block returned its a, mx and ns arrays in a different order each time with the same members. Sort before you diff, and compare on set membership rather than on array position. Section-level failures also move between runs, which is exactly what the per-source ok flags and meta.sections are there to record.

What is dns_history, and why do its timestamps look different?

It is passive-DNS resolution history: when each hostname-to-IP mapping was first and last observed. A measured hackerone.com report returned count 155 with rows such as {hostname docs.hackerone.com, record_type AAAA, address 2a06:98c1:310c::6812:24d6, first_seen 2026-08-02T19:56:09, last_seen 2026-08-25T20:14:38}. Those timestamps carry no timezone suffix, while the ssl and archive sections return proper Z-suffixed UTC. Normalize before you sort a mixed timeline. The source is otx-passive-dns and confidence is medium.

What comes back for a domain that does not exist?

ok:true with an empty result and a per-source explanation, not an error. A made-up domain returned count 0, an empty subdomains array and an empty source_matrix, with sources showing certspotter ok:true count 0, otx ok:true count 0, and crtsh, hackertarget and wayback all ok:false with their own notes. An empty count with several sources reporting ok:true is a real negative; an empty count where every source reports ok:false means you learned nothing and should retry.

What is the Passive OSINT & Recon API?

Passive OSINT & Recon API is a ReefAPI endpoint group for passive osint & recon It returns live JSON through POST requests under /passive-osint/v1.

Is the Passive OSINT & Recon API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Passive OSINT & Recon calls use the same shared credit balance as every other ReefAPI engine.

Do I need a Passive OSINT & Recon login or account?

No login to Passive OSINT & Recon is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.

How fresh is the Passive OSINT & Recon data?

The page example is captured from a live subdomains call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Passive OSINT & Recon API use?

Passive OSINT & Recon actions currently cost 1-3 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

Can I call Passive OSINT & Recon from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call passive-osint actions with the same key, credit pool and JSON envelope used by normal REST requests.

18 Developer Tools APIs on the same key

One key, one credit pool, one response envelope. If you are pulling Passive OSINT & Recon, you are one call away from the rest of the category — no second contract, no second integration.

Need something this API does not do?

Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.

0/4000

No account needed · we reply from [email protected]

Try it on your own data before you pay anything

The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.

Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-30.