# Netzwerkzeug API

Canonical v1 base: `/api/v1/`

## Envelope

Every endpoint returns:

```json
{"ok":true,"data":{},"error":null}
```

Errors return `ok: false`, `data: null`, and an error object with
`code` and `message`.

## v1 contract

All v1 endpoints use `POST` with exactly
`Content-Type: application/json`. Requests are JSON objects, limited to 64 KiB;
fields reject control characters and have endpoint-specific limits. Responses
are `application/json`, no-store, same-origin only, with no CORS headers.

Network-backed endpoints use the established validated network handlers, so DNS-worker isolation, public-target validation, SSRF blocking,
DNS-rebinding protection, redirect revalidation, timeouts, response caps,
rate limits, and concurrency limits are shared rather than duplicated.

Local transformations do not require the UI to upload data. The UI remains
local by default; v1 equivalents are available for clients that need them.
Payloads are processed transiently and are not intentionally persisted.

## UI/API parity

| UI route | API route | Method | Request |
|---|---|---|---|
| `/ip/` | `/api/v1/ip/` | POST | `{"cidr":"192.168.42.17/27"}` |
| `/cidr/` | `/api/v1/cidr/` | POST | `{"operation":"network\|split","cidr":"...","target":"20"}` |
| `/dns/` | `/api/v1/dns/` | POST | `{"domain":"example.com"}` |
| `/dns-delegation/` | `/api/v1/dns-delegation/` | POST | `{"domain":"example.com"}` |
| `/dns-propagation/` | `/api/v1/dns-propagation/` | POST | `{"domain":"example.com","record_type":"A"}` |
| `/reverse-dns/` | `/api/v1/reverse-dns/` | POST | `{"ip":"8.8.8.8"}` |
| `/http-headers/` | `/api/v1/http-headers/` | POST | `{"url":"https://example.com/"}` |
| `/redirects/` | `/api/v1/redirects/` | POST | `{"url":"https://example.com/"}` |
| `/tls/` | `/api/v1/tls/` | POST | `{"host":"example.com","port":"443"}` |
| `/port/` | `/api/v1/port/` | POST | `{"query":"https"}` |
| `/mac/` | `/api/v1/mac/` | POST | `{"mac":"00:1B:63:00:00:00"}` |
| `/mail-dns/` | `/api/v1/mail-dns/` | POST | `{"domain":"example.com","selector":"default"}` |
| `/dnssec/` | `/api/v1/dnssec/` | POST | `{"domain":"example.com"}` |
| `/rdap/` | `/api/v1/rdap/` | POST | `{"resource":"example.com"}` |
| `/bgp/` | `/api/v1/bgp/` | POST | `{"resource":"AS15169"}` |
| `/smtp-test/` | `/api/v1/smtp-test/` | POST | `{"domain":"example.com"}` |
| `/http-security/` | `/api/v1/http-security/` | POST | `{"url":"https://example.com/"}` |
| `/domain-health/` | `/api/v1/domain-health/` | POST | `{"domain":"example.com"}` |
| `/internet-identity/` | `/api/v1/internet-identity/` | POST | `{"ip":"8.8.8.8"}` |
| `/ping/` | `/api/v1/ping/` | POST | `{"host":"example.com"}` |
| `/traceroute/` | `/api/v1/traceroute/` | POST | `{"host":"example.com"}` |
| `/network-path/` | `/api/v1/network-path/` | POST | `{"url":"https://example.com/"}` |
| `/port-connectivity/` | `/api/v1/port-connectivity/` | POST | `{"host":"example.com","port":"443"}` |
| `/http-protocol/` | `/api/v1/http-protocol/` | POST | `{"url":"https://example.com/"}` |
| `/mail-health/` | `/api/v1/mail-health/` | POST | `{"domain":"example.com"}` |
| `/ipv6/` | `/api/v1/ipv6/` | POST | `{"operation":"reverse","input":"2001:db8::1"}` |
| `/cidr-overlap/` | `/api/v1/cidr-overlap/` | POST | `{"input":"192.0.2.0/24,192.0.2.0/25"}` |
| `/firewall-rule/` | `/api/v1/firewall-rule/` | POST | `{"input":"{...}"}` |
| `/bgp/` | `/api/v1/bgp/` | POST | `{"resource":"AS15169"}` |
| `/encode/` | `/api/v1/encode/` | POST | `{"operation":"base64-encode","input":"hello"}` |
| `/eicar-mail/` | `/api/v1/eicar-mail/` | POST | `{"domain":"example.org","variant_id":"eicar-txt"}` |

## BGP / ASN / RPKI

`POST /api/v1/bgp/` accepts a public IPv4 or IPv6 address, normalized prefix, or ASN in `AS15169` or `15169` form. The bounded response reports the normalized query, observed prefix, origin ASN, organization, RIPE NCC registry context, up to ten related prefixes, and an RPKI state of `VALID`, `INVALID`, or `UNKNOWN`. RPKI is never inferred: unavailable validator data is reported as `UNKNOWN` with evidence.

The worker uses fixed RIPE NCC RIPEstat endpoints over HTTPS, validates the fixed upstream hostname and all resolved addresses once per request, rejects redirects, caps each response at 64 KiB, allows at most three upstream calls, and enforces the existing 12-second aggregate request deadline with 2-second connect/4-second per-call limits.

## Local operations

### IP

`POST /api/v1/ip/`

Request: `{"cidr":"192.168.42.17/27"}`

Returns family, normalized network prefix, broadcast for IPv4, address count,
usable host count, and classification. IPv6 arithmetic returns the total as a
bounded exponent string.

### CIDR

`POST /api/v1/cidr/`

Use `operation: "network"` for one network or `operation: "split"` with a
numeric `target` prefix. Splits are capped at 4096 IPv4 networks; IPv6 split
API support is rejected explicitly until its bounded representation is added.

### Encoding

`POST /api/v1/encode/`

Supported operations: `url-encode`, `url-decode`, `base64-encode`,
`base64-decode`, `hex-encode`, `hex-decode`, `sha256`, and `sha512`.
Input is capped at 64 KiB.

## Network endpoint behavior

The v1 DNS, reverse DNS, HTTP, redirect, TLS, port, MAC, mail DNS, DNSSEC,
and RDAP routes use the same validators and response structures as the


## SMTP transport analyzer

`POST /api/v1/smtp-test/` accepts a public mail domain in the `domain` field. If the value has public MX records, the analyzer tests the bounded MX transport; if it is a public mail hostname without MX records, that hostname is tested directly on TCP/25. No DATA, AUTH, VRFY, EXPN, relay test, or recipient enumeration is performed.

## EICAR mail scanner test

`POST /api/v1/eicar-mail/` accepts only a public `domain` and exactly one selected `variant_id`: `eicar-txt`, `eicar-zip`, `eicar-tar`, `eicar-tar-gz`, or `eicar-bzip2`. The server constructs the recipient as `postmaster@` plus the validated domain, reads only the five fixed files under `/files`, uses a fixed sender and subject, resolves public MX targets, and connects directly to public TCP/25. Arbitrary recipient fields, SMTP hosts, ports, paths, uploads, and multiple attachments are rejected.

## EICAR delivery limitations

Direct-to-MX delivery can be rejected by SPF, DKIM, DMARC, reverse-DNS policy, reputation, anti-spam policy, or outbound TCP/25 filtering. Such rejection is reported as a controlled upstream result; the service does not weaken recipient security or automatically change SPF, DKIM, or DMARC.

## Limits and errors

- JSON body: 64 KiB; response: 1 MiB.
- Network query fields: 2048 characters; RDAP resource: 253 characters.
- Network operations retain the existing per-client expensive-operation rate and
  concurrency limits.
- Local APIs reject unsupported methods, content types, fields, and malformed
  schemas.
- Errors include `INVALID_INPUT`, `METHOD_NOT_ALLOWED`,
  `UNSUPPORTED_MEDIA_TYPE`, `REQUEST_TOO_LARGE`, `RESPONSE_TOO_LARGE`,
  `RATE_LIMITED`, `TIMEOUT`, `SERVICE_UNAVAILABLE`, and
  `INTERNAL_ERROR`.
- No CORS, no authentication, no arbitrary target override, no shell execution,
  and no sensitive-payload logging by the API.
