openapi: 3.0.3
info:
  title: Netzwerkzeug Diagnostic API
  version: 1.0.0
  description: Versioned same-origin API for network diagnostics and bounded local transformations.
servers:
  - url: https://www.netzwerkzeug.ch
    description: Canonical HTTPS host
paths:
  /api/v1/ip/:
    post: { $ref: '#/components/x-tool-post/ip' }
  /api/v1/cidr/:
    post: { $ref: '#/components/x-tool-post/cidr' }
  /api/v1/dns/:
    post: { $ref: '#/components/x-tool-post/dns' }
  /api/v1/reverse-dns/:
    post: { $ref: '#/components/x-tool-post/reverse-dns' }
  /api/v1/http-headers/:
    post: { $ref: '#/components/x-tool-post/http' }
  /api/v1/redirects/:
    post: { $ref: '#/components/x-tool-post/redirects' }
  /api/v1/tls/:
    post: { $ref: '#/components/x-tool-post/tls' }
  /api/v1/port/:
    post: { $ref: '#/components/x-tool-post/port' }
  /api/v1/mac/:
    post: { $ref: '#/components/x-tool-post/mac' }
  /api/v1/mail-dns/:
    post: { $ref: '#/components/x-tool-post/mail' }
  /api/v1/dnssec/:
    post: { $ref: '#/components/x-tool-post/dnssec' }
  /api/v1/rdap/:
    post: { $ref: '#/components/x-tool-post/rdap' }
  /api/v1/encode/:
    post: { $ref: '#/components/x-tool-post/encode' }
  /api/v1/timestamp/:
    post: { $ref: '#/components/x-tool-post/timestamp' }
  /api/v1/chmod/:
    post: { $ref: '#/components/x-tool-post/chmod' }
  /api/v1/cron/:
    post: { $ref: '#/components/x-tool-post/cron' }
  /api/v1/eicar-mail/:
    post: { $ref: '#/components/x-tool-post/eicar-mail' }

components:
  x-tool-post:
    ip:
      summary: Calculate IPv4 or IPv6 network details
      operationId: ip
      requestBody: { $ref: '#/components/requestBodies/Ip' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '405': { $ref: '#/components/responses/MethodNotAllowed' }, '415': { $ref: '#/components/responses/UnsupportedMediaType' } }
    cidr:
      summary: Calculate or split bounded CIDR networks
      operationId: cidr
      requestBody: { $ref: '#/components/requestBodies/Cidr' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '405': { $ref: '#/components/responses/MethodNotAllowed' }, '415': { $ref: '#/components/responses/UnsupportedMediaType' } }
    dns:
      summary: Public DNS records
      operationId: dns
      requestBody: { $ref: '#/components/requestBodies/Domain' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' } }
    reverse-dns:
      summary: Public reverse DNS
      operationId: reverseDns
      requestBody: { $ref: '#/components/requestBodies/IpAddress' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' } }
    http:
      summary: Inspect public HTTP headers
      operationId: httpHeaders
      requestBody: { $ref: '#/components/requestBodies/Url' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' } }
    redirects:
      summary: Check public redirects
      operationId: redirects
      requestBody: { $ref: '#/components/requestBodies/Url' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' } }
    tls:
      summary: Inspect a public TLS certificate
      operationId: tls
      requestBody: { $ref: '#/components/requestBodies/Tls' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' } }
    port:
      summary: Look up a port or service
      operationId: port
      requestBody: { $ref: '#/components/requestBodies/Query' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' } }
    mac:
      summary: Look up a MAC or OUI
      operationId: mac
      requestBody: { $ref: '#/components/requestBodies/Mac' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' } }
    mail:
      summary: Check mail DNS policy
      operationId: mailDns
      requestBody: { $ref: '#/components/requestBodies/Mail' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' } }
    dnssec:
      summary: Inspect DNSSEC records
      operationId: dnssec
      requestBody: { $ref: '#/components/requestBodies/Domain' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' } }
    rdap:
      summary: Look up a domain, IP, or ASN
      operationId: rdap
      requestBody: { $ref: '#/components/requestBodies/Rdap' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' } }
    encode:
      summary: Perform a bounded local encoding transform
      operationId: encode
      requestBody: { $ref: '#/components/requestBodies/Encode' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' } }
    timestamp:
      summary: Convert timestamp/date
      operationId: timestamp
      requestBody: { $ref: '#/components/requestBodies/Timestamp' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' } }
    chmod:
      summary: Convert chmod modes
      operationId: chmod
      requestBody: { $ref: '#/components/requestBodies/Chmod' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' } }
    cron:
      summary: Validate five-field cron syntax
      operationId: cron
      requestBody: { $ref: '#/components/requestBodies/Cron' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' } }
    eicar-mail:
      summary: Send one fixed EICAR attachment to an allowlisted scanner mailbox
      operationId: eicarMail
      requestBody: { $ref: '#/components/requestBodies/EicarMail' }
      responses: { '200': { $ref: '#/components/responses/Success' }, '400': { $ref: '#/components/responses/BadRequest' }, '403': { $ref: '#/components/responses/Forbidden' }, '429': { $ref: '#/components/responses/RateLimited' }, '502': { $ref: '#/components/responses/UpstreamError' }, '503': { $ref: '#/components/responses/Unavailable' } }
  requestBodies:
    Ip: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/IpRequest' } } } }
    Cidr: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CidrRequest' } } } }
    Domain: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/DomainRequest' } } } }
    IpAddress: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/IpAddressRequest' } } } }
    Url: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/UrlRequest' } } } }
    Tls: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TlsRequest' } } } }
    Query: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/QueryRequest' } } } }
    Mac: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/MacRequest' } } } }
    Mail: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/MailRequest' } } } }
    Rdap: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RdapRequest' } } } }
    Encode: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/EncodeRequest' } } } }
    Timestamp: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TimestampRequest' } } } }
    Chmod: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ChmodRequest' } } } }
    Cron: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CronRequest' } } } }
    EicarMail: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/EicarMailRequest' } } } }
  schemas:
    Envelope:
      type: object
      required: [ok, data, error]
      properties:
        ok: { type: boolean }
        data: { nullable: true, type: object, additionalProperties: true }
        error: { nullable: true, type: object, additionalProperties: true }
    IpRequest: { type: object, required: [cidr], additionalProperties: false, properties: { cidr: { type: string, maxLength: 256 } } }
    CidrRequest: { type: object, required: [operation, cidr], additionalProperties: false, properties: { operation: { type: string, enum: [network, split] }, cidr: { type: string, maxLength: 256 }, target: { type: string, pattern: '^[0-9]{1,3}$' } } }
    DomainRequest: { type: object, required: [domain], additionalProperties: false, properties: { domain: { type: string, maxLength: 253 } } }
    IpAddressRequest: { type: object, required: [ip], additionalProperties: false, properties: { ip: { type: string, maxLength: 128 } } }
    UrlRequest: { type: object, required: [url], additionalProperties: false, properties: { url: { type: string, maxLength: 2048, format: uri } } }
    TlsRequest: { type: object, required: [host], additionalProperties: false, properties: { host: { type: string, maxLength: 253 }, port: { type: string, pattern: '^[0-9]{1,5}$', default: '443' } } }
    QueryRequest: { type: object, required: [query], additionalProperties: false, properties: { query: { type: string, maxLength: 2048 } } }
    MacRequest: { type: object, required: [mac], additionalProperties: false, properties: { mac: { type: string, maxLength: 2048 } } }
    MailRequest: { type: object, required: [domain], additionalProperties: false, properties: { domain: { type: string, maxLength: 253 }, selector: { type: string, maxLength: 63 } } }
    RdapRequest: { type: object, required: [resource], additionalProperties: false, properties: { resource: { type: string, maxLength: 253 } } }
    EncodeRequest: { type: object, required: [operation, input], additionalProperties: false, properties: { operation: { type: string }, input: { type: string, maxLength: 65536 } } }
    TimestampRequest: { type: object, required: [operation, value], additionalProperties: false, properties: { operation: { type: string, enum: [to-date, to-timestamp] }, value: { type: string, maxLength: 128 } } }
    ChmodRequest: { type: object, required: [value], additionalProperties: false, properties: { value: { type: string, maxLength: 16 } } }
    CronRequest: { type: object, required: [expression], additionalProperties: false, properties: { expression: { type: string, maxLength: 128 } } }
    EicarMailRequest: { type: object, required: [recipient_id, variant_id], additionalProperties: false, properties: { recipient_id: { type: string, maxLength: 64 }, variant_id: { type: string, enum: [eicar-txt, eicar-zip, eicar-tar, eicar-tar-gz, eicar-bzip2] } } }
  responses:
    Forbidden: { description: Recipient is not allowlisted, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    Unavailable: { description: EICAR sending is disabled or unavailable, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    Success: { description: Success, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    BadRequest: { description: Invalid input, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    MethodNotAllowed: { description: POST required, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    UnsupportedMediaType: { description: application/json required, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    TooLarge: { description: Request or response too large, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    RateLimited: { description: Rate or concurrency limit exceeded, headers: { Retry-After: { schema: { type: integer } } }, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
    UpstreamError: { description: Controlled upstream failure, content: { application/json: { schema: { $ref: '#/components/schemas/Envelope' } } } }
