{
  "openapi": "3.1.0",
  "info": {
    "title": "Rexity Website-Check",
    "version": "1.0.0",
    "summary": "Checks one public website and returns a short result for six areas: speed, findability, readiness for enquiries, trust, security settings and e-mail domain protection. The full result with every check is on the page.",
    "description": "Free check of a publicly reachable website by Rexity Labs. One GET request runs the check (up to about a minute) or returns the result of the last 24 hours. The answer is a short version: an overall score (0–100) with a band, the scores of six areas (Speed & technology, Findability, Readiness for enquiries, Trust & legal, Website security settings, E-mail domain protection), one verdict line per area, the number of checks per state, a short verdict, the checked address and time, and an attribution block. The single checks with their measured values are not part of this interface; the full result is shown free of charge on https://www.rexity.ai/website-check. Terms of use (https://www.rexity.ai/website-check/nutzung): free for individual checks by people and their assistants, with the source \"Rexity Labs Website-Check\" and a link to https://www.rexity.ai/website-check; no bulk use, no resale, no building of a competing checking service on it; contact info@rexity.ai for other uses. It states what was measured and what that means, and contains no recommendations. The areas on security settings and e-mail domain protection are built only from what every browser and public DNS receive anyway (response headers, cookies and HTML of the page, the http address of the same host, one TLS handshake on port 443, the file security.txt, the DNS records MX, SPF, DMARC and CAA): Settings visible from outside, checked without interfering with the website; not a security audit and no warranty. A report by e-mail (the full result; where the lookup is active also the Google position and backlink figures) can be requested on https://www.rexity.ai/website-check for a confirmed address only, not through this interface. No key is needed. Quotas for fresh checks, currently: 5 per IP address and day, 200 per hour and 1000 per day for all callers together; in addition 30 requests per IP address in 10 minutes (cached results included). A reached quota answers 429 with Retry-After and says when it is restored. The same check is available as an MCP tool at https://www.rexity.ai/mcp. The checker identifies itself as RexityWebsiteCheck/1.0 (+https://www.rexity.ai/website-check/bot).",
    "termsOfService": "https://www.rexity.ai/website-check/nutzung",
    "contact": {
      "name": "Rexity Labs UG (haftungsbeschränkt)",
      "email": "info@rexity.ai",
      "url": "https://www.rexity.ai/"
    }
  },
  "servers": [
    {
      "url": "https://www.rexity.ai"
    }
  ],
  "externalDocs": {
    "description": "The tool for people, with the scoring rule",
    "url": "https://www.rexity.ai/website-check"
  },
  "paths": {
    "/api/check": {
      "get": {
        "operationId": "checkWebsite",
        "summary": "Check a website (scores, verdict lines and counts)",
        "description": "Runs the check for one address or returns the cached result. JSON by default; Markdown with format=md or the header Accept: text/markdown. Errors are always JSON.",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Address of the website, with or without https://. Public http/https websites on standard ports only; IP addresses and internal host names are refused.",
            "schema": {
              "type": "string",
              "maxLength": 500
            },
            "example": "www.example.de"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language of the texts in the result",
            "schema": {
              "type": "string",
              "enum": [
                "de",
                "en"
              ],
              "default": "de"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "json (default) or md (Markdown)",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "md"
              ],
              "default": "json"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Result"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "description": "The same short result as Markdown, with the source and the link to the full result"
                }
              }
            }
          },
          "400": {
            "description": "The parameter url is missing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The address cannot be checked: not a valid public web address (bad_url, bad_scheme, bad_port, private_host), not found (dns), or its owner opted out (optout)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A limit is reached: rate (too many requests in a short time), quota_ip (fresh checks of this IP address today), quota_hour (fresh checks of all callers this hour) or quota_day (fresh checks of all callers today). With format=md a quota is answered as Markdown.",
            "headers": {
              "Retry-After": {
                "description": "Seconds until a new attempt makes sense",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "The check failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Result": {
        "type": "object",
        "required": [
          "ok",
          "tier",
          "lang",
          "url",
          "finalUrl",
          "host",
          "checkedAt",
          "cached",
          "overall",
          "blocks",
          "attribution",
          "full",
          "links"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "tier": {
            "type": "string",
            "const": "compact",
            "description": "The short version for assistants and programs: scores, one verdict line and the counts per area, the short verdict. The single checks with their measured values are shown on the page only (full.url). (Report format 5 returned every check here, marked \"full\".)"
          },
          "v": {
            "type": "integer",
            "description": "Version of the report format"
          },
          "lang": {
            "type": "string",
            "enum": [
              "de",
              "en"
            ]
          },
          "url": {
            "type": "string",
            "description": "The address as checked"
          },
          "finalUrl": {
            "type": "string",
            "description": "The address after redirects"
          },
          "host": {
            "type": "string",
            "description": "Host name of the checked site"
          },
          "checkedAt": {
            "type": "string",
            "description": "Time of the check (ISO 8601, UTC)",
            "format": "date-time"
          },
          "cached": {
            "type": "boolean",
            "description": "true: a result of the last 24 hours (no new check was run)"
          },
          "overall": {
            "type": "object",
            "required": [
              "score",
              "blocksUsed"
            ],
            "properties": {
              "score": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "maximum": 100,
                "description": "Weighted mean of the areas that have a score; null when no area could be checked"
              },
              "band": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "good",
                  "mid",
                  "low",
                  null
                ]
              },
              "bandLabel": {
                "type": "string",
                "description": "The band in the requested language"
              },
              "blocksUsed": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "tempo",
                    "find",
                    "contact",
                    "trust",
                    "security",
                    "mail"
                  ]
                },
                "description": "The areas that went into the overall score"
              }
            }
          },
          "blocks": {
            "type": "object",
            "required": [
              "tempo",
              "find",
              "contact",
              "trust",
              "security",
              "mail"
            ],
            "properties": {
              "tempo": {
                "$ref": "#/components/schemas/Block"
              },
              "find": {
                "$ref": "#/components/schemas/Block"
              },
              "contact": {
                "$ref": "#/components/schemas/Block"
              },
              "trust": {
                "$ref": "#/components/schemas/Block"
              },
              "security": {
                "$ref": "#/components/schemas/Block"
              },
              "mail": {
                "$ref": "#/components/schemas/Block"
              }
            }
          },
          "summary": {
            "type": [
              "object",
              "null"
            ],
            "description": "Short verdict: overall score, strongest and weakest area, the open check with the most weight (named by its label, as a plain statement), how speed was measured. No advice.",
            "properties": {
              "sentences": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "source": {
                "type": "string",
                "enum": [
                  "rules",
                  "model"
                ],
                "description": "rules: fixed text; model: worded by an AI from the scores and the open checks"
              }
            }
          },
          "statusLabels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "The words for the states of counts in the requested language"
          },
          "attribution": {
            "type": "object",
            "description": "The source to name, with its link, whenever the result is passed on. Required by the terms of use.",
            "required": [
              "source",
              "url",
              "terms"
            ],
            "properties": {
              "source": {
                "type": "string",
                "const": "Rexity Labs Website-Check"
              },
              "url": {
                "type": "string",
                "const": "https://www.rexity.ai/website-check"
              },
              "terms": {
                "type": "string",
                "const": "https://www.rexity.ai/website-check/nutzung",
                "description": "The terms of use of this interface"
              }
            }
          },
          "full": {
            "type": "object",
            "description": "Where the full result is: the page shows every single check with its measured value, free of charge",
            "properties": {
              "note": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "links": {
            "type": "object",
            "description": "Related addresses",
            "properties": {
              "page": {
                "type": "string"
              },
              "bot": {
                "type": "string"
              },
              "openapi": {
                "type": "string"
              },
              "mcp": {
                "type": "string"
              },
              "terms": {
                "type": "string"
              }
            }
          }
        }
      },
      "Block": {
        "type": "object",
        "required": [
          "name",
          "checked",
          "score",
          "weight",
          "counts"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the area in the requested language"
          },
          "checked": {
            "type": "boolean",
            "description": "false: the area could not be checked; score is null and reason says why"
          },
          "score": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Points of the area, 0 to 100"
          },
          "band": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "good",
              "mid",
              "low",
              null
            ],
            "description": "good from 80 points, mid from 50, low below"
          },
          "bandLabel": {
            "type": "string",
            "description": "The band in the requested language"
          },
          "weight": {
            "type": "integer",
            "description": "Share of the area in the overall score, in percent"
          },
          "verdict": {
            "type": "string",
            "description": "One plain sentence on the area"
          },
          "reason": {
            "type": "string",
            "description": "Why the area could not be checked or does not apply (only when checked is false)"
          },
          "notApplicable": {
            "type": "boolean",
            "description": "true: the area does not apply to this site (e-mail domain protection for a site under a provider's shared address)"
          },
          "counts": {
            "type": "object",
            "description": "How many checks of the area ended in which state. The single checks are not part of this interface: they are on the page (full.url).",
            "required": [
              "ok",
              "partial",
              "fail",
              "info",
              "unknown",
              "na",
              "total"
            ],
            "properties": {
              "ok": {
                "type": "integer",
                "description": "met"
              },
              "partial": {
                "type": "integer",
                "description": "partly met"
              },
              "fail": {
                "type": "integer",
                "description": "open"
              },
              "info": {
                "type": "integer",
                "description": "notes (shown, never scored)"
              },
              "unknown": {
                "type": "integer",
                "description": "could not be checked"
              },
              "na": {
                "type": "integer",
                "description": "does not apply to this page"
              },
              "total": {
                "type": "integer",
                "description": "all checks of the area"
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "error",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "description": "Error code",
            "enum": [
              "bad_url",
              "bad_scheme",
              "bad_port",
              "private_host",
              "optout",
              "dns",
              "rate",
              "quota_ip",
              "quota_hour",
              "quota_day",
              "server"
            ]
          },
          "message": {
            "type": "string",
            "description": "A plain sentence in the requested language"
          },
          "links": {
            "type": "object"
          }
        }
      }
    }
  }
}
