# Netzwerkzeug API

Canonical v1 base: `https://www.netzwerkzeug.ch/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"}` |
| `/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"}` |
| `/encode/` | `/api/v1/encode/` | POST | `{"operation":"base64-encode","input":"hello"}` |
| `/unix/` | `/api/v1/timestamp/`, `/chmod/`, `/cron/` | POST | Operation-specific JSON |
| `/eicar-mail/` | `/api/v1/eicar-mail/` | POST | `{"recipient_id":"scanner-test-1","variant_id":"eicar-txt"}` |

## 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.

### Unix utilities

- `POST /api/v1/timestamp/`: `{"operation":"to-date","value":"0"}` or
  `{"operation":"to-timestamp","value":"2026-01-01T00:00:00Z"}`.
- `POST /api/v1/chmod/`: `{"value":"755"}` or
  `{"value":"rwxr-xr-x"}`.
- `POST /api/v1/cron/`: `{"expression":"*/5 * * * *"}`.

## 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


## EICAR mail scanner test

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

The protected recipient configuration maps opaque `scanner-test-1` to the explicitly authorized `neo@spacerat.ch` mailbox outside document root.

## 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.
