Web API

Note

The endpoints below are listed under their application paths – the paths each route handler registers. At runtime the application is usually served under a deployment-specific mount prefix, so every route is reached one level deeper than it appears here. ivre httpd and the bundled NGINX example use /cgi/ (/scans is reached at /cgi/scans, /audit/ at /cgi/audit/, and so on); the bundled Apache example instead mounts the application at /ivre/cgi. Prepend your deployment’s prefix, if any, to every path in this reference when calling the API (a deployment that mounts the application at the root serves the paths exactly as shown).

GET /config

Returns JavaScript code to set client-side configuration values

Status Codes:
Response JSON Object:
  • config (object) – the configuration values

GET /(subdb:re:scans|view)/(action:re:onlyips|ipsports|timeline|coordinates|countopenports|diffcats)

Get special values from Nmap & View databases

Parameters:
  • subdb (str) – database to query (must be “scans” or “view”)

  • action (str) – specific value to get (must be one of “onlyips”, “ipsports”, “timeline”, “coordinates”, “countopenports” or “diffcats”)

Query Parameters:
  • q (str) – query (including limit/skip and sort)

  • f (str) – filter

  • ipsasnumbers (bool) – to get IP addresses as numbers rather than as strings

  • datesasstrings (bool) – to get dates as strings rather than as timestamps

  • format (str) – “json” (the default), “ndjson” or “txt”

Status Codes:
Response JSON Array of Objects:
  • object – results

GET /(subdb:re:scans|view)/count

Get special values from Nmap & View databases

Parameters:
  • subdb (str) – database to query (must be “scans” or “view”)

Query Parameters:
  • q (str) – query (including limit/skip and sort)

  • f (str) – filter

Status Codes:
Response JSON Object:
  • int – count

GET /(subdb:re:scans|view|passive|rir)/top/(field: path)

Get top values from Nmap, View, Passive & RIR databases

Parameters:
  • subdb (str) – database to query (must be “scans”, “view”, “passive” or “rir”)

  • field (str) – (pseudo-)field to get top values (e.g., “service”)

Query Parameters:
  • q (str) – query (including limit/skip and sort)

  • f (str) – filter

  • ipsasnumbers (bool) – to get IP addresses as numbers rather than as strings

  • datesasstrings (bool) – to get dates as strings rather than as timestamps

  • format (str) – “json” (the default) or “ndjson”

Status Codes:
Response JSON Array of Objects:
  • label (str) – field value

  • value (int) – count for this value

GET /(subdb:re:scans|view|passive|rir)/distinct/(field: path)

Get distinct values from Nmap, View, Passive & RIR databases

Parameters:
  • subdb (str) – database to query (must be “scans”, “view”, “passive” or “rir”)

  • field (str) – (pseudo-)field to get distinct values (e.g., “service”)

Query Parameters:
  • q (str) – query (including limit/skip and sort)

  • f (str) – filter

  • ipsasnumbers (bool) – to get IP addresses as numbers rather than as strings

  • datesasstrings (bool) – to get dates as strings rather than as timestamps

  • format (str) – “json” (the default) or “ndjson”

Status Codes:
Response JSON Array of Objects:
  • label (str) – field value

  • value (int) – count for this value

GET /(subdb:re:scans|view)

Get records from Nmap & View databases

Parameters:
  • subdb (str) – database to query (must be “scans” or “view”)

Query Parameters:
  • q (str) – query (including limit/skip and sort)

  • f (str) – filter

  • ipsasnumbers (bool) – to get IP addresses as numbers rather than as strings

  • datesasstrings (bool) – to get dates as strings rather than as timestamps

  • format (str) – “json” (the default) or “ndjson”

Status Codes:
Response JSON Array of Objects:
  • object – results

POST /(subdb:re:scans|view)

Add records to Nmap & View databases

Parameters:
  • subdb (str) – database to query (must be “scans” or “view”)

Form Parameters:
  • categories – a coma-separated list of categories

  • source – the source of the scan results (mandatory)

  • result – scan results (as XML or JSON files)

Status Codes:
Response JSON Object:
  • count (int) – number of inserted results

GET /flows

Get a flow graph, count, or details payload.

The query is JSON-encoded under the q URL parameter and carries nodes / edges filter lists in the flow.Query grammar plus the pagination / mode knobs listed below. action=details returns details for a single node or edge instead of a graph.

Query Parameters:
  • q (str) –

    JSON-encoded query object. Recognised keys:

    • nodes list of node-filter clauses

    • edges list of edge-filter clauses

    • limit cap on returned edges; defaults to

      config.WEB_GRAPH_LIMIT (1000)

    • skip pagination offset; defaults to 0

    • mode default / flow_map / talk_map

    • count true returns ``{clients, servers,

      flows}`` instead of the graph

    • orderby src / dst / flow (or unset)

    • timeline true embeds data.meta.times per edge

    • before / after "YYYY-MM-DD HH:MM" time bounds

  • action (str) – "details" to fetch host_details / flow_details for the node or edge id supplied in q.id; q.type is "node" or "edge".

Status Codes:
Response JSON Object:
  • object – results

POST /flows

Ingest a bulk of flow records.

Mirrors the bulk-insert API documented in ivre.db.mongo.MongoDBFlow: the request body is a JSON object {"records": [{"kind": "...", ...}, ...]} where each entry carries one of the three ingestion kinds:

  • {"kind": "any", "name": "<zeek-log>", "rec": {...}} maps to db.flow.any2flow(),

  • {"kind": "conn", "rec": {...}} maps to db.flow.conn2flow(),

  • {"kind": "flow", "rec": {...}} maps to db.flow.flow2flow().

Records are dispatched in order, then a single db.flow.bulk_commit() flushes the bulk. Returns {"count": <records-ingested>}.

Status Codes:
Response JSON Object:
  • count (int) – number of records ingested

POST /flows/cleanup

Run the backend’s cleanup_flows heuristic.

The handler dispatches to the configured backend’s cleanup_flows() (a no-op on the SQL backend until the host-swap heuristic is ported); the response carries no body besides {"status": "ok"} so the ivre.db.http.HttpDBFlow client can treat any non-2xx as an error.

Status Codes:
GET /ipdata/(addr)

Returns (estimated) geographical and AS data for a given IP address.

Parameters:
  • addr (str) – IP address to query

Status Codes:
Response JSON Object:
  • object – the result values

GET /iprange

Enumerate IP addresses matching a selector (country, AS, network, range, or all routable IPs).

Exactly one selector must be set. The response always carries count; the additional fields depend on output.

Query Parameters:
  • country – comma-separated ISO 3166-1 alpha-2 codes

  • registered_country – comma-separated ISO 3166-1 codes matched against the “registered” GeoIP attribute

  • regionCC,REGION (country code, region code)

  • cityCC,CITY (country code, city name)

  • asnum – comma-separated AS numbers (AS3215 or 3215)

  • range_start – start of an explicit address range

  • range_stop – stop of an explicit address range

  • network – CIDR network

  • routable – any truthy value selects the full routable APNIC BGP set

  • output – one of count / ranges / cidrs (default) / addrs

  • limit – cap the number of returned entries

Status Codes:
Response JSON Object:
  • count (int) – total number of IP addresses matched

  • cidrs (array) – list of CIDRs (output=cidrs)

  • ranges (array) – list of [start, stop] pairs (output=ranges)

  • addrs (array) – list of IP strings (output=addrs, capped)

GET /passivedns/(query: path)

Query passive DNS data. This API is compatible with the Common Output Format and implemented in CIRCL’s PyPDNS.

It accepts two extra parameters, not supported (yet?) in PyPDNS:

  • subdomains: if this parameter exists and a domain name is queried, records for any subdomains will also be returned.

  • reverse: if this parameter exists and a domain name is queried, records pointing to the queried domain (CNAME, NS, MX) will be returned.

It also returns additional information:

  • “sensor”: the “sensor” field of the record; this is useful to know where this answer has been seen.

  • “source”: the IP address of the DNS server sending the answer.

Parameters:
  • query (str) – IP address or domains name to query

Query Parameters:
  • subdomains (bool) – query subdomains (domain name only)

  • reverse (bool) – use a reverse query (domain name only)

  • type (str) – specify the DNS query type

Status Codes:
Response JSON Object:
  • object – the result values (JSONL format: one JSON result per line)

GET /passive

Get records from Passive database

Query Parameters:
  • q (str) – query (only used for limit/skip and sort)

  • f (str) – filter

  • ipsasnumbers (bool) – to get IP addresses as numbers rather than as strings

  • datesasstrings (bool) – to get dates as strings rather than as timestamps

  • format (str) – “json” (the default) or “ndjson”

Status Codes:
Response JSON Array of Objects:
  • object – results

GET /passive/count

Get special values from Nmap & View databases

Query Parameters:
  • q (str) – query (only used for limit/skip and sort)

  • f (str) – filter

Status Codes:
Response JSON Object:
  • int – count

GET /dns

Return a merged DNS view across the active scan database (db.nmap) and the passive observation database (db.passive).

Each result is a pseudo-record keyed on (name, addr): a single row aggregates every observation of that pair across both backends, with count being the sum of the per-source counts (rec['count'] on the passive side, one per matching nmap document on the active side). types and sources are unions of the contributing backend values (e.g. ["A", "PTR", "user"], ["sensor1", "scan-2024-Q1"]); firstseen / lastseen extend the union of the contributing intervals.

Results are sorted lastseen descending, then count descending. The user’s q= filter is applied to both backends — tokens that are meaningful only on one side (e.g. recontype: on passive, port: on nmap) are silently dropped on the other via the standard hasattr(dbase, "searchXXX") gate in flt_from_query.

Note: the merge happens in-process; every contributing record is materialised before sorting and pagination. The server-side MONGODB_QUERY_TIMEOUT_MS cap bounds the worst-case request time. For deployments where this matters, a future change can introduce a materialised summary collection updated at ingest time.

Query Parameters:
  • q (str) – query (filter, plus skip, limit meta-params)

  • datesasstrings (bool) – emit ISO-ish date strings rather than Unix timestamps

  • format (str) – "json" (default) or "ndjson"

Status Codes:
Response JSON Array of Objects:
  • object – pseudo-records as {name, addr, count, firstseen, lastseen, types, sources}

GET /rir

Get records from the RIR database.

Records are sorted narrowest-first by default (most-specific inet[6]num allocation at the top), so a host: / net: / range: filter naturally surfaces the leaf record covering the queried address. aut-num records (no range, no size) sort to the end. Pass ?sortby=<field> (or ?sortby=~<field> for descending) to override.

Query Parameters:
  • q (str) – query (only used for limit/skip and sort)

  • f (str) – filter

  • format (str) – “json” (the default) or “ndjson”

  • sortby (str) – optional sort field; default is size ascending then start descending then stop ascending (narrowest range first)

Status Codes:
Response JSON Array of Objects:
  • object – results

GET /rir/count

Count records from the RIR database.

Query Parameters:
  • q (str) – query (only used for limit/skip and sort)

  • f (str) – filter

Status Codes:
Response JSON Object:
  • int – count

GET /audit/

List audit events.

Query Parameters:
  • event_type (str) – narrow to one event type (one of upload / admin_action / oversize_query).

  • user_email (str) – narrow to one user’s events. Non-admins may only supply their own email (any other value returns 403); admins may filter by any user.

  • since (str) – lower bound on created_at (inclusive); Unix timestamp or ISO 8601 string.

  • until (str) – upper bound on created_at (exclusive); same format as since.

  • limit (int) – cap on returned entries (default WEB_LIMIT; capped by WEB_MAXRESULTS).

  • skip (int) – pagination offset (default 0).

Status Codes:
GET /audit/count

Count audit events matching a filter (same filter semantics as list_audit_events()).

Query Parameters:
  • event_type (str) – narrow to one event type.

  • user_email (str) – narrow to one user’s events. Non-admins may only supply their own email.

  • since (str) – lower bound on created_at.

  • until (str) – upper bound on created_at.

Status Codes:
GET /audit/(event_id)

Read a single audit event by event_id.

Parameters:
  • event_id (str) – any UUID textual form uuid.UUID accepts – 32-char hex, 36-char hex with dashes, brace-wrapped {...}, or urn:uuid:.... Normalised to the 32-char dashes-less hex form before reaching the storage layer.

Status Codes:
  • 200 OK – JSON object.

  • 401 Unauthorized – authentication required.

  • 404 Not Found – no event with that id (or the caller is not permitted to see it – the two are indistinguishable on purpose, so the route does not double as an existence oracle for events outside the caller’s scope).

  • 501 Not Implemented – audit backend not configured on this server.

GET /notes/(entity_type)/(entity_key)

Read a single note.

Parameters:
  • entity_type (str) – entity type registered with _ENTITY_CANONICALIZERS ("host" only at v1)

  • entity_key (str) – caller-facing entity key (e.g. printable IP string for host)

Status Codes:
PUT /notes/(entity_type)/(entity_key)

Create or update a note.

Body must be valid UTF-8 markdown; invalid byte sequences are rejected with HTTP 400 (no silent U+FFFD substitution). Optimistic concurrency is opt-in via If-Match (matching the ETag returned by GET) or ?expected_revision=<int>. If-None-Match: * opts into create-only semantics (HTTP 409 if a note already exists).

If-Match accepts the standard HTTP forms: bare integer (7), double-quoted ("7"), weak validator (W/"7"), and the first ETag of a comma-list ("7", "8" is treated as 7). If-Match: * (generic “must exist”) is not supported and returns 400.

Parameters:
  • entity_type (str) – entity type

  • entity_key (str) – caller-facing entity key

Request Headers:
Status Codes:
DELETE /notes/(entity_type)/(entity_key)

Delete a note (and its full revision history).

Parameters:
  • entity_type (str) – entity type

  • entity_key (str) – caller-facing entity key

Status Codes:
GET /notes/(entity_type)/(entity_key)/revisions

Read the full revision history of a note, newest first.

Parameters:
  • entity_type (str) – entity type

  • entity_key (str) – caller-facing entity key

Status Codes:
GET /notes/

List or search notes.

With no parameters, returns every note in the database (full body included). Add entity_type to narrow to one type, q to free-text search across note bodies (results ranked by relevance), or fields to skip the bodies and paginate cheaply.

Query Parameters:
  • entity_type (str) – narrow to one entity type

  • q (str) – free-text search query ($text over note bodies; requires the notes_body_text index)

  • fields (str) – comma-separated projection list (e.g. "entity_type,entity_key,updated_at,revision"). The storage halves entity_key_0 / entity_key_1 are always added internally so the caller-facing entity_key can be reassembled.

  • limit (int) – cap on returned entries (default WEB_LIMIT; capped by WEB_MAXRESULTS)

  • skip (int) – pagination offset (default 0)

Status Codes:
GET /auth/check

When auth is disabled, allow all requests.