Firehose

View as markdown

Synthient streams every data feed in real time as newline-delimited JSON (NDJSON) over a long-lived HTTP connection. Each line of the response is one complete JSON event. Connections stay open for up to 30 minutes before the server cleanly closes them; clients should reconnect immediately on disconnect. The server also emits a blank-line heartbeat every 15 seconds so intermediaries don't drop idle connections.

The stream identifiers covered on this page are:

proxies, anonymizers, torrents, ja4t.

Honeypot captures (honeypot_http, honeypot_https, honeypot_dns, honeypot_adb) are documented separately under Helios, the Synthient honeypot platform.

Authentication

All endpoints are served from https://api.synthient.com under /api/v4 and require your API key in the x-api-key header. Each stream requires its own scope (PROXY_FIREHOSE, ANONYMIZERS_STREAM, TORRENTS_STREAM, JA4T_STREAM).

curl -N https://api.synthient.com/api/v4/feeds/proxies/stream \
  -H "x-api-key: $SYNTHIENT_API_KEY"

Use curl -N (or your client's equivalent unbuffered/streaming mode) so that lines are delivered to your handler as soon as they arrive. A single API key may only hold a small number of concurrent streams per feed; excess connections are rejected with 429.


Common response codes

A successful stream returns 200 with an NDJSON body, one JSON object per line, held open for up to 30 minutes. 403 means the key lacks the per-stream feed scope. 429 can indicate a team request-rate limit, exhausted key monthly budget, or too many concurrent streams. Retry only when it carries a valid Retry-After. See Errors for the full reference.


GET/api/v4/feeds/proxies/stream

Stream proxies

Real-time stream of proxy IP observations.

  • Name
    ip
    Type
    string
    Description

    IPv4 or IPv6 address of the proxy.

  • Name
    provider
    Type
    string
    Description

    Provider name, such as BRIGHTDATA or IPIDEA.

  • Name
    type
    Type
    string
    Description

    Proxy type, such as RESIDENTIAL_PROXY, DATACENTER_PROXY, or MOBILE_PROXY.

  • Name
    timestamp
    Type
    integer
    Description

    Unix timestamp in seconds when the proxy was observed.

  • Name
    country_code
    Type
    string
    Description

    ISO 3166-1 alpha-2 country of the proxy IP.

  • Name
    asn
    Type
    integer
    Description

    Autonomous System Number of the proxy IP.

Request

GET/api/v4/feeds/proxies/stream
curl -N https://api.synthient.com/api/v4/feeds/proxies/stream \
  -H "x-api-key: $SYNTHIENT_API_KEY"

Sample event

{
  "ip": "38.238.45.9",
  "provider": "DATAIMPULSE",
  "type": "RESIDENTIAL_PROXY",
  "timestamp": 1762605697,
  "country_code": "US",
  "asn": 174
}

Events are delivered as newline-delimited JSON: each event arrives as a single line. The samples above are pretty-printed for readability.


GET/api/v4/feeds/anonymizers/stream

Stream anonymizers

Real-time stream of anonymizer observations: VPNs, Tor exits, and relay-class detections. Anonymizer events emit IP ranges rather than individual addresses.

  • Name
    range_start
    Type
    string
    Description

    First IP in the anonymizer range.

  • Name
    range_end
    Type
    string
    Description

    Last IP in the anonymizer range.

  • Name
    provider
    Type
    string
    Description

    Provider name, such as NORDVPN or MULLVAD.

  • Name
    type
    Type
    string
    Description

    Anonymizer type, such as COMMERCIAL_VPN, TOR_NODE, or PRIVATE_RELAY.

  • Name
    timestamp
    Type
    integer
    Description

    Unix timestamp in milliseconds when the range was observed.

  • Name
    country_code
    Type
    string
    Description

    ISO 3166-1 alpha-2 country of range_start, when available.

  • Name
    asn
    Type
    integer
    Description

    Autonomous System Number of range_start, when available.

Request

GET/api/v4/feeds/anonymizers/stream
curl -N https://api.synthient.com/api/v4/feeds/anonymizers/stream \
  -H "x-api-key: $SYNTHIENT_API_KEY"

Sample event

{
  "range_start": "2.56.252.0",
  "range_end": "2.56.252.255",
  "provider": "NORDVPN",
  "type": "COMMERCIAL_VPN",
  "country_code": "NL",
  "asn": 9009,
  "timestamp": 1762605697000
}

GET/api/v4/feeds/torrents/stream

Stream torrents

Real-time stream of torrent peer sightings from the DHT network and trackers, with info hash, metadata, and observed peers.

  • Name
    info_hash
    Type
    string
    Description

    40-character hex SHA-1 info hash of the torrent.

  • Name
    name
    Type
    string
    Description

    Torrent name from metadata.

  • Name
    magnet_uri
    Type
    string
    Description

    Magnet URI for the torrent.

  • Name
    total_size
    Type
    integer
    Description

    Total size of files in bytes.

  • Name
    piece_length
    Type
    integer
    Description

    Piece length in bytes.

  • Name
    file_count
    Type
    integer
    Description

    Number of files in the torrent.

  • Name
    files
    Type
    array<object>
    Description

    Per-file path and length in bytes.

  • Name
    peers
    Type
    array<object>
    Description

    Observed peers: ip, port, source of DHT, PEX, or tracker, and encrypted.

  • Name
    timestamp
    Type
    integer
    Description

    Unix timestamp in seconds when the torrent was observed.

Request

GET/api/v4/feeds/torrents/stream
curl -N https://api.synthient.com/api/v4/feeds/torrents/stream \
  -H "x-api-key: $SYNTHIENT_API_KEY"

Sample event

{
  "info_hash": "abcdef0123456789abcdef0123456789abcdef01",
  "name": "ubuntu-26.04-desktop-amd64.iso",
  "magnet_uri": "magnet:?xt=urn:btih:abcdef0123456789abcdef0123456789abcdef01&dn=ubuntu-26.04-desktop-amd64.iso",
  "total_size": 4831838208,
  "piece_length": 2097152,
  "file_count": 1,
  "files": [
    { "path": "ubuntu-26.04-desktop-amd64.iso", "length": 4831838208 }
  ],
  "peers": [
    { "ip": "203.0.113.42", "port": 51413, "source": "DHT", "encrypted": true },
    { "ip": "198.51.100.17", "port": 6881, "source": "PEX", "encrypted": false }
  ],
  "timestamp": 1762605697
}

GET/api/v4/feeds/ja4t/stream

Stream JA4T fingerprints

Real-time stream of JA4T TCP fingerprints observed from proxy addresses. Requires the JA4T_STREAM scope; Parquet exports use JA4T_FEED.

  • Name
    ip
    Type
    string
    Description

    IPv4 or IPv6 address the fingerprint was observed from.

  • Name
    ja4t
    Type
    string
    Description

    JA4T TCP fingerprint.

  • Name
    provider
    Type
    string
    Description

    Provider service tag associated with the address.

  • Name
    type
    Type
    string
    Description

    Service category, such as DATACENTER_PROXY.

  • Name
    timestamp
    Type
    integer
    Description

    Unix timestamp in seconds when the fingerprint was observed.

  • Name
    country_code
    Type
    string
    Description

    ISO 3166-1 alpha-2 country code of the address.

  • Name
    asn
    Type
    integer
    Description

    Autonomous System Number of the address.

Request

GET/api/v4/feeds/ja4t/stream
curl -N https://api.synthient.com/api/v4/feeds/ja4t/stream \
  -H "x-api-key: $SYNTHIENT_API_KEY"

Sample event

{
  "ip": "109.176.45.49",
  "ja4t": "43080_2-4-8-1-3_1436_9",
  "provider": "PROXYJET_DATACENTER",
  "type": "DATACENTER_PROXY",
  "timestamp": 1779818967,
  "country_code": "US",
  "asn": 16276
}

Consuming streams

A raw NDJSON consumer reads the response body line by line, skips blank heartbeat lines, and parses each remaining line as JSON. The SDKs handle this framing and retry transient connection-establishment failures with bounded backoff and Retry-After handling.

These consumers reconnect immediately after the server's clean close, normally every ~30 minutes. Any error that remains after the SDK's connection retries, or occurs while reading an established stream, is surfaced to the application. This also stops a 429 without Retry-After from becoming an endless reconnect loop. There is no resume cursor, so events sent while disconnected are missed. See Rate Limits for the retry policy.

NDJSON Consumer

from synthient import Client

with Client() as client:
    while True:
        with client.proxies.stream() as events:
            for event in events:
                print(event.ip, event.provider, event.type)