{
  "openapi": "3.1.0",
  "info": {
    "title": "Remove LLM Watermark API",
    "version": "1.0.0",
    "description": "Detect and remove hidden watermark characters in text. Character-level marks (zero-width code points, variation selectors, homoglyphs, exotic spaces) are removed exactly. Statistical watermarks, which live in the model's word choices rather than in the characters, cannot be removed by this or any cleaner; responses say so in `caveats`.",
    "contact": {
      "url": "https://removellmwatermark.com"
    }
  },
  "servers": [
    {
      "url": "https://api.removellmwatermark.com"
    }
  ],
  "security": [
    {},
    {
      "apiKey": []
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Optional. Raises the limits. See https://removellmwatermark.com/auth.md."
      }
    },
    "schemas": {
      "Finding": {
        "type": "object",
        "properties": {
          "technique": {
            "type": "string",
            "enum": [
              "zero-width",
              "variation-selector",
              "homoglyph",
              "nbsp",
              "punctuation",
              "whitespace"
            ]
          },
          "name": {
            "type": "string",
            "description": "Unicode name, e.g. ZERO WIDTH SPACE."
          },
          "codePoint": {
            "type": "string",
            "example": "U+200B"
          },
          "count": {
            "type": "integer"
          },
          "removed": {
            "type": "boolean",
            "description": "False when the character was kept because it carries meaning in context."
          }
        }
      }
    }
  },
  "paths": {
    "/v1/clean": {
      "post": {
        "summary": "Clean text and report what was removed",
        "operationId": "cleanText",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "text"
                ],
                "properties": {
                  "text": {
                    "type": "string",
                    "maxLength": 200000
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "zeroWidth": {
                        "type": "boolean",
                        "default": true
                      },
                      "variationSelectors": {
                        "type": "boolean",
                        "default": true
                      },
                      "homoglyphs": {
                        "type": "boolean",
                        "default": true
                      },
                      "spaces": {
                        "type": "boolean",
                        "default": true
                      },
                      "punctuation": {
                        "type": "boolean",
                        "default": false
                      },
                      "whitespace": {
                        "type": "boolean",
                        "default": false
                      }
                    }
                  },
                  "model": {
                    "type": "string",
                    "description": "Optional hint, e.g. claude/opus-5. Analytics only."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cleaned text and report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "integer"
                        },
                        "replaced": {
                          "type": "integer"
                        },
                        "suspicion": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 100
                        },
                        "verdict": {
                          "type": "string"
                        },
                        "findings": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Finding"
                          }
                        },
                        "caveats": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Daily quota exhausted or feature not on plan"
          },
          "429": {
            "description": "Rate limited"
          }
        }
      }
    },
    "/v1/detect": {
      "post": {
        "summary": "Report hidden characters without modifying the text",
        "operationId": "detectWatermark",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "text"
                ],
                "properties": {
                  "text": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Report only, no rewritten text"
          }
        }
      }
    },
    "/v1/limits": {
      "get": {
        "summary": "What the caller may do right now",
        "operationId": "getLimits",
        "responses": {
          "200": {
            "description": "Plan and limits for the current caller"
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Service status",
        "operationId": "health",
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    }
  }
}