{
    "openapi": "3.1.0",
    "info": {
        "title": "whois.me.uk API",
        "version": "1.0",
        "description": "Domain, DNS, mail-authentication, web/TLS and reputation checks. Every result uses one envelope: normalised data plus Findings (pass/caution/fail/note/skipped) with stable codes that link to fix guides at /learn/fix/{code}. Results are cached for ten minutes per target.",
        "contact": {
            "email": "support@theemailshop.co.uk"
        },
        "termsOfService": "https://whois.me.uk/legal/terms"
    },
    "servers": [
        {
            "url": "https://whois.me.uk/api/v1"
        }
    ],
    "security": [
        {
            "bearer": []
        },
        {
            "apiKey": []
        }
    ],
    "paths": {
        "/me": {
            "get": {
                "summary": "Key, plan and remaining allowance",
                "responses": {
                    "200": {
                        "description": "Key details"
                    }
                }
            }
        },
        "/lookup": {
            "get": {
                "summary": "Lookup bar: quick verbs and auto-detection",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "mx bbc.co.uk"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    },
                    {
                        "name": "raw",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Include the raw source data."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Result for the detected facet",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/whois/{domain}": {
            "get": {
                "summary": "Registry record (RDAP first, port-43 in raw)",
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Registrable domain",
                        "example": "bbc.co.uk"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    },
                    {
                        "name": "raw",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Include the raw source data."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Registry result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/dns/{domain}": {
            "get": {
                "summary": "DNS records with nameserver consistency checks",
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Any host name",
                        "example": "www.bbc.co.uk"
                    },
                    {
                        "name": "resolver",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Query this resolver IP instead of ours"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    },
                    {
                        "name": "raw",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Include the raw source data."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "DNS result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/mail/{domain}": {
            "get": {
                "summary": "MX, SPF, DKIM, DMARC, MTA-STS, TLS-RPT, BIMI and a live SMTP test",
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Registrable domain",
                        "example": "gmail.com"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    },
                    {
                        "name": "raw",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Include the raw source data."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Mail result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/web/{host}": {
            "get": {
                "summary": "HTTP/HTTPS, redirects, TLS certificate and protocols, security headers, ping and traceroute",
                "parameters": [
                    {
                        "name": "host",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Host name",
                        "example": "whois.me.uk"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    },
                    {
                        "name": "raw",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Include the raw source data."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Web result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ip/{target}": {
            "get": {
                "summary": "IP or AS ownership, reverse DNS and blocklist scan (a domain scans the addresses behind it)",
                "parameters": [
                    {
                        "name": "target",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "IP address, ASn or domain",
                        "example": "8.8.8.8"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    },
                    {
                        "name": "raw",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Include the raw source data."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reputation result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/checkup/{domain}": {
            "get": {
                "summary": "Domain Check-up: every facet merged into one report",
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Registrable domain",
                        "example": "bbc.co.uk"
                    },
                    {
                        "name": "fresh",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Bypass the 10-minute cache. Costs 3 calls instead of 1."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Check-up result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing or invalid key",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid target",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Daily allowance (X-Quota-*) or per-second rate (X-RateLimit-*) exceeded; Retry-After is set",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Upstream registry, resolver or probe failed; the envelope carries error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Result"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/watches": {
            "get": {
                "summary": "List your watches",
                "responses": {
                    "200": {
                        "description": "Watches"
                    }
                }
            },
            "post": {
                "summary": "Create a watch (same rules and plan limits as the dashboard)",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WatchInput"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created"
                    },
                    "422": {
                        "description": "Validation failed: errors keyed by field"
                    }
                }
            }
        },
        "/watches/{id}": {
            "get": {
                "summary": "One watch with recent checks and incidents",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Watch"
                    },
                    "404": {
                        "description": "Not yours or missing"
                    }
                }
            },
            "delete": {
                "summary": "Delete a watch and its history",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted"
                    },
                    "404": {
                        "description": "Not yours or missing"
                    }
                }
            }
        },
        "/watches/{id}/pause": {
            "post": {
                "summary": "Pause a watch",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paused"
                    }
                }
            }
        },
        "/watches/{id}/resume": {
            "post": {
                "summary": "Resume a paused watch (runs within a minute)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resumed"
                    }
                }
            }
        },
        "/watches/{id}/check": {
            "post": {
                "summary": "Queue a check now (at most once a minute)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Queued"
                    },
                    "409": {
                        "description": "Paused"
                    },
                    "429": {
                        "description": "Checked less than a minute ago"
                    }
                }
            }
        },
        "/dmarc/{domain}": {
            "get": {
                "summary": "DMARC aggregate report summary for a domain you have verified: sources, alignment, dispositions, daily series, findings",
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "A verified domain (subdomain reports roll up to it)",
                        "example": "example.co.uk"
                    },
                    {
                        "name": "days",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "enum": [
                                7,
                                30,
                                90,
                                365
                            ],
                            "default": 30
                        },
                        "description": "Period; the longer ones need the plan history to cover them"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Summary"
                    },
                    "404": {
                        "description": "Not a verified domain on this account"
                    },
                    "422": {
                        "description": "Period not allowed on this plan"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer",
                "description": "Authorization: Bearer wm_live_\u2026"
            },
            "apiKey": {
                "type": "apiKey",
                "in": "header",
                "name": "X-Api-Key"
            }
        },
        "schemas": {
            "Result": {
                "type": "object",
                "properties": {
                    "engine": {
                        "type": "string"
                    },
                    "target": {
                        "type": "string"
                    },
                    "checked_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "cached": {
                        "type": "boolean"
                    },
                    "duration_ms": {
                        "type": "integer"
                    },
                    "error": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "score": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 100
                    },
                    "counts": {
                        "type": "object",
                        "properties": {
                            "pass": {
                                "type": "integer"
                            },
                            "caution": {
                                "type": "integer"
                            },
                            "fail": {
                                "type": "integer"
                            },
                            "note": {
                                "type": "integer"
                            },
                            "skipped": {
                                "type": "integer"
                            }
                        }
                    },
                    "data": {
                        "type": "object",
                        "description": "Engine-specific normalised data (see the facet pages for field meanings)."
                    },
                    "findings": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Finding"
                        }
                    },
                    "raw": {
                        "type": "object",
                        "description": "Source data (registry text, RDAP JSON); only present with raw=1."
                    }
                }
            },
            "Finding": {
                "type": "object",
                "properties": {
                    "level": {
                        "type": "string",
                        "enum": [
                            "pass",
                            "caution",
                            "fail",
                            "note",
                            "skipped"
                        ]
                    },
                    "code": {
                        "type": "string",
                        "example": "SPF-LOOKUPS-EXCEEDED"
                    },
                    "title": {
                        "type": "string"
                    },
                    "detail": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "fix": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "facet": {
                        "type": "string"
                    }
                }
            },
            "Error": {
                "type": "object",
                "properties": {
                    "error": {
                        "type": "string"
                    },
                    "message": {
                        "type": "string"
                    }
                }
            },
            "WatchInput": {
                "type": "object",
                "required": [
                    "kind",
                    "target"
                ],
                "properties": {
                    "kind": {
                        "type": "string",
                        "enum": [
                            "http",
                            "tcp",
                            "ping",
                            "dns",
                            "smtp",
                            "tls_expiry",
                            "domain_expiry",
                            "dns_change",
                            "blocklist"
                        ]
                    },
                    "target": {
                        "type": "string",
                        "example": "www.example.co.uk"
                    },
                    "label": {
                        "type": "string"
                    },
                    "port": {
                        "type": "integer",
                        "description": "tcp only"
                    },
                    "expect_status": {
                        "type": "integer",
                        "description": "http only"
                    },
                    "type": {
                        "type": "string",
                        "description": "dns only, record type"
                    },
                    "expect": {
                        "type": "string",
                        "description": "dns only, answer must contain"
                    },
                    "channels": {
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "description": "alert channel ids from your account"
                    }
                }
            }
        }
    }
}