{"openapi":"3.1.0","info":{"title":"thenetworkery.com API","version":"1.1.0","summary":"Free network diagnostics as JSON: DNS, email authentication, TLS, IP and routing, calculators, DN42.","description":"Every tool on https://thenetworkery.com is available here. No key or sign-up is needed.\n\n* **Webhook bins:** `POST /webhooks` makes a URL that records requests sent to it; reading them needs the bin's key as `Authorization: Bearer <key>`.\n* **Rate limit:** 60 requests a minute per IP address (HTTP 429 with Retry-After above that).\n* **Results:** each answer has an overall `status` (pass, info, warn or fail), the `findings` with explanations and fixes, the raw `data` and a `url` that opens the check in a browser. MCP tools and saved results (`/r/{id}.json`) return the same shape.\n* **Text:** `format=text` (or `Accept: text/plain`) and `format=md` (or `Accept: text/markdown`) return the result as text. curl, wget and HTTPie get a tool's own text form where it has one, JSON otherwise; send `format=json` to force JSON.\n* **Browsers:** CORS is open, so you can call it from any web page.\n* **Language:** findings come in English with their values filled in (`text`, and the same in `title`); `params` holds the values on their own.","contact":{"name":"thenetworkery.com","url":"https://thenetworkery.com/about"}},"servers":[{"url":"https://thenetworkery.com/api/v1"}],"security":[],"externalDocs":{"description":"API reference","url":"https://thenetworkery.com/api"},"tags":[{"name":"Discovery","description":"What the API offers."},{"name":"Web & TLS","description":"Certificates, TLS and HTTP security headers."},{"name":"Your connection","description":"About the caller's own connection."},{"name":"DNS","description":"Records, propagation across public resolvers and DNSSEC."},{"name":"Email","description":"SPF, DKIM, DMARC, MTA-STS, BIMI and blocklists."},{"name":"IP & routing","description":"Registration data, BGP routing and hardware addresses."},{"name":"Calculators","description":"Subnet maths and key generation; nothing leaves the server."},{"name":"Developer","description":"Tools for building and testing integrations."},{"name":"DN42","description":"The DN42 hobby network: registry, free resources, peering."},{"name":"Webhook bins","description":"A URL that records every request sent to it. Create one, point a sender at it, then read what arrived. Reading needs the bin's key."},{"name":"DNS resolver monitor","description":"Our own measurements of public DNS resolvers from London, every 5 minutes: availability, query time, DNSSEC validation, NXDOMAIN behaviour, EDNS Client Subnet and filtering."}],"paths":{"/":{"get":{"operationId":"listTools","summary":"List the tools","description":"Every tool with its slug, title, summary, parameter names and URL.","tags":["Discovery"],"responses":{"200":{"description":"The tools.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolList"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/domain-report":{"get":{"operationId":"domainReport","summary":"Domain health report","description":"DNS, DNSSEC, email security, blocklists, certificates, HTTPS and registration in one report with a security grade (A+ to F) and what to fix first.\n\nWeb page: https://thenetworkery.com/tools/domain-report","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"domain","in":"query","required":true,"description":"Domain","schema":{"type":"string","maxLength":253},"example":"thenetworkery.com"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Domain health report (JSON body)","operationId":"postDomainReport","description":"DNS, DNSSEC, email security, blocklists, certificates, HTTPS and registration in one report with a security grade (A+ to F) and what to fix first.\n\nWeb page: https://thenetworkery.com/tools/domain-report","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"description":"Domain"}},"required":["domain"],"example":{"domain":"thenetworkery.com"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"description":"Domain"}},"required":["domain"],"example":{"domain":"thenetworkery.com"}}}}}}},"/my-ip":{"get":{"operationId":"myIp","summary":"What's my IP?","description":"Your public IP address, reverse DNS and network, plus IPv6, latency and WebRTC leak checks in your browser – also as plain text for curl.\n\nWeb page: https://thenetworkery.com/tools/my-ip","tags":["Your connection"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"$ref":"#/components/parameters/format"}]},"post":{"summary":"What's my IP? (JSON body)","operationId":"postMyIp","description":"Your public IP address, reverse DNS and network, plus IPv6, latency and WebRTC leak checks in your browser – also as plain text for curl.\n\nWeb page: https://thenetworkery.com/tools/my-ip","tags":["Your connection"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{}}}}}}},"/dns-lookup":{"get":{"operationId":"dnsLookup","summary":"DNS lookup","description":"Every record for a name from its authoritative nameservers or a public resolver, or one record compared across 13 resolvers worldwide.\n\nWeb page: https://thenetworkery.com/tools/dns-lookup","tags":["DNS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"name","in":"query","required":true,"description":"Domain or host name","schema":{"type":"string","maxLength":253},"example":"thenetworkery.com"},{"name":"type","in":"query","required":false,"description":"Record type","schema":{"type":"string","enum":["ALL","A","AAAA","CNAME","MX","NS","TXT","SOA","CAA","SRV","PTR","HTTPS","TLSA","DS","DNSKEY"],"description":"`ALL` – All common types","default":"ALL"},"example":"ALL"},{"name":"resolver","in":"query","required":false,"description":"Resolver","schema":{"type":"string","enum":["authoritative","cloudflare","google","quad9","all"],"description":"`authoritative` – Our resolver (authoritative path); `cloudflare` – Cloudflare; `google` – Google; `quad9` – Quad9; `all` – All 13 public resolvers (propagation)","default":"authoritative"},"example":"authoritative"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"DNS lookup (JSON body)","operationId":"postDnsLookup","description":"Every record for a name from its authoritative nameservers or a public resolver, or one record compared across 13 resolvers worldwide.\n\nWeb page: https://thenetworkery.com/tools/dns-lookup","tags":["DNS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"description":"Domain or host name"},"type":{"type":"string","enum":["ALL","A","AAAA","CNAME","MX","NS","TXT","SOA","CAA","SRV","PTR","HTTPS","TLSA","DS","DNSKEY"],"description":"`ALL` – All common types","default":"ALL"},"resolver":{"type":"string","enum":["authoritative","cloudflare","google","quad9","all"],"description":"`authoritative` – Our resolver (authoritative path); `cloudflare` – Cloudflare; `google` – Google; `quad9` – Quad9; `all` – All 13 public resolvers (propagation)","default":"authoritative"}},"required":["name"],"example":{"name":"thenetworkery.com","type":"ALL","resolver":"authoritative"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"description":"Domain or host name"},"type":{"type":"string","enum":["ALL","A","AAAA","CNAME","MX","NS","TXT","SOA","CAA","SRV","PTR","HTTPS","TLSA","DS","DNSKEY"],"description":"`ALL` – All common types","default":"ALL"},"resolver":{"type":"string","enum":["authoritative","cloudflare","google","quad9","all"],"description":"`authoritative` – Our resolver (authoritative path); `cloudflare` – Cloudflare; `google` – Google; `quad9` – Quad9; `all` – All 13 public resolvers (propagation)","default":"authoritative"}},"required":["name"],"example":{"name":"thenetworkery.com","type":"ALL","resolver":"authoritative"}}}}}}},"/dnssec":{"get":{"operationId":"dnssec","summary":"DNSSEC check","description":"Is the zone signed, does the chain of trust validate, and are the algorithms current?\n\nWeb page: https://thenetworkery.com/tools/dnssec","tags":["DNS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"name","in":"query","required":true,"description":"Domain","schema":{"type":"string","maxLength":253},"example":"ietf.org"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"DNSSEC check (JSON body)","operationId":"postDnssec","description":"Is the zone signed, does the chain of trust validate, and are the algorithms current?\n\nWeb page: https://thenetworkery.com/tools/dnssec","tags":["DNS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"description":"Domain"}},"required":["name"],"example":{"name":"ietf.org"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":253,"description":"Domain"}},"required":["name"],"example":{"name":"ietf.org"}}}}}}},"/nameserver-check":{"get":{"operationId":"nameserverCheck","summary":"Nameserver health check","description":"Tests every nameserver of a domain directly: lame or unreachable servers, NS and glue mismatches, SOA serials, open recursion, TCP and EDNS.\n\nWeb page: https://thenetworkery.com/tools/nameserver-check","tags":["DNS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"zone","in":"query","required":true,"description":"Domain","schema":{"type":"string","maxLength":253},"example":"ietf.org"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Nameserver health check (JSON body)","operationId":"postNameserverCheck","description":"Tests every nameserver of a domain directly: lame or unreachable servers, NS and glue mismatches, SOA serials, open recursion, TCP and EDNS.\n\nWeb page: https://thenetworkery.com/tools/nameserver-check","tags":["DNS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"zone":{"type":"string","maxLength":253,"description":"Domain"}},"required":["zone"],"example":{"zone":"ietf.org"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"zone":{"type":"string","maxLength":253,"description":"Domain"}},"required":["zone"],"example":{"zone":"ietf.org"}}}}}}},"/email-auth":{"get":{"operationId":"emailAuth","summary":"Email security check","description":"SPF, DKIM, DMARC, MTA-STS, TLS-RPT and BIMI graded, with the exact records to fix what is missing.\n\nWeb page: https://thenetworkery.com/tools/email-auth","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"domain","in":"query","required":true,"description":"Domain","schema":{"type":"string","maxLength":253},"example":"gov.uk"},{"name":"check","in":"query","required":false,"description":"Check","schema":{"type":"string","enum":["all","spf","dkim","dmarc"],"description":"`all` – Everything (MX, SPF, DKIM, DMARC, MTA-STS, BIMI); `spf` – SPF only; `dkim` – DKIM only; `dmarc` – DMARC only","default":"all"}},{"name":"selector","in":"query","required":false,"description":"DKIM selector (optional) (check=dkim)","schema":{"type":"string","maxLength":63},"example":"google or selector1"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Email security check (JSON body)","operationId":"postEmailAuth","description":"SPF, DKIM, DMARC, MTA-STS, TLS-RPT and BIMI graded, with the exact records to fix what is missing.\n\nWeb page: https://thenetworkery.com/tools/email-auth","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"description":"Domain"},"check":{"type":"string","enum":["all","spf","dkim","dmarc"],"description":"`all` – Everything (MX, SPF, DKIM, DMARC, MTA-STS, BIMI); `spf` – SPF only; `dkim` – DKIM only; `dmarc` – DMARC only","default":"all"},"selector":{"type":"string","maxLength":63,"description":"DKIM selector (optional) (check=dkim)"}},"required":["domain"],"example":{"domain":"gov.uk"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"description":"Domain"},"check":{"type":"string","enum":["all","spf","dkim","dmarc"],"description":"`all` – Everything (MX, SPF, DKIM, DMARC, MTA-STS, BIMI); `spf` – SPF only; `dkim` – DKIM only; `dmarc` – DMARC only","default":"all"},"selector":{"type":"string","maxLength":63,"description":"DKIM selector (optional) (check=dkim)"}},"required":["domain"],"example":{"domain":"gov.uk"}}}}}}},"/email-headers":{"post":{"summary":"Email test","operationId":"postEmailHeaders","description":"Paste a message's headers to see its route and delays, SPF, DKIM and DMARC results with alignment, and why it may have gone to spam.\n\nWeb page: https://thenetworkery.com/tools/email-headers","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"headers":{"type":"string","maxLength":200000,"description":"Message headers Never stored or logged."}},"required":["headers"]}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"headers":{"type":"string","maxLength":200000,"description":"Message headers Never stored or logged."}},"required":["headers"]}}}}}},"/email-record-builder":{"get":{"operationId":"emailRecordBuilder","summary":"Email record builder","description":"Build an SPF record from the services that send your mail, or a DMARC record from a policy, and compare it with the one you publish now.\n\nWeb page: https://thenetworkery.com/tools/email-record-builder","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"type","in":"query","required":false,"description":"Record","schema":{"type":"string","enum":["spf","dmarc"],"description":"`spf` – SPF record; `dmarc` – DMARC record","default":"spf"},"example":"spf"},{"name":"domain","in":"query","required":true,"description":"Domain","schema":{"type":"string","maxLength":253},"example":"example.com"},{"name":"all","in":"query","required":false,"description":"Mail from anywhere else (type=spf)","schema":{"type":"string","enum":["~all","-all"],"description":"`~all` – Soft fail (~all); `-all` – Fail (-all)","default":"~all"},"example":"~all"},{"name":"providers","in":"query","required":false,"description":"Services that send mail as this domain (type=spf)","schema":{"type":"string","maxLength":500},"example":"google,sendgrid"},{"name":"extra","in":"query","required":false,"description":"Extra entries (optional) (type=spf)","schema":{"type":"string","maxLength":1000},"example":"ip4:192.0.2.10"},{"name":"p","in":"query","required":false,"description":"Policy (p) (type=dmarc)","schema":{"type":"string","enum":["none","quarantine","reject"],"description":"`none` – none – monitor only; `quarantine` – quarantine – send to spam; `reject` – reject – refuse","default":"none"}},{"name":"sp","in":"query","required":false,"description":"Subdomain policy (sp) (type=dmarc)","schema":{"type":"string","enum":["none","quarantine","reject"],"description":"`` – Same as p"}},{"name":"rua","in":"query","required":false,"description":"Aggregate reports to (rua) (type=dmarc)","schema":{"type":"string","maxLength":500},"example":"dmarc-reports@example.com"},{"name":"ruf","in":"query","required":false,"description":"Failure reports to (ruf, optional) (type=dmarc)","schema":{"type":"string","maxLength":500},"example":"dmarc-failures@example.com"},{"name":"adkim","in":"query","required":false,"description":"DKIM alignment (adkim) (type=dmarc)","schema":{"type":"string","enum":["r","s"],"description":"`r` – relaxed (r); `s` – strict (s)","default":"r"}},{"name":"aspf","in":"query","required":false,"description":"SPF alignment (aspf) (type=dmarc)","schema":{"type":"string","enum":["r","s"],"description":"`r` – relaxed (r); `s` – strict (s)","default":"r"}},{"name":"t","in":"query","required":false,"description":"Test mode (t) (type=dmarc)","schema":{"type":"string","enum":["n","y"],"description":"`n` – off (t=n); `y` – on (t=y)","default":"n"}},{"name":"pct","in":"query","required":false,"description":"pct (legacy, optional) (type=dmarc)","schema":{"type":"integer","minimum":0,"maximum":100},"example":"100"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Email record builder (JSON body)","operationId":"postEmailRecordBuilder","description":"Build an SPF record from the services that send your mail, or a DMARC record from a policy, and compare it with the one you publish now.\n\nWeb page: https://thenetworkery.com/tools/email-record-builder","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["spf","dmarc"],"description":"`spf` – SPF record; `dmarc` – DMARC record","default":"spf"},"domain":{"type":"string","maxLength":253,"description":"Domain"},"all":{"type":"string","enum":["~all","-all"],"description":"`~all` – Soft fail (~all); `-all` – Fail (-all)","default":"~all"},"providers":{"type":"string","maxLength":500,"description":"Services that send mail as this domain (type=spf)"},"extra":{"type":"string","maxLength":1000,"description":"Extra entries (optional) (type=spf)"},"p":{"type":"string","enum":["none","quarantine","reject"],"description":"`none` – none – monitor only; `quarantine` – quarantine – send to spam; `reject` – reject – refuse","default":"none"},"sp":{"type":"string","enum":["none","quarantine","reject"],"description":"`` – Same as p"},"rua":{"type":"string","maxLength":500,"description":"Aggregate reports to (rua) (type=dmarc)"},"ruf":{"type":"string","maxLength":500,"description":"Failure reports to (ruf, optional) (type=dmarc)"},"adkim":{"type":"string","enum":["r","s"],"description":"`r` – relaxed (r); `s` – strict (s)","default":"r"},"aspf":{"type":"string","enum":["r","s"],"description":"`r` – relaxed (r); `s` – strict (s)","default":"r"},"t":{"type":"string","enum":["n","y"],"description":"`n` – off (t=n); `y` – on (t=y)","default":"n"},"pct":{"type":"integer","minimum":0,"maximum":100,"description":"pct (legacy, optional) (type=dmarc)"}},"required":["domain"],"example":{"type":"spf","domain":"example.com","providers":"google,sendgrid","extra":"ip4:192.0.2.10","all":"~all"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["spf","dmarc"],"description":"`spf` – SPF record; `dmarc` – DMARC record","default":"spf"},"domain":{"type":"string","maxLength":253,"description":"Domain"},"all":{"type":"string","enum":["~all","-all"],"description":"`~all` – Soft fail (~all); `-all` – Fail (-all)","default":"~all"},"providers":{"type":"string","maxLength":500,"description":"Services that send mail as this domain (type=spf)"},"extra":{"type":"string","maxLength":1000,"description":"Extra entries (optional) (type=spf)"},"p":{"type":"string","enum":["none","quarantine","reject"],"description":"`none` – none – monitor only; `quarantine` – quarantine – send to spam; `reject` – reject – refuse","default":"none"},"sp":{"type":"string","enum":["none","quarantine","reject"],"description":"`` – Same as p"},"rua":{"type":"string","maxLength":500,"description":"Aggregate reports to (rua) (type=dmarc)"},"ruf":{"type":"string","maxLength":500,"description":"Failure reports to (ruf, optional) (type=dmarc)"},"adkim":{"type":"string","enum":["r","s"],"description":"`r` – relaxed (r); `s` – strict (s)","default":"r"},"aspf":{"type":"string","enum":["r","s"],"description":"`r` – relaxed (r); `s` – strict (s)","default":"r"},"t":{"type":"string","enum":["n","y"],"description":"`n` – off (t=n); `y` – on (t=y)","default":"n"},"pct":{"type":"integer","minimum":0,"maximum":100,"description":"pct (legacy, optional) (type=dmarc)"}},"required":["domain"],"example":{"type":"spf","domain":"example.com","providers":"google,sendgrid","extra":"ip4:192.0.2.10","all":"~all"}}}}}}},"/blacklist":{"get":{"operationId":"blacklist","summary":"Blacklist check","description":"Is an IP, a domain or its mail servers on the spam blocklists receivers use – and how to get delisted.\n\nWeb page: https://thenetworkery.com/tools/blacklist","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"target","in":"query","required":true,"description":"IP address or domain","schema":{"type":"string","maxLength":253},"example":"127.0.0.2"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Blacklist check (JSON body)","operationId":"postBlacklist","description":"Is an IP, a domain or its mail servers on the spam blocklists receivers use – and how to get delisted.\n\nWeb page: https://thenetworkery.com/tools/blacklist","tags":["Email"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"string","maxLength":253,"description":"IP address or domain"}},"required":["target"],"example":{"target":"127.0.0.2"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"target":{"type":"string","maxLength":253,"description":"IP address or domain"}},"required":["target"],"example":{"target":"127.0.0.2"}}}}}}},"/ssl-check":{"get":{"operationId":"sslCheck","summary":"SSL/TLS certificate check","description":"Certificate, chain, expiry, hostname match, key strength and the TLS version a server negotiates.\n\nWeb page: https://thenetworkery.com/tools/ssl-check","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"host","in":"query","required":true,"description":"Host name","schema":{"type":"string","maxLength":253},"example":"thenetworkery.com"},{"name":"port","in":"query","required":false,"description":"Port","schema":{"type":"string","enum":["443","8443","465","993","995","636","853","5061"],"description":"`443` – HTTPS (443); `8443` – HTTPS alt (8443); `465` – SMTPS (465); `993` – IMAPS (993); `995` – POP3S (995); `636` – LDAPS (636); `853` – DNS over TLS (853); `5061` – SIP-TLS (5061)","default":"443"},"example":"443"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"SSL/TLS certificate check (JSON body)","operationId":"postSslCheck","description":"Certificate, chain, expiry, hostname match, key strength and the TLS version a server negotiates.\n\nWeb page: https://thenetworkery.com/tools/ssl-check","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string","maxLength":253,"description":"Host name"},"port":{"type":"string","enum":["443","8443","465","993","995","636","853","5061"],"description":"`443` – HTTPS (443); `8443` – HTTPS alt (8443); `465` – SMTPS (465); `993` – IMAPS (993); `995` – POP3S (995); `636` – LDAPS (636); `853` – DNS over TLS (853); `5061` – SIP-TLS (5061)","default":"443"}},"required":["host"],"example":{"host":"thenetworkery.com","port":"443"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"host":{"type":"string","maxLength":253,"description":"Host name"},"port":{"type":"string","enum":["443","8443","465","993","995","636","853","5061"],"description":"`443` – HTTPS (443); `8443` – HTTPS alt (8443); `465` – SMTPS (465); `993` – IMAPS (993); `995` – POP3S (995); `636` – LDAPS (636); `853` – DNS over TLS (853); `5061` – SIP-TLS (5061)","default":"443"}},"required":["host"],"example":{"host":"thenetworkery.com","port":"443"}}}}}}},"/http-headers":{"get":{"operationId":"httpHeaders","summary":"HTTP headers & security check","description":"Redirect chain, response headers and a graded check of HSTS, CSP and the other security headers.\n\nWeb page: https://thenetworkery.com/tools/http-headers","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"url","in":"query","required":true,"description":"URL or host name","schema":{"type":"string","format":"uri","maxLength":2048},"example":"http://thenetworkery.com"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"HTTP headers & security check (JSON body)","operationId":"postHttpHeaders","description":"Redirect chain, response headers and a graded check of HSTS, CSP and the other security headers.\n\nWeb page: https://thenetworkery.com/tools/http-headers","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2048,"description":"URL or host name"}},"required":["url"],"example":{"url":"http://thenetworkery.com"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2048,"description":"URL or host name"}},"required":["url"],"example":{"url":"http://thenetworkery.com"}}}}}}},"/ct-search":{"get":{"operationId":"ctSearch","summary":"Certificate Transparency search","description":"Every publicly logged certificate for a domain and its subdomains – find forgotten hosts and unexpected issuers.\n\nWeb page: https://thenetworkery.com/tools/ct-search","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"domain","in":"query","required":true,"description":"Domain","schema":{"type":"string","maxLength":253},"example":"thenetworkery.com"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Certificate Transparency search (JSON body)","operationId":"postCtSearch","description":"Every publicly logged certificate for a domain and its subdomains – find forgotten hosts and unexpected issuers.\n\nWeb page: https://thenetworkery.com/tools/ct-search","tags":["Web & TLS"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"description":"Domain"}},"required":["domain"],"example":{"domain":"thenetworkery.com"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"description":"Domain"}},"required":["domain"],"example":{"domain":"thenetworkery.com"}}}}}}},"/network-report":{"get":{"operationId":"networkReport","summary":"Network report","description":"Who holds an IP address, prefix or AS number, how it is routed (origin AS, RPKI, IRR), its reverse DNS, blocklist listings and PeeringDB record, with what to fix first.\n\nWeb page: https://thenetworkery.com/tools/network-report","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"query","in":"query","required":true,"description":"IP address, prefix or AS number","schema":{"type":"string","maxLength":64},"example":"1.1.1.1"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Network report (JSON body)","operationId":"postNetworkReport","description":"Who holds an IP address, prefix or AS number, how it is routed (origin AS, RPKI, IRR), its reverse DNS, blocklist listings and PeeringDB record, with what to fix first.\n\nWeb page: https://thenetworkery.com/tools/network-report","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":64,"description":"IP address, prefix or AS number"}},"required":["query"],"example":{"query":"1.1.1.1"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":64,"description":"IP address, prefix or AS number"}},"required":["query"],"example":{"query":"1.1.1.1"}}}}}}},"/whois":{"get":{"operationId":"whois","summary":"WHOIS / RDAP lookup","description":"Who holds a domain, IP address or AS number – from the registry, via RDAP.\n\nWeb page: https://thenetworkery.com/tools/whois","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"query","in":"query","required":true,"description":"Domain, IP, prefix or AS number","schema":{"type":"string","maxLength":255},"example":"AS13335"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"WHOIS / RDAP lookup (JSON body)","operationId":"postWhois","description":"Who holds a domain, IP address or AS number – from the registry, via RDAP.\n\nWeb page: https://thenetworkery.com/tools/whois","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":255,"description":"Domain, IP, prefix or AS number"}},"required":["query"],"example":{"query":"AS13335"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":255,"description":"Domain, IP, prefix or AS number"}},"required":["query"],"example":{"query":"AS13335"}}}}}}},"/bgp":{"get":{"operationId":"bgp","summary":"ASN & BGP prefix lookup","description":"Origin AS, visibility, RPKI validity, upstreams and announced prefixes from the global routing table.\n\nWeb page: https://thenetworkery.com/tools/bgp","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"query","in":"query","required":true,"description":"AS number, IP address or prefix","schema":{"type":"string","maxLength":64},"example":"AS13335"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"ASN & BGP prefix lookup (JSON body)","operationId":"postBgp","description":"Origin AS, visibility, RPKI validity, upstreams and announced prefixes from the global routing table.\n\nWeb page: https://thenetworkery.com/tools/bgp","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":64,"description":"AS number, IP address or prefix"}},"required":["query"],"example":{"query":"AS13335"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":64,"description":"AS number, IP address or prefix"}},"required":["query"],"example":{"query":"AS13335"}}}}}}},"/rpki":{"get":{"operationId":"rpki","summary":"RPKI / ROA validator","description":"Whether a route is RPKI valid, invalid or not found, with the ROAs covering the prefix, max-length mistakes and how to fix them.\n\nWeb page: https://thenetworkery.com/tools/rpki","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"prefix","in":"query","required":true,"description":"Prefix","schema":{"type":"string","maxLength":64},"example":"1.1.1.0/24"},{"name":"asn","in":"query","required":false,"description":"Origin AS (optional)","schema":{"type":"string"},"example":"13335"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"RPKI / ROA validator (JSON body)","operationId":"postRpki","description":"Whether a route is RPKI valid, invalid or not found, with the ROAs covering the prefix, max-length mistakes and how to fix them.\n\nWeb page: https://thenetworkery.com/tools/rpki","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prefix":{"type":"string","maxLength":64,"description":"Prefix"},"asn":{"type":"string","description":"Origin AS (optional)"}},"required":["prefix"],"example":{"prefix":"1.1.1.0/24","asn":"13335"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"prefix":{"type":"string","maxLength":64,"description":"Prefix"},"asn":{"type":"string","description":"Origin AS (optional)"}},"required":["prefix"],"example":{"prefix":"1.1.1.0/24","asn":"13335"}}}}}}},"/peeringdb":{"get":{"operationId":"peeringdb","summary":"PeeringDB lookup","description":"A network’s peering policy, internet exchange ports, facilities and NOC contacts from PeeringDB.\n\nWeb page: https://thenetworkery.com/tools/peeringdb","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"asn","in":"query","required":true,"description":"AS number","schema":{"type":"string"},"example":"13335"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"PeeringDB lookup (JSON body)","operationId":"postPeeringdb","description":"A network’s peering policy, internet exchange ports, facilities and NOC contacts from PeeringDB.\n\nWeb page: https://thenetworkery.com/tools/peeringdb","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"asn":{"type":"string","description":"AS number"}},"required":["asn"],"example":{"asn":"13335"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"asn":{"type":"string","description":"AS number"}},"required":["asn"],"example":{"asn":"13335"}}}}}}},"/reverse-dns":{"get":{"operationId":"reverseDns","summary":"Reverse DNS (PTR) check","description":"The PTR name of an IP address, whether it resolves back to the same IP (FCrDNS), and whether it looks generic.\n\nWeb page: https://thenetworkery.com/tools/reverse-dns","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"query","in":"query","required":true,"description":"IP address or host name","schema":{"type":"string","maxLength":253},"example":"1.1.1.1"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Reverse DNS (PTR) check (JSON body)","operationId":"postReverseDns","description":"The PTR name of an IP address, whether it resolves back to the same IP (FCrDNS), and whether it looks generic.\n\nWeb page: https://thenetworkery.com/tools/reverse-dns","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":253,"description":"IP address or host name"}},"required":["query"],"example":{"query":"1.1.1.1"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":253,"description":"IP address or host name"}},"required":["query"],"example":{"query":"1.1.1.1"}}}}}}},"/port-check":{"get":{"operationId":"portCheck","summary":"Open port check","description":"Whether a TCP port is open, closed or filtered from the internet, from one timed connection from our server.\n\nWeb page: https://thenetworkery.com/tools/port-check","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"host","in":"query","required":true,"description":"Host name or IP address","schema":{"type":"string","maxLength":253},"example":"thenetworkery.com"},{"name":"port","in":"query","required":true,"description":"TCP port","schema":{"type":"integer"},"example":"443"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"Open port check (JSON body)","operationId":"postPortCheck","description":"Whether a TCP port is open, closed or filtered from the internet, from one timed connection from our server.\n\nWeb page: https://thenetworkery.com/tools/port-check","tags":["IP & routing"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string","maxLength":253,"description":"Host name or IP address"},"port":{"type":"integer","description":"TCP port"}},"required":["host","port"],"example":{"host":"thenetworkery.com","port":"443"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"host":{"type":"string","maxLength":253,"description":"Host name or IP address"},"port":{"type":"integer","description":"TCP port"}},"required":["host","port"],"example":{"host":"thenetworkery.com","port":"443"}}}}}}},"/subnet-calculator":{"get":{"operationId":"subnetCalculator","summary":"IP calculator","description":"Subnet ranges, masks and splits for IPv4 and IPv6, IPv6 and EUI-64 address details, and merging lists into the fewest CIDRs.\n\nWeb page: https://thenetworkery.com/tools/subnet-calculator","tags":["Calculators"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"mode","in":"query","required":false,"description":"Calculate","schema":{"type":"string","enum":["subnet","ipv6","merge"],"description":"`subnet` – Subnet; `ipv6` – IPv6 address; `merge` – Merge CIDRs","default":"subnet"}},{"name":"cidr","in":"query","required":false,"description":"Address or prefix (mode=subnet)","schema":{"type":"string","maxLength":64},"example":"172.20.0.0/14"},{"name":"split","in":"query","required":false,"description":"Split into prefix length (optional) (mode=subnet)","schema":{"type":"integer","minimum":0,"maximum":128},"example":"16"},{"name":"address","in":"query","required":false,"description":"IPv6 address or MAC address (mode=ipv6)","schema":{"type":"string","maxLength":100},"example":"2001:db8::1 or 00:1a:2b:3c:4d:5e"},{"name":"prefix","in":"query","required":false,"description":"Prefix for EUI-64 (optional) (mode=ipv6)","schema":{"type":"string","maxLength":64},"example":"fe80::/64"},{"name":"list","in":"query","required":false,"description":"Addresses, ranges and CIDRs (one per line) (mode=merge)","schema":{"type":"string","maxLength":1000000},"example":"192.0.2.0/25\n192.0.2.128/25\n198.51.100.10-198.51.100.20\n2001:db8::/33\n2001:db8:8000::/33"},{"name":"exclude","in":"query","required":false,"description":"Exclude (optional) (mode=merge)","schema":{"type":"string","maxLength":200000},"example":"192.0.2.64/26"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"IP calculator (JSON body)","operationId":"postSubnetCalculator","description":"Subnet ranges, masks and splits for IPv4 and IPv6, IPv6 and EUI-64 address details, and merging lists into the fewest CIDRs.\n\nWeb page: https://thenetworkery.com/tools/subnet-calculator","tags":["Calculators"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["subnet","ipv6","merge"],"description":"`subnet` – Subnet; `ipv6` – IPv6 address; `merge` – Merge CIDRs","default":"subnet"},"cidr":{"type":"string","maxLength":64,"description":"Address or prefix (mode=subnet)"},"split":{"type":"integer","minimum":0,"maximum":128,"description":"Split into prefix length (optional) (mode=subnet)"},"address":{"type":"string","maxLength":100,"description":"IPv6 address or MAC address (mode=ipv6)"},"prefix":{"type":"string","maxLength":64,"description":"Prefix for EUI-64 (optional) (mode=ipv6)"},"list":{"type":"string","maxLength":1000000,"description":"Addresses, ranges and CIDRs (one per line) (mode=merge)"},"exclude":{"type":"string","maxLength":200000,"description":"Exclude (optional) (mode=merge)"}},"example":{"cidr":"172.20.0.0/14","split":"16"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["subnet","ipv6","merge"],"description":"`subnet` – Subnet; `ipv6` – IPv6 address; `merge` – Merge CIDRs","default":"subnet"},"cidr":{"type":"string","maxLength":64,"description":"Address or prefix (mode=subnet)"},"split":{"type":"integer","minimum":0,"maximum":128,"description":"Split into prefix length (optional) (mode=subnet)"},"address":{"type":"string","maxLength":100,"description":"IPv6 address or MAC address (mode=ipv6)"},"prefix":{"type":"string","maxLength":64,"description":"Prefix for EUI-64 (optional) (mode=ipv6)"},"list":{"type":"string","maxLength":1000000,"description":"Addresses, ranges and CIDRs (one per line) (mode=merge)"},"exclude":{"type":"string","maxLength":200000,"description":"Exclude (optional) (mode=merge)"}},"example":{"cidr":"172.20.0.0/14","split":"16"}}}}}}},"/mcp-server-test":{"post":{"summary":"MCP server tester","operationId":"postMcpServerTest","description":"Connect to a remote MCP server like an AI assistant would: handshake, tools, resources, prompts, OAuth discovery and context cost, checked against the spec.\n\nWeb page: https://thenetworkery.com/tools/mcp-server-test","tags":["Developer"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2048,"description":"MCP server URL"},"token":{"type":"string","maxLength":4096,"description":"Bearer token (optional, never stored) Never stored or logged."},"tool":{"type":"string","maxLength":128,"description":"Call a tool (optional)"},"arguments":{"type":"string","contentMediaType":"application/json","maxLength":20000,"description":"Tool arguments as JSON (optional)"}},"required":["url"],"example":{"url":"https://thenetworkery.com/mcp"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2048,"description":"MCP server URL"},"token":{"type":"string","maxLength":4096,"description":"Bearer token (optional, never stored) Never stored or logged."},"tool":{"type":"string","maxLength":128,"description":"Call a tool (optional)"},"arguments":{"type":"string","contentMediaType":"application/json","maxLength":20000,"description":"Tool arguments as JSON (optional)"}},"required":["url"],"example":{"url":"https://thenetworkery.com/mcp"}}}}}}},"/jwt-decoder":{"post":{"summary":"JWT decoder","operationId":"postJwtDecoder","description":"Decode a JSON Web Token's header and claims, check alg, exp, nbf and iat, and verify its signature if you give a key; the token is never stored.\n\nWeb page: https://thenetworkery.com/tools/jwt-decoder","tags":["Developer"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","maxLength":16000,"description":"JSON Web Token Never stored or logged."},"key":{"type":"string","maxLength":20000,"description":"Key to verify the signature (optional): the HMAC secret, or a PEM public key or certificate Never stored or logged."}},"required":["token"]}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string","maxLength":16000,"description":"JSON Web Token Never stored or logged."},"key":{"type":"string","maxLength":20000,"description":"Key to verify the signature (optional): the HMAC secret, or a PEM public key or certificate Never stored or logged."}},"required":["token"]}}}}}},"/mac-lookup":{"get":{"operationId":"macLookup","summary":"MAC address vendor lookup","description":"Who made a network card, from the IEEE registry – and whether the address is randomised.\n\nWeb page: https://thenetworkery.com/tools/mac-lookup","tags":["Calculators"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"mac","in":"query","required":true,"description":"MAC address or prefix","schema":{"type":"string","maxLength":32},"example":"B8:27:EB:12:34:56"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"MAC address vendor lookup (JSON body)","operationId":"postMacLookup","description":"Who made a network card, from the IEEE registry – and whether the address is randomised.\n\nWeb page: https://thenetworkery.com/tools/mac-lookup","tags":["Calculators"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mac":{"type":"string","maxLength":32,"description":"MAC address or prefix"}},"required":["mac"],"example":{"mac":"B8:27:EB:12:34:56"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"mac":{"type":"string","maxLength":32,"description":"MAC address or prefix"}},"required":["mac"],"example":{"mac":"B8:27:EB:12:34:56"}}}}}}},"/dn42-registry":{"get":{"operationId":"dn42Registry","summary":"DN42 registry search","description":"Look up any DN42 object – AS, IP, prefix, maintainer, person or .dn42 domain – with everything linked to it.\n\nWeb page: https://thenetworkery.com/tools/dn42-registry","tags":["DN42"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"query","in":"query","required":true,"description":"AS number, IP, prefix, maintainer, person or domain","schema":{"type":"string","maxLength":100},"example":"AS4242421711"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"DN42 registry search (JSON body)","operationId":"postDn42Registry","description":"Look up any DN42 object – AS, IP, prefix, maintainer, person or .dn42 domain – with everything linked to it.\n\nWeb page: https://thenetworkery.com/tools/dn42-registry","tags":["DN42"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":100,"description":"AS number, IP, prefix, maintainer, person or domain"}},"required":["query"],"example":{"query":"AS4242421711"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"query":{"type":"string","maxLength":100,"description":"AS number, IP, prefix, maintainer, person or domain"}},"required":["query"],"example":{"query":"AS4242421711"}}}}}}},"/dn42-free":{"get":{"operationId":"dn42Free","summary":"DN42 free resource finder","description":"Unregistered AS numbers, free IPv4 blocks and a random unused IPv6 /48 – checked against the live registry.\n\nWeb page: https://thenetworkery.com/tools/dn42-free","tags":["DN42"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"size","in":"query","required":false,"description":"IPv4 block size","schema":{"type":"string","enum":["29","28","27","26","25","24"],"description":"`29` – /29 (8); `28` – /28 (16); `27` – /27 (32); `26` – /26 (64); `25` – /25 (128); `24` – /24 (256)","default":"27"},"example":"27"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"DN42 free resource finder (JSON body)","operationId":"postDn42Free","description":"Unregistered AS numbers, free IPv4 blocks and a random unused IPv6 /48 – checked against the live registry.\n\nWeb page: https://thenetworkery.com/tools/dn42-free","tags":["DN42"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"size":{"type":"string","enum":["29","28","27","26","25","24"],"description":"`29` – /29 (8); `28` – /28 (16); `27` – /27 (32); `26` – /26 (64); `25` – /25 (128); `24` – /24 (256)","default":"27"}},"example":{"size":"27"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"size":{"type":"string","enum":["29","28","27","26","25","24"],"description":"`29` – /29 (8); `28` – /28 (16); `27` – /27 (32); `26` – /26 (64); `25` – /25 (128); `24` – /24 (256)","default":"27"}},"example":{"size":"27"}}}}}}},"/dn42-peering-config":{"get":{"operationId":"dn42PeeringConfig","summary":"DN42 peering config generator","description":"WireGuard, BIRD 2 and RouterOS 7 configs for a DN42 peering, following the wiki conventions.\n\nWeb page: https://thenetworkery.com/tools/dn42-peering-config","tags":["DN42"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"our_asn","in":"query","required":true,"description":"Your AS number","schema":{"type":"integer","minimum":1,"maximum":4294967295},"example":"4242421711"},{"name":"peer_asn","in":"query","required":true,"description":"Peer AS number","schema":{"type":"integer","minimum":1,"maximum":4294967295},"example":"4242423914"},{"name":"peer_ll6","in":"query","required":true,"description":"Peer link-local IPv6","schema":{"type":"string","format":"ipv6"},"example":"fe80::3914"},{"name":"our_ll6","in":"query","required":false,"description":"Your link-local IPv6 (optional)","schema":{"type":"string","format":"ipv6"},"example":"fe80::1711"},{"name":"peer_ipv4","in":"query","required":false,"description":"Peer tunnel IPv4 (optional)","schema":{"type":"string","format":"ipv4"},"example":"172.20.53.97"},{"name":"our_ipv4","in":"query","required":false,"description":"Your DN42 IPv4 (optional)","schema":{"type":"string","format":"ipv4"},"example":"172.23.141.33"},{"name":"endpoint","in":"query","required":false,"description":"Peer endpoint host:port (optional)","schema":{"type":"string","maxLength":255},"example":"uk1.example.net:21711"},{"name":"peer_pubkey","in":"query","required":false,"description":"Peer WireGuard public key (optional)","schema":{"type":"string"},"example":"base64…="},{"name":"enh","in":"query","required":false,"description":"Session type","schema":{"type":"string","enum":["yes","no"],"description":"`yes` – One MP-BGP session over IPv6 (extended next hop); `no` – Separate IPv4 and IPv6 sessions","default":"yes"},"example":"yes"},{"$ref":"#/components/parameters/format"}]},"post":{"summary":"DN42 peering config generator (JSON body)","operationId":"postDn42PeeringConfig","description":"WireGuard, BIRD 2 and RouterOS 7 configs for a DN42 peering, following the wiki conventions.\n\nWeb page: https://thenetworkery.com/tools/dn42-peering-config","tags":["DN42"],"responses":{"200":{"description":"The result. Text instead with the `format` parameter or an Accept header; curl-like clients may get `text/plain` (see `format`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResult"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"our_asn":{"type":"integer","minimum":1,"maximum":4294967295,"description":"Your AS number"},"peer_asn":{"type":"integer","minimum":1,"maximum":4294967295,"description":"Peer AS number"},"peer_ll6":{"type":"string","format":"ipv6","description":"Peer link-local IPv6"},"our_ll6":{"type":"string","format":"ipv6","description":"Your link-local IPv6 (optional)"},"peer_ipv4":{"type":"string","format":"ipv4","description":"Peer tunnel IPv4 (optional)"},"our_ipv4":{"type":"string","format":"ipv4","description":"Your DN42 IPv4 (optional)"},"endpoint":{"type":"string","maxLength":255,"description":"Peer endpoint host:port (optional)"},"peer_pubkey":{"type":"string","description":"Peer WireGuard public key (optional)"},"enh":{"type":"string","enum":["yes","no"],"description":"`yes` – One MP-BGP session over IPv6 (extended next hop); `no` – Separate IPv4 and IPv6 sessions","default":"yes"}},"required":["our_asn","peer_asn","peer_ll6"],"example":{"our_asn":"4242421711","peer_asn":"4242423914","peer_ll6":"fe80::3914","our_ll6":"fe80::1711","peer_ipv4":"172.20.53.97","our_ipv4":"172.23.141.33","endpoint":"uk1.example.net:21711","enh":"yes"}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"our_asn":{"type":"integer","minimum":1,"maximum":4294967295,"description":"Your AS number"},"peer_asn":{"type":"integer","minimum":1,"maximum":4294967295,"description":"Peer AS number"},"peer_ll6":{"type":"string","format":"ipv6","description":"Peer link-local IPv6"},"our_ll6":{"type":"string","format":"ipv6","description":"Your link-local IPv6 (optional)"},"peer_ipv4":{"type":"string","format":"ipv4","description":"Peer tunnel IPv4 (optional)"},"our_ipv4":{"type":"string","format":"ipv4","description":"Your DN42 IPv4 (optional)"},"endpoint":{"type":"string","maxLength":255,"description":"Peer endpoint host:port (optional)"},"peer_pubkey":{"type":"string","description":"Peer WireGuard public key (optional)"},"enh":{"type":"string","enum":["yes","no"],"description":"`yes` – One MP-BGP session over IPv6 (extended next hop); `no` – Separate IPv4 and IPv6 sessions","default":"yes"}},"required":["our_asn","peer_asn","peer_ll6"],"example":{"our_asn":"4242421711","peer_asn":"4242423914","peer_ll6":"fe80::3914","our_ll6":"fe80::1711","peer_ipv4":"172.20.53.97","our_ipv4":"172.23.141.33","endpoint":"uk1.example.net:21711","enh":"yes"}}}}}}},"/webhooks":{"post":{"operationId":"createWebhookBin","summary":"Create a webhook bin","description":"Opens a new bin without an account: a capture URL that records any request sent to it, a secret key for reading them, and a private page link for watching them in a browser. Bins last 7 days and keep their newest 500 requests.\n\nLimited to 30 new bins an hour per address (on top of the general API limit). Keep the key: it is shown only once.","tags":["Webhook bins"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80,"description":"An optional label."}}}}}},"responses":{"201":{"description":"The new bin, with its key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBinCreated"}}}},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/webhooks/{bin}":{"parameters":[{"name":"bin","in":"path","required":true,"description":"The bin id.","schema":{"type":"string","pattern":"^[a-z0-9]{12}$"},"example":"abc123def456"}],"get":{"operationId":"getWebhookBin","summary":"Get a bin","description":"The bin's URLs, expiry, request count, the id of its newest request (start polling after it to see only new requests) and what it answers senders with.","responses":{"200":{"description":"The bin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBin"}}}},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]},"put":{"operationId":"updateWebhookBin","summary":"Change what a bin answers","description":"Sets the response every sender gets. Send only the fields to change. HTML is not offered, so a bin can never serve a web page.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":["string","null"],"maxLength":80},"response_status":{"type":"integer","minimum":200,"maximum":599},"response_type":{"type":"string","enum":["application/json","text/plain","application/xml","text/xml","text/csv","application/x-www-form-urlencoded"]},"response_body":{"type":["string","null"],"maxLength":65536},"cors":{"type":"boolean","description":"Answer browser preflight (OPTIONS) requests and allow any origin."}}}}}},"responses":{"200":{"description":"The bin after the change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBin"}}}},"422":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]},"delete":{"operationId":"deleteWebhookBin","summary":"Delete a bin","description":"Deletes the bin and every request in it. Its capture URL answers 404 from then on.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]}},"/webhooks/{bin}/requests":{"parameters":[{"name":"bin","in":"path","required":true,"description":"The bin id.","schema":{"type":"string","pattern":"^[a-z0-9]{12}$"},"example":"abc123def456"}],"get":{"operationId":"listWebhookRequests","summary":"List captured requests","description":"Requests oldest first. To follow a bin, poll with `after` set to the `last_id` of the previous answer (every 2 seconds is fine); `has_more` says another page is waiting.\n\nReading has its own limit of 120 requests a minute per address.","parameters":[{"name":"after","in":"query","required":false,"description":"Only requests with a higher id. Default 0: from the oldest kept request.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"limit","in":"query","required":false,"description":"Most requests to return.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"A page of requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRequestList"}}}},"422":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]},"delete":{"operationId":"clearWebhookRequests","summary":"Delete all captured requests","description":"Empties the bin. The bin and its URLs stay.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]}},"/webhooks/{bin}/requests/{id}":{"parameters":[{"name":"bin","in":"path","required":true,"description":"The bin id.","schema":{"type":"string","pattern":"^[a-z0-9]{12}$"},"example":"abc123def456"},{"name":"id","in":"path","required":true,"description":"The request id.","schema":{"type":"integer"}}],"get":{"operationId":"getWebhookRequest","summary":"Get one captured request","description":"One request, plus a curl command that sends it again.","responses":{"200":{"description":"The request.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookRequest"},{"type":"object","properties":{"curl":{"type":"string","description":"The same request as a curl command, aimed at the capture URL."}}}]}}}},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]},"delete":{"operationId":"deleteWebhookRequest","summary":"Delete one captured request","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/WebhookKeyMissing"},"404":{"$ref":"#/components/responses/WebhookNotFound"},"410":{"$ref":"#/components/responses/WebhookExpired"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Webhook bins"],"security":[{"binKey":[]},{"binKeyQuery":[]}]}},"/dns-resolvers":{"get":{"operationId":"listDnsResolvers","summary":"Public DNS resolver status","description":"Every monitored resolver: current status, last-24-hour availability and median/95th-percentile query time per transport (DNS over HTTPS, plain DNS over UDP 53), and the behaviour tests. Updated every 5 minutes; cached for up to a minute.","tags":["DNS resolver monitor"],"responses":{"200":{"description":"All resolvers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolverList"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/dns-resolvers/{key}":{"get":{"operationId":"getDnsResolver","summary":"One resolver with history","description":"The same as in the list, plus daily availability and latency for the last 90 days and hourly latency for the last 7 days.","tags":["DNS resolver monitor"],"parameters":[{"name":"key","in":"path","required":true,"description":"The resolver key.","schema":{"type":"string","enum":["cloudflare","google","quad9","opendns","adguard","mullvad","dnssb","controld","cira","alidns","dnspod","digiges","ffmuc"]},"example":"cloudflare"}],"responses":{"200":{"description":"The resolver.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resolver"}}}},"404":{"description":"No resolver with that key."},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"parameters":{"format":{"name":"format","in":"query","required":false,"description":"Response format: `json`, `text` (plain text) or `md` (Markdown). Without it, the Accept header decides (text/plain, text/markdown); command-line clients (curl, wget, HTTPie) get the tool's own text form where it has one; everyone else JSON.","schema":{"type":"string","enum":["json","text","md"]}}},"responses":{"NotFound":{"description":"No tool by that name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"Unknown tool 'nope'. The tools are listed at https://thenetworkery.com/api/v1."}}}},"ValidationError":{"description":"The input is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"RateLimited":{"description":"More than 60 requests a minute from this address.","headers":{"Retry-After":{"description":"Seconds to wait.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"WebhookKeyMissing":{"description":"No key was sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"WebhookNotFound":{"description":"No such bin, or the key is wrong (the API does not say which).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"WebhookExpired":{"description":"The bin has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Finding":{"type":"object","required":["level","text","title"],"properties":{"level":{"type":"string","enum":["pass","info","warn","fail"]},"text":{"type":"string","description":"What was found, in one English sentence.","examples":["SPF ends in -all."]},"title":{"type":"string","description":"The same as text (kept for older clients)."},"params":{"type":"object","additionalProperties":true,"description":"The values filled into text, detail and fix, on their own."},"detail":{"type":"string","description":"Why it matters."},"fix":{"type":"string","description":"What to change."},"record":{"type":"string","description":"A suggested DNS record or config line, ready to paste."}}},"ToolResult":{"type":"object","required":["tool","input","status","data","findings","url"],"properties":{"tool":{"type":"string","description":"The tool slug."},"input":{"type":"object","additionalProperties":true,"description":"The input after normalising (e.g. a URL reduced to its host name). Secrets are left out."},"status":{"type":"string","enum":["pass","info","warn","fail"],"description":"The worst finding level."},"data":{"type":"object","additionalProperties":true,"description":"Raw results. The shape differs per tool."},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"url":{"type":"string","format":"uri","description":"The check on the website: opening it runs it again (API results are not saved), or the tool page when the input cannot go in a link."}}},"ToolList":{"type":"object","properties":{"tools":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"params":{"type":"array","items":{"type":"string"}},"url":{"type":"string","format":"uri"}}}}}},"ValidationError":{"type":"object","properties":{"message":{"type":"string"},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"Error":{"type":"object","properties":{"message":{"type":"string"}}},"Ok":{"type":"object","properties":{"ok":{"type":"boolean"}}},"WebhookBin":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"capture_url":{"type":"string","format":"uri","description":"Give this to the sender. Any method and any path after it is recorded."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time","description":"The bin and its requests are deleted after this."},"request_count":{"type":"integer","description":"Requests received since the bin was made (including ones no longer kept)."},"last_request_at":{"type":["string","null"],"format":"date-time"},"last_request_id":{"type":"integer","description":"Id of the newest kept request, 0 if none. Poll with after= this to see only new ones."},"response":{"type":"object","properties":{"status":{"type":"integer"},"content_type":{"type":"string"},"body":{"type":["string","null"]},"cors":{"type":"boolean"}}},"limits":{"type":"object","properties":{"requests_kept":{"type":"integer"},"requests_per_minute":{"type":"integer"},"max_body_bytes":{"type":"integer"},"lifetime_days":{"type":"integer"}}}}},"WebhookBinCreated":{"allOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"capture_url":{"type":"string","format":"uri","description":"Give this to the sender. Any method and any path after it is recorded."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time","description":"The bin and its requests are deleted after this."},"request_count":{"type":"integer","description":"Requests received since the bin was made (including ones no longer kept)."},"last_request_at":{"type":["string","null"],"format":"date-time"},"last_request_id":{"type":"integer","description":"Id of the newest kept request, 0 if none. Poll with after= this to see only new ones."},"response":{"type":"object","properties":{"status":{"type":"integer"},"content_type":{"type":"string"},"body":{"type":["string","null"]},"cors":{"type":"boolean"}}},"limits":{"type":"object","properties":{"requests_kept":{"type":"integer"},"requests_per_minute":{"type":"integer"},"max_body_bytes":{"type":"integer"},"lifetime_days":{"type":"integer"}}}}},{"type":"object","properties":{"key":{"type":"string","description":"The secret key. Shown only here."},"page_url":{"type":"string","format":"uri","description":"Private link to the bin's page, with the key in it."},"api":{"type":"object","properties":{"bin":{"type":"string","format":"uri"},"requests":{"type":"string","format":"uri"},"auth":{"type":"string"}}}}}]},"WebhookRequest":{"type":"object","properties":{"id":{"type":"integer"},"method":{"type":"string"},"path":{"type":"string","description":"The part after the capture URL, starting with /."},"query":{"type":["string","null"],"description":"The raw query string, without ?."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Headers as the sender sent them (lower-case names)."},"proxy_headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Headers our CDN and host added on the way in."},"content_type":{"type":["string","null"]},"ip":{"type":["string","null"],"description":"The sender's address."},"body":{"type":["string","null"],"description":"The body as text, or base64 when body_base64 is true. For multipart uploads, a JSON summary of the fields and files instead."},"body_base64":{"type":"boolean","description":"True when the body was not valid UTF-8 and is base64-encoded."},"body_size":{"type":"integer","description":"Size of the body as received, in bytes."},"body_truncated":{"type":"boolean","description":"True when the body was larger than 524288 bytes and was cut off."},"created_at":{"type":"string","format":"date-time"}}},"WebhookRequestList":{"type":"object","properties":{"bin":{"type":"string"},"count":{"type":"integer","description":"Requests received since the bin was made."},"requests":{"type":"array","items":{"$ref":"#/components/schemas/WebhookRequest"}},"last_id":{"type":"integer","description":"Pass as after= next time. Equals after when nothing new arrived."},"has_more":{"type":"boolean"}}},"Resolver":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"},"operator":{"type":"string"},"url":{"type":"string","format":"uri"},"endpoints":{"type":"object","properties":{"doh":{"type":"string","format":"uri"},"udp":{"type":"string","description":"IPv4 address, if plain DNS is offered."}}},"status":{"type":"string","enum":["up","warn","down","unknown"],"description":"The worse of the transports."},"transports":{"type":"object","properties":{"doh":{"type":"object","properties":{"status":{"type":"string","enum":["up","warn","down","unknown"]},"last_checked":{"type":["string","null"],"format":"date-time"},"last_ms":{"type":["integer","null"]},"availability_24h":{"type":["number","null"],"description":"Percentage of probes answered correctly."},"p50_ms_24h":{"type":["integer","null"]},"p95_ms_24h":{"type":["integer","null"]},"samples_24h":{"type":"integer"},"daily":{"type":"array","description":"Detail endpoint only: days with data, oldest first.","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"availability":{"type":["number","null"]},"samples":{"type":"integer"},"p50_ms":{"type":["integer","null"]},"p95_ms":{"type":["integer","null"]}}}},"hourly":{"type":"array","description":"Detail endpoint only: hours with data in the last 7 days.","items":{"type":"object","properties":{"hour":{"type":"string","format":"date-time"},"p50_ms":{"type":["integer","null"]},"p95_ms":{"type":["integer","null"]}}}}}},"udp":{"type":"object","properties":{"status":{"type":"string","enum":["up","warn","down","unknown"]},"last_checked":{"type":["string","null"],"format":"date-time"},"last_ms":{"type":["integer","null"]},"availability_24h":{"type":["number","null"],"description":"Percentage of probes answered correctly."},"p50_ms_24h":{"type":["integer","null"]},"p95_ms_24h":{"type":["integer","null"]},"samples_24h":{"type":"integer"},"daily":{"type":"array","description":"Detail endpoint only: days with data, oldest first.","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"availability":{"type":["number","null"]},"samples":{"type":"integer"},"p50_ms":{"type":["integer","null"]},"p95_ms":{"type":["integer","null"]}}}},"hourly":{"type":"array","description":"Detail endpoint only: hours with data in the last 7 days.","items":{"type":"object","properties":{"hour":{"type":"string","format":"date-time"},"p50_ms":{"type":["integer","null"]},"p95_ms":{"type":["integer","null"]}}}}}}}},"features":{"type":"object","properties":{"dnssec_validation":{"type":["string","null"],"enum":["yes","no","partial",null]},"nxdomain_honest":{"type":["string","null"],"enum":["yes","no",null]},"ecs":{"type":["string","null"],"enum":["none","ours","other","sent",null],"description":"What Akamai's test name received: no client subnet, one containing our server's address, or another one."},"ecs_detail":{"type":["string","null"]},"filtering":{"type":"string","enum":["not_advertised","blocked","not_blocked","unknown"]},"filtering_advertised":{"type":["string","null"]},"checked_at":{"type":["string","null"],"format":"date-time"}}}}},"ResolverList":{"type":"object","properties":{"generated_at":{"type":"string","format":"date-time"},"last_run_at":{"type":["string","null"],"format":"date-time"},"vantage_point":{"type":"string"},"interval_minutes":{"type":"integer"},"methodology":{"type":"string","format":"uri"},"resolvers":{"type":"array","items":{"$ref":"#/components/schemas/Resolver"}}}}},"securitySchemes":{"binKey":{"type":"http","scheme":"bearer","description":"The bin's secret key from POST /webhooks: `Authorization: Bearer <key>`. Preferred."},"binKeyQuery":{"type":"apiKey","in":"query","name":"key","description":"The same key as ?key=. Convenient, but URLs end up in logs and histories."}}}}