{
	"openapi": "3.1.0",
	"info": {
		"title": "dns-doctor.com API",
		"version": "1.1.0",
		"description": "Free DNS health checks, raw DNS lookups, propagation comparison, availability, DKIM/DNSSEC inspection, IDN conversion, record generators and email header analysis. Anonymous use is rate-limited per IP and day. Higher limits with an API key: either a dns-doctor key or your existing regfish API key (api.regfish.de/.com), sent as X-Api-Key or Authorization: Bearer; regfish keys are verified server-side with regfish. Findings of the health check are available in English (default) and German (?lang=de).",
		"contact": {
			"url": "https://dns-doctor.com/api"
		}
	},
	"servers": [
		{
			"url": "https://dns-doctor.com"
		}
	],
	"paths": {
		"/api/v1/check/{domain}": {
			"get": {
				"summary": "Full DNS health check",
				"description": "Runs 25+ checks (delegation, SOA, MX, SPF, DKIM, DMARC, MTA-STS, TLS-RPT, web records, CAA, DNSSEC) and returns a score with findings and copy-ready fixes.",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "example.com"
					},
					{
						"name": "lang",
						"in": "query",
						"schema": {
							"type": "string",
							"enum": [
								"en",
								"de"
							],
							"default": "en"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Health report",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/DomainHealth"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/lookup/{name}/{type}": {
			"get": {
				"summary": "Raw DNS lookup via DoH",
				"parameters": [
					{
						"name": "name",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"description": "DNS name; an IP address is accepted for type PTR.",
						"example": "example.com"
					},
					{
						"name": "type",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"A",
								"NS",
								"CNAME",
								"SOA",
								"PTR",
								"MX",
								"TXT",
								"AAAA",
								"SRV",
								"DS",
								"DNSKEY",
								"CAA"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "DNS answer",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/LookupResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					},
					"502": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/propagation/{name}/{type}": {
			"get": {
				"summary": "DNS propagation check across public resolvers",
				"description": "Queries the same name and type on five public resolvers (cloudflare, google, alidns, dnssb, adguard) and reports whether all reachable resolvers agree on the answer set.",
				"parameters": [
					{
						"name": "name",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"description": "DNS name; an IP address is accepted for type PTR.",
						"example": "regfish.de"
					},
					{
						"name": "type",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"A",
								"NS",
								"CNAME",
								"SOA",
								"PTR",
								"MX",
								"TXT",
								"AAAA",
								"SRV",
								"DS",
								"DNSKEY",
								"CAA"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "Per-resolver answers plus consistency verdict",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/PropagationResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/availability/{domain}": {
			"get": {
				"summary": "Domain availability via RDAP",
				"description": "Non-binding availability check via public RDAP. Important: TLDs without public RDAP (for example .de) return state \"unknown\" together with noRdapForTld=true; only the responsible registry decides at registration time.",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "regfish.com"
					}
				],
				"responses": {
					"200": {
						"description": "Availability result",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/AvailabilityResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/dkim/{domain}/{selector}": {
			"get": {
				"summary": "DKIM key check",
				"description": "Fetches selector._domainkey.domain as TXT and inspects the DKIM key: key type, key length, revoked (empty p=) and testing (t=y) flags. If no DKIM record is found, found=false is returned with no further fields except status (the DNS RCODE).",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "regfish.de"
					},
					{
						"name": "selector",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "k1"
					}
				],
				"responses": {
					"200": {
						"description": "DKIM key details (or found=false)",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/DkimResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					},
					"502": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/dnssec/{domain}": {
			"get": {
				"summary": "DNSSEC chain inspection",
				"description": "Fetches DS and DNSKEY records, computes key tags and reports which DS entries match a published DNSKEY. status is \"unsigned\" (no DS), \"valid\" (resolver-validated and at least one DS matches) or \"broken\".",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "denic.de"
					}
				],
				"responses": {
					"200": {
						"description": "DS/DNSKEY chain and status",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/DnssecResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					},
					"502": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/mail-check/{domain}": {
			"get": {
				"summary": "Mail server check",
				"description": "Resolves the MX hosts (forward), their reverse DNS (PTR) with FCrDNS match, and probes TCP availability of the common mail ports (SMTP, IMAP, POP3) and web ports. Only connects to public target IPs. Extra burst limit because port probes are expensive.",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "example.com"
					}
				],
				"responses": {
					"200": {
						"description": "Mail hosts with ports, PTR and FCrDNS",
						"content": {
							"application/json": {
								"schema": {
									"type": "object"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/seo-check/{domain}": {
			"get": {
				"summary": "SEO & AI visibility check",
				"description": "Fetches the page (soft-404-guarded), robots.txt and metadata, then scores how well the domain is visible to search engines and AI assistants. Findings cover indexing, content, technical and AI-crawler access. Localized (?lang=de). Extra burst limit because each run makes several outbound requests.",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"example": "example.com"
					},
					{
						"name": "lang",
						"in": "query",
						"schema": {
							"type": "string",
							"enum": [
								"en",
								"de"
							],
							"default": "en"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Score, finalUrl and findings",
						"content": {
							"application/json": {
								"schema": {
									"type": "object"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/idn/{name}": {
			"get": {
				"summary": "IDN/Punycode conversion",
				"description": "Converts a domain name between Unicode and ASCII (Punycode) form, in both directions. Pure conversion, no network access and no rate limit.",
				"parameters": [
					{
						"name": "name",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						},
						"description": "Domain name, Unicode or Punycode.",
						"example": "xn--mller-kva.de"
					}
				],
				"responses": {
					"200": {
						"description": "Both representations",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/IdnResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/generate/{kind}": {
			"post": {
				"summary": "Generate SPF, DMARC, CAA or MTA-STS records",
				"description": "Pure record builders, no DNS queries. Warnings and errors are returned as structured, machine-readable codes (for example \"too-many-lookups\"), never as display text; this is intentional so integrations can localize them.",
				"parameters": [
					{
						"name": "kind",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"spf",
								"dmarc",
								"caa",
								"mta-sts"
							]
						}
					}
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"oneOf": [
									{
										"$ref": "#/components/schemas/SpfGenerateInput"
									},
									{
										"$ref": "#/components/schemas/DmarcGenerateInput"
									},
									{
										"$ref": "#/components/schemas/CaaGenerateInput"
									},
									{
										"$ref": "#/components/schemas/MtaStsGenerateInput"
									}
								]
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Generated record(s), shape depends on kind",
						"content": {
							"application/json": {
								"schema": {
									"oneOf": [
										{
											"$ref": "#/components/schemas/SpfGenerateResult"
										},
										{
											"$ref": "#/components/schemas/DmarcGenerateResult"
										},
										{
											"$ref": "#/components/schemas/CaaGenerateResult"
										},
										{
											"$ref": "#/components/schemas/MtaStsGenerateResult"
										}
									]
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"405": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/api/v1/header-analysis": {
			"post": {
				"summary": "Email header analysis",
				"description": "Parses a raw email header: Received hops with time deltas, Authentication-Results (SPF/DKIM/DMARC), key sender fields and a From/Return-Path alignment hint. Body: raw header as text/plain, or JSON {\"raw\": \"...\"}. Maximum size 64 KiB. Privacy: processing is ephemeral, nothing is stored or passed on; the response is sent with Cache-Control: no-store.",
				"requestBody": {
					"required": true,
					"content": {
						"text/plain": {
							"schema": {
								"type": "string",
								"description": "Raw email header block."
							}
						},
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"raw"
								],
								"properties": {
									"raw": {
										"type": "string"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Parsed header (Cache-Control: no-store)",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/HeaderAnalysisResult"
								}
							}
						}
					},
					"400": {
						"$ref": "#/components/responses/Error"
					},
					"405": {
						"$ref": "#/components/responses/Error"
					},
					"413": {
						"$ref": "#/components/responses/Error"
					},
					"429": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		},
		"/badge/{domain}.svg": {
			"get": {
				"summary": "Embeddable DNS health badge (SVG)",
				"parameters": [
					{
						"name": "domain",
						"in": "path",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "SVG badge",
						"content": {
							"image/svg+xml": {}
						}
					}
				}
			}
		},
		"/mcp": {
			"post": {
				"summary": "MCP server (Model Context Protocol) over JSON-RPC 2.0",
				"description": "Stateless MCP endpoint (Streamable HTTP transport) for AI assistants. Send JSON-RPC 2.0 messages; methods: initialize, tools/list, tools/call, ping. Every check is exposed as a tool (dns_health_check, dns_lookup, dns_propagation, domain_availability, dkim_check, dnssec_check, mail_check, seo_check, idn_convert, generate_record) calling the same engine as the REST endpoints, with the same auth and rate limits. In Claude, add as a connector with URL https://dns-doctor.com/mcp. This is JSON-RPC, not REST: the schemas below are a generic JSON-RPC envelope.",
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"jsonrpc",
									"method"
								],
								"properties": {
									"jsonrpc": {
										"type": "string",
										"enum": [
											"2.0"
										]
									},
									"id": {
										"description": "Request id (string or number). Omit for notifications."
									},
									"method": {
										"type": "string",
										"enum": [
											"initialize",
											"tools/list",
											"tools/call",
											"ping"
										]
									},
									"params": {
										"type": "object"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "JSON-RPC 2.0 response",
						"content": {
							"application/json": {
								"schema": {
									"type": "object"
								}
							}
						}
					},
					"202": {
						"description": "Accepted (notifications get no response body)"
					},
					"413": {
						"$ref": "#/components/responses/Error"
					}
				}
			}
		}
	},
	"components": {
		"securitySchemes": {
			"apiKey": {
				"type": "apiKey",
				"in": "header",
				"name": "X-Api-Key",
				"description": "Optional; raises the daily rate limit."
			},
			"regfishToken": {
				"type": "http",
				"scheme": "bearer",
				"description": "Your existing regfish API key (same key as for api.regfish.de/.com), sent as Bearer or X-Api-Key. Verified server-side with regfish; a valid key counts like an API key and raises the daily rate limit."
			}
		},
		"responses": {
			"Error": {
				"description": "Error",
				"content": {
					"application/json": {
						"schema": {
							"type": "object",
							"properties": {
								"error": {
									"type": "object",
									"properties": {
										"code": {
											"type": "string"
										},
										"message": {
											"type": "string"
										}
									}
								}
							}
						}
					}
				}
			}
		},
		"schemas": {
			"Finding": {
				"type": "object",
				"properties": {
					"id": {
						"type": "string"
					},
					"category": {
						"type": "string",
						"enum": [
							"dns",
							"email",
							"web",
							"security"
						]
					},
					"severity": {
						"type": "string",
						"enum": [
							"ok",
							"info",
							"warn",
							"problem"
						]
					},
					"title": {
						"type": "string"
					},
					"detail": {
						"type": "string"
					},
					"fix": {
						"type": "object",
						"properties": {
							"steps": {
								"type": "string"
							},
							"record": {
								"type": "object",
								"properties": {
									"host": {
										"type": "string"
									},
									"type": {
										"type": "string"
									},
									"value": {
										"type": "string"
									}
								}
							},
							"cta": {
								"type": "object",
								"properties": {
									"label": {
										"type": "string"
									},
									"href": {
										"type": "string"
									}
								}
							}
						}
					}
				}
			},
			"DomainHealth": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"domain": {
						"type": "string"
					},
					"displayDomain": {
						"type": "string"
					},
					"resolvable": {
						"type": "boolean"
					},
					"score": {
						"type": "integer",
						"minimum": 0,
						"maximum": 100
					},
					"findings": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/Finding"
						}
					},
					"summary": {
						"type": "object",
						"properties": {
							"ok": {
								"type": "integer"
							},
							"info": {
								"type": "integer"
							},
							"warn": {
								"type": "integer"
							},
							"problem": {
								"type": "integer"
							}
						}
					},
					"checkedAt": {
						"type": "string",
						"format": "date-time"
					},
					"locale": {
						"type": "string",
						"enum": [
							"en",
							"de"
						]
					}
				}
			},
			"LookupResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"name": {
						"type": "string"
					},
					"type": {
						"type": "string"
					},
					"typeCode": {
						"type": "integer"
					},
					"status": {
						"type": "integer",
						"description": "DNS RCODE (0 NOERROR, 3 NXDOMAIN, ...)"
					},
					"ad": {
						"type": "boolean",
						"description": "DNSSEC-validated by the resolver"
					},
					"answers": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"name": {
									"type": "string"
								},
								"type": {
									"type": "integer"
								},
								"ttl": {
									"type": [
										"integer",
										"null"
									]
								},
								"data": {
									"type": "string"
								}
							}
						}
					}
				}
			},
			"PropagationResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"name": {
						"type": "string"
					},
					"type": {
						"type": "string"
					},
					"resolvers": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"id": {
									"type": "string",
									"enum": [
										"cloudflare",
										"google",
										"alidns",
										"dnssb",
										"adguard"
									]
								},
								"label": {
									"type": "string"
								},
								"reachable": {
									"type": "boolean"
								},
								"status": {
									"type": "integer",
									"description": "DNS RCODE; -1 when the resolver was unreachable"
								},
								"ad": {
									"type": "boolean",
									"description": "DNSSEC-validated by this resolver"
								},
								"answers": {
									"type": "array",
									"items": {
										"type": "object",
										"properties": {
											"ttl": {
												"type": [
													"integer",
													"null"
												]
											},
											"data": {
												"type": "string"
											}
										}
									}
								}
							}
						}
					},
					"consistency": {
						"type": "object",
						"properties": {
							"reachable": {
								"type": "integer"
							},
							"total": {
								"type": "integer"
							},
							"agreeing": {
								"type": "integer",
								"description": "Size of the largest group of reachable resolvers with an identical answer set"
							},
							"consistent": {
								"type": "boolean",
								"description": "true when all reachable resolvers agree"
							}
						}
					}
				}
			},
			"AvailabilityResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"domain": {
						"type": "string"
					},
					"state": {
						"type": "string",
						"enum": [
							"registered",
							"available",
							"unknown"
						]
					},
					"noRdapForTld": {
						"type": "boolean",
						"description": "true when the TLD offers no public RDAP (for example .de); state is then \"unknown\""
					},
					"registrar": {
						"type": [
							"string",
							"null"
						]
					},
					"created": {
						"type": [
							"string",
							"null"
						]
					},
					"expires": {
						"type": [
							"string",
							"null"
						]
					},
					"disclaimer": {
						"type": "string"
					}
				}
			},
			"DkimResult": {
				"type": "object",
				"description": "When found=false, only api, domain, selector, name, found and status (DNS RCODE) are returned.",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"domain": {
						"type": "string"
					},
					"selector": {
						"type": "string"
					},
					"name": {
						"type": "string",
						"description": "Queried TXT name: selector._domainkey.domain"
					},
					"found": {
						"type": "boolean"
					},
					"status": {
						"type": "integer",
						"description": "DNS RCODE; only present when found=false"
					},
					"valid": {
						"type": "boolean"
					},
					"revoked": {
						"type": "boolean",
						"description": "Key revoked (empty p= tag)"
					},
					"testing": {
						"type": "boolean",
						"description": "Testing mode (t=y)"
					},
					"keyType": {
						"type": "string",
						"enum": [
							"rsa",
							"ed25519"
						]
					},
					"keyBits": {
						"type": [
							"integer",
							"null"
						]
					},
					"record": {
						"type": "string"
					}
				}
			},
			"DnssecResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"domain": {
						"type": "string"
					},
					"status": {
						"type": "string",
						"enum": [
							"unsigned",
							"valid",
							"broken"
						]
					},
					"adValidated": {
						"type": "boolean",
						"description": "The validating resolver set the AD flag for the zone"
					},
					"ds": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"keyTag": {
									"type": "integer"
								},
								"algorithm": {
									"type": "string"
								},
								"digestType": {
									"type": "string"
								},
								"digest": {
									"type": "string"
								}
							}
						}
					},
					"dnskeys": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"keyTag": {
									"type": "integer"
								},
								"flags": {
									"type": "integer"
								},
								"algorithm": {
									"type": "string"
								},
								"role": {
									"type": "string",
									"enum": [
										"ksk",
										"zsk"
									]
								}
							}
						}
					},
					"links": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"keyTag": {
									"type": "integer"
								},
								"matched": {
									"type": "boolean",
									"description": "A published DNSKEY matches this DS key tag"
								}
							}
						}
					}
				}
			},
			"IdnResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"input": {
						"type": "string"
					},
					"ascii": {
						"type": "string",
						"description": "Punycode (ASCII) form"
					},
					"unicode": {
						"type": "string",
						"description": "Unicode form"
					}
				}
			},
			"IssueCode": {
				"type": "object",
				"description": "Structured, machine-readable warning or error code (for example \"too-many-lookups\"), intentionally not display text so integrations can localize.",
				"properties": {
					"code": {
						"type": "string"
					},
					"value": {
						"type": [
							"string",
							"number"
						],
						"description": "Optional offending value or measurement"
					}
				},
				"required": [
					"code"
				]
			},
			"GeneratedRecord": {
				"type": "object",
				"properties": {
					"host": {
						"type": "string"
					},
					"type": {
						"type": "string"
					},
					"value": {
						"type": "string"
					}
				}
			},
			"SpfGenerateInput": {
				"type": "object",
				"description": "Body for kind=spf.",
				"properties": {
					"allowA": {
						"type": "boolean"
					},
					"allowMx": {
						"type": "boolean"
					},
					"ip4": {
						"type": "array",
						"items": {
							"type": "string"
						}
					},
					"ip6": {
						"type": "array",
						"items": {
							"type": "string"
						}
					},
					"includes": {
						"type": "array",
						"items": {
							"type": "string"
						}
					},
					"all": {
						"type": "string",
						"enum": [
							"fail",
							"softfail",
							"neutral",
							"pass"
						],
						"default": "softfail"
					}
				}
			},
			"SpfGenerateResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"kind": {
						"type": "string",
						"const": "spf"
					},
					"host": {
						"type": "string",
						"const": "@"
					},
					"type": {
						"type": "string",
						"const": "TXT"
					},
					"record": {
						"type": "string"
					},
					"lookupCount": {
						"type": "integer",
						"description": "DNS lookups the record will cause (RFC 7208 limit: 10)"
					},
					"warnings": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/IssueCode"
						}
					},
					"errors": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/IssueCode"
						}
					}
				}
			},
			"DmarcGenerateInput": {
				"type": "object",
				"description": "Body for kind=dmarc.",
				"required": [
					"policy"
				],
				"properties": {
					"policy": {
						"type": "string",
						"enum": [
							"none",
							"quarantine",
							"reject"
						]
					},
					"subdomainPolicy": {
						"type": "string",
						"enum": [
							"none",
							"quarantine",
							"reject"
						],
						"description": "Omit to inherit policy"
					},
					"rua": {
						"type": "array",
						"items": {
							"type": "string"
						},
						"description": "Aggregate report addresses (plain emails, no mailto:)"
					},
					"ruf": {
						"type": "array",
						"items": {
							"type": "string"
						}
					},
					"pct": {
						"type": "integer",
						"minimum": 0,
						"maximum": 100,
						"default": 100
					},
					"adkim": {
						"type": "string",
						"enum": [
							"r",
							"s"
						],
						"default": "r"
					},
					"aspf": {
						"type": "string",
						"enum": [
							"r",
							"s"
						],
						"default": "r"
					},
					"fo": {
						"type": "string",
						"default": "0"
					},
					"domain": {
						"type": "string",
						"description": "Used to derive the host name (_dmarc.<domain>)"
					}
				}
			},
			"DmarcGenerateResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"kind": {
						"type": "string",
						"const": "dmarc"
					},
					"host": {
						"type": "string",
						"description": "_dmarc or _dmarc.<domain>"
					},
					"type": {
						"type": "string",
						"const": "TXT"
					},
					"record": {
						"type": "string"
					},
					"warnings": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/IssueCode"
						}
					},
					"errors": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/IssueCode"
						}
					}
				}
			},
			"CaaGenerateInput": {
				"type": "object",
				"description": "Body for kind=caa. The single value \";\" in issue forbids all certificate issuance.",
				"properties": {
					"issue": {
						"type": "array",
						"items": {
							"type": "string"
						},
						"description": "CA domains allowed to issue; [\";\"] forbids all"
					},
					"issuewild": {
						"type": "array",
						"items": {
							"type": "string"
						}
					},
					"iodef": {
						"type": "string",
						"description": "Report email address"
					},
					"critical": {
						"type": "boolean"
					}
				}
			},
			"CaaGenerateResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"kind": {
						"type": "string",
						"const": "caa"
					},
					"records": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/GeneratedRecord"
						}
					},
					"warnings": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/IssueCode"
						}
					}
				}
			},
			"MtaStsGenerateInput": {
				"type": "object",
				"description": "Body for kind=mta-sts.",
				"required": [
					"mode"
				],
				"properties": {
					"domain": {
						"type": "string"
					},
					"mode": {
						"type": "string",
						"enum": [
							"testing",
							"enforce",
							"none"
						]
					},
					"mx": {
						"type": "array",
						"items": {
							"type": "string"
						}
					},
					"maxAgeDays": {
						"type": "integer",
						"minimum": 1,
						"maximum": 365,
						"default": 7
					},
					"id": {
						"type": "string",
						"description": "Policy id; defaults to a UTC timestamp"
					},
					"tlsRptEmail": {
						"type": "string",
						"description": "Adds a TLS-RPT record when set"
					}
				}
			},
			"MtaStsGenerateResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"kind": {
						"type": "string",
						"const": "mta-sts"
					},
					"dnsRecord": {
						"$ref": "#/components/schemas/GeneratedRecord"
					},
					"policyFile": {
						"type": "string",
						"description": "Content of mta-sts.txt"
					},
					"policyUrl": {
						"type": "string",
						"description": "Where the policy file must be served (HTTPS)"
					},
					"tlsRptRecord": {
						"$ref": "#/components/schemas/GeneratedRecord"
					},
					"warnings": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/IssueCode"
						}
					}
				}
			},
			"HeaderAnalysisResult": {
				"type": "object",
				"properties": {
					"api": {
						"type": "string",
						"const": "v1"
					},
					"hops": {
						"type": "array",
						"description": "Received hops, oldest first",
						"items": {
							"type": "object",
							"properties": {
								"index": {
									"type": "integer"
								},
								"from": {
									"type": "string"
								},
								"by": {
									"type": "string"
								},
								"with": {
									"type": "string"
								},
								"date": {
									"type": "string"
								},
								"timestamp": {
									"type": "integer",
									"description": "Milliseconds since epoch, when parsable"
								},
								"deltaSec": {
									"type": "integer",
									"description": "Seconds since the previous hop"
								}
							}
						}
					},
					"auth": {
						"type": "object",
						"description": "Results from the first Authentication-Results header",
						"properties": {
							"spf": {
								"type": "string"
							},
							"dkim": {
								"type": "string"
							},
							"dmarc": {
								"type": "string"
							},
							"dmarcHeaderFrom": {
								"type": "string"
							},
							"raw": {
								"type": "string"
							}
						}
					},
					"fields": {
						"type": "object",
						"properties": {
							"from": {
								"type": "string"
							},
							"returnPath": {
								"type": "string"
							},
							"replyTo": {
								"type": "string"
							},
							"messageId": {
								"type": "string"
							},
							"subject": {
								"type": "string"
							},
							"date": {
								"type": "string"
							}
						}
					},
					"alignment": {
						"type": "object",
						"properties": {
							"fromDomain": {
								"type": "string"
							},
							"returnPathDomain": {
								"type": "string"
							},
							"dmarcFromDomain": {
								"type": "string"
							},
							"aligned": {
								"type": "boolean"
							}
						}
					}
				}
			}
		}
	}
}