/ Go / threat context / API
Security Enrichment
A public Go service for gathering source-specific context about IPs, domains, hashes, and URLs.
Threat context, not a verdict
A threat intelligence enrichment API is most useful when it adds evidence to an investigation rather than pretending to settle one. An IP can have abuse reports without explaining the traffic in front of you; a hash can be absent from a provider; a URL can be risky to disclose. Security Enrichment gathers source-specific context for public IPs, domains, supported file hashes, and URLs while leaving those boundaries visible.
The service validates an indicator, requests configured providers for that input type, and returns normalized data with source metadata. A source timing out or being unavailable can still leave a useful partial response. It does not turn absent data into a “safe” result, and it is not an automated blocking or malware-verdict engine.
How to read an enrichment result
| Result | What it means |
|---|---|
| Source returned no match | That provider did not return a matching record; it is not a clean verdict. |
| Source timed out or errored | Coverage is incomplete for this request. |
| One provider flagged an indicator | One source has concerning evidence that needs context and review. |
| All configured sources returned | Context is more complete, but still not certainty about safety or intent. |
One request, several source outcomes
indicator → validation → configured source requests → normalized response + source outcomesDifferent sources answer different questions. IPinfo, AbuseIPDB, and VirusTotal add IP context; domain requests can combine WHOIS, DNS, TLS, VirusTotal, and OTX; hash requests use VirusTotal, MalwareBazaar, and CIRCL HashLookup. URL requests use Safe Browsing and VirusTotal, with URLScan submission available only when the deployment enables it and the caller explicitly asks for it.
The response preserves those outcomes instead of collapsing a timeout, null block, missing field, or source error into “clean.” Server-side caching reduces repeat provider requests: complete success is cached longer than a partial result, while a total upstream failure is not cached. URL responses declare Cache-Control: no-store for clients and intermediaries; that does not disable the service's own guarded server-side cache.
Using the service safely
The hosted tool is the simplest way to inspect a benign public indicator. API consumers can use the public endpoints below. There is no visitor API-key flow at the public edge, and scripted access may still encounter CDN or origin controls.
Send only indicators that are appropriate to disclose. In particular, do not submit credentials, private reset or invitation links, bearer tokens, or other sensitive URLs. URL lookup uses POST so the value is not placed in a query string, and URLScan is opt-in because submission can disclose a URL to that third party.
API
Base URL: https://api.ahlyxlabs.com. The API returns source-level context and explicit errors; it does not advertise a Swagger or OpenAPI endpoint.
| Method and path | Purpose and configured source mappings |
|---|---|
GET /health | Health response. |
GET /api/v1/capabilities | Reports urlscan_active_submission. |
GET /api/v1/ip/{address} | IPinfo, AbuseIPDB, and VirusTotal context. |
GET /api/v1/domain/{name} | WHOIS, DNS, TLS, VirusTotal, and OTX context. |
GET /api/v1/hash/{hash} | VirusTotal, MalwareBazaar, and CIRCL HashLookup context. |
POST /api/v1/url | Safe Browsing and VirusTotal context; URLScan only when enabled and explicitly requested. |
GET /api/v1/url | Retired; returns 410 Gone. |
curl 'https://api.ahlyxlabs.com/api/v1/ip/8.8.8.8'
curl 'https://api.ahlyxlabs.com/api/v1/url' \
-H 'Content-Type: application/json' \
--data '{"url":"https://example.com","submit_urlscan":false}'URLScan submission requires both deployment enablement and submit_urlscan: true. The default example does not submit a URL to URLScan.
Per-client buckets replenish at 30/minute for IP, domain, and hash requests, and 10/minute for URL requests; shared and CDN limits can apply as well. Invalid input can return 400, throttling 429, an origin denial 403, and the retired GET route 410. Backend errors use {"error":"message"}; CDN errors can differ.
Sanitized URL response shape
{
"query": "https://example.com",
"query_type": "url",
"timestamp": "2026-09-18T00:00:00Z",
"sources": [],
"url": "https://example.com",
"safe_browsing": null,
"urlscan": null,
"virustotal": null,
"is_malicious": false
}Null or absent source data means context was unavailable for that response; it is not proof that the URL is safe. The example shows the envelope shape only and does not treat an empty sources array or is_malicious: false as a clean verdict.
URL privacy and interpretation limits
URL lookup uses POST so an indicator URL is not placed in the request line or query string. That is a useful privacy choice, not a promise that a sensitive URL is safe to submit. Do not send credentials, private reset or invitation links, tokens, or other values that should not leave your control.
URLScan is deliberately different from passive context gathering: active submission can disclose a URL to a third party. The deployment must enable it and the caller must send submit_urlscan: true; the default is not to submit. Provider coverage can also be incomplete, stale, quota-limited, or contradictory. Use the response as context for an analyst's judgment, not an SLA or guarantee of safety.
Sources and further reading
Public router (commit e8db6f2) · Enrichment implementation (commit e8db6f2) · URL handler (commit e8db6f2)