Skip to main content

Python client for the TechRecon JA4 + web-crawl technology intelligence API

Project description

techrecon (Python client)

Python client for the TechRecon JA4 fingerprinting + web-crawl technology intelligence API. Generated from docs/openapi.yaml (spec version 1.1.0).

  • Zero runtime dependencies — built on urllib.request from the standard library only.
  • Typed — one method per endpoint, TypedDict response shapes, typed exceptions per HTTP status code.
  • Requires Python 3.10+.

PyPI status: techrecon 0.1.0 was uploaded on 2026-07-08, but it was built from a stale tree — its default base URL points at the dead api.techrecon.io host, so it fails out of the box unless you pass base_url explicitly. Use 0.1.1 or later once published (default base URL fixed to the live /api edge).

Install

pip install techrecon

Or install from a local checkout:

cd sdk/python
pip install -e .

5-minute quickstart

1. Get an API key

Every endpoint except health checks and docs requires an API key, sent as the X-API-Key header. Get one from your TechRecon account (POST /v1/account/keys), or ask your TechRecon contact for one.

2. Create a client

from techrecon import TechRecon

client = TechRecon(api_key="<YOUR_TECHRECON_API_KEY>")

Point at a local dev server instead of production with base_url:

client = TechRecon(api_key="<YOUR_TECHRECON_API_KEY>", base_url="http://localhost:8080")

3. Your first lookup

Look up a domain's detected technology stack:

domain = client.get_domain("wordpress.org")
print(domain["tech_count"], "technologies detected")
for tech in domain["technologies"]:
    print(f"  {tech['technology']} ({tech['confidence']:.2f} confidence)")
4 technologies detected
  WordPress (0.99 confidence)
  PHP (0.95 confidence)

Or look up a JA4 TLS fingerprint directly:

result = client.lookup("t13d1516h2_8daaf6152771_b0da82dd1658", ip="93.184.216.34")
if result["ja4_tech_match"]:
    print(result["ja4_tech_match"]["technology"])  # "nginx"
else:
    print("no mapping for this fingerprint yet")

4. Handle errors

Every non-2xx response raises a typed exception carrying the status code and the API's {"error": "..."} message:

from techrecon import NotFoundError, RateLimitError, TechRecon

client = TechRecon(api_key="trk_live_...")
try:
    client.get_domain("does-not-exist.example")
except NotFoundError as exc:
    print(f"not found: {exc.message}")
except RateLimitError as exc:
    print(f"rate limited (429): {exc.message}")

See Exceptions below for the full hierarchy.

5. That's it

You now have a working client. See Endpoints covered below for the full method list, or browse the interactive spec at https://techrecon.whoisxmlapi.com/api/v1/docs (GET /v1/docs relative to the API base).

More examples

Bulk domain lookup (up to 100 domains per call):

result = client.bulk_domain_lookup(["example.com", "wordpress.org"])
for r in result["results"]:
    print(r["domain"], r["tech_count"])

Search by technology:

page = client.search(technology="WordPress", min_confidence=0.8, limit=50)
for hit in page["results"]:
    print(hit["domain"])
if page["has_more"]:
    next_page = client.search(technology="WordPress", cursor=page["next_cursor"])

Change feed (technology adds/removes/updates in the last N days):

changes = client.get_changes(since="2026-06-01T00:00:00Z", technology="WordPress")
for event in changes["changes"]:
    print(event["domain"], event["change_type"], event["technology"])

Reverse pivot from a JA4 hash to the domains that present it:

page = client.pivot_ja4("t13d1516h2_8daaf6152771_02713d6af862")
print(page["summary"]["total_domains"], "domains observed with this fingerprint")

Create a Slack alert on any technology change for a domain:

alert = client.create_alert(
    channel="slack",
    endpoint="https://hooks.slack.com/services/XXX/YYY/ZZZ",
    domain="example.com",
)
print(alert["id"])

Endpoints covered

This client covers the stable, public surface of docs/openapi.yaml. Endpoints marked x-internal: true in the spec — self-serve signup/email-verification (beta, not GA), Stripe billing (beta, being replaced by the NAF gateway), and the privacy admin routes — are intentionally not wrapped here; they're beta or admin-only per the spec's own descriptions. Everything else is covered:

Area Methods
Health health, readiness
JA4 Lookup lookup, bulk_lookup, stats, top_unknown
Domain get_domain, bulk_domain_lookup, get_domain_history, get_domain_changes
Change feed get_changes
Search search
Technologies get_tech_stats, get_tech_trend
Exports create_export, get_export_status, download_export
System get_system_stats, get_system_health
Ingestion ingest_crawl_results (system identity only — 403 for tenant keys)
Crawl requests create_crawl_request, list_pending_crawl_requests, get_crawl_request_status
Priority crawl submit_priority_crawl, get_priority_crawl_status
IP lookup ip_batch_lookup
Pivots pivot_ja4, pivot_jarm, pivot_favicon, pivot_analytics_ga, pivot_analytics_gtm, pivot_analytics_fb_pixel
Alerts create_alert, list_alerts, delete_alert
Auth login, logout
Account get_account, list_api_keys, issue_api_key, revoke_api_key, get_account_usage

Exceptions

All exceptions inherit from techrecon.TechReconError. HTTP errors raise techrecon.APIError subclasses, each carrying .status_code, .message (the API's error field), and .body (raw response text):

Exception HTTP status
BadRequestError 400
AuthenticationError 401
ForbiddenError 403
NotFoundError 404
ConflictError 409
PayloadTooLargeError 413
RateLimitError 429 (rate limiting and quota exhaustion — the spec has no 402; 429 is used uniformly, e.g. alert quota, API-key cap)
ServiceUnavailableError 503 (a required storage backend isn't configured)

Development

cd sdk/python
python3 -m py_compile src/techrecon/*.py tests/*.py   # syntax check
python3 -m pytest tests/                               # run tests (network-free)

Tests use a fake in-memory transport (tests/fake_transport.py) — no network access or live API key is required to run them.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

techrecon-0.1.1.tar.gz (21.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

techrecon-0.1.1-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

Details for the file techrecon-0.1.1.tar.gz.

File metadata

  • Download URL: techrecon-0.1.1.tar.gz
  • Upload date:
  • Size: 21.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for techrecon-0.1.1.tar.gz
Algorithm Hash digest
SHA256 0481c3f5c5f111c7324b6ef7873a77561cd7fe7aa98ec5e3f0b12f0a996688ae
MD5 7a6821760c60dbe992a7e7509e1f22b7
BLAKE2b-256 adc3f6ac903dc06159db76b4a599056f253ff80dd5c6be179bae5fbd1e8adbdb

See more details on using hashes here.

File details

Details for the file techrecon-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: techrecon-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 17.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for techrecon-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dd64ac8eaa5449d4090ffe2cc55dbade76d3f57275180449b03065edd084134d
MD5 e4ca2ed49c9f4b3e6771fcdd7d8b823e
BLAKE2b-256 375c67bd1c2d50b02cf39527c31e227e456d7d889a6cf5111db2f995273ed97c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page